aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2006-03-14 18:05:45 -0500
committerDave Kleikamp <shaggy@austin.ibm.com>2006-03-14 18:05:45 -0500
commitc5111f504d2a9b0d258d7c4752b4093523315989 (patch)
tree6a52864aff79691689aea21cb0cb928327d5de5b /drivers/net/r8169.c
parent69eb66d7da7dba2696281981347698e1693c2340 (diff)
parenta488edc914aa1d766a4e2c982b5ae03d5657ec1b (diff)
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c202
1 files changed, 153 insertions, 49 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2e1bed153c39..8cc0d0bbdf50 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -287,6 +287,20 @@ enum RTL8169_register_content {
287 TxInterFrameGapShift = 24, 287 TxInterFrameGapShift = 24,
288 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 288 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
289 289
290 /* Config1 register p.24 */
291 PMEnable = (1 << 0), /* Power Management Enable */
292
293 /* Config3 register p.25 */
294 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
295 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
296
297 /* Config5 register p.27 */
298 BWF = (1 << 6), /* Accept Broadcast wakeup frame */
299 MWF = (1 << 5), /* Accept Multicast wakeup frame */
300 UWF = (1 << 4), /* Accept Unicast wakeup frame */
301 LanWake = (1 << 1), /* LanWake enable/disable */
302 PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
303
290 /* TBICSR p.28 */ 304 /* TBICSR p.28 */
291 TBIReset = 0x80000000, 305 TBIReset = 0x80000000,
292 TBILoopback = 0x40000000, 306 TBILoopback = 0x40000000,
@@ -433,6 +447,7 @@ struct rtl8169_private {
433 unsigned int (*phy_reset_pending)(void __iomem *); 447 unsigned int (*phy_reset_pending)(void __iomem *);
434 unsigned int (*link_ok)(void __iomem *); 448 unsigned int (*link_ok)(void __iomem *);
435 struct work_struct task; 449 struct work_struct task;
450 unsigned wol_enabled : 1;
436}; 451};
437 452
438MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 453MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -484,13 +499,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
484 int i; 499 int i;
485 500
486 RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); 501 RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
487 udelay(1000);
488 502
489 for (i = 2000; i > 0; i--) { 503 for (i = 20; i > 0; i--) {
490 /* Check if the RTL8169 has completed writing to the specified MII register */ 504 /* Check if the RTL8169 has completed writing to the specified MII register */
491 if (!(RTL_R32(PHYAR) & 0x80000000)) 505 if (!(RTL_R32(PHYAR) & 0x80000000))
492 break; 506 break;
493 udelay(100); 507 udelay(25);
494 } 508 }
495} 509}
496 510
@@ -499,15 +513,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr)
499 int i, value = -1; 513 int i, value = -1;
500 514
501 RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); 515 RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
502 udelay(1000);
503 516
504 for (i = 2000; i > 0; i--) { 517 for (i = 20; i > 0; i--) {
505 /* Check if the RTL8169 has completed retrieving data from the specified MII register */ 518 /* Check if the RTL8169 has completed retrieving data from the specified MII register */
506 if (RTL_R32(PHYAR) & 0x80000000) { 519 if (RTL_R32(PHYAR) & 0x80000000) {
507 value = (int) (RTL_R32(PHYAR) & 0xFFFF); 520 value = (int) (RTL_R32(PHYAR) & 0xFFFF);
508 break; 521 break;
509 } 522 }
510 udelay(100); 523 udelay(25);
511 } 524 }
512 return value; 525 return value;
513} 526}
@@ -609,6 +622,80 @@ static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
609 *duplex = p->duplex; 622 *duplex = p->duplex;
610} 623}
611 624
625static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
626{
627 struct rtl8169_private *tp = netdev_priv(dev);
628 void __iomem *ioaddr = tp->mmio_addr;
629 u8 options;
630
631 wol->wolopts = 0;
632
633#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
634 wol->supported = WAKE_ANY;
635
636 spin_lock_irq(&tp->lock);
637
638 options = RTL_R8(Config1);
639 if (!(options & PMEnable))
640 goto out_unlock;
641
642 options = RTL_R8(Config3);
643 if (options & LinkUp)
644 wol->wolopts |= WAKE_PHY;
645 if (options & MagicPacket)
646 wol->wolopts |= WAKE_MAGIC;
647
648 options = RTL_R8(Config5);
649 if (options & UWF)
650 wol->wolopts |= WAKE_UCAST;
651 if (options & BWF)
652 wol->wolopts |= WAKE_BCAST;
653 if (options & MWF)
654 wol->wolopts |= WAKE_MCAST;
655
656out_unlock:
657 spin_unlock_irq(&tp->lock);
658}
659
660static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
661{
662 struct rtl8169_private *tp = netdev_priv(dev);
663 void __iomem *ioaddr = tp->mmio_addr;
664 int i;
665 static struct {
666 u32 opt;
667 u16 reg;
668 u8 mask;
669 } cfg[] = {
670 { WAKE_ANY, Config1, PMEnable },
671 { WAKE_PHY, Config3, LinkUp },
672 { WAKE_MAGIC, Config3, MagicPacket },
673 { WAKE_UCAST, Config5, UWF },
674 { WAKE_BCAST, Config5, BWF },
675 { WAKE_MCAST, Config5, MWF },
676 { WAKE_ANY, Config5, LanWake }
677 };
678
679 spin_lock_irq(&tp->lock);
680
681 RTL_W8(Cfg9346, Cfg9346_Unlock);
682
683 for (i = 0; i < ARRAY_SIZE(cfg); i++) {
684 u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
685 if (wol->wolopts & cfg[i].opt)
686 options |= cfg[i].mask;
687 RTL_W8(cfg[i].reg, options);
688 }
689
690 RTL_W8(Cfg9346, Cfg9346_Lock);
691
692 tp->wol_enabled = (wol->wolopts) ? 1 : 0;
693
694 spin_unlock_irq(&tp->lock);
695
696 return 0;
697}
698
612static void rtl8169_get_drvinfo(struct net_device *dev, 699static void rtl8169_get_drvinfo(struct net_device *dev,
613 struct ethtool_drvinfo *info) 700 struct ethtool_drvinfo *info)
614{ 701{
@@ -677,6 +764,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
677 764
678 if (duplex == DUPLEX_HALF) 765 if (duplex == DUPLEX_HALF)
679 auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); 766 auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
767
768 if (duplex == DUPLEX_FULL)
769 auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
680 } 770 }
681 771
682 tp->phy_auto_nego_reg = auto_nego; 772 tp->phy_auto_nego_reg = auto_nego;
@@ -1024,6 +1114,8 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
1024 .get_tso = ethtool_op_get_tso, 1114 .get_tso = ethtool_op_get_tso,
1025 .set_tso = ethtool_op_set_tso, 1115 .set_tso = ethtool_op_set_tso,
1026 .get_regs = rtl8169_get_regs, 1116 .get_regs = rtl8169_get_regs,
1117 .get_wol = rtl8169_get_wol,
1118 .set_wol = rtl8169_set_wol,
1027 .get_strings = rtl8169_get_strings, 1119 .get_strings = rtl8169_get_strings,
1028 .get_stats_count = rtl8169_get_stats_count, 1120 .get_stats_count = rtl8169_get_stats_count,
1029 .get_ethtool_stats = rtl8169_get_ethtool_stats, 1121 .get_ethtool_stats = rtl8169_get_ethtool_stats,
@@ -1441,6 +1533,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
1441 } 1533 }
1442 tp->chipset = i; 1534 tp->chipset = i;
1443 1535
1536 RTL_W8(Cfg9346, Cfg9346_Unlock);
1537 RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
1538 RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
1539 RTL_W8(Cfg9346, Cfg9346_Lock);
1540
1444 *ioaddr_out = ioaddr; 1541 *ioaddr_out = ioaddr;
1445 *dev_out = dev; 1542 *dev_out = dev;
1446out: 1543out:
@@ -1611,49 +1708,6 @@ rtl8169_remove_one(struct pci_dev *pdev)
1611 pci_set_drvdata(pdev, NULL); 1708 pci_set_drvdata(pdev, NULL);
1612} 1709}
1613 1710
1614#ifdef CONFIG_PM
1615
1616static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
1617{
1618 struct net_device *dev = pci_get_drvdata(pdev);
1619 struct rtl8169_private *tp = netdev_priv(dev);
1620 void __iomem *ioaddr = tp->mmio_addr;
1621 unsigned long flags;
1622
1623 if (!netif_running(dev))
1624 return 0;
1625
1626 netif_device_detach(dev);
1627 netif_stop_queue(dev);
1628 spin_lock_irqsave(&tp->lock, flags);
1629
1630 /* Disable interrupts, stop Rx and Tx */
1631 RTL_W16(IntrMask, 0);
1632 RTL_W8(ChipCmd, 0);
1633
1634 /* Update the error counts. */
1635 tp->stats.rx_missed_errors += RTL_R32(RxMissed);
1636 RTL_W32(RxMissed, 0);
1637 spin_unlock_irqrestore(&tp->lock, flags);
1638
1639 return 0;
1640}
1641
1642static int rtl8169_resume(struct pci_dev *pdev)
1643{
1644 struct net_device *dev = pci_get_drvdata(pdev);
1645
1646 if (!netif_running(dev))
1647 return 0;
1648
1649 netif_device_attach(dev);
1650 rtl8169_hw_start(dev);
1651
1652 return 0;
1653}
1654
1655#endif /* CONFIG_PM */
1656
1657static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, 1711static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
1658 struct net_device *dev) 1712 struct net_device *dev)
1659{ 1713{
@@ -2699,6 +2753,56 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
2699 return &tp->stats; 2753 return &tp->stats;
2700} 2754}
2701 2755
2756#ifdef CONFIG_PM
2757
2758static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
2759{
2760 struct net_device *dev = pci_get_drvdata(pdev);
2761 struct rtl8169_private *tp = netdev_priv(dev);
2762 void __iomem *ioaddr = tp->mmio_addr;
2763
2764 if (!netif_running(dev))
2765 goto out;
2766
2767 netif_device_detach(dev);
2768 netif_stop_queue(dev);
2769
2770 spin_lock_irq(&tp->lock);
2771
2772 rtl8169_asic_down(ioaddr);
2773
2774 tp->stats.rx_missed_errors += RTL_R32(RxMissed);
2775 RTL_W32(RxMissed, 0);
2776
2777 spin_unlock_irq(&tp->lock);
2778
2779 pci_save_state(pdev);
2780 pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
2781 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2782out:
2783 return 0;
2784}
2785
2786static int rtl8169_resume(struct pci_dev *pdev)
2787{
2788 struct net_device *dev = pci_get_drvdata(pdev);
2789
2790 if (!netif_running(dev))
2791 goto out;
2792
2793 netif_device_attach(dev);
2794
2795 pci_set_power_state(pdev, PCI_D0);
2796 pci_restore_state(pdev);
2797 pci_enable_wake(pdev, PCI_D0, 0);
2798
2799 rtl8169_schedule_work(dev, rtl8169_reset_task);
2800out:
2801 return 0;
2802}
2803
2804#endif /* CONFIG_PM */
2805
2702static struct pci_driver rtl8169_pci_driver = { 2806static struct pci_driver rtl8169_pci_driver = {
2703 .name = MODULENAME, 2807 .name = MODULENAME,
2704 .id_table = rtl8169_pci_tbl, 2808 .id_table = rtl8169_pci_tbl,