From 2a7e19af94104b270d675c52bba2ca1bc20efa70 Mon Sep 17 00:00:00 2001 From: David Ertman Date: Fri, 11 Jul 2014 06:21:31 +0000 Subject: [PATCH] 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 Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) 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); -- 2.20.1