# forcedeth on nforce4 board (A8N SLI): no wake on lan (wol)

## nermal0

I can't get my PC to wake on LAN using the forcedeth driver included in kernel 2.6.14-gentoo-r4. I issued:

ethtool -s eth0 wol g

before shutdown, which seems to have no effect. The only solution I've found is to use NVIDIA's nforce nvnet driver. WOL works here without any need for setup. Sadly it has been removed from portage, so I have to manually recompile it everytime I upgrade the kernel using:

./NFORCE-Linux-x86_64-1.0-0310-pkg1.run -s

Anyone with a nforce4 board got WOL working with forcedeth? I prefer the open source drivers!

Cheers,

Christoph

----------

## j-m

Try this...  :Idea: 

----------

## nermal0

I added this to my /etc/conf.d/net:

```

postdown() {

  ethtool -s "${IFACE}" wol g

  return 0

}

```

and changed the line in /etc/init.d/shutdown.sh to:

```

/sbin/halt -hdp

```

(removed the i).

Still no WOL with the forcedeth driver.

----------

## sibov

*bump*

same issue with my nforce4 setup.

Any solution would be appreciated  :Wink: 

Thanks and regards,

Sibov

----------

## l10n3l

Hi,

This is due to several enhancements that are in progress in the forcedeth driver.

