diff mbox

[RFC,01/15] via-rhine: YARB: fix broken resume of ifdown case (NetworkManager).

Message ID 1356967549-5056-2-git-send-email-andi@lisas.de
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Andreas Mohr Dec. 31, 2012, 3:25 p.m. UTC
From: Andreas Mohr <andim2@users.sf.net>

Well, it's probably not a *breakage* this time after all
(handling probably was never fully correct before).

resume() in the case of an ifdown iface
(as e.g. usually done by NetworkManager)
did not restore the card to proper full post-probe() card state
(see resume()s !netif_running() check),
thereby causing the subsequent iface open() as done by NM to fail,
since that one requires full post-probe() card state
(e.g. PHY available) yet the PHY was not available
(at least in the case of full-shutdown S2R).

Some related NetworkManager links are
  https://bugs.mageia.org/show_bug.cgi?id=7498
  http://crunchbang.org/forums/viewtopic.php?id=15169
  https://bugzilla.redhat.com/show_bug.cgi?id=477964
  https://bugzilla.redhat.com/show_bug.cgi?id=549089

Suspend/resume behaviour verified with both NM running and not running,
and with both mem (S2R) and standby.
Tested on Neoware CA10 (VIA C3), will also test on EPoX 8K5A2+.

Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
 drivers/net/ethernet/via/via-rhine.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 7992b3e..5facb0b 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -2324,13 +2324,20 @@  static int rhine_resume(struct device *device)
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
 
-	if (!netif_running(dev))
-		return 0;
-
 #ifdef USE_MMIO
 	enable_mmio(rp->pioaddr, rp->quirks);
 #endif
+	/*
+	 * FIXME: some power calls here are being done
+	 * internally in netdev setup parts below, too -
+	 * should be corrected eventually.
+	 */
 	rhine_power_init(dev);
+	rhine_hw_init(dev, rp->pioaddr);
+
+	if (!netif_running(dev))
+		return 0;
+
 	free_tbufs(dev);
 	free_rbufs(dev);
 	alloc_tbufs(dev);