diff options
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r-- | drivers/net/igb/igb_main.c | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ca842163dce4..03aa9593dd9e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -135,8 +135,8 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int); | |||
135 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); | 135 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); |
136 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); | 136 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); |
137 | 137 | ||
138 | static int igb_suspend(struct pci_dev *, pm_message_t); | ||
139 | #ifdef CONFIG_PM | 138 | #ifdef CONFIG_PM |
139 | static int igb_suspend(struct pci_dev *, pm_message_t); | ||
140 | static int igb_resume(struct pci_dev *); | 140 | static int igb_resume(struct pci_dev *); |
141 | #endif | 141 | #endif |
142 | static void igb_shutdown(struct pci_dev *); | 142 | static void igb_shutdown(struct pci_dev *); |
@@ -420,6 +420,9 @@ static void igb_free_queues(struct igb_adapter *adapter) | |||
420 | for (i = 0; i < adapter->num_rx_queues; i++) | 420 | for (i = 0; i < adapter->num_rx_queues; i++) |
421 | netif_napi_del(&adapter->rx_ring[i].napi); | 421 | netif_napi_del(&adapter->rx_ring[i].napi); |
422 | 422 | ||
423 | adapter->num_rx_queues = 0; | ||
424 | adapter->num_tx_queues = 0; | ||
425 | |||
423 | kfree(adapter->tx_ring); | 426 | kfree(adapter->tx_ring); |
424 | kfree(adapter->rx_ring); | 427 | kfree(adapter->rx_ring); |
425 | } | 428 | } |
@@ -1476,9 +1479,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1476 | netdev->name, | 1479 | netdev->name, |
1477 | ((hw->bus.speed == e1000_bus_speed_2500) | 1480 | ((hw->bus.speed == e1000_bus_speed_2500) |
1478 | ? "2.5Gb/s" : "unknown"), | 1481 | ? "2.5Gb/s" : "unknown"), |
1479 | ((hw->bus.width == e1000_bus_width_pcie_x4) | 1482 | ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : |
1480 | ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1) | 1483 | (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" : |
1481 | ? "Width x1" : "unknown"), | 1484 | (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" : |
1485 | "unknown"), | ||
1482 | netdev->dev_addr); | 1486 | netdev->dev_addr); |
1483 | 1487 | ||
1484 | igb_read_part_num(hw, &part_num); | 1488 | igb_read_part_num(hw, &part_num); |
@@ -5056,7 +5060,7 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx) | |||
5056 | return 0; | 5060 | return 0; |
5057 | } | 5061 | } |
5058 | 5062 | ||
5059 | static int igb_suspend(struct pci_dev *pdev, pm_message_t state) | 5063 | static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake) |
5060 | { | 5064 | { |
5061 | struct net_device *netdev = pci_get_drvdata(pdev); | 5065 | struct net_device *netdev = pci_get_drvdata(pdev); |
5062 | struct igb_adapter *adapter = netdev_priv(netdev); | 5066 | struct igb_adapter *adapter = netdev_priv(netdev); |
@@ -5115,15 +5119,9 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5115 | wr32(E1000_WUFC, 0); | 5119 | wr32(E1000_WUFC, 0); |
5116 | } | 5120 | } |
5117 | 5121 | ||
5118 | /* make sure adapter isn't asleep if manageability/wol is enabled */ | 5122 | *enable_wake = wufc || adapter->en_mng_pt; |
5119 | if (wufc || adapter->en_mng_pt) { | 5123 | if (!*enable_wake) |
5120 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
5121 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
5122 | } else { | ||
5123 | igb_shutdown_fiber_serdes_link_82575(hw); | 5124 | igb_shutdown_fiber_serdes_link_82575(hw); |
5124 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
5125 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
5126 | } | ||
5127 | 5125 | ||
5128 | /* Release control of h/w to f/w. If f/w is AMT enabled, this | 5126 | /* Release control of h/w to f/w. If f/w is AMT enabled, this |
5129 | * would have already happened in close and is redundant. */ | 5127 | * would have already happened in close and is redundant. */ |
@@ -5131,12 +5129,29 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5131 | 5129 | ||
5132 | pci_disable_device(pdev); | 5130 | pci_disable_device(pdev); |
5133 | 5131 | ||
5134 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
5135 | |||
5136 | return 0; | 5132 | return 0; |
5137 | } | 5133 | } |
5138 | 5134 | ||
5139 | #ifdef CONFIG_PM | 5135 | #ifdef CONFIG_PM |
5136 | static int igb_suspend(struct pci_dev *pdev, pm_message_t state) | ||
5137 | { | ||
5138 | int retval; | ||
5139 | bool wake; | ||
5140 | |||
5141 | retval = __igb_shutdown(pdev, &wake); | ||
5142 | if (retval) | ||
5143 | return retval; | ||
5144 | |||
5145 | if (wake) { | ||
5146 | pci_prepare_to_sleep(pdev); | ||
5147 | } else { | ||
5148 | pci_wake_from_d3(pdev, false); | ||
5149 | pci_set_power_state(pdev, PCI_D3hot); | ||
5150 | } | ||
5151 | |||
5152 | return 0; | ||
5153 | } | ||
5154 | |||
5140 | static int igb_resume(struct pci_dev *pdev) | 5155 | static int igb_resume(struct pci_dev *pdev) |
5141 | { | 5156 | { |
5142 | struct net_device *netdev = pci_get_drvdata(pdev); | 5157 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -5189,7 +5204,14 @@ static int igb_resume(struct pci_dev *pdev) | |||
5189 | 5204 | ||
5190 | static void igb_shutdown(struct pci_dev *pdev) | 5205 | static void igb_shutdown(struct pci_dev *pdev) |
5191 | { | 5206 | { |
5192 | igb_suspend(pdev, PMSG_SUSPEND); | 5207 | bool wake; |
5208 | |||
5209 | __igb_shutdown(pdev, &wake); | ||
5210 | |||
5211 | if (system_state == SYSTEM_POWER_OFF) { | ||
5212 | pci_wake_from_d3(pdev, wake); | ||
5213 | pci_set_power_state(pdev, PCI_D3hot); | ||
5214 | } | ||
5193 | } | 5215 | } |
5194 | 5216 | ||
5195 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5217 | #ifdef CONFIG_NET_POLL_CONTROLLER |