From a18c6f1f21f09ca50e4467a484b18b4d6fd87dbb 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 commit 2a7e19af94104b270d675c52bba2ca1bc20efa70 upstream. 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 Signed-off-by: Ben Hutchings --- 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 fe03a752b84b..5d39f3432029 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6031,6 +6031,28 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) 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)); @@ -6331,6 +6353,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); @@ -6409,6 +6433,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.43.0