diff options
author | David Ertman <david.m.ertman@intel.com> | 2014-07-11 06:21:31 +0000 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-07-25 21:15:20 -0700 |
commit | 2a7e19af94104b270d675c52bba2ca1bc20efa70 (patch) | |
tree | 9d63b4275f2a973060a1ebfb4353e6082d8b5610 /drivers | |
parent | 2116bc25e8aefd76503dfa2fc328eb8da684bb38 (diff) |
e1000e: Fix Runtime PM blocks EEE link negotiation in S5
Adding a function, and associated calls, to flush writes to (read) the LPIC
MAC register before entering the shutdown flow. This fixes the problem
of the PHY never negotiating a 100M link (if both sides of the link support
EEE and 100M link) when Runtime PM is enabled.
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 1ce0d743029c..65c3aef2bd36 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6033,6 +6033,28 @@ release: return retval; } +static void e1000e_flush_lpic(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 ret_val; + + pm_runtime_get_sync(netdev->dev.parent); + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto fl_out; + + pr_info("EEE TX LPI TIMER: %08X\n", + er32(LPIC) >> E1000_LPIC_LPIET_SHIFT); + + hw->phy.ops.release(hw); + +fl_out: + pm_runtime_put_sync(netdev->dev.parent); +} + static int e1000e_pm_freeze(struct device *dev) { struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); @@ -6333,6 +6355,8 @@ static int e1000e_pm_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + e1000e_flush_lpic(pdev); + e1000e_pm_freeze(dev); return __e1000_shutdown(pdev, false); @@ -6416,6 +6440,8 @@ static int e1000e_pm_runtime_suspend(struct device *dev) static void e1000_shutdown(struct pci_dev *pdev) { + e1000e_flush_lpic(pdev); + e1000e_pm_freeze(&pdev->dev); __e1000_shutdown(pdev, false); |