From: Jesse Brandeburg jesse.brandeburg@intel.com
stable inclusion form stable-v5.10.82 commit 4e6cce20fbc02d45e8505e0381ad6f9afb1b873b bugzilla: 185877 https://gitee.com/openeuler/kernel/issues/I4QU6V
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 5d2ca2e12dfb2aff3388ca57b06f570fa6206ced ]
As reported in [1], e100 was no longer working for suspend/resume cycles. The previous commit mentioned in the fixes appears to have broken things and this attempts to practice best known methods for device power management and keep wake-up working while allowing suspend/resume to work. To do this, I reorder a little bit of code and fix the resume path to make sure the device is enabled.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=214933
Fixes: 69a74aef8a18 ("e100: use generic power management") Cc: Vaibhav Gupta vaibhavgupta40@gmail.com Reported-by: Alexey Kuznetsov axet@me.com Signed-off-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Alexey Kuznetsov axet@me.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Chen Jun chenjun102@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/net/ethernet/intel/e100.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index afe824aad954..8f7d2a335654 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -3001,9 +3001,10 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev);
+ netif_device_detach(netdev); + if (netif_running(netdev)) e100_down(nic); - netif_device_detach(netdev);
if ((nic->flags & wol_magic) | e100_asf(nic)) { /* enable reverse auto-negotiation */ @@ -3020,7 +3021,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) *enable_wake = false; }
- pci_clear_master(pdev); + pci_disable_device(pdev); }
static int __e100_power_off(struct pci_dev *pdev, bool wake) @@ -3040,8 +3041,6 @@ static int __maybe_unused e100_suspend(struct device *dev_d)
__e100_shutdown(to_pci_dev(dev_d), &wake);
- device_wakeup_disable(dev_d); - return 0; }
@@ -3049,6 +3048,14 @@ static int __maybe_unused e100_resume(struct device *dev_d) { struct net_device *netdev = dev_get_drvdata(dev_d); struct nic *nic = netdev_priv(netdev); + int err; + + err = pci_enable_device(to_pci_dev(dev_d)); + if (err) { + netdev_err(netdev, "Resume cannot enable PCI device, aborting\n"); + return err; + } + pci_set_master(to_pci_dev(dev_d));
/* disable reverse auto-negotiation */ if (nic->phy == phy_82552_v) { @@ -3060,10 +3067,11 @@ static int __maybe_unused e100_resume(struct device *dev_d) smartspeed & ~(E100_82552_REV_ANEG)); }
- netif_device_attach(netdev); if (netif_running(netdev)) e100_up(nic);
+ netif_device_attach(netdev); + return 0; }