diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-05-11 04:33:26 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-08-30 22:17:40 -0400 |
commit | 0ac1e8cee674d492d336355b99bf63c906f0a2e4 (patch) | |
tree | 2010e80820eb8847938169c4c94f820835e9757e /drivers/net/ethernet/intel | |
parent | 076d807024052a2c0d76050edd89cd94d0515684 (diff) |
ixgbevf: Add suspend and resume support to the VF
This change adds PCI suspend and resume support to ixgbevf.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 60ef64587412..87f87d81addb 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -1867,6 +1867,22 @@ err_set_interrupt: | |||
1867 | } | 1867 | } |
1868 | 1868 | ||
1869 | /** | 1869 | /** |
1870 | * ixgbevf_clear_interrupt_scheme - Clear the current interrupt scheme settings | ||
1871 | * @adapter: board private structure to clear interrupt scheme on | ||
1872 | * | ||
1873 | * We go through and clear interrupt specific resources and reset the structure | ||
1874 | * to pre-load conditions | ||
1875 | **/ | ||
1876 | static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter) | ||
1877 | { | ||
1878 | adapter->num_tx_queues = 0; | ||
1879 | adapter->num_rx_queues = 0; | ||
1880 | |||
1881 | ixgbevf_free_q_vectors(adapter); | ||
1882 | ixgbevf_reset_interrupt_capability(adapter); | ||
1883 | } | ||
1884 | |||
1885 | /** | ||
1870 | * ixgbevf_sw_init - Initialize general software structures | 1886 | * ixgbevf_sw_init - Initialize general software structures |
1871 | * (struct ixgbevf_adapter) | 1887 | * (struct ixgbevf_adapter) |
1872 | * @adapter: board private structure to initialize | 1888 | * @adapter: board private structure to initialize |
@@ -2889,23 +2905,85 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) | |||
2889 | return 0; | 2905 | return 0; |
2890 | } | 2906 | } |
2891 | 2907 | ||
2892 | static void ixgbevf_shutdown(struct pci_dev *pdev) | 2908 | static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state) |
2893 | { | 2909 | { |
2894 | struct net_device *netdev = pci_get_drvdata(pdev); | 2910 | struct net_device *netdev = pci_get_drvdata(pdev); |
2895 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 2911 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
2912 | #ifdef CONFIG_PM | ||
2913 | int retval = 0; | ||
2914 | #endif | ||
2896 | 2915 | ||
2897 | netif_device_detach(netdev); | 2916 | netif_device_detach(netdev); |
2898 | 2917 | ||
2899 | if (netif_running(netdev)) { | 2918 | if (netif_running(netdev)) { |
2919 | rtnl_lock(); | ||
2900 | ixgbevf_down(adapter); | 2920 | ixgbevf_down(adapter); |
2901 | ixgbevf_free_irq(adapter); | 2921 | ixgbevf_free_irq(adapter); |
2902 | ixgbevf_free_all_tx_resources(adapter); | 2922 | ixgbevf_free_all_tx_resources(adapter); |
2903 | ixgbevf_free_all_rx_resources(adapter); | 2923 | ixgbevf_free_all_rx_resources(adapter); |
2924 | rtnl_unlock(); | ||
2904 | } | 2925 | } |
2905 | 2926 | ||
2906 | pci_save_state(pdev); | 2927 | ixgbevf_clear_interrupt_scheme(adapter); |
2928 | |||
2929 | #ifdef CONFIG_PM | ||
2930 | retval = pci_save_state(pdev); | ||
2931 | if (retval) | ||
2932 | return retval; | ||
2907 | 2933 | ||
2934 | #endif | ||
2908 | pci_disable_device(pdev); | 2935 | pci_disable_device(pdev); |
2936 | |||
2937 | return 0; | ||
2938 | } | ||
2939 | |||
2940 | #ifdef CONFIG_PM | ||
2941 | static int ixgbevf_resume(struct pci_dev *pdev) | ||
2942 | { | ||
2943 | struct ixgbevf_adapter *adapter = pci_get_drvdata(pdev); | ||
2944 | struct net_device *netdev = adapter->netdev; | ||
2945 | u32 err; | ||
2946 | |||
2947 | pci_set_power_state(pdev, PCI_D0); | ||
2948 | pci_restore_state(pdev); | ||
2949 | /* | ||
2950 | * pci_restore_state clears dev->state_saved so call | ||
2951 | * pci_save_state to restore it. | ||
2952 | */ | ||
2953 | pci_save_state(pdev); | ||
2954 | |||
2955 | err = pci_enable_device_mem(pdev); | ||
2956 | if (err) { | ||
2957 | dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); | ||
2958 | return err; | ||
2959 | } | ||
2960 | pci_set_master(pdev); | ||
2961 | |||
2962 | rtnl_lock(); | ||
2963 | err = ixgbevf_init_interrupt_scheme(adapter); | ||
2964 | rtnl_unlock(); | ||
2965 | if (err) { | ||
2966 | dev_err(&pdev->dev, "Cannot initialize interrupts\n"); | ||
2967 | return err; | ||
2968 | } | ||
2969 | |||
2970 | ixgbevf_reset(adapter); | ||
2971 | |||
2972 | if (netif_running(netdev)) { | ||
2973 | err = ixgbevf_open(netdev); | ||
2974 | if (err) | ||
2975 | return err; | ||
2976 | } | ||
2977 | |||
2978 | netif_device_attach(netdev); | ||
2979 | |||
2980 | return err; | ||
2981 | } | ||
2982 | |||
2983 | #endif /* CONFIG_PM */ | ||
2984 | static void ixgbevf_shutdown(struct pci_dev *pdev) | ||
2985 | { | ||
2986 | ixgbevf_suspend(pdev, PMSG_SUSPEND); | ||
2909 | } | 2987 | } |
2910 | 2988 | ||
2911 | static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, | 2989 | static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, |
@@ -2946,7 +3024,7 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, | |||
2946 | return stats; | 3024 | return stats; |
2947 | } | 3025 | } |
2948 | 3026 | ||
2949 | static const struct net_device_ops ixgbe_netdev_ops = { | 3027 | static const struct net_device_ops ixgbevf_netdev_ops = { |
2950 | .ndo_open = ixgbevf_open, | 3028 | .ndo_open = ixgbevf_open, |
2951 | .ndo_stop = ixgbevf_close, | 3029 | .ndo_stop = ixgbevf_close, |
2952 | .ndo_start_xmit = ixgbevf_xmit_frame, | 3030 | .ndo_start_xmit = ixgbevf_xmit_frame, |
@@ -2962,7 +3040,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { | |||
2962 | 3040 | ||
2963 | static void ixgbevf_assign_netdev_ops(struct net_device *dev) | 3041 | static void ixgbevf_assign_netdev_ops(struct net_device *dev) |
2964 | { | 3042 | { |
2965 | dev->netdev_ops = &ixgbe_netdev_ops; | 3043 | dev->netdev_ops = &ixgbevf_netdev_ops; |
2966 | ixgbevf_set_ethtool_ops(dev); | 3044 | ixgbevf_set_ethtool_ops(dev); |
2967 | dev->watchdog_timeo = 5 * HZ; | 3045 | dev->watchdog_timeo = 5 * HZ; |
2968 | } | 3046 | } |
@@ -3131,6 +3209,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, | |||
3131 | return 0; | 3209 | return 0; |
3132 | 3210 | ||
3133 | err_register: | 3211 | err_register: |
3212 | ixgbevf_clear_interrupt_scheme(adapter); | ||
3134 | err_sw_init: | 3213 | err_sw_init: |
3135 | ixgbevf_reset_interrupt_capability(adapter); | 3214 | ixgbevf_reset_interrupt_capability(adapter); |
3136 | iounmap(hw->hw_addr); | 3215 | iounmap(hw->hw_addr); |
@@ -3168,6 +3247,7 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev) | |||
3168 | if (netdev->reg_state == NETREG_REGISTERED) | 3247 | if (netdev->reg_state == NETREG_REGISTERED) |
3169 | unregister_netdev(netdev); | 3248 | unregister_netdev(netdev); |
3170 | 3249 | ||
3250 | ixgbevf_clear_interrupt_scheme(adapter); | ||
3171 | ixgbevf_reset_interrupt_capability(adapter); | 3251 | ixgbevf_reset_interrupt_capability(adapter); |
3172 | 3252 | ||
3173 | iounmap(adapter->hw.hw_addr); | 3253 | iounmap(adapter->hw.hw_addr); |
@@ -3267,6 +3347,11 @@ static struct pci_driver ixgbevf_driver = { | |||
3267 | .id_table = ixgbevf_pci_tbl, | 3347 | .id_table = ixgbevf_pci_tbl, |
3268 | .probe = ixgbevf_probe, | 3348 | .probe = ixgbevf_probe, |
3269 | .remove = __devexit_p(ixgbevf_remove), | 3349 | .remove = __devexit_p(ixgbevf_remove), |
3350 | #ifdef CONFIG_PM | ||
3351 | /* Power Management Hooks */ | ||
3352 | .suspend = ixgbevf_suspend, | ||
3353 | .resume = ixgbevf_resume, | ||
3354 | #endif | ||
3270 | .shutdown = ixgbevf_shutdown, | 3355 | .shutdown = ixgbevf_shutdown, |
3271 | .err_handler = &ixgbevf_err_handler | 3356 | .err_handler = &ixgbevf_err_handler |
3272 | }; | 3357 | }; |