Hi there, I added 'Wake on LAN' support to the sis900 driver. It works pretty well with my on board SIS900 NIC. To activate the WOL feature simply use the module parameter enable_wol=1. Regards, Deti
--- /usr/src/linux/drivers/net/sis900.c Fri Dec 21 18:41:54 2001 +++ linux/drivers/net/sis900.c Fri Jan 11 01:26:33 2002 @@ -18,6 +18,7 @@ preliminary Rev. 1.0 Jan. 18, 1998 http://www.sis.com.tw/support/databook.htm + Rev 1.08.02 Jan. 10 2002 Deti Fliegl <deti@fliegl.de> support for wake on lan enable_wol Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3 @@ -66,10 +67,11 @@ #include "sis900.h" static char version[] __devinitdata = -KERN_INFO "sis900.c: v1.08.01 9/25/2001\n"; +KERN_INFO "sis900.c: v1.08.02 1/10/2002\n"; static int max_interrupt_work = 40; static int multicast_filter_limit = 128; +static int enable_wol=0; #define sis900_debug debug static int sis900_debug; @@ -166,10 +168,12 @@ MODULE_PARM(multicast_filter_limit, "i"); MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(enable_wol, "i"); MODULE_PARM(debug, "i"); MODULE_PARM_DESC(multicast_filter_limit, "SiS 900/7016 maximum number of filtered multicast addresses"); MODULE_PARM_DESC(max_interrupt_work, "SiS 900/7016 maximum events handled per interrupt"); MODULE_PARM_DESC(debug, "SiS 900/7016 debug level (2-4)"); +MODULE_PARM_DESC(enable_wol, "sis900: Turn on Wake-on-LAN for adapter(s) (0-1)"); static int sis900_open(struct net_device *net_dev); static int sis900_mii_probe (struct net_device * net_dev); @@ -848,6 +852,7 @@ struct sis900_private *sis_priv = net_dev->priv; long ioaddr = net_dev->base_addr; u8 revision; + u32 cfgpmcsr; int ret; /* Soft reset the chip. */ @@ -870,11 +875,20 @@ netif_start_queue(net_dev); + /* Enable WOL if wol_enable parameter is set */ + if(enable_wol) { + pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr); + cfgpmcsr|=PME_EN; + pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr); + outl( inl(ioaddr + pmctrl) | MAGICPKT | ALGORITHM, ioaddr + pmctrl); + } else + outl( inl(ioaddr + pmctrl) & ~MAGICPKT, ioaddr + pmctrl); + /* Enable all known interrupts by setting the interrupt mask. */ outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); outl(RxENA | inl(ioaddr + cr), ioaddr + cr); outl(IE, ioaddr + ier); - + sis900_check_mode(net_dev, sis_priv->mii); /* Set the timer to switch to check for link beat and perhaps switch --- /usr/src/linux/drivers/net/sis900.h Wed Oct 10 00:13:03 2001 +++ linux/drivers/net/sis900.h Fri Jan 11 01:09:23 2002 @@ -135,6 +135,24 @@ EEaddrMask = 0x013F, EEcmdShift = 16 }; +enum sis900_power_management_control_register_bits { +LINKLOSS = 0x00000001, +LINKON = 0x00000002, +MAGICPKT = 0x00000400, +ALGORITHM = 0x00000800, +FRM1EN = 0x00100000, +FRM2EN = 0x00200000, +FRM3EN = 0x00400000, +FRM1ACS = 0x01000000, +FRM2ACS = 0x02000000, +FRM3ACS = 0x04000000, +WAKEALL = 0x40000000, +GATECLK = 0x80000000 +}; + +#define CFGPMCSR 0x44 +#define PME_EN 0x100 + /* Manamgement Data I/O (mdio) frame */ #define MIIread 0x6000 #define MIIwrite 0x5002