Firstly, check the version of your forcedeth driver (you'll see the version of the driver in /var/log/messages when loading the forcedeth module).

For forcedeth v0.56, there is a bug in the driver that requires to send the WOL packet with a reverse MAC address, eg:

```

piano:~# ifconfig eth0

eth0      Link encap:Ethernet  HWaddr 00:0C:76:5E:FE:3D

```

The wake-up command will be 

```
wol -h 192.168.254.255 3d:fe:5e:76:0c:00
```

This is due to reverse byte orders of the forcedeth driver that is currently being investigated (see http://www.nvnews.net/vbulletin/showthread.php?t=70384).

For forcedeth v0.49 and prior, you can try the following patch (at your own risks) (it did work for me with 0.49 within the 2.6.16 kernel):

This changes in the forcedeth have been performed to reproduce what had been done manually before by Carl-Daniel Hailfinger.

See:

http://www.oss.sgi.com/archives/netdev/2004-03/msg00245.html

http://atlas.et.tudelft.nl/verwei90/nforce2/wol.html

http://bugzilla.kernel.org/show_bug.cgi?id=1636

The only advantages compared to the pci-config method described by Carl-Daniel Hailfinger is that this fix directly updates the forcedeth and thus:

The kernel does not complain anymore about timeouts on rx/tx when put in WOL mode... (even when this happened, it this didn't lead to a kernel crash though)

There is no need to tweak DEV_NEED_TIMERIRQ anymore (we actually stop interrupts processing before moving the D3 sleep mode)

This patch worked on a debian with kernel 2.6.16 (forcedeth v0.49). It requires recompiling the module from the kernel sources (forcedeth.c)

Using the modified forcedeth driver, I just had to add the following script at shutdown (in /etc/rc0.d/S21nforce-wol for me)

```

#!/bin/sh

ethtool -s eth0 wol g

```

This allows the forcedeth driver to be set as WOL just before shutting down the network interface

Here is the patch for the kernel module:

```

--- drivers/net/forcedeth.c.orig   2007-08-17 10:25:00.000000000 +0200

+++ drivers/net/forcedeth.c   2007-08-17 10:55:54.000000000 +0200

@@ -102,8 +102,41 @@

  *   0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.

  *   0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single

  *   0.49: 10 Dec 2005: Fix tso for large buffers.

+ *         10 Aug 2007: Fix WOL support (D3 PCI power save mode)

  *

  * Known bugs:

+ * Lionel Ains (wol fix):

+ * 1) Enable wol g mode with ethtool will only work if interface is up

+ * 2) When set to wol g mode, the NIC will be brought down immediately,

+ * so this is something you want to do only at shutdown (ie: around S2

+ * in /etc/rc0.d for debian)

+ * 2) If you put your NIC in wol mode, then rmmod forcedeth, modprobe forcedeth

+ * will always fail afterwards (until next reboot). The failure actually occurs

+ * within nv_probe() which fails detecting the nforce NIC when in D3 sleep mode

+ * 

+ * This changes in the forcedeth have been performed to reproduce

+ * what had been done manually before by Carl-Daniel Hailfinger

+ * See:

+ * http://www.oss.sgi.com/archives/netdev/2004-03/msg00245.html

+ * http://atlas.et.tudelft.nl/verwei90/nforce2/wol.html

+ * http://bugzilla.kernel.org/show_bug.cgi?id=1636

+ * The only advantages brought by the fact this fix directly updates the 

+ * forcedeth module are that:

+ * - kernel does not complain anymore about timeouts on rx/tx when put

+ * in WOL mode... (even when this happened, it this didn't lead to a kernel

+ * crash though)

+ * - No need to tweak DEV_NEED_TIMERIRQ anymore (we actually stop interrupts

+ * processing before moving the D3 sleep mode)

+ *

+ * This worked on a debian with kernel 2.6.16 (forcedeth v0.49)

+ * Using the modified forcedeth driver, I just had to add the following

+ * script at shutdown (in /etc/rc0.d/S21nforce-wol for me)

+

+#!/bin/sh

+ethtool -s eth0 wol g

+

+ *

+ *

  * We suspect that on some hardware no TX done interrupts are generated.

  * This means recovery from netif_stop_queue only happens if the hw timer

  * interrupt fires (100 times/second, configurable with NVREG_POLL_DEFAULT)

@@ -1014,6 +1047,34 @@

    nv_drain_rx(dev);

 }

 

+static void nv_powersave_D0(struct net_device *dev)

+{

+   u8 __iomem *base = get_hwbase(dev);

+

+   if ((readl(base + NvRegPowerState) & NVREG_POWERSTATE_D0) == 0) {

+      writel(NVREG_POWERSTATE_D0, base + NvRegPowerState);

+      pci_push(base);

+      udelay(10);

+      printk(KERN_INFO "%s: Switching to D0 active mode\n", dev->name);

+   }

+   writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);

+   pci_push(base);

+}

+

+static void nv_powersave_D3(struct net_device *dev)

+{

+   u8 __iomem *base = get_hwbase(dev);

+

+   if ((readl(base + NvRegPowerState) & NVREG_POWERSTATE_D3) == 0) {

+      writel(NVREG_POWERSTATE_D3, base + NvRegPowerState);

+      pci_push(base);

+      udelay(10);

+      printk(KERN_INFO "%s: Switching to D3 sleep mode (WOL)\n", dev->name);

+   }

+   writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);

+   pci_push(base);

+}

+

 /*

  * nv_start_xmit: dev->hard_start_xmit function

  * Called with dev->xmit_lock held.

@@ -1974,11 +2035,21 @@

 

    spin_lock_irq(&np->lock);

    if (wolinfo->wolopts == 0) {

+      /* Disabling wol */

       writel(0, base + NvRegWakeUpFlags);

+      if ((np->wolenabled) && (!(dev->flags & IFF_UP))) {   /* wol was enabled, and interface is down, switch NIC to D0 power state right now */

+//         printk(KERN_INFO "%s: Switching to D0 active while %s is down\n", dev->name, dev->name);

+         nv_powersave_D0(dev);

+      }

       np->wolenabled = 0;

    }

    if (wolinfo->wolopts & WAKE_MAGIC) {

+      /* Enabling wol on magic */

       writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags);

+      if (!(np->wolenabled) && (!(dev->flags & IFF_UP))) {   /* wol was disabled, and interface is down, switch to D3 power state right now */

+         printk(KERN_WARNING "%s: Switching to D3 sleep mode will only be effective at next up+down cycle for %s\n", dev->name, dev->name);

+//         nv_powersave_D3(dev);   /* Not working, because if must be listening on rx/tx before being put to sleep mode */

+      }

       np->wolenabled = 1;

    }

    spin_unlock_irq(&np->lock);

@@ -2376,8 +2447,11 @@

    netif_stop_queue(dev);

    spin_lock_irq(&np->lock);

    nv_stop_tx(dev);

-   nv_stop_rx(dev);

-   nv_txrx_reset(dev);

+   /* Lionel Ains: stop TX even if going to WOL */

+   if (!np->wolenabled) {

+      nv_stop_rx(dev);

+      nv_txrx_reset(dev);

+   }

 

    /* disable interrupts on the nic or we will lock up */

    base = get_hwbase(dev);

@@ -2392,7 +2466,8 @@

    drain_ring(dev);

 

    if (np->wolenabled)

-      nv_start_rx(dev);

+//      nv_start_rx(dev); /* Not needed... we skipped nv_stop_rx() above! */

+      nv_powersave_D3(dev);

 

    /* special op: write back the misordered MAC address - otherwise

     * the next nv_probe would see a wrong address.

@@ -2400,7 +2475,11 @@

    writel(np->orig_mac[0], base + NvRegMacAddrA);

    writel(np->orig_mac[1], base + NvRegMacAddrB);

 

-   /* FIXME: power down nic */

+   /* Lionel Ains: NIC power down was done for WOL above */

+   /* We could power down NIC (to D3 mode) while bringing down interface by

+      uncommenting the lines below */

+//   if (!np->wolenabled)

+//      nv_powersave_D3(dev);

 

    return 0;

 }

```

Lionel Ains

----------

## TheBigK

Thanks for this description.

In 2.6.28, this bug is till up 2 date.

----------

## l10n3l

 *TheBigK wrote:*   

> 
> 
> In 2.6.28, this bug is till up 2 date.

 

I guess you didn't have to apply the patch (forcedeth must be v0.56 at least in 2.4.28), so the only action to perform was to reverse byte orders. I may submit a patch to sort this out for forcedeth, but I am not sure that the byte reversal is required for all hardware NICs supported by forcedeth. With network card do you have (output of lspci)? A nforce2 like mine or a more recent network adapter?

----------

## Crash_Maxed

Here's my experience with WOL and forcedeth as of 1/25/2009.  I have two machines that apply so there's two sets of data.

Asus K8N-E Deluxe motherboard - Chipset: nVidia Corporation nForce3 250Gb

gentoo-sources-2.6.24-r8 : WOL follows correct byte order

gentoo-sources-2.6.27-r7 : WOL follows reverse byte order

Asus A8N-SLI motherboard - Chipset: nVidia Corporation CK804 (This is what lspci shows, but it's a nForce4 SLI chipset fyi)

gentoo-sources-2.6.25-r9 : WOL follows correct byte order

gentoo-sources-2.6.27-r7 : WOL follows revers byte order

Just to clear any confusion, for example the K8N-E with nForce3 has a MAC of 00:E0:18:99:88:77.  in 2.6.24-r8 I could wake it up with:

```
ragnarok ~ # wol 00:E0:18:99:88:77
```

Now that the machines have since been upgraded to 2.6.27-r7 (and broken current WOL implementation I had setup) it now wakes up correctly with:

```
ragnarok ~ # wol 77:88:99:18:E0:00
```

The same was tested on the A8N-SLI board and it too experienced the same thing.  WOL byte order must now be reversed and everything is happy.

Note:  I haven't done any testing with sleep states such as suspend to ram and suspend to disk.  The only use of WOL that I do is from clean shutdowns via init 0 and the line 'ethtool -s eth0 wol g' in my /etc/conf.d/local.stop file.

----------

## Paczesiowa

if it still doesn't work for you, you can try other software for waking. when I shutdown with windows, I can wake it with wol tool. when I shutdown it with linux there is no way to wake it up with wol (reversed mac or not), but it wakes up fine with etherwake and reversed mac.

----------

