Manual for patch, which enables Wake-On-Lan functionality
for a network cards integrated with nVidia nForce boards.

It's concerned about the following hardware:

* nForce Ethernet Controller
* nForce2 Ethernet Controller
* nForce3 Ethernet Controller
* CK804 Ethernet Controller
* MCP04 Ethernet Controller
* MCP51 Ethernet Controller
* MCP55 Ethernet Controller

The fix requires modifications in two areas:

* in the kernel module called forcedeth
* in the rc-scripts which are stopping the system

The fix requires you to have installed the following commands:

* wget
* patch
* diff
* make
* gcc

If you're using PLD-Linux then check, whether you have it
in your distro already by calling:

grep -qi forcedeth_workaround /etc/rc.d/rc.shutdown && echo got it in scripts!
/sbin/modinfo -F description forcedeth | grep -qi "timerirq disabled" && echo got supported kernel module!

Ok, if there is support already and you are familiar with GNU/Linux,
you know which steps and commads need to be abandoned.

1.) Install ethtool
    - if you don't have it in your distro, get it from z http://sourceforge.net/projects/gkernel/


2.) Make sure, that ethtool is in /sbin lub w /usr/sbin
    - execute: type ethtool


3.) Get the sources for your currently used kernel
    - shay should be in /usr/src/linux


4.) Login as root and execute:

cd /tmp && mkdir cosik && cd cosik
wget ftp://ftp.pld-linux.org/people/siefca/\
patches/nvidia/pci-config.c
wget ftp://ftp.pld-linux.org/people/siefca/\
patches/nvidia/forcedeth_sleep.sh
kver=`uname -r | awk -F'[ .]' '{print $1"."$2"."$3}'`
export kver
wget -O linux-forcedeth-WON.patch \
ftp://ftp.pld-linux.org/people/siefca/\
patches/nvidia/linux-${kver}-forcedeth-WON.patch

gcc -O2 ./pci-config.c -o ./pci-config
strip ./pci-config
mv ./pci-config /sbin

[ -d /etc/rc.d ] || mkdir /etc/rc.d
mv forcedeth_sleep.sh /etc/rc.d
chmod a+rx /etc/rc.d/forcedeth_sleep.sh /sbin/pci-config


5.) Check in the current directory, whether there is
    NON-EMPTY file called: linux-forcedeth-WON.patch

     If IT IS NON-EMPTY then go to 5.2.
     If IT'S EMPTY OR NON-EXISTENT go to 5.1 (next step).


5.1) You have to prepare fix for the kernel module on your own.
     That is easy and consis of finding few strings and replacing them.
     Go to the directory: /usr/src/linux/drivers/net
     Execute: cp forcedeth.c forcedeth.c.orig

     Open the file with your editor: forcedeth.c

     [1] replace the line:

        #define DEV_NEED_TIMERIRQ      0x0001  /* set the timer irq flag in the irq mask */

       with these two:

        #define DEV_NEED_TIMERIRQ      0x0000  /* work-around for Wake-On-Lan */
        #define DEV_NEED_TIMERIRQ_ORIG 0x0001  /* set the timer irq flag in the irq mask */

     [2] replace the line:

        if (id->driver_data & DEV_NEED_TIMERIRQ)

       with that:

        if (id->driver_data & DEV_NEED_TIMERIRQ_ORIG)

     [3] replace the line:

        MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");

       with that:

        MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver (TIMERIRQ DISABLED)");

     Ok. Almost done. :)

     Execute: diff -Nu forcedeth.c.orig forcedeth.c >./linux-${kver}-forcedeth-WON.patch
     Send me an e-mail (at the bottom) the file which has just appeared. You are helping
     other people by doing so. If you do not know the filename execute: ls linux-*forcedeth*

     Go to 5.3.


5.2) Module patching.

# kernel-module part (patching)
mv linux-2.6-forcedeth-WON.patch /usr/src/linux
cd /usr/src/linux && patch -p1 <./linux-2.6-forcedeth-WON.patch


5.3) Module compiling and installing.

# kernel module part (compiling)
cd /usr/src/linux
make menuconfig   # execute if these kernel sources were not compiled before and you've just unpacked sources
		  # when menu appear exit with answering 'yes' to question about saving configuration
make
make modules

# kernel module part (installing)
cd /usr/src/linux
make modules install
depmod -a

6.) Reboot your system, to let it work with a new module:

ifdown your_trouble_making_interface   (e.g. ifdown eth0)
rmmod forcedeth
reboot


7.) Now important thing - you have to enable work-around functionality
    in the file, which is responsible for shutting down the system.
    Find such file in your system (in my distro it's /etc/rc.d/rc.shutdown)
    and add in it, in the right place calling: /etc/rc.d/forcedeth_sleep.sh

    Just look inside the directory called /etc/rc.d/ for a filecontaining
    the message "Turning off swap" and/or "unmounting filesystems" and just
    above that operation (swap unmounting in this case) add the line:
    /etc/rc.d/forcedeth_sleep.sh.

   In my case it looked like:

|    /etc/rc.d/forcedeth_sleep.sh
|
|   # Turn off swap, then unmount file systems.
|    run_cmd "Turning off swap" swapoff -a
|
|    [ -x /etc/rc.d/rc.acct ] && /etc/rc.d/rc.acct stop


8.) If you do not knoe how to perform point 5. it is ok to ask someone, who is
    able to help you. You have to know the exact place in exact rc file,
    the place responsible for unmounting filesystems when the system goes down.
    You have to put the script executing line just before that.


9.) Do not forget to tell your ethernet card to sleep (not to be disabled),
    when the machine is turned off/suspended, by issuing a command:

	ethtool -s interface_name wol g


10.) Check whether it works.

-- 
Pawel Wilk < pw at gnu dot org >