Dear Mr. Ollie Lho, Please find attached a patch to enable Wake-on-Lan for SiS 900 Ethernet adapter on Linux kernels. The patch was tested on various SiS mainboards with 963 Southbridge which has integrated SiS 900 Ethernet adapter. It is used to wake up the mainboards in a cluster configuration. The patch is short, applies cleanly against kernel 2.6.8-rc2 and could be submitted directly to Mr. Linux Torvalds or Mr. Andrew Morton for inclusion in future 2.6.x kernels. Thank you in advance, Best regards, Andrew D. Balsa
--- ./drivers/net/sis900.c.orig 2004-07-18 06:58:21.000000000 +0200 +++ ./drivers/net/sis900.c 2004-07-25 20:00:15.444711768 +0200 @@ -18,6 +18,7 @@ preliminary Rev. 1.0 Jan. 18, 1998 http://www.sis.com.tw/support/databook.htm + Rev 1.08.08 Jul. 25 2004 Deti Fliegl <deti@fliegl.de> add Wake-on-Lan support Rev 1.08.07 Nov. 2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support Rev 1.08.05 Jun. 6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary @@ -73,13 +74,14 @@ #include "sis900.h" #define SIS900_MODULE_NAME "sis900" -#define SIS900_DRV_VERSION "v1.08.07 11/02/2003" +#define SIS900_DRV_VERSION "v1.08.08 25/07/2004" static char version[] __devinitdata = KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\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; @@ -180,9 +182,11 @@ 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(enable_wol, "SiS 900: enable Wake-on-Lan (0-1)"); MODULE_PARM_DESC(debug, "SiS 900/7016 debug level (2-4)"); static int sis900_open(struct net_device *net_dev); @@ -930,6 +934,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. */ @@ -951,6 +956,15 @@ set_rx_mode(net_dev); 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); /* Workaround for EDB */ sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); --- ./drivers/net/sis900.h.orig 2004-07-18 06:57:46.000000000 +0200 +++ ./drivers/net/sis900.h 2004-07-25 19:52:20.792869816 +0200 @@ -134,6 +134,25 @@ EEeraseAll = 0x0120, EEwriteAll = 0x0110, EEaddrMask = 0x013F, EEcmdShift = 16 }; + +/* The following are needed by the Wake-on-Lan feature */ +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 /* For SiS962 or SiS963, request the eeprom software access */ enum sis96x_eeprom_command {