diff options
| -rw-r--r-- | drivers/net/r8169.c | 102 |
1 files changed, 59 insertions, 43 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 6e1018448eea..999fd6cef77e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -287,6 +287,12 @@ 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 | /* Config5 register p.27 */ | ||
| 294 | PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ | ||
| 295 | |||
| 290 | /* TBICSR p.28 */ | 296 | /* TBICSR p.28 */ |
| 291 | TBIReset = 0x80000000, | 297 | TBIReset = 0x80000000, |
| 292 | TBILoopback = 0x40000000, | 298 | TBILoopback = 0x40000000, |
| @@ -1442,6 +1448,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out, | |||
| 1442 | } | 1448 | } |
| 1443 | tp->chipset = i; | 1449 | tp->chipset = i; |
| 1444 | 1450 | ||
| 1451 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
| 1452 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | ||
| 1453 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); | ||
| 1454 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
| 1455 | |||
| 1445 | *ioaddr_out = ioaddr; | 1456 | *ioaddr_out = ioaddr; |
| 1446 | *dev_out = dev; | 1457 | *dev_out = dev; |
| 1447 | out: | 1458 | out: |
| @@ -1612,49 +1623,6 @@ rtl8169_remove_one(struct pci_dev *pdev) | |||
| 1612 | pci_set_drvdata(pdev, NULL); | 1623 | pci_set_drvdata(pdev, NULL); |
| 1613 | } | 1624 | } |
| 1614 | 1625 | ||
| 1615 | #ifdef CONFIG_PM | ||
| 1616 | |||
| 1617 | static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 1618 | { | ||
| 1619 | struct net_device *dev = pci_get_drvdata(pdev); | ||
| 1620 | struct rtl8169_private *tp = netdev_priv(dev); | ||
| 1621 | void __iomem *ioaddr = tp->mmio_addr; | ||
| 1622 | unsigned long flags; | ||
| 1623 | |||
| 1624 | if (!netif_running(dev)) | ||
| 1625 | return 0; | ||
| 1626 | |||
| 1627 | netif_device_detach(dev); | ||
| 1628 | netif_stop_queue(dev); | ||
| 1629 | spin_lock_irqsave(&tp->lock, flags); | ||
| 1630 | |||
| 1631 | /* Disable interrupts, stop Rx and Tx */ | ||
| 1632 | RTL_W16(IntrMask, 0); | ||
| 1633 | RTL_W8(ChipCmd, 0); | ||
| 1634 | |||
| 1635 | /* Update the error counts. */ | ||
| 1636 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | ||
| 1637 | RTL_W32(RxMissed, 0); | ||
| 1638 | spin_unlock_irqrestore(&tp->lock, flags); | ||
| 1639 | |||
| 1640 | return 0; | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | static int rtl8169_resume(struct pci_dev *pdev) | ||
| 1644 | { | ||
| 1645 | struct net_device *dev = pci_get_drvdata(pdev); | ||
| 1646 | |||
| 1647 | if (!netif_running(dev)) | ||
| 1648 | return 0; | ||
| 1649 | |||
| 1650 | netif_device_attach(dev); | ||
| 1651 | rtl8169_hw_start(dev); | ||
| 1652 | |||
| 1653 | return 0; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | #endif /* CONFIG_PM */ | ||
| 1657 | |||
| 1658 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, | 1626 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, |
| 1659 | struct net_device *dev) | 1627 | struct net_device *dev) |
| 1660 | { | 1628 | { |
| @@ -2700,6 +2668,54 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | |||
| 2700 | return &tp->stats; | 2668 | return &tp->stats; |
| 2701 | } | 2669 | } |
| 2702 | 2670 | ||
| 2671 | #ifdef CONFIG_PM | ||
| 2672 | |||
| 2673 | static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 2674 | { | ||
| 2675 | struct net_device *dev = pci_get_drvdata(pdev); | ||
| 2676 | struct rtl8169_private *tp = netdev_priv(dev); | ||
| 2677 | void __iomem *ioaddr = tp->mmio_addr; | ||
| 2678 | |||
| 2679 | if (!netif_running(dev)) | ||
| 2680 | goto out; | ||
| 2681 | |||
| 2682 | netif_device_detach(dev); | ||
| 2683 | netif_stop_queue(dev); | ||
| 2684 | |||
| 2685 | spin_lock_irq(&tp->lock); | ||
| 2686 | |||
| 2687 | rtl8169_asic_down(ioaddr); | ||
| 2688 | |||
| 2689 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | ||
| 2690 | RTL_W32(RxMissed, 0); | ||
| 2691 | |||
| 2692 | spin_unlock_irq(&tp->lock); | ||
| 2693 | |||
| 2694 | pci_save_state(pdev); | ||
| 2695 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 2696 | out: | ||
| 2697 | return 0; | ||
| 2698 | } | ||
| 2699 | |||
| 2700 | static int rtl8169_resume(struct pci_dev *pdev) | ||
| 2701 | { | ||
| 2702 | struct net_device *dev = pci_get_drvdata(pdev); | ||
| 2703 | |||
| 2704 | if (!netif_running(dev)) | ||
| 2705 | goto out; | ||
| 2706 | |||
| 2707 | netif_device_attach(dev); | ||
| 2708 | |||
| 2709 | pci_set_power_state(pdev, PCI_D0); | ||
| 2710 | pci_restore_state(pdev); | ||
| 2711 | |||
| 2712 | rtl8169_schedule_work(dev, rtl8169_reset_task); | ||
| 2713 | out: | ||
| 2714 | return 0; | ||
| 2715 | } | ||
| 2716 | |||
| 2717 | #endif /* CONFIG_PM */ | ||
| 2718 | |||
| 2703 | static struct pci_driver rtl8169_pci_driver = { | 2719 | static struct pci_driver rtl8169_pci_driver = { |
| 2704 | .name = MODULENAME, | 2720 | .name = MODULENAME, |
| 2705 | .id_table = rtl8169_pci_tbl, | 2721 | .id_table = rtl8169_pci_tbl, |
