diff options
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 212 |
1 files changed, 163 insertions, 49 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index dbb1f5a1824c..217e709bda3e 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> |
@@ -509,6 +510,7 @@ struct rtl8169_private { | |||
509 | 510 | ||
510 | struct mii_if_info mii; | 511 | struct mii_if_info mii; |
511 | struct rtl8169_counters counters; | 512 | struct rtl8169_counters counters; |
513 | u32 saved_wolopts; | ||
512 | }; | 514 | }; |
513 | 515 | ||
514 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 516 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -748,53 +750,61 @@ static void rtl8169_check_link_status(struct net_device *dev, | |||
748 | 750 | ||
749 | spin_lock_irqsave(&tp->lock, flags); | 751 | spin_lock_irqsave(&tp->lock, flags); |
750 | if (tp->link_ok(ioaddr)) { | 752 | if (tp->link_ok(ioaddr)) { |
753 | /* This is to cancel a scheduled suspend if there's one. */ | ||
754 | pm_request_resume(&tp->pci_dev->dev); | ||
751 | netif_carrier_on(dev); | 755 | netif_carrier_on(dev); |
752 | netif_info(tp, ifup, dev, "link up\n"); | 756 | netif_info(tp, ifup, dev, "link up\n"); |
753 | } else { | 757 | } else { |
754 | netif_carrier_off(dev); | 758 | netif_carrier_off(dev); |
755 | netif_info(tp, ifdown, dev, "link down\n"); | 759 | netif_info(tp, ifdown, dev, "link down\n"); |
760 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | ||
756 | } | 761 | } |
757 | spin_unlock_irqrestore(&tp->lock, flags); | 762 | spin_unlock_irqrestore(&tp->lock, flags); |
758 | } | 763 | } |
759 | 764 | ||
760 | static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 765 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) |
766 | |||
767 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) | ||
761 | { | 768 | { |
762 | struct rtl8169_private *tp = netdev_priv(dev); | ||
763 | void __iomem *ioaddr = tp->mmio_addr; | 769 | void __iomem *ioaddr = tp->mmio_addr; |
764 | u8 options; | 770 | u8 options; |
765 | 771 | u32 wolopts = 0; | |
766 | wol->wolopts = 0; | ||
767 | |||
768 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | ||
769 | wol->supported = WAKE_ANY; | ||
770 | |||
771 | spin_lock_irq(&tp->lock); | ||
772 | 772 | ||
773 | options = RTL_R8(Config1); | 773 | options = RTL_R8(Config1); |
774 | if (!(options & PMEnable)) | 774 | if (!(options & PMEnable)) |
775 | goto out_unlock; | 775 | return 0; |
776 | 776 | ||
777 | options = RTL_R8(Config3); | 777 | options = RTL_R8(Config3); |
778 | if (options & LinkUp) | 778 | if (options & LinkUp) |
779 | wol->wolopts |= WAKE_PHY; | 779 | wolopts |= WAKE_PHY; |
780 | if (options & MagicPacket) | 780 | if (options & MagicPacket) |
781 | wol->wolopts |= WAKE_MAGIC; | 781 | wolopts |= WAKE_MAGIC; |
782 | 782 | ||
783 | options = RTL_R8(Config5); | 783 | options = RTL_R8(Config5); |
784 | if (options & UWF) | 784 | if (options & UWF) |
785 | wol->wolopts |= WAKE_UCAST; | 785 | wolopts |= WAKE_UCAST; |
786 | if (options & BWF) | 786 | if (options & BWF) |
787 | wol->wolopts |= WAKE_BCAST; | 787 | wolopts |= WAKE_BCAST; |
788 | if (options & MWF) | 788 | if (options & MWF) |
789 | wol->wolopts |= WAKE_MCAST; | 789 | wolopts |= WAKE_MCAST; |
790 | 790 | ||
791 | out_unlock: | 791 | return wolopts; |
792 | spin_unlock_irq(&tp->lock); | ||
793 | } | 792 | } |
794 | 793 | ||
795 | static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 794 | static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
796 | { | 795 | { |
797 | struct rtl8169_private *tp = netdev_priv(dev); | 796 | struct rtl8169_private *tp = netdev_priv(dev); |
797 | |||
798 | spin_lock_irq(&tp->lock); | ||
799 | |||
800 | wol->supported = WAKE_ANY; | ||
801 | wol->wolopts = __rtl8169_get_wol(tp); | ||
802 | |||
803 | spin_unlock_irq(&tp->lock); | ||
804 | } | ||
805 | |||
806 | static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) | ||
807 | { | ||
798 | void __iomem *ioaddr = tp->mmio_addr; | 808 | void __iomem *ioaddr = tp->mmio_addr; |
799 | unsigned int i; | 809 | unsigned int i; |
800 | static const struct { | 810 | static const struct { |
@@ -811,23 +821,29 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
811 | { WAKE_ANY, Config5, LanWake } | 821 | { WAKE_ANY, Config5, LanWake } |
812 | }; | 822 | }; |
813 | 823 | ||
814 | spin_lock_irq(&tp->lock); | ||
815 | |||
816 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 824 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
817 | 825 | ||
818 | for (i = 0; i < ARRAY_SIZE(cfg); i++) { | 826 | for (i = 0; i < ARRAY_SIZE(cfg); i++) { |
819 | u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; | 827 | u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; |
820 | if (wol->wolopts & cfg[i].opt) | 828 | if (wolopts & cfg[i].opt) |
821 | options |= cfg[i].mask; | 829 | options |= cfg[i].mask; |
822 | RTL_W8(cfg[i].reg, options); | 830 | RTL_W8(cfg[i].reg, options); |
823 | } | 831 | } |
824 | 832 | ||
825 | RTL_W8(Cfg9346, Cfg9346_Lock); | 833 | RTL_W8(Cfg9346, Cfg9346_Lock); |
834 | } | ||
835 | |||
836 | static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
837 | { | ||
838 | struct rtl8169_private *tp = netdev_priv(dev); | ||
839 | |||
840 | spin_lock_irq(&tp->lock); | ||
826 | 841 | ||
827 | if (wol->wolopts) | 842 | if (wol->wolopts) |
828 | tp->features |= RTL_FEATURE_WOL; | 843 | tp->features |= RTL_FEATURE_WOL; |
829 | else | 844 | else |
830 | tp->features &= ~RTL_FEATURE_WOL; | 845 | tp->features &= ~RTL_FEATURE_WOL; |
846 | __rtl8169_set_wol(tp, wol->wolopts); | ||
831 | device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); | 847 | device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); |
832 | 848 | ||
833 | spin_unlock_irq(&tp->lock); | 849 | spin_unlock_irq(&tp->lock); |
@@ -1042,14 +1058,14 @@ static void rtl8169_vlan_rx_register(struct net_device *dev, | |||
1042 | } | 1058 | } |
1043 | 1059 | ||
1044 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, | 1060 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, |
1045 | struct sk_buff *skb) | 1061 | struct sk_buff *skb, int polling) |
1046 | { | 1062 | { |
1047 | u32 opts2 = le32_to_cpu(desc->opts2); | 1063 | u32 opts2 = le32_to_cpu(desc->opts2); |
1048 | struct vlan_group *vlgrp = tp->vlgrp; | 1064 | struct vlan_group *vlgrp = tp->vlgrp; |
1049 | int ret; | 1065 | int ret; |
1050 | 1066 | ||
1051 | if (vlgrp && (opts2 & RxVlanTag)) { | 1067 | if (vlgrp && (opts2 & RxVlanTag)) { |
1052 | vlan_hwaccel_receive_skb(skb, vlgrp, swab16(opts2 & 0xffff)); | 1068 | __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling); |
1053 | ret = 0; | 1069 | ret = 0; |
1054 | } else | 1070 | } else |
1055 | ret = -1; | 1071 | ret = -1; |
@@ -1066,7 +1082,7 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, | |||
1066 | } | 1082 | } |
1067 | 1083 | ||
1068 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, | 1084 | static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, |
1069 | struct sk_buff *skb) | 1085 | struct sk_buff *skb, int polling) |
1070 | { | 1086 | { |
1071 | return -1; | 1087 | return -1; |
1072 | } | 1088 | } |
@@ -2759,6 +2775,7 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, | |||
2759 | { | 2775 | { |
2760 | iounmap(ioaddr); | 2776 | iounmap(ioaddr); |
2761 | pci_release_regions(pdev); | 2777 | pci_release_regions(pdev); |
2778 | pci_clear_mwi(pdev); | ||
2762 | pci_disable_device(pdev); | 2779 | pci_disable_device(pdev); |
2763 | free_netdev(dev); | 2780 | free_netdev(dev); |
2764 | } | 2781 | } |
@@ -2825,8 +2842,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) | |||
2825 | spin_lock_irq(&tp->lock); | 2842 | spin_lock_irq(&tp->lock); |
2826 | 2843 | ||
2827 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 2844 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
2845 | |||
2828 | RTL_W32(MAC4, high); | 2846 | RTL_W32(MAC4, high); |
2847 | RTL_R32(MAC4); | ||
2848 | |||
2829 | RTL_W32(MAC0, low); | 2849 | RTL_W32(MAC0, low); |
2850 | RTL_R32(MAC0); | ||
2851 | |||
2830 | RTL_W8(Cfg9346, Cfg9346_Lock); | 2852 | RTL_W8(Cfg9346, Cfg9346_Lock); |
2831 | 2853 | ||
2832 | spin_unlock_irq(&tp->lock); | 2854 | spin_unlock_irq(&tp->lock); |
@@ -3014,9 +3036,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3014 | goto err_out_free_dev_1; | 3036 | goto err_out_free_dev_1; |
3015 | } | 3037 | } |
3016 | 3038 | ||
3017 | rc = pci_set_mwi(pdev); | 3039 | if (pci_set_mwi(pdev) < 0) |
3018 | if (rc < 0) | 3040 | netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n"); |
3019 | goto err_out_disable_2; | ||
3020 | 3041 | ||
3021 | /* make sure PCI base addr 1 is MMIO */ | 3042 | /* make sure PCI base addr 1 is MMIO */ |
3022 | if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { | 3043 | if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { |
@@ -3024,7 +3045,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3024 | "region #%d not an MMIO resource, aborting\n", | 3045 | "region #%d not an MMIO resource, aborting\n", |
3025 | region); | 3046 | region); |
3026 | rc = -ENODEV; | 3047 | rc = -ENODEV; |
3027 | goto err_out_mwi_3; | 3048 | goto err_out_mwi_2; |
3028 | } | 3049 | } |
3029 | 3050 | ||
3030 | /* check for weird/broken PCI region reporting */ | 3051 | /* check for weird/broken PCI region reporting */ |
@@ -3032,13 +3053,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3032 | netif_err(tp, probe, dev, | 3053 | netif_err(tp, probe, dev, |
3033 | "Invalid PCI region size(s), aborting\n"); | 3054 | "Invalid PCI region size(s), aborting\n"); |
3034 | rc = -ENODEV; | 3055 | rc = -ENODEV; |
3035 | goto err_out_mwi_3; | 3056 | goto err_out_mwi_2; |
3036 | } | 3057 | } |
3037 | 3058 | ||
3038 | rc = pci_request_regions(pdev, MODULENAME); | 3059 | rc = pci_request_regions(pdev, MODULENAME); |
3039 | if (rc < 0) { | 3060 | if (rc < 0) { |
3040 | netif_err(tp, probe, dev, "could not request regions\n"); | 3061 | netif_err(tp, probe, dev, "could not request regions\n"); |
3041 | goto err_out_mwi_3; | 3062 | goto err_out_mwi_2; |
3042 | } | 3063 | } |
3043 | 3064 | ||
3044 | tp->cp_cmd = PCIMulRW | RxChkSum; | 3065 | tp->cp_cmd = PCIMulRW | RxChkSum; |
@@ -3051,7 +3072,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3051 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 3072 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
3052 | if (rc < 0) { | 3073 | if (rc < 0) { |
3053 | netif_err(tp, probe, dev, "DMA configuration failed\n"); | 3074 | netif_err(tp, probe, dev, "DMA configuration failed\n"); |
3054 | goto err_out_free_res_4; | 3075 | goto err_out_free_res_3; |
3055 | } | 3076 | } |
3056 | } | 3077 | } |
3057 | 3078 | ||
@@ -3060,7 +3081,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3060 | if (!ioaddr) { | 3081 | if (!ioaddr) { |
3061 | netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n"); | 3082 | netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n"); |
3062 | rc = -EIO; | 3083 | rc = -EIO; |
3063 | goto err_out_free_res_4; | 3084 | goto err_out_free_res_3; |
3064 | } | 3085 | } |
3065 | 3086 | ||
3066 | tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 3087 | tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); |
@@ -3102,7 +3123,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3102 | if (i == ARRAY_SIZE(rtl_chip_info)) { | 3123 | if (i == ARRAY_SIZE(rtl_chip_info)) { |
3103 | dev_err(&pdev->dev, | 3124 | dev_err(&pdev->dev, |
3104 | "driver bug, MAC version not found in rtl_chip_info\n"); | 3125 | "driver bug, MAC version not found in rtl_chip_info\n"); |
3105 | goto err_out_msi_5; | 3126 | goto err_out_msi_4; |
3106 | } | 3127 | } |
3107 | tp->chipset = i; | 3128 | tp->chipset = i; |
3108 | 3129 | ||
@@ -3167,7 +3188,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3167 | 3188 | ||
3168 | rc = register_netdev(dev); | 3189 | rc = register_netdev(dev); |
3169 | if (rc < 0) | 3190 | if (rc < 0) |
3170 | goto err_out_msi_5; | 3191 | goto err_out_msi_4; |
3171 | 3192 | ||
3172 | pci_set_drvdata(pdev, dev); | 3193 | pci_set_drvdata(pdev, dev); |
3173 | 3194 | ||
@@ -3187,17 +3208,22 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3187 | 3208 | ||
3188 | device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); | 3209 | device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); |
3189 | 3210 | ||
3211 | if (pci_dev_run_wake(pdev)) { | ||
3212 | pm_runtime_set_active(&pdev->dev); | ||
3213 | pm_runtime_enable(&pdev->dev); | ||
3214 | } | ||
3215 | pm_runtime_idle(&pdev->dev); | ||
3216 | |||
3190 | out: | 3217 | out: |
3191 | return rc; | 3218 | return rc; |
3192 | 3219 | ||
3193 | err_out_msi_5: | 3220 | err_out_msi_4: |
3194 | rtl_disable_msi(pdev, tp); | 3221 | rtl_disable_msi(pdev, tp); |
3195 | iounmap(ioaddr); | 3222 | iounmap(ioaddr); |
3196 | err_out_free_res_4: | 3223 | err_out_free_res_3: |
3197 | pci_release_regions(pdev); | 3224 | pci_release_regions(pdev); |
3198 | err_out_mwi_3: | 3225 | err_out_mwi_2: |
3199 | pci_clear_mwi(pdev); | 3226 | pci_clear_mwi(pdev); |
3200 | err_out_disable_2: | ||
3201 | pci_disable_device(pdev); | 3227 | pci_disable_device(pdev); |
3202 | err_out_free_dev_1: | 3228 | err_out_free_dev_1: |
3203 | free_netdev(dev); | 3229 | free_netdev(dev); |
@@ -3209,10 +3235,18 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3209 | struct net_device *dev = pci_get_drvdata(pdev); | 3235 | struct net_device *dev = pci_get_drvdata(pdev); |
3210 | struct rtl8169_private *tp = netdev_priv(dev); | 3236 | struct rtl8169_private *tp = netdev_priv(dev); |
3211 | 3237 | ||
3238 | pm_runtime_get_sync(&pdev->dev); | ||
3239 | |||
3212 | flush_scheduled_work(); | 3240 | flush_scheduled_work(); |
3213 | 3241 | ||
3214 | unregister_netdev(dev); | 3242 | unregister_netdev(dev); |
3215 | 3243 | ||
3244 | if (pci_dev_run_wake(pdev)) { | ||
3245 | pm_runtime_disable(&pdev->dev); | ||
3246 | pm_runtime_set_suspended(&pdev->dev); | ||
3247 | } | ||
3248 | pm_runtime_put_noidle(&pdev->dev); | ||
3249 | |||
3216 | /* restore original MAC address */ | 3250 | /* restore original MAC address */ |
3217 | rtl_rar_set(tp, dev->perm_addr); | 3251 | rtl_rar_set(tp, dev->perm_addr); |
3218 | 3252 | ||
@@ -3239,6 +3273,7 @@ static int rtl8169_open(struct net_device *dev) | |||
3239 | struct pci_dev *pdev = tp->pci_dev; | 3273 | struct pci_dev *pdev = tp->pci_dev; |
3240 | int retval = -ENOMEM; | 3274 | int retval = -ENOMEM; |
3241 | 3275 | ||
3276 | pm_runtime_get_sync(&pdev->dev); | ||
3242 | 3277 | ||
3243 | /* | 3278 | /* |
3244 | * Note that we use a magic value here, its wierd I know | 3279 | * Note that we use a magic value here, its wierd I know |
@@ -3259,7 +3294,7 @@ static int rtl8169_open(struct net_device *dev) | |||
3259 | tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, | 3294 | tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, |
3260 | &tp->TxPhyAddr); | 3295 | &tp->TxPhyAddr); |
3261 | if (!tp->TxDescArray) | 3296 | if (!tp->TxDescArray) |
3262 | goto out; | 3297 | goto err_pm_runtime_put; |
3263 | 3298 | ||
3264 | tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, | 3299 | tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, |
3265 | &tp->RxPhyAddr); | 3300 | &tp->RxPhyAddr); |
@@ -3286,6 +3321,9 @@ static int rtl8169_open(struct net_device *dev) | |||
3286 | 3321 | ||
3287 | rtl8169_request_timer(dev); | 3322 | rtl8169_request_timer(dev); |
3288 | 3323 | ||
3324 | tp->saved_wolopts = 0; | ||
3325 | pm_runtime_put_noidle(&pdev->dev); | ||
3326 | |||
3289 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | 3327 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); |
3290 | out: | 3328 | out: |
3291 | return retval; | 3329 | return retval; |
@@ -3295,9 +3333,13 @@ err_release_ring_2: | |||
3295 | err_free_rx_1: | 3333 | err_free_rx_1: |
3296 | pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, | 3334 | pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, |
3297 | tp->RxPhyAddr); | 3335 | tp->RxPhyAddr); |
3336 | tp->RxDescArray = NULL; | ||
3298 | err_free_tx_0: | 3337 | err_free_tx_0: |
3299 | pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, | 3338 | pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, |
3300 | tp->TxPhyAddr); | 3339 | tp->TxPhyAddr); |
3340 | tp->TxDescArray = NULL; | ||
3341 | err_pm_runtime_put: | ||
3342 | pm_runtime_put_noidle(&pdev->dev); | ||
3301 | goto out; | 3343 | goto out; |
3302 | } | 3344 | } |
3303 | 3345 | ||
@@ -4441,12 +4483,20 @@ out: | |||
4441 | return done; | 4483 | return done; |
4442 | } | 4484 | } |
4443 | 4485 | ||
4486 | /* | ||
4487 | * Warning : rtl8169_rx_interrupt() might be called : | ||
4488 | * 1) from NAPI (softirq) context | ||
4489 | * (polling = 1 : we should call netif_receive_skb()) | ||
4490 | * 2) from process context (rtl8169_reset_task()) | ||
4491 | * (polling = 0 : we must call netif_rx() instead) | ||
4492 | */ | ||
4444 | static int rtl8169_rx_interrupt(struct net_device *dev, | 4493 | static int rtl8169_rx_interrupt(struct net_device *dev, |
4445 | struct rtl8169_private *tp, | 4494 | struct rtl8169_private *tp, |
4446 | void __iomem *ioaddr, u32 budget) | 4495 | void __iomem *ioaddr, u32 budget) |
4447 | { | 4496 | { |
4448 | unsigned int cur_rx, rx_left; | 4497 | unsigned int cur_rx, rx_left; |
4449 | unsigned int delta, count; | 4498 | unsigned int delta, count; |
4499 | int polling = (budget != ~(u32)0) ? 1 : 0; | ||
4450 | 4500 | ||
4451 | cur_rx = tp->cur_rx; | 4501 | cur_rx = tp->cur_rx; |
4452 | rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; | 4502 | rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; |
@@ -4508,8 +4558,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
4508 | skb_put(skb, pkt_size); | 4558 | skb_put(skb, pkt_size); |
4509 | skb->protocol = eth_type_trans(skb, dev); | 4559 | skb->protocol = eth_type_trans(skb, dev); |
4510 | 4560 | ||
4511 | if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0) | 4561 | if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) { |
4512 | netif_receive_skb(skb); | 4562 | if (likely(polling)) |
4563 | netif_receive_skb(skb); | ||
4564 | else | ||
4565 | netif_rx(skb); | ||
4566 | } | ||
4513 | 4567 | ||
4514 | dev->stats.rx_bytes += pkt_size; | 4568 | dev->stats.rx_bytes += pkt_size; |
4515 | dev->stats.rx_packets++; | 4569 | dev->stats.rx_packets++; |
@@ -4704,6 +4758,8 @@ static int rtl8169_close(struct net_device *dev) | |||
4704 | struct rtl8169_private *tp = netdev_priv(dev); | 4758 | struct rtl8169_private *tp = netdev_priv(dev); |
4705 | struct pci_dev *pdev = tp->pci_dev; | 4759 | struct pci_dev *pdev = tp->pci_dev; |
4706 | 4760 | ||
4761 | pm_runtime_get_sync(&pdev->dev); | ||
4762 | |||
4707 | /* update counters before going down */ | 4763 | /* update counters before going down */ |
4708 | rtl8169_update_counters(dev); | 4764 | rtl8169_update_counters(dev); |
4709 | 4765 | ||
@@ -4718,6 +4774,8 @@ static int rtl8169_close(struct net_device *dev) | |||
4718 | tp->TxDescArray = NULL; | 4774 | tp->TxDescArray = NULL; |
4719 | tp->RxDescArray = NULL; | 4775 | tp->RxDescArray = NULL; |
4720 | 4776 | ||
4777 | pm_runtime_put_sync(&pdev->dev); | ||
4778 | |||
4721 | return 0; | 4779 | return 0; |
4722 | } | 4780 | } |
4723 | 4781 | ||
@@ -4743,12 +4801,12 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
4743 | rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; | 4801 | rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; |
4744 | mc_filter[1] = mc_filter[0] = 0xffffffff; | 4802 | mc_filter[1] = mc_filter[0] = 0xffffffff; |
4745 | } else { | 4803 | } else { |
4746 | struct dev_mc_list *mclist; | 4804 | struct netdev_hw_addr *ha; |
4747 | 4805 | ||
4748 | rx_mode = AcceptBroadcast | AcceptMyPhys; | 4806 | rx_mode = AcceptBroadcast | AcceptMyPhys; |
4749 | mc_filter[1] = mc_filter[0] = 0; | 4807 | mc_filter[1] = mc_filter[0] = 0; |
4750 | netdev_for_each_mc_addr(mclist, dev) { | 4808 | netdev_for_each_mc_addr(ha, dev) { |
4751 | int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; | 4809 | int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; |
4752 | mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); | 4810 | mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); |
4753 | rx_mode |= AcceptMulticast; | 4811 | rx_mode |= AcceptMulticast; |
4754 | } | 4812 | } |
@@ -4816,21 +4874,74 @@ static int rtl8169_suspend(struct device *device) | |||
4816 | return 0; | 4874 | return 0; |
4817 | } | 4875 | } |
4818 | 4876 | ||
4877 | static void __rtl8169_resume(struct net_device *dev) | ||
4878 | { | ||
4879 | netif_device_attach(dev); | ||
4880 | rtl8169_schedule_work(dev, rtl8169_reset_task); | ||
4881 | } | ||
4882 | |||
4819 | static int rtl8169_resume(struct device *device) | 4883 | static int rtl8169_resume(struct device *device) |
4820 | { | 4884 | { |
4821 | struct pci_dev *pdev = to_pci_dev(device); | 4885 | struct pci_dev *pdev = to_pci_dev(device); |
4822 | struct net_device *dev = pci_get_drvdata(pdev); | 4886 | struct net_device *dev = pci_get_drvdata(pdev); |
4823 | 4887 | ||
4824 | if (!netif_running(dev)) | 4888 | if (netif_running(dev)) |
4825 | goto out; | 4889 | __rtl8169_resume(dev); |
4826 | 4890 | ||
4827 | netif_device_attach(dev); | 4891 | return 0; |
4892 | } | ||
4893 | |||
4894 | static int rtl8169_runtime_suspend(struct device *device) | ||
4895 | { | ||
4896 | struct pci_dev *pdev = to_pci_dev(device); | ||
4897 | struct net_device *dev = pci_get_drvdata(pdev); | ||
4898 | struct rtl8169_private *tp = netdev_priv(dev); | ||
4899 | |||
4900 | if (!tp->TxDescArray) | ||
4901 | return 0; | ||
4902 | |||
4903 | spin_lock_irq(&tp->lock); | ||
4904 | tp->saved_wolopts = __rtl8169_get_wol(tp); | ||
4905 | __rtl8169_set_wol(tp, WAKE_ANY); | ||
4906 | spin_unlock_irq(&tp->lock); | ||
4907 | |||
4908 | rtl8169_net_suspend(dev); | ||
4828 | 4909 | ||
4829 | rtl8169_schedule_work(dev, rtl8169_reset_task); | ||
4830 | out: | ||
4831 | return 0; | 4910 | return 0; |
4832 | } | 4911 | } |
4833 | 4912 | ||
4913 | static int rtl8169_runtime_resume(struct device *device) | ||
4914 | { | ||
4915 | struct pci_dev *pdev = to_pci_dev(device); | ||
4916 | struct net_device *dev = pci_get_drvdata(pdev); | ||
4917 | struct rtl8169_private *tp = netdev_priv(dev); | ||
4918 | |||
4919 | if (!tp->TxDescArray) | ||
4920 | return 0; | ||
4921 | |||
4922 | spin_lock_irq(&tp->lock); | ||
4923 | __rtl8169_set_wol(tp, tp->saved_wolopts); | ||
4924 | tp->saved_wolopts = 0; | ||
4925 | spin_unlock_irq(&tp->lock); | ||
4926 | |||
4927 | __rtl8169_resume(dev); | ||
4928 | |||
4929 | return 0; | ||
4930 | } | ||
4931 | |||
4932 | static int rtl8169_runtime_idle(struct device *device) | ||
4933 | { | ||
4934 | struct pci_dev *pdev = to_pci_dev(device); | ||
4935 | struct net_device *dev = pci_get_drvdata(pdev); | ||
4936 | struct rtl8169_private *tp = netdev_priv(dev); | ||
4937 | |||
4938 | if (!tp->TxDescArray) | ||
4939 | return 0; | ||
4940 | |||
4941 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | ||
4942 | return -EBUSY; | ||
4943 | } | ||
4944 | |||
4834 | static const struct dev_pm_ops rtl8169_pm_ops = { | 4945 | static const struct dev_pm_ops rtl8169_pm_ops = { |
4835 | .suspend = rtl8169_suspend, | 4946 | .suspend = rtl8169_suspend, |
4836 | .resume = rtl8169_resume, | 4947 | .resume = rtl8169_resume, |
@@ -4838,6 +4949,9 @@ static const struct dev_pm_ops rtl8169_pm_ops = { | |||
4838 | .thaw = rtl8169_resume, | 4949 | .thaw = rtl8169_resume, |
4839 | .poweroff = rtl8169_suspend, | 4950 | .poweroff = rtl8169_suspend, |
4840 | .restore = rtl8169_resume, | 4951 | .restore = rtl8169_resume, |
4952 | .runtime_suspend = rtl8169_runtime_suspend, | ||
4953 | .runtime_resume = rtl8169_runtime_resume, | ||
4954 | .runtime_idle = rtl8169_runtime_idle, | ||
4841 | }; | 4955 | }; |
4842 | 4956 | ||
4843 | #define RTL8169_PM_OPS (&rtl8169_pm_ops) | 4957 | #define RTL8169_PM_OPS (&rtl8169_pm_ops) |