diff options
author | David Ertman <david.m.ertman@intel.com> | 2014-07-11 02:21:31 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-07-26 00:15:20 -0400 |
commit | 2a7e19af94104b270d675c52bba2ca1bc20efa70 (patch) | |
tree | 9d63b4275f2a973060a1ebfb4353e6082d8b5610 /drivers/net/ethernet/intel/e1000e | |
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/net/ethernet/intel/e1000e')
-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: | |||
6033 | return retval; | 6033 | return retval; |
6034 | } | 6034 | } |
6035 | 6035 | ||
6036 | static void e1000e_flush_lpic(struct pci_dev *pdev) | ||
6037 | { | ||
6038 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
6039 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
6040 | struct e1000_hw *hw = &adapter->hw; | ||
6041 | u32 ret_val; | ||
6042 | |||
6043 | pm_runtime_get_sync(netdev->dev.parent); | ||
6044 | |||
6045 | ret_val = hw->phy.ops.acquire(hw); | ||
6046 | if (ret_val) | ||
6047 | goto fl_out; | ||
6048 | |||
6049 | pr_info("EEE TX LPI TIMER: %08X\n", | ||
6050 | er32(LPIC) >> E1000_LPIC_LPIET_SHIFT); | ||
6051 | |||
6052 | hw->phy.ops.release(hw); | ||
6053 | |||
6054 | fl_out: | ||
6055 | pm_runtime_put_sync(netdev->dev.parent); | ||
6056 | } | ||
6057 | |||
6036 | static int e1000e_pm_freeze(struct device *dev) | 6058 | static int e1000e_pm_freeze(struct device *dev) |
6037 | { | 6059 | { |
6038 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); | 6060 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
@@ -6333,6 +6355,8 @@ static int e1000e_pm_suspend(struct device *dev) | |||
6333 | { | 6355 | { |
6334 | struct pci_dev *pdev = to_pci_dev(dev); | 6356 | struct pci_dev *pdev = to_pci_dev(dev); |
6335 | 6357 | ||
6358 | e1000e_flush_lpic(pdev); | ||
6359 | |||
6336 | e1000e_pm_freeze(dev); | 6360 | e1000e_pm_freeze(dev); |
6337 | 6361 | ||
6338 | return __e1000_shutdown(pdev, false); | 6362 | return __e1000_shutdown(pdev, false); |
@@ -6416,6 +6440,8 @@ static int e1000e_pm_runtime_suspend(struct device *dev) | |||
6416 | 6440 | ||
6417 | static void e1000_shutdown(struct pci_dev *pdev) | 6441 | static void e1000_shutdown(struct pci_dev *pdev) |
6418 | { | 6442 | { |
6443 | e1000e_flush_lpic(pdev); | ||
6444 | |||
6419 | e1000e_pm_freeze(&pdev->dev); | 6445 | e1000e_pm_freeze(&pdev->dev); |
6420 | 6446 | ||
6421 | __e1000_shutdown(pdev, false); | 6447 | __e1000_shutdown(pdev, false); |