aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-11 04:33:26 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-08-30 22:17:40 -0400
commit0ac1e8cee674d492d336355b99bf63c906f0a2e4 (patch)
tree2010e80820eb8847938169c4c94f820835e9757e /drivers/net/ethernet/intel
parent076d807024052a2c0d76050edd89cd94d0515684 (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.c93
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 **/
1876static 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
2892static void ixgbevf_shutdown(struct pci_dev *pdev) 2908static 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
2941static 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 */
2984static void ixgbevf_shutdown(struct pci_dev *pdev)
2985{
2986 ixgbevf_suspend(pdev, PMSG_SUSPEND);
2909} 2987}
2910 2988
2911static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, 2989static 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
2949static const struct net_device_ops ixgbe_netdev_ops = { 3027static 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
2963static void ixgbevf_assign_netdev_ops(struct net_device *dev) 3041static 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
3133err_register: 3211err_register:
3212 ixgbevf_clear_interrupt_scheme(adapter);
3134err_sw_init: 3213err_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};