Commit 34edaa88 authored by Tobias Diedrich's avatar Tobias Diedrich Committed by David S. Miller

net: forcedeth: Fix wake-on-lan regression

Commit f55c21fd ("forcedeth: call
restore mac addr in nv_shutdown path"), which was introduced to fix
the regression tracked at
http://bugzilla.kernel.org/show_bug.cgi?id=11358 causes the
wake-on-lan mac to be reversed in the shutdown path.  Apparently the
forcedeth situation is rather messy in that the mac we need to
writeback for a subsequent modprobe to work is exactly the reverse of
what is needed for proper wake-on-lan.

The following patch explains the situation in the comments and
makes the call to nv_restore_mac_addr() conditional (only called if
we are not really going for poweroff).

Tobias Diedrich wrote:
> Hmm, I had not tried WOL for some time.
> With 2.6.29-rc3 is see the following behaviour:
> 
> State            WOL Behaviour
> ------------------------------
> shutdown         reversed MAC
> disk/shutdown    reversed MAC
> disk/platform    OK
> 
> Apparently nv_restore_mac_addr() restores the MAC in the wrong order
> for WOL (at least for my PCI_DEVICE_ID_NVIDIA_NVENET_15).  platform
> works, because the MAC is not touched in the nv_suspend() path.
> 
> A possible fix might be to only call nv_restore_mac_addr() if
> system_state != SYSTEM_POWER_OFF.

With the following patch:
shutdown         OK
disk/shutdown    OK
disk/platform    OK
kexec            OK
Signed-off-by: default avatarTobias Diedrich <ranma+kernel@tdiedrich.de>
Tested-by: default avatarPhilipp Matthias Hahn <pmhahn@titan.lahn.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d7b33f7
...@@ -6011,9 +6011,20 @@ static void nv_shutdown(struct pci_dev *pdev) ...@@ -6011,9 +6011,20 @@ static void nv_shutdown(struct pci_dev *pdev)
if (netif_running(dev)) if (netif_running(dev))
nv_close(dev); nv_close(dev);
/*
* Restore the MAC so a kernel started by kexec won't get confused.
* If we really go for poweroff, we must not restore the MAC,
* otherwise the MAC for WOL will be reversed at least on some boards.
*/
if (system_state != SYSTEM_POWER_OFF) {
nv_restore_mac_addr(pdev); nv_restore_mac_addr(pdev);
}
pci_disable_device(pdev); pci_disable_device(pdev);
/*
* Apparently it is not possible to reinitialise from D3 hot,
* only put the device into D3 if we really go for poweroff.
*/
if (system_state == SYSTEM_POWER_OFF) { if (system_state == SYSTEM_POWER_OFF) {
if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled)) if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
pci_enable_wake(pdev, PCI_D3hot, np->wolenabled); pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment