|
@@ -3327,6 +3327,9 @@ static void e1000e_set_rx_mode(struct net_device *netdev)
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
u32 rctl;
|
|
u32 rctl;
|
|
|
|
|
|
|
|
+ if (pm_runtime_suspended(netdev->dev.parent))
|
|
|
|
+ return;
|
|
|
|
+
|
|
/* Check for Promiscuous and All Multicast modes */
|
|
/* Check for Promiscuous and All Multicast modes */
|
|
rctl = er32(RCTL);
|
|
rctl = er32(RCTL);
|
|
|
|
|
|
@@ -4317,7 +4320,6 @@ static int e1000_open(struct net_device *netdev)
|
|
adapter->tx_hang_recheck = false;
|
|
adapter->tx_hang_recheck = false;
|
|
netif_start_queue(netdev);
|
|
netif_start_queue(netdev);
|
|
|
|
|
|
- adapter->idle_check = true;
|
|
|
|
hw->mac.get_link_status = true;
|
|
hw->mac.get_link_status = true;
|
|
pm_runtime_put(&pdev->dev);
|
|
pm_runtime_put(&pdev->dev);
|
|
|
|
|
|
@@ -4369,6 +4371,9 @@ static int e1000_close(struct net_device *netdev)
|
|
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
|
e1000e_down(adapter, true);
|
|
e1000e_down(adapter, true);
|
|
e1000_free_irq(adapter);
|
|
e1000_free_irq(adapter);
|
|
|
|
+
|
|
|
|
+ /* Link status message must follow this format */
|
|
|
|
+ pr_info("%s NIC Link is Down\n", adapter->netdev->name);
|
|
}
|
|
}
|
|
|
|
|
|
napi_disable(&adapter->napi);
|
|
napi_disable(&adapter->napi);
|
|
@@ -5678,6 +5683,9 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
|
adapter->max_frame_size = max_frame;
|
|
adapter->max_frame_size = max_frame;
|
|
e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
|
|
e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
|
|
netdev->mtu = new_mtu;
|
|
netdev->mtu = new_mtu;
|
|
|
|
+
|
|
|
|
+ pm_runtime_get_sync(netdev->dev.parent);
|
|
|
|
+
|
|
if (netif_running(netdev))
|
|
if (netif_running(netdev))
|
|
e1000e_down(adapter, true);
|
|
e1000e_down(adapter, true);
|
|
|
|
|
|
@@ -5705,6 +5713,8 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
|
else
|
|
else
|
|
e1000e_reset(adapter);
|
|
e1000e_reset(adapter);
|
|
|
|
|
|
|
|
+ pm_runtime_put_sync(netdev->dev.parent);
|
|
|
|
+
|
|
clear_bit(__E1000_RESETTING, &adapter->state);
|
|
clear_bit(__E1000_RESETTING, &adapter->state);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -5979,6 +5989,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
|
|
ew32(CTRL_EXT, ctrl_ext);
|
|
ew32(CTRL_EXT, ctrl_ext);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (!runtime)
|
|
|
|
+ e1000e_power_up_phy(adapter);
|
|
|
|
+
|
|
if (adapter->flags & FLAG_IS_ICH)
|
|
if (adapter->flags & FLAG_IS_ICH)
|
|
e1000_suspend_workarounds_ich8lan(&adapter->hw);
|
|
e1000_suspend_workarounds_ich8lan(&adapter->hw);
|
|
|
|
|
|
@@ -6108,11 +6121,6 @@ static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_PM
|
|
#ifdef CONFIG_PM
|
|
-static bool e1000e_pm_ready(struct e1000_adapter *adapter)
|
|
|
|
-{
|
|
|
|
- return !!adapter->tx_ring->buffer_info;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int __e1000_resume(struct pci_dev *pdev)
|
|
static int __e1000_resume(struct pci_dev *pdev)
|
|
{
|
|
{
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
@@ -6167,11 +6175,6 @@ static int __e1000_resume(struct pci_dev *pdev)
|
|
|
|
|
|
e1000_init_manageability_pt(adapter);
|
|
e1000_init_manageability_pt(adapter);
|
|
|
|
|
|
- if (netif_running(netdev))
|
|
|
|
- e1000e_up(adapter);
|
|
|
|
-
|
|
|
|
- netif_device_attach(netdev);
|
|
|
|
-
|
|
|
|
/* If the controller has AMT, do not set DRV_LOAD until the interface
|
|
/* If the controller has AMT, do not set DRV_LOAD until the interface
|
|
* is up. For all other cases, let the f/w know that the h/w is now
|
|
* is up. For all other cases, let the f/w know that the h/w is now
|
|
* under the control of the driver.
|
|
* under the control of the driver.
|
|
@@ -6226,47 +6229,59 @@ static int e1000e_pm_resume(struct device *dev)
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
|
#ifdef CONFIG_PM_RUNTIME
|
|
#ifdef CONFIG_PM_RUNTIME
|
|
-static int e1000_runtime_suspend(struct device *dev)
|
|
|
|
|
|
+static int e1000e_pm_runtime_idle(struct device *dev)
|
|
{
|
|
{
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
|
|
|
- if (!e1000e_pm_ready(adapter))
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (!e1000e_has_link(adapter))
|
|
|
|
+ pm_schedule_suspend(dev, 5 * MSEC_PER_SEC);
|
|
|
|
|
|
- return __e1000_shutdown(pdev, true);
|
|
|
|
|
|
+ return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
-static int e1000_idle(struct device *dev)
|
|
|
|
|
|
+static int e1000e_pm_runtime_resume(struct device *dev)
|
|
{
|
|
{
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
|
+ int rc;
|
|
|
|
|
|
- if (!e1000e_pm_ready(adapter))
|
|
|
|
- return 0;
|
|
|
|
|
|
+ rc = __e1000_resume(pdev);
|
|
|
|
+ if (rc)
|
|
|
|
+ return rc;
|
|
|
|
|
|
- if (adapter->idle_check) {
|
|
|
|
- adapter->idle_check = false;
|
|
|
|
- if (!e1000e_has_link(adapter))
|
|
|
|
- pm_schedule_suspend(dev, MSEC_PER_SEC);
|
|
|
|
- }
|
|
|
|
|
|
+ if (netdev->flags & IFF_UP)
|
|
|
|
+ rc = e1000e_up(adapter);
|
|
|
|
|
|
- return -EBUSY;
|
|
|
|
|
|
+ return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-static int e1000_runtime_resume(struct device *dev)
|
|
|
|
|
|
+static int e1000e_pm_runtime_suspend(struct device *dev)
|
|
{
|
|
{
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
|
|
|
- if (!e1000e_pm_ready(adapter))
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (netdev->flags & IFF_UP) {
|
|
|
|
+ int count = E1000_CHECK_RESET_COUNT;
|
|
|
|
+
|
|
|
|
+ while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
|
|
|
|
+ usleep_range(10000, 20000);
|
|
|
|
|
|
- adapter->idle_check = !dev->power.runtime_auto;
|
|
|
|
- return __e1000_resume(pdev);
|
|
|
|
|
|
+ WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
|
|
|
|
+
|
|
|
|
+ /* Down the device without resetting the hardware */
|
|
|
|
+ e1000e_down(adapter, false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (__e1000_shutdown(pdev, true)) {
|
|
|
|
+ e1000e_pm_runtime_resume(dev);
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
#endif /* CONFIG_PM_RUNTIME */
|
|
#endif /* CONFIG_PM_RUNTIME */
|
|
#endif /* CONFIG_PM */
|
|
#endif /* CONFIG_PM */
|
|
@@ -7051,8 +7066,8 @@ static const struct dev_pm_ops e1000_pm_ops = {
|
|
.thaw = e1000e_pm_thaw,
|
|
.thaw = e1000e_pm_thaw,
|
|
.poweroff = e1000e_pm_suspend,
|
|
.poweroff = e1000e_pm_suspend,
|
|
.restore = e1000e_pm_resume,
|
|
.restore = e1000e_pm_resume,
|
|
- SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume,
|
|
|
|
- e1000_idle)
|
|
|
|
|
|
+ SET_RUNTIME_PM_OPS(e1000e_pm_runtime_suspend, e1000e_pm_runtime_resume,
|
|
|
|
+ e1000e_pm_runtime_idle)
|
|
};
|
|
};
|
|
|
|
|
|
/* PCI Device API Driver */
|
|
/* PCI Device API Driver */
|