diff options
-rw-r--r-- | drivers/net/sis900.c | 73 | ||||
-rw-r--r-- | drivers/net/sis900.h | 45 |
2 files changed, 116 insertions, 2 deletions
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 1d4d88680db1..3d95fa20cd88 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux. | 1 | /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux. |
2 | Copyright 1999 Silicon Integrated System Corporation | 2 | Copyright 1999 Silicon Integrated System Corporation |
3 | Revision: 1.08.08 Jan. 22 2005 | 3 | Revision: 1.08.09 Sep. 19 2005 |
4 | 4 | ||
5 | Modified from the driver which is originally written by Donald Becker. | 5 | Modified from the driver which is originally written by Donald Becker. |
6 | 6 | ||
@@ -17,6 +17,7 @@ | |||
17 | SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, | 17 | SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, |
18 | preliminary Rev. 1.0 Jan. 18, 1998 | 18 | preliminary Rev. 1.0 Jan. 18, 1998 |
19 | 19 | ||
20 | Rev 1.08.09 Sep. 19 2005 Daniele Venzano add Wake on LAN support | ||
20 | Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages | 21 | Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages |
21 | Rev 1.08.07 Nov. 2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support | 22 | Rev 1.08.07 Nov. 2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support |
22 | Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support | 23 | Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support |
@@ -76,7 +77,7 @@ | |||
76 | #include "sis900.h" | 77 | #include "sis900.h" |
77 | 78 | ||
78 | #define SIS900_MODULE_NAME "sis900" | 79 | #define SIS900_MODULE_NAME "sis900" |
79 | #define SIS900_DRV_VERSION "v1.08.08 Jan. 22 2005" | 80 | #define SIS900_DRV_VERSION "v1.08.09 Sep. 19 2005" |
80 | 81 | ||
81 | static char version[] __devinitdata = | 82 | static char version[] __devinitdata = |
82 | KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n"; | 83 | KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n"; |
@@ -538,6 +539,11 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, | |||
538 | printk("%2.2x:", (u8)net_dev->dev_addr[i]); | 539 | printk("%2.2x:", (u8)net_dev->dev_addr[i]); |
539 | printk("%2.2x.\n", net_dev->dev_addr[i]); | 540 | printk("%2.2x.\n", net_dev->dev_addr[i]); |
540 | 541 | ||
542 | /* Detect Wake on Lan support */ | ||
543 | ret = inl(CFGPMC & PMESP); | ||
544 | if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0) | ||
545 | printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name); | ||
546 | |||
541 | return 0; | 547 | return 0; |
542 | 548 | ||
543 | err_unmap_rx: | 549 | err_unmap_rx: |
@@ -2015,6 +2021,67 @@ static int sis900_nway_reset(struct net_device *net_dev) | |||
2015 | return mii_nway_restart(&sis_priv->mii_info); | 2021 | return mii_nway_restart(&sis_priv->mii_info); |
2016 | } | 2022 | } |
2017 | 2023 | ||
2024 | /** | ||
2025 | * sis900_set_wol - Set up Wake on Lan registers | ||
2026 | * @net_dev: the net device to probe | ||
2027 | * @wol: container for info passed to the driver | ||
2028 | * | ||
2029 | * Process ethtool command "wol" to setup wake on lan features. | ||
2030 | * SiS900 supports sending WoL events if a correct packet is received, | ||
2031 | * but there is no simple way to filter them to only a subset (broadcast, | ||
2032 | * multicast, unicast or arp). | ||
2033 | */ | ||
2034 | |||
2035 | static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) | ||
2036 | { | ||
2037 | struct sis900_private *sis_priv = net_dev->priv; | ||
2038 | long pmctrl_addr = net_dev->base_addr + pmctrl; | ||
2039 | u32 cfgpmcsr = 0, pmctrl_bits = 0; | ||
2040 | |||
2041 | if (wol->wolopts == 0) { | ||
2042 | pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr); | ||
2043 | cfgpmcsr |= ~PME_EN; | ||
2044 | pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr); | ||
2045 | outl(pmctrl_bits, pmctrl_addr); | ||
2046 | if (netif_msg_wol(sis_priv)) | ||
2047 | printk(KERN_DEBUG "%s: Wake on LAN disabled\n", net_dev->name); | ||
2048 | return 0; | ||
2049 | } | ||
2050 | |||
2051 | if (wol->wolopts & (WAKE_MAGICSECURE | WAKE_UCAST | WAKE_MCAST | ||
2052 | | WAKE_BCAST | WAKE_ARP)) | ||
2053 | return -EINVAL; | ||
2054 | |||
2055 | if (wol->wolopts & WAKE_MAGIC) | ||
2056 | pmctrl_bits |= MAGICPKT; | ||
2057 | if (wol->wolopts & WAKE_PHY) | ||
2058 | pmctrl_bits |= LINKON; | ||
2059 | |||
2060 | outl(pmctrl_bits, pmctrl_addr); | ||
2061 | |||
2062 | pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr); | ||
2063 | cfgpmcsr |= PME_EN; | ||
2064 | pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr); | ||
2065 | if (netif_msg_wol(sis_priv)) | ||
2066 | printk(KERN_DEBUG "%s: Wake on LAN enabled\n", net_dev->name); | ||
2067 | |||
2068 | return 0; | ||
2069 | } | ||
2070 | |||
2071 | static void sis900_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) | ||
2072 | { | ||
2073 | long pmctrl_addr = net_dev->base_addr + pmctrl; | ||
2074 | u32 pmctrl_bits; | ||
2075 | |||
2076 | pmctrl_bits = inl(pmctrl_addr); | ||
2077 | if (pmctrl_bits & MAGICPKT) | ||
2078 | wol->wolopts |= WAKE_MAGIC; | ||
2079 | if (pmctrl_bits & LINKON) | ||
2080 | wol->wolopts |= WAKE_PHY; | ||
2081 | |||
2082 | wol->supported = (WAKE_PHY | WAKE_MAGIC); | ||
2083 | } | ||
2084 | |||
2018 | static struct ethtool_ops sis900_ethtool_ops = { | 2085 | static struct ethtool_ops sis900_ethtool_ops = { |
2019 | .get_drvinfo = sis900_get_drvinfo, | 2086 | .get_drvinfo = sis900_get_drvinfo, |
2020 | .get_msglevel = sis900_get_msglevel, | 2087 | .get_msglevel = sis900_get_msglevel, |
@@ -2023,6 +2090,8 @@ static struct ethtool_ops sis900_ethtool_ops = { | |||
2023 | .get_settings = sis900_get_settings, | 2090 | .get_settings = sis900_get_settings, |
2024 | .set_settings = sis900_set_settings, | 2091 | .set_settings = sis900_set_settings, |
2025 | .nway_reset = sis900_nway_reset, | 2092 | .nway_reset = sis900_nway_reset, |
2093 | .get_wol = sis900_get_wol, | ||
2094 | .set_wol = sis900_set_wol | ||
2026 | }; | 2095 | }; |
2027 | 2096 | ||
2028 | /** | 2097 | /** |
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h index de3c06735d15..4233ea55670f 100644 --- a/drivers/net/sis900.h +++ b/drivers/net/sis900.h | |||
@@ -33,6 +33,7 @@ enum sis900_registers { | |||
33 | rxcfg=0x34, //Receive Configuration Register | 33 | rxcfg=0x34, //Receive Configuration Register |
34 | flctrl=0x38, //Flow Control Register | 34 | flctrl=0x38, //Flow Control Register |
35 | rxlen=0x3c, //Receive Packet Length Register | 35 | rxlen=0x3c, //Receive Packet Length Register |
36 | cfgpmcsr=0x44, //Configuration Power Management Control/Status Register | ||
36 | rfcr=0x48, //Receive Filter Control Register | 37 | rfcr=0x48, //Receive Filter Control Register |
37 | rfdr=0x4C, //Receive Filter Data Register | 38 | rfdr=0x4C, //Receive Filter Data Register |
38 | pmctrl=0xB0, //Power Management Control Register | 39 | pmctrl=0xB0, //Power Management Control Register |
@@ -140,6 +141,50 @@ enum sis96x_eeprom_command { | |||
140 | EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100 | 141 | EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100 |
141 | }; | 142 | }; |
142 | 143 | ||
144 | /* PCI Registers */ | ||
145 | enum sis900_pci_registers { | ||
146 | CFGPMC = 0x40, | ||
147 | CFGPMCSR = 0x44 | ||
148 | }; | ||
149 | |||
150 | /* Power management capabilities bits */ | ||
151 | enum sis900_cfgpmc_register_bits { | ||
152 | PMVER = 0x00070000, | ||
153 | DSI = 0x00100000, | ||
154 | PMESP = 0xf8000000 | ||
155 | }; | ||
156 | |||
157 | enum sis900_pmesp_bits { | ||
158 | PME_D0 = 0x1, | ||
159 | PME_D1 = 0x2, | ||
160 | PME_D2 = 0x4, | ||
161 | PME_D3H = 0x8, | ||
162 | PME_D3C = 0x10 | ||
163 | }; | ||
164 | |||
165 | /* Power management control/status bits */ | ||
166 | enum sis900_cfgpmcsr_register_bits { | ||
167 | PMESTS = 0x00004000, | ||
168 | PME_EN = 0x00000100, // Power management enable | ||
169 | PWR_STA = 0x00000003 // Current power state | ||
170 | }; | ||
171 | |||
172 | /* Wake-on-LAN support. */ | ||
173 | enum sis900_power_management_control_register_bits { | ||
174 | LINKLOSS = 0x00000001, | ||
175 | LINKON = 0x00000002, | ||
176 | MAGICPKT = 0x00000400, | ||
177 | ALGORITHM = 0x00000800, | ||
178 | FRM1EN = 0x00100000, | ||
179 | FRM2EN = 0x00200000, | ||
180 | FRM3EN = 0x00400000, | ||
181 | FRM1ACS = 0x01000000, | ||
182 | FRM2ACS = 0x02000000, | ||
183 | FRM3ACS = 0x04000000, | ||
184 | WAKEALL = 0x40000000, | ||
185 | GATECLK = 0x80000000 | ||
186 | }; | ||
187 | |||
143 | /* Management Data I/O (mdio) frame */ | 188 | /* Management Data I/O (mdio) frame */ |
144 | #define MIIread 0x6000 | 189 | #define MIIread 0x6000 |
145 | #define MIIwrite 0x5002 | 190 | #define MIIwrite 0x5002 |