aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/r8169.c152
1 files changed, 125 insertions, 27 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 9d3ebf3e975e..964305c7f9f1 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -23,6 +23,7 @@
23#include <linux/tcp.h> 23#include <linux/tcp.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/pm_runtime.h>
26 27
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/io.h> 29#include <asm/io.h>
@@ -504,6 +505,7 @@ struct rtl8169_private {
504 505
505 struct mii_if_info mii; 506 struct mii_if_info mii;
506 struct rtl8169_counters counters; 507 struct rtl8169_counters counters;
508 u32 saved_wolopts;
507}; 509};
508 510
509MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 511MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -744,53 +746,61 @@ static void rtl8169_check_link_status(struct net_device *dev,
744 746
745 spin_lock_irqsave(&tp->lock, flags); 747 spin_lock_irqsave(&tp->lock, flags);
746 if (tp->link_ok(ioaddr)) { 748 if (tp->link_ok(ioaddr)) {
749 /* This is to cancel a scheduled suspend if there's one. */
750 pm_request_resume(&tp->pci_dev->dev);
747 netif_carrier_on(dev); 751 netif_carrier_on(dev);
748 netif_info(tp, ifup, dev, "link up\n"); 752 netif_info(tp, ifup, dev, "link up\n");
749 } else { 753 } else {
750 netif_carrier_off(dev); 754 netif_carrier_off(dev);
751 netif_info(tp, ifdown, dev, "link down\n"); 755 netif_info(tp, ifdown, dev, "link down\n");
756 pm_schedule_suspend(&tp->pci_dev->dev, 100);
752 } 757 }
753 spin_unlock_irqrestore(&tp->lock, flags); 758 spin_unlock_irqrestore(&tp->lock, flags);
754} 759}
755 760
756static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 761#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
762
763static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
757{ 764{
758 struct rtl8169_private *tp = netdev_priv(dev);
759 void __iomem *ioaddr = tp->mmio_addr; 765 void __iomem *ioaddr = tp->mmio_addr;
760 u8 options; 766 u8 options;
761 767 u32 wolopts = 0;
762 wol->wolopts = 0;
763
764#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
765 wol->supported = WAKE_ANY;
766
767 spin_lock_irq(&tp->lock);
768 768
769 options = RTL_R8(Config1); 769 options = RTL_R8(Config1);
770 if (!(options & PMEnable)) 770 if (!(options & PMEnable))
771 goto out_unlock; 771 return 0;
772 772
773 options = RTL_R8(Config3); 773 options = RTL_R8(Config3);
774 if (options & LinkUp) 774 if (options & LinkUp)
775 wol->wolopts |= WAKE_PHY; 775 wolopts |= WAKE_PHY;
776 if (options & MagicPacket) 776 if (options & MagicPacket)
777 wol->wolopts |= WAKE_MAGIC; 777 wolopts |= WAKE_MAGIC;
778 778
779 options = RTL_R8(Config5); 779 options = RTL_R8(Config5);
780 if (options & UWF) 780 if (options & UWF)
781 wol->wolopts |= WAKE_UCAST; 781 wolopts |= WAKE_UCAST;
782 if (options & BWF) 782 if (options & BWF)
783 wol->wolopts |= WAKE_BCAST; 783 wolopts |= WAKE_BCAST;
784 if (options & MWF) 784 if (options & MWF)
785 wol->wolopts |= WAKE_MCAST; 785 wolopts |= WAKE_MCAST;
786 786
787out_unlock: 787 return wolopts;
788 spin_unlock_irq(&tp->lock);
789} 788}
790 789
791static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 790static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
792{ 791{
793 struct rtl8169_private *tp = netdev_priv(dev); 792 struct rtl8169_private *tp = netdev_priv(dev);
793
794 spin_lock_irq(&tp->lock);
795
796 wol->supported = WAKE_ANY;
797 wol->wolopts = __rtl8169_get_wol(tp);
798
799 spin_unlock_irq(&tp->lock);
800}
801
802static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
803{
794 void __iomem *ioaddr = tp->mmio_addr; 804 void __iomem *ioaddr = tp->mmio_addr;
795 unsigned int i; 805 unsigned int i;
796 static const struct { 806 static const struct {
@@ -807,23 +817,29 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
807 { WAKE_ANY, Config5, LanWake } 817 { WAKE_ANY, Config5, LanWake }
808 }; 818 };
809 819
810 spin_lock_irq(&tp->lock);
811
812 RTL_W8(Cfg9346, Cfg9346_Unlock); 820 RTL_W8(Cfg9346, Cfg9346_Unlock);
813 821
814 for (i = 0; i < ARRAY_SIZE(cfg); i++) { 822 for (i = 0; i < ARRAY_SIZE(cfg); i++) {
815 u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; 823 u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
816 if (wol->wolopts & cfg[i].opt) 824 if (wolopts & cfg[i].opt)
817 options |= cfg[i].mask; 825 options |= cfg[i].mask;
818 RTL_W8(cfg[i].reg, options); 826 RTL_W8(cfg[i].reg, options);
819 } 827 }
820 828
821 RTL_W8(Cfg9346, Cfg9346_Lock); 829 RTL_W8(Cfg9346, Cfg9346_Lock);
830}
831
832static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
833{
834 struct rtl8169_private *tp = netdev_priv(dev);
835
836 spin_lock_irq(&tp->lock);
822 837
823 if (wol->wolopts) 838 if (wol->wolopts)
824 tp->features |= RTL_FEATURE_WOL; 839 tp->features |= RTL_FEATURE_WOL;
825 else 840 else
826 tp->features &= ~RTL_FEATURE_WOL; 841 tp->features &= ~RTL_FEATURE_WOL;
842 __rtl8169_set_wol(tp, wol->wolopts);
827 device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); 843 device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts);
828 844
829 spin_unlock_irq(&tp->lock); 845 spin_unlock_irq(&tp->lock);
@@ -3189,6 +3205,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3189 3205
3190 device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); 3206 device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
3191 3207
3208 if (pci_dev_run_wake(pdev)) {
3209 pm_runtime_set_active(&pdev->dev);
3210 pm_runtime_enable(&pdev->dev);
3211 }
3212 pm_runtime_idle(&pdev->dev);
3213
3192out: 3214out:
3193 return rc; 3215 return rc;
3194 3216
@@ -3211,10 +3233,18 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
3211 struct net_device *dev = pci_get_drvdata(pdev); 3233 struct net_device *dev = pci_get_drvdata(pdev);
3212 struct rtl8169_private *tp = netdev_priv(dev); 3234 struct rtl8169_private *tp = netdev_priv(dev);
3213 3235
3236 pm_runtime_get_sync(&pdev->dev);
3237
3214 flush_scheduled_work(); 3238 flush_scheduled_work();
3215 3239
3216 unregister_netdev(dev); 3240 unregister_netdev(dev);
3217 3241
3242 if (pci_dev_run_wake(pdev)) {
3243 pm_runtime_disable(&pdev->dev);
3244 pm_runtime_set_suspended(&pdev->dev);
3245 }
3246 pm_runtime_put_noidle(&pdev->dev);
3247
3218 /* restore original MAC address */ 3248 /* restore original MAC address */
3219 rtl_rar_set(tp, dev->perm_addr); 3249 rtl_rar_set(tp, dev->perm_addr);
3220 3250
@@ -3237,6 +3267,7 @@ static int rtl8169_open(struct net_device *dev)
3237 struct pci_dev *pdev = tp->pci_dev; 3267 struct pci_dev *pdev = tp->pci_dev;
3238 int retval = -ENOMEM; 3268 int retval = -ENOMEM;
3239 3269
3270 pm_runtime_get_sync(&pdev->dev);
3240 3271
3241 rtl8169_set_rxbufsize(tp, dev); 3272 rtl8169_set_rxbufsize(tp, dev);
3242 3273
@@ -3247,7 +3278,7 @@ static int rtl8169_open(struct net_device *dev)
3247 tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, 3278 tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
3248 &tp->TxPhyAddr); 3279 &tp->TxPhyAddr);
3249 if (!tp->TxDescArray) 3280 if (!tp->TxDescArray)
3250 goto out; 3281 goto err_pm_runtime_put;
3251 3282
3252 tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, 3283 tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
3253 &tp->RxPhyAddr); 3284 &tp->RxPhyAddr);
@@ -3274,6 +3305,9 @@ static int rtl8169_open(struct net_device *dev)
3274 3305
3275 rtl8169_request_timer(dev); 3306 rtl8169_request_timer(dev);
3276 3307
3308 tp->saved_wolopts = 0;
3309 pm_runtime_put_noidle(&pdev->dev);
3310
3277 rtl8169_check_link_status(dev, tp, tp->mmio_addr); 3311 rtl8169_check_link_status(dev, tp, tp->mmio_addr);
3278out: 3312out:
3279 return retval; 3313 return retval;
@@ -3283,9 +3317,13 @@ err_release_ring_2:
3283err_free_rx_1: 3317err_free_rx_1:
3284 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, 3318 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
3285 tp->RxPhyAddr); 3319 tp->RxPhyAddr);
3320 tp->RxDescArray = NULL;
3286err_free_tx_0: 3321err_free_tx_0:
3287 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, 3322 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
3288 tp->TxPhyAddr); 3323 tp->TxPhyAddr);
3324 tp->TxDescArray = NULL;
3325err_pm_runtime_put:
3326 pm_runtime_put_noidle(&pdev->dev);
3289 goto out; 3327 goto out;
3290} 3328}
3291 3329
@@ -4692,6 +4730,8 @@ static int rtl8169_close(struct net_device *dev)
4692 struct rtl8169_private *tp = netdev_priv(dev); 4730 struct rtl8169_private *tp = netdev_priv(dev);
4693 struct pci_dev *pdev = tp->pci_dev; 4731 struct pci_dev *pdev = tp->pci_dev;
4694 4732
4733 pm_runtime_get_sync(&pdev->dev);
4734
4695 /* update counters before going down */ 4735 /* update counters before going down */
4696 rtl8169_update_counters(dev); 4736 rtl8169_update_counters(dev);
4697 4737
@@ -4706,6 +4746,8 @@ static int rtl8169_close(struct net_device *dev)
4706 tp->TxDescArray = NULL; 4746 tp->TxDescArray = NULL;
4707 tp->RxDescArray = NULL; 4747 tp->RxDescArray = NULL;
4708 4748
4749 pm_runtime_put_sync(&pdev->dev);
4750
4709 return 0; 4751 return 0;
4710} 4752}
4711 4753
@@ -4804,21 +4846,74 @@ static int rtl8169_suspend(struct device *device)
4804 return 0; 4846 return 0;
4805} 4847}
4806 4848
4849static void __rtl8169_resume(struct net_device *dev)
4850{
4851 netif_device_attach(dev);
4852 rtl8169_schedule_work(dev, rtl8169_reset_task);
4853}
4854
4807static int rtl8169_resume(struct device *device) 4855static int rtl8169_resume(struct device *device)
4808{ 4856{
4809 struct pci_dev *pdev = to_pci_dev(device); 4857 struct pci_dev *pdev = to_pci_dev(device);
4810 struct net_device *dev = pci_get_drvdata(pdev); 4858 struct net_device *dev = pci_get_drvdata(pdev);
4811 4859
4812 if (!netif_running(dev)) 4860 if (netif_running(dev))
4813 goto out; 4861 __rtl8169_resume(dev);
4814 4862
4815 netif_device_attach(dev); 4863 return 0;
4864}
4865
4866static int rtl8169_runtime_suspend(struct device *device)
4867{
4868 struct pci_dev *pdev = to_pci_dev(device);
4869 struct net_device *dev = pci_get_drvdata(pdev);
4870 struct rtl8169_private *tp = netdev_priv(dev);
4871
4872 if (!tp->TxDescArray)
4873 return 0;
4874
4875 spin_lock_irq(&tp->lock);
4876 tp->saved_wolopts = __rtl8169_get_wol(tp);
4877 __rtl8169_set_wol(tp, WAKE_ANY);
4878 spin_unlock_irq(&tp->lock);
4879
4880 rtl8169_net_suspend(dev);
4881
4882 return 0;
4883}
4884
4885static int rtl8169_runtime_resume(struct device *device)
4886{
4887 struct pci_dev *pdev = to_pci_dev(device);
4888 struct net_device *dev = pci_get_drvdata(pdev);
4889 struct rtl8169_private *tp = netdev_priv(dev);
4890
4891 if (!tp->TxDescArray)
4892 return 0;
4893
4894 spin_lock_irq(&tp->lock);
4895 __rtl8169_set_wol(tp, tp->saved_wolopts);
4896 tp->saved_wolopts = 0;
4897 spin_unlock_irq(&tp->lock);
4898
4899 __rtl8169_resume(dev);
4816 4900
4817 rtl8169_schedule_work(dev, rtl8169_reset_task);
4818out:
4819 return 0; 4901 return 0;
4820} 4902}
4821 4903
4904static int rtl8169_runtime_idle(struct device *device)
4905{
4906 struct pci_dev *pdev = to_pci_dev(device);
4907 struct net_device *dev = pci_get_drvdata(pdev);
4908 struct rtl8169_private *tp = netdev_priv(dev);
4909
4910 if (!tp->TxDescArray)
4911 return 0;
4912
4913 rtl8169_check_link_status(dev, tp, tp->mmio_addr);
4914 return -EBUSY;
4915}
4916
4822static const struct dev_pm_ops rtl8169_pm_ops = { 4917static const struct dev_pm_ops rtl8169_pm_ops = {
4823 .suspend = rtl8169_suspend, 4918 .suspend = rtl8169_suspend,
4824 .resume = rtl8169_resume, 4919 .resume = rtl8169_resume,
@@ -4826,6 +4921,9 @@ static const struct dev_pm_ops rtl8169_pm_ops = {
4826 .thaw = rtl8169_resume, 4921 .thaw = rtl8169_resume,
4827 .poweroff = rtl8169_suspend, 4922 .poweroff = rtl8169_suspend,
4828 .restore = rtl8169_resume, 4923 .restore = rtl8169_resume,
4924 .runtime_suspend = rtl8169_runtime_suspend,
4925 .runtime_resume = rtl8169_runtime_resume,
4926 .runtime_idle = rtl8169_runtime_idle,
4829}; 4927};
4830 4928
4831#define RTL8169_PM_OPS (&rtl8169_pm_ops) 4929#define RTL8169_PM_OPS (&rtl8169_pm_ops)