Bug Summary

File:obj-scan-build/../linux/src/drivers/net/sis900.c
Location:line 643, column 2
Description:Value stored to 'status' is never read

Annotated Source Code

1/* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
2 Copyright 1999 Silicon Integrated System Corporation
3 Revision: 1.06.11 Apr. 30 2002
4
5 Modified from the driver which is originally written by Donald Becker.
6
7 This software may be used and distributed according to the terms
8 of the GNU Public License (GPL), incorporated herein by reference.
9 Drivers based on this skeleton fall under the GPL and must retain
10 the authorship (implicit copyright) notice.
11
12 References:
13 SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
14 preliminary Rev. 1.0 Jan. 14, 1998
15 SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
16 preliminary Rev. 1.0 Nov. 10, 1998
17 SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
18 preliminary Rev. 1.0 Jan. 18, 1998
19 http://www.sis.com.tw/support/databook.htm
20
21 Rev 1.06.11 Apr. 25 2002 Mufasa Yang (mufasa@sis.com.tw) added SiS962 support
22 Rev 1.06.10 Dec. 18 2001 Hui-Fen Hsu workaround for EDB & RTL8201 PHY
23 Rev 1.06.09 Sep. 28 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
24 Rev 1.06.08 Mar. 2 2001 Hui-Fen Hsu (hfhsu@sis.com.tw) some bug fix & 635M/B support
25 Rev 1.06.07 Jan. 8 2001 Lei-Chun Chang added RTL8201 PHY support
26 Rev 1.06.06 Sep. 6 2000 Lei-Chun Chang added ICS1893 PHY support
27 Rev 1.06.05 Aug. 22 2000 Lei-Chun Chang (lcchang@sis.com.tw) modified 630E equalier workaroung rule
28 Rev 1.06.03 Dec. 23 1999 Ollie Lho Third release
29 Rev 1.06.02 Nov. 23 1999 Ollie Lho bug in mac probing fixed
30 Rev 1.06.01 Nov. 16 1999 Ollie Lho CRC calculation provide by Joseph Zbiciak (im14u2c@primenet.com)
31 Rev 1.06 Nov. 4 1999 Ollie Lho (ollie@sis.com.tw) Second release
32 Rev 1.05.05 Oct. 29 1999 Ollie Lho (ollie@sis.com.tw) Single buffer Tx/Rx
33 Chin-Shan Li (lcs@sis.com.tw) Added AMD Am79c901 HomePNA PHY support
34 Rev 1.05 Aug. 7 1999 Jim Huang (cmhuang@sis.com.tw) Initial release
35*/
36
37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/kernel.h>
40#include <linux/sched.h>
41#include <linux/string.h>
42#include <linux/timer.h>
43#include <linux/errno.h>
44#include <linux/ioport.h>
45#include <linux/malloc.h>
46#include <linux/interrupt.h>
47#include <linux/pci.h>
48#include <linux/netdevice.h>
49#include <linux/bios32.h>
50#include <linux/compatmac.h>
51
52#include <linux/etherdevice.h>
53#include <linux/skbuff.h>
54#include <asm/processor.h> /* Processor type for cache alignment. */
55#include <asm/bitops.h>
56#include <asm/io.h>
57#include <linux/delay.h>
58#include <asm/types.h>
59#include "sis900.h"
60
61
62#if LINUX_VERSION_CODE131108 < 0x20159
63#define dev_free_skb(skb)dev_kfree_skb (skb, 0); dev_kfree_skb (skb, FREE_WRITE0);
64#else /* Grrr, incompatible changes should change the name. */
65#define dev_free_skb(skb)dev_kfree_skb (skb, 0); dev_kfree_skb(skb);
66#endif
67
68static const char *version =
69"sis900.c: modified v1.06.11 4/30/2002";
70
71static int max_interrupt_work = 20;
72static int multicast_filter_limit = 128;
73
74#define sis900_debugdebug debug
75static int sis900_debugdebug = 0;
76
77/* Time in jiffies before concluding the transmitter is hung. */
78#define TX_TIMEOUT(4*100) (4*HZ100)
79
80enum pci_flags_bit {
81 PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
82 PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
83};
84
85struct mac_chip_info {
86 const char *name;
87 u16 vendor_id, device_id, flags;
88 int io_size;
89 struct devicelinux_device *(*probe) (struct mac_chip_info *mac, long ioaddr, int irq,
90 int pci_index, unsigned char pci_device_fn, unsigned char pci_bus, struct devicelinux_device * net_dev);
91};
92static struct devicelinux_device * sis900_mac_probe (struct mac_chip_info * mac, long ioaddr, int irq,
93 int pci_index, unsigned char pci_device_fn,
94 unsigned char pci_bus, struct devicelinux_device * net_dev);
95static struct mac_chip_info mac_chip_table[] = {
96 { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SI0x1039, PCI_DEVICE_ID_SI_9000x900,
97 PCI_COMMAND_IO0x1|PCI_COMMAND_MASTER0x4, SIS900_TOTAL_SIZE0x100, sis900_mac_probe},
98 { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SI0x1039, PCI_DEVICE_ID_SI_70160x7016,
99 PCI_COMMAND_IO0x1|PCI_COMMAND_MASTER0x4, SIS900_TOTAL_SIZE0x100, sis900_mac_probe},
100 {0,}, /* 0 terminatted list. */
101};
102
103static void sis900_read_mode(struct devicelinux_device *net_dev, int *speed, int *duplex);
104
105static struct mii_chip_info {
106 const char * name;
107 u16 phy_id0;
108 u16 phy_id1;
109 u8 phy_types;
110#define HOME0x0001 0x0001
111#define LAN0x0002 0x0002
112#define MIX0x0003 0x0003
113} mii_chip_table[] = {
114 { "SiS 900 Internal MII PHY", 0x001d, 0x8000, LAN0x0002 },
115 { "SiS 7014 Physical Layer Solution", 0x0016, 0xf830, LAN0x0002 },
116 { "AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, LAN0x0002 },
117 { "AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, HOME0x0001},
118 { "ICS LAN PHY", 0x0015, 0xF440, LAN0x0002 },
119 { "NS 83851 PHY", 0x2000, 0x5C20, MIX0x0003 },
120 { "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN0x0002 },
121 {0,},
122};
123
124struct mii_phy {
125 struct mii_phy * next;
126 int phy_addr;
127 u16 phy_id0;
128 u16 phy_id1;
129 u16 status;
130 u8 phy_types;
131};
132
133typedef struct _BufferDesc {
134 u32 link;
135 u32 cmdsts;
136 u32 bufptr;
137} BufferDesc;
138
139struct sis900_private {
140 struct devicelinux_device *next_module;
141 struct enet_statistics stats;
142
143 /* struct pci_dev * pci_dev;*/
144 unsigned char pci_bus;
145 unsigned char pci_device_fn;
146 int pci_index;
147
148 struct mac_chip_info * mac;
149 struct mii_phy * mii;
150 struct mii_phy * first_mii; /* record the first mii structure */
151 unsigned int cur_phy;
152
153 struct timer_list timer; /* Link status detection timer. */
154 u8 autong_complete; /* 1: auto-negotiate complete */
155
156 unsigned int cur_rx, dirty_rx; /* producer/comsumer pointers for Tx/Rx ring */
157 unsigned int cur_tx, dirty_tx;
158
159 /* The saved address of a sent/receive-in-place packet buffer */
160 struct sk_buff *tx_skbuff[NUM_TX_DESC16];
161 struct sk_buff *rx_skbuff[NUM_RX_DESC16];
162 BufferDesc tx_ring[NUM_TX_DESC16];
163 BufferDesc rx_ring[NUM_RX_DESC16];
164
165 unsigned int tx_full; /* The Tx queue is full. */
166 int LinkOn;
167};
168
169#ifdef MODULE
170#if LINUX_VERSION_CODE131108 > 0x20115
171MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
172MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
173MODULE_PARM(multicast_filter_limit, "i");
174MODULE_PARM(max_interrupt_work, "i");
175MODULE_PARM(debug, "i");
176#endif
177#endif
178
179static int sis900_open(struct devicelinux_device *net_dev);
180static int sis900_mii_probe (unsigned char pci_bus, unsigned char pci_device_fn, struct devicelinux_device * net_dev);
181static void sis900_init_rxfilter (struct devicelinux_device * net_dev);
182static u16 read_eeprom(long ioaddr, int location);
183static u16 mdio_read(struct devicelinux_device *net_dev, int phy_id, int location);
184static void mdio_write(struct devicelinux_device *net_dev, int phy_id, int location, int val);
185static void sis900_timer(unsigned long data);
186static void sis900_check_mode (struct devicelinux_device *net_dev, struct mii_phy *mii_phy);
187static void sis900_tx_timeout(struct devicelinux_device *net_dev);
188static void sis900_init_tx_ring(struct devicelinux_device *net_dev);
189static void sis900_init_rx_ring(struct devicelinux_device *net_dev);
190static int sis900_start_xmit(struct sk_buff *skb, struct devicelinux_device *net_dev);
191static int sis900_rx(struct devicelinux_device *net_dev);
192static void sis900_finish_xmit (struct devicelinux_device *net_dev);
193static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
194static int sis900_close(struct devicelinux_device *net_dev);
195static int mii_ioctl(struct devicelinux_device *net_dev, struct ifreq *rq, int cmd);
196static struct enet_statistics *sis900_get_stats(struct devicelinux_device *net_dev);
197static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision);
198static void set_rx_mode(struct devicelinux_device *net_dev);
199static void sis900_reset(struct devicelinux_device *net_dev);
200static void sis630_set_eq(struct devicelinux_device *net_dev, u8 revision);
201static u16 sis900_default_phy(struct devicelinux_device * net_dev);
202static void sis900_set_capability( struct devicelinux_device *net_dev ,struct mii_phy *phy);
203static u16 sis900_reset_phy(struct devicelinux_device *net_dev, int phy_addr);
204static void sis900_auto_negotiate(struct devicelinux_device *net_dev, int phy_addr);
205static void sis900_set_mode (long ioaddr, int speed, int duplex);
206
207/* A list of all installed SiS900 devices, for removing the driver module. */
208static struct devicelinux_device *root_sis900_dev = NULL((void *) 0);
209
210#ifdef HAVE_DEVLIST
211struct netdev_entry netcard_drv =
212 {"sis900", sis900_probe, SIS900_TOTAL_SIZE0x100, NULL((void *) 0)};
213#endif
214
215/* walk through every ethernet PCI devices to see if some of them are matched with our card list*/
216int sis900_probe (struct devicelinux_device * net_dev)
217{
218 int found = 0;
219 int pci_index = 0;
220 unsigned char pci_bus, pci_device_fn;
221 long ioaddr;
222 int irq;
223
224 if (!pcibios_present())
225 return -ENODEV19;
226
227 for (; pci_index < 0xff; pci_index++)
228 {
229 u16 vendor, devicelinux_device, pci_command;
230 struct mac_chip_info *mac;
231
232 if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET0x0200 << 8, pci_index,
233 &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL0x00)
234 break;
235
236 pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID0x00, &vendor);
237 pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID0x02, &devicelinux_device);
238
239 for (mac = mac_chip_table; mac->vendor_id; mac++)
240 {
241 if (vendor == mac->vendor_id && devicelinux_device == mac->device_id) break;
242 }
243
244 /* pci_dev does not match any of our cards */
245 if (mac->vendor_id == 0)
246 continue;
247
248 {
249 u32 pci_ioaddr;
250 u8 pci_irq_line;
251
252 pcibios_read_config_byte(pci_bus, pci_device_fn,
253 PCI_INTERRUPT_LINE0x3c, &pci_irq_line);
254 pcibios_read_config_dword(pci_bus, pci_device_fn,
255 PCI_BASE_ADDRESS_00x10, &pci_ioaddr);
256 ioaddr = pci_ioaddr & ~3;
257 irq = pci_irq_line;
258
259 if ((mac->flags & PCI_USES_IO) &&
260 check_region (pci_ioaddr, mac->io_size))
261 continue;
262
263 pcibios_read_config_word(pci_bus, pci_device_fn,
264 PCI_COMMAND0x04, &pci_command);
265
266 {
267 u8 lat;
268
269 pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER0x0d, &lat);
270 if (lat < 16) {
271 printk("PCI: Increasing latency timer of device %02x:%02x to 64\n",
272 pci_bus, pci_device_fn);
273 pcibios_write_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER0x0d, 64);
274 }
275 }
276 net_dev = mac->probe (mac, ioaddr, irq, pci_index, pci_device_fn, pci_bus, net_dev);
277 if (net_dev != NULL((void *) 0))
278 {
279 found++;
280 }
281 net_dev = NULL((void *) 0);
282 }
283 }
284 return found ? 0 : -ENODEV19;
285
286}
287
288/* older SiS900 and friends, use EEPROM to store MAC address */
289static int
290sis900_get_mac_addr(long ioaddr, struct devicelinux_device *net_dev)
291{
292 u16 signature;
293 int i;
294
295 /* check to see if we have sane EEPROM */
296 signature = (u16) read_eeprom(ioaddr, EEPROMSignature);
297 if (signature == 0xffff || signature == 0x0000) {
298 printk (KERN_INFO"<6>" "%s: Error EERPOM read %x\n",
299 net_dev->name, signature);
300 return 0;
301 }
302
303 /* get MAC address from EEPROM */
304 for (i = 0; i < 3; i++)
305 ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
306 return 1;
307}
308
309/* SiS630E model, use APC CMOS RAM to store MAC address */
310static int sis630e_get_mac_addr(long ioaddr, int pci_index, struct devicelinux_device *net_dev)
311{
312 u8 reg;
313 int i;
314 u8 pci_bus, pci_dfn;
315 int not_found;
316
317 not_found = pcibios_find_device(0x1039, 0x0008,
318 pci_index,
319 &pci_bus,
320 &pci_dfn);
321 if (not_found) {
322 printk("%s: Can not find ISA bridge\n", net_dev->name);
323 return 0;
324 }
325 pcibios_read_config_byte(pci_bus, pci_dfn, 0x48, &reg);
326 pcibios_write_config_byte(pci_bus, pci_dfn, 0x48, reg | 0x40);
327
328 for (i = 0; i < 6; i++) {
329 outb(0x09 + i, 0x70)((__builtin_constant_p((0x70)) && (0x70) < 256) ? __outbc
((0x09 + i),(0x70)) : __outb((0x09 + i),(0x70)))
;
330 ((u8 *)(net_dev->dev_addr))[i] = inb(0x71)((__builtin_constant_p((0x71)) && (0x71) < 256) ? __inbc
(0x71) : __inb(0x71))
;
331 }
332 pcibios_write_config_byte(pci_bus, pci_dfn, 0x48, reg & ~0x40);
333
334 return 1;
335}
336
337/* 635 model : set Mac reload bit and get mac address from rfdr */
338static int sis635_get_mac_addr(struct devicelinux_device *net_dev)
339{
340 long ioaddr = net_dev->base_addr;
341 u32 rfcrSave;
342 u32 i;
343
344 rfcrSave = inl(rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __inlc(rfcr + ioaddr) : __inl(rfcr + ioaddr))
;
345
346 outl(rfcrSave | RELOAD, ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((rfcrSave | RELOAD),(ioaddr + cr)) : __outl
((rfcrSave | RELOAD),(ioaddr + cr)))
;
347 outl(0, ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((0),(ioaddr + cr)) : __outl((0),(ioaddr
+ cr)))
;
348
349 /* disable packet filtering before setting filter */
350 outl(rfcrSave & ~RFEN, rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __outlc((rfcrSave & ~RFEN),(rfcr + ioaddr))
: __outl((rfcrSave & ~RFEN),(rfcr + ioaddr)))
;
351
352 /* load MAC addr to filter data register */
353 for (i = 0 ; i < 3 ; i++) {
354 outl((i << RFADDR_shift), ioaddr + rfcr)((__builtin_constant_p((ioaddr + rfcr)) && (ioaddr + rfcr
) < 256) ? __outlc(((i << 16)),(ioaddr + rfcr)) : __outl
(((i << 16)),(ioaddr + rfcr)))
;
355 *( ((u16 *)net_dev->dev_addr) + i) = inw(ioaddr + rfdr)((__builtin_constant_p((ioaddr + rfdr)) && (ioaddr + rfdr
) < 256) ? __inwc(ioaddr + rfdr) : __inw(ioaddr + rfdr))
;
356 }
357
358 /* enable packet filitering */
359 outl(rfcrSave | RFEN, rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __outlc((rfcrSave | RFEN),(rfcr + ioaddr)) : __outl
((rfcrSave | RFEN),(rfcr + ioaddr)))
;
360
361 return 1;
362}
363
364
365/**
366 * sis962_get_mac_addr: - Get MAC address for SiS962 model
367 * @pci_dev: the sis900 pci device
368 * @net_dev: the net device to get address for
369 *
370 * SiS962 model, use EEPROM to store MAC address. And EEPROM is shared by
371 * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
372 * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
373 * by LAN, otherwise is not. After MAC address is read from EEPROM, send
374 * EEDONE signal to refuse EEPROM access by LAN.
375 * MAC address is read into @net_dev->dev_addr.
376 */
377
378static int sis962_get_mac_addr(struct devicelinux_device *net_dev)
379{
380 long ioaddr = net_dev->base_addr;
381 long ee_addr = ioaddr + mear;
382 u32 waittime = 0;
383 int i;
384
385 outl(EEREQ, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EEREQ),(ee_addr)) : __outl((EEREQ),(ee_addr)))
;
386 while(waittime < 2000) {
387 if(inl(ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
& EEGNT) {
388 /* get MAC address from EEPROM */
389 for (i = 0; i < 3; i++)
390 ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
391 outl(EEDONE, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EEDONE),(ee_addr)) : __outl((EEDONE),(ee_addr)))
;
392 return 1;
393 } else {
394 udelay(1)(__builtin_constant_p(1) ? __const_udelay((1) * 0x10c6ul) : __udelay
(1))
;
395 waittime ++;
396 }
397 }
398 outl(EEDONE, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EEDONE),(ee_addr)) : __outl((EEDONE),(ee_addr)))
;
399 return 0;
400}
401
402struct devicelinux_device *
403sis900_mac_probe (struct mac_chip_info *mac, long ioaddr, int irq, int pci_index,
404 unsigned char pci_device_fn, unsigned char pci_bus, struct devicelinux_device * net_dev)
405{
406 struct sis900_private *sis_priv;
407 static int did_version = 0;
408
409 u8 revision;
410 int i, ret = 0;
411
412 if (did_version++ == 0)
413 printk(KERN_INFO"<6>" "%s\n", version);
414
415 if ((net_dev = init_etherdev(net_dev, 0)) == NULL((void *) 0))
416 return NULL((void *) 0);
417
418 if ((net_dev->priv = kmalloclinux_kmalloc(sizeof(struct sis900_private), GFP_KERNEL0x03)) == NULL((void *) 0)) {
419 unregister_netdev(net_dev);
420 return NULL((void *) 0);
421 }
422
423 sis_priv = net_dev->priv;
424 memset(sis_priv, 0, sizeof(struct sis900_private))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
sis900_private))) ? __constant_c_and_count_memset(((sis_priv
)),((0x01010101UL*(unsigned char)(0))),((sizeof(struct sis900_private
)))) : __constant_c_memset(((sis_priv)),((0x01010101UL*(unsigned
char)(0))),((sizeof(struct sis900_private))))) : (__builtin_constant_p
((sizeof(struct sis900_private))) ? __memset_generic((((sis_priv
))),(((0))),(((sizeof(struct sis900_private))))) : __memset_generic
(((sis_priv)),((0)),((sizeof(struct sis900_private))))))
;
425
426 /* We do a request_region() to register /proc/ioports info. */
427 request_region(ioaddr, mac->io_size, net_dev->name);
428 net_dev->base_addr = ioaddr;
429 net_dev->irq = irq;
430
431 sis_priv->mac = mac;
432 sis_priv->pci_bus = pci_bus;
433 sis_priv->pci_device_fn = pci_device_fn;
434 sis_priv->pci_index = pci_index;
435
436 pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
437
438 if ( revision == SIS630E_900_REV )
439 ret = sis630e_get_mac_addr(ioaddr, pci_index, net_dev);
440 else if ((revision > 0x81) && (revision <= 0x90))
441 ret = sis635_get_mac_addr(net_dev);
442 else if (revision == SIS962_900_REV)
443 ret = sis962_get_mac_addr(net_dev);
444 else
445 ret = sis900_get_mac_addr(ioaddr, net_dev);
446
447 if (ret == 0) {
448 unregister_netdev(net_dev);
449 return NULL((void *) 0);
450 }
451
452 /* print some information about our NIC */
453 printk(KERN_INFO"<6>" "%s: %s at %#lx, IRQ %d, ", net_dev->name, mac->name,
454 ioaddr, irq);
455 for (i = 0; i < 5; i++)
456 printk("%2.2x:", (u8)net_dev->dev_addr[i]);
457 printk("%2.2x.\n", net_dev->dev_addr[i]);
458
459 /* 630ET : set the mii access mode as software-mode */
460 if (revision == SIS630ET_900_REV)
461 outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((ACCESSMODE | ((__builtin_constant_p((ioaddr
+ cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr + cr
) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((ACCESSMODE |
((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __inlc(ioaddr + cr) : __inl(ioaddr + cr))),(ioaddr
+ cr)))
;
462
463 /* probe for mii transceiver */
464 if (sis900_mii_probe(pci_bus, pci_device_fn, net_dev) == 0) {
465 unregister_netdev(net_dev);
466 kfreelinux_kfree(sis_priv);
467 release_region(ioaddr, mac->io_size);
468 return NULL((void *) 0);
469 }
470
471 sis_priv->next_module = root_sis900_dev;
472 root_sis900_dev = net_dev;
473
474 /* The SiS900-specific entries in the device structure. */
475 net_dev->open = &sis900_open;
476 net_dev->hard_start_xmit = &sis900_start_xmit;
477 net_dev->stop = &sis900_close;
478 net_dev->get_stats = &sis900_get_stats;
479 net_dev->set_multicast_list = &set_rx_mode;
480 net_dev->do_ioctl = &mii_ioctl;
481
482 return net_dev;
483}
484
485/* sis900_mii_probe: - Probe MII PHY for sis900 */
486static int sis900_mii_probe (unsigned char pci_bus, unsigned char pci_device_fn, struct devicelinux_device * net_dev)
487{
488 struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
489 u16 poll_bit = MII_STAT_LINK, status = 0;
490 unsigned int timeout = jiffies + 5 * HZ100;
491 int phy_addr;
492 u8 revision;
493
494 sis_priv->mii = NULL((void *) 0);
495
496 /* search for total of 32 possible mii phy addresses */
497 for (phy_addr = 0; phy_addr < 32; phy_addr++) {
498 struct mii_phy * mii_phy = NULL((void *) 0);
499 u16 mii_status;
500 int i;
501
502 for(i=0; i<2; i++)
503 mii_status = mdio_read(net_dev, phy_addr, MII_STATUS);
504
505 if (mii_status == 0xffff || mii_status == 0x0000)
506 /* the mii is not accessable, try next one */
507 continue;
508
509 if ((mii_phy = kmalloclinux_kmalloc(sizeof(struct mii_phy), GFP_KERNEL0x03)) == NULL((void *) 0)) {
510 printk(KERN_INFO"<6>" "Cannot allocate mem for struct mii_phy\n");
511 return 0;
512 }
513
514 mii_phy->phy_id0 = mdio_read(net_dev, phy_addr, MII_PHY_ID0);
515 mii_phy->phy_id1 = mdio_read(net_dev, phy_addr, MII_PHY_ID1);
516 mii_phy->phy_addr = phy_addr;
517 mii_phy->status = mii_status;
518 mii_phy->next = sis_priv->mii;
519 sis_priv->mii = mii_phy;
520 sis_priv->first_mii = mii_phy;
521
522 for (i=0; mii_chip_table[i].phy_id1; i++)
523 if ( ( mii_phy->phy_id0 == mii_chip_table[i].phy_id0 ) &&
524 ( (mii_phy->phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1 )){
525
526 mii_phy->phy_types = mii_chip_table[i].phy_types;
527 if(mii_chip_table[i].phy_types == MIX0x0003)
528 mii_phy->phy_types =
529 (mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX))?LAN0x0002:HOME0x0001;
530 printk(KERN_INFO"<6>" "%s: %s transceiver found at address %d.\n",
531 net_dev->name, mii_chip_table[i].name, phy_addr);
532 break;
533 }
534
535 if( !mii_chip_table[i].phy_id1 )
536 printk(KERN_INFO"<6>" "%s: Unknown PHY transceiver found at address %d.\n",
537 net_dev->name, phy_addr);
538 }
539
540 if (sis_priv->mii == NULL((void *) 0)) {
541 printk(KERN_INFO"<6>" "%s: No MII transceivers found!\n",
542 net_dev->name);
543 return 0;
544 }
545
546 /* Slect Default PHY to put in sis_priv->mii & sis_priv->cur_phy */
547 sis_priv->mii = NULL((void *) 0);
548 sis900_default_phy( net_dev );
549
550 /* Reset PHY if default PHY is internal sis900 */
551 if( (sis_priv->mii->phy_id0 == 0x001D) &&
552 ( (sis_priv->mii->phy_id1&0xFFF0) == 0x8000) )
553 status = sis900_reset_phy( net_dev, sis_priv->cur_phy );
554
555 /* workaround for ICS1893 PHY */
556 if ((sis_priv->mii->phy_id0 == 0x0015) &&
557 ((sis_priv->mii->phy_id1&0xFFF0) == 0xF440))
558 mdio_write(net_dev, sis_priv->cur_phy, 0x0018, 0xD200);
559
560 if( status & MII_STAT_LINK ){
561 while (poll_bit)
562 {
563 poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit);
564 if (jiffies >= timeout)
565 {
566 printk(KERN_WARNING"<4>" "%s: reset phy and link down now\n", net_dev->name);
567 return -ETIME62;
568 }
569 }
570 }
571
572 pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
573 if (revision == SIS630E_900_REV) {
574 /* SiS 630E has some bugs on default value of PHY registers */
575 mdio_write(net_dev, sis_priv->cur_phy, MII_ANADV, 0x05e1);
576 mdio_write(net_dev, sis_priv->cur_phy, MII_CONFIG1, 0x22);
577 mdio_write(net_dev, sis_priv->cur_phy, MII_CONFIG2, 0xff00);
578 mdio_write(net_dev, sis_priv->cur_phy, MII_MASK, 0xffc0);
579 //mdio_write(net_dev, sis_priv->cur_phy, MII_CONTROL, 0x1000);
580 }
581
582 if (sis_priv->mii->status & MII_STAT_LINK)
583 sis_priv->LinkOn = TRUE1;
584 else
585 sis_priv->LinkOn = FALSE0;
586
587 return 1;
588}
589
590
591/* sis900_default_phy : Select one default PHY for sis900 mac */
592static u16 sis900_default_phy(struct devicelinux_device * net_dev)
593{
594 struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
595 struct mii_phy *phy = NULL((void *) 0), *phy_home = NULL((void *) 0), *default_phy = NULL((void *) 0);
596 u16 status;
597
598 for( phy=sis_priv->first_mii; phy; phy=phy->next ){
599 status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
600 status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
601
602 /* Link ON & Not select deafalut PHY */
603 if ( (status & MII_STAT_LINK) && !(default_phy) )
604 default_phy = phy;
605 else{
606 status = mdio_read(net_dev, phy->phy_addr, MII_CONTROL);
607 mdio_write(net_dev, phy->phy_addr, MII_CONTROL,
608 status | MII_CNTL_AUTO | MII_CNTL_ISOLATE);
609 if( phy->phy_types == HOME0x0001 )
610 phy_home = phy;
611 }
612 }
613
614 if( (!default_phy) && phy_home )
615 default_phy = phy_home;
616 else if(!default_phy)
617 default_phy = sis_priv->first_mii;
618
619 if( sis_priv->mii != default_phy ){
620 sis_priv->mii = default_phy;
621 sis_priv->cur_phy = default_phy->phy_addr;
622 printk(KERN_INFO"<6>" "%s: Using transceiver found at address %d as default\n", net_dev->name,sis_priv->cur_phy);
623 }
624
625 status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
626 status &= (~MII_CNTL_ISOLATE);
627
628 mdio_write(net_dev, sis_priv->cur_phy, MII_CONTROL, status);
629 status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
630 status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
631
632 return status;
633}
634
635
636/* sis900_set_capability : set the media capability of network adapter */
637static void sis900_set_capability( struct devicelinux_device *net_dev , struct mii_phy *phy )
638{
639 u16 cap;
640 u16 status;
641
642 status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
643 status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
Value stored to 'status' is never read
644
645 cap = MII_NWAY_CSMA_CD |
646 ((phy->status & MII_STAT_CAN_TX_FDX)? MII_NWAY_TX_FDX:0) |
647 ((phy->status & MII_STAT_CAN_TX) ? MII_NWAY_TX:0) |
648 ((phy->status & MII_STAT_CAN_T_FDX) ? MII_NWAY_T_FDX:0)|
649 ((phy->status & MII_STAT_CAN_T) ? MII_NWAY_T:0);
650
651 mdio_write( net_dev, phy->phy_addr, MII_ANADV, cap );
652}
653
654
655/* Delay between EEPROM clock transitions. */
656#define eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
inl(ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
657
658/* Read Serial EEPROM through EEPROM Access Register, Note that location is
659 in word (16 bits) unit */
660static u16 read_eeprom(long ioaddr, int location)
661{
662 int i;
663 u16 retval = 0;
664 long ee_addr = ioaddr + mear;
665 u32 read_cmd = location | EEread;
666
667 outl(0, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((0),(ee_addr)) : __outl((0),(ee_addr)))
;
668 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
669 outl(EECS, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EECS),(ee_addr)) : __outl((EECS),(ee_addr)))
;
670 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
671
672 /* Shift the read command (9) bits out. */
673 for (i = 8; i >= 0; i--) {
674 u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
675 outl(dataval, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((dataval),(ee_addr)) : __outl((dataval),(ee_addr)
))
;
676 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
677 outl(dataval | EECLK, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((dataval | EECLK),(ee_addr)) : __outl((dataval | EECLK
),(ee_addr)))
;
678 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
679 }
680 outb(EECS, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outbc((EECS),(ee_addr)) : __outb((EECS),(ee_addr)))
;
681 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
682
683 /* read the 16-bits data in */
684 for (i = 16; i > 0; i--) {
685 outl(EECS, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EECS),(ee_addr)) : __outl((EECS),(ee_addr)))
;
686 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
687 outl(EECS | EECLK, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((EECS | EECLK),(ee_addr)) : __outl((EECS | EECLK)
,(ee_addr)))
;
688 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
689 retval = (retval << 1) | ((inl(ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
& EEDO) ? 1 : 0);
690 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
691 }
692
693 /* Terminate the EEPROM access. */
694 outl(0, ee_addr)((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __outlc((0),(ee_addr)) : __outl((0),(ee_addr)))
;
695 eeprom_delay()((__builtin_constant_p((ee_addr)) && (ee_addr) < 256
) ? __inlc(ee_addr) : __inl(ee_addr))
;
696// outl(EECLK, ee_addr);
697
698 return (retval);
699}
700
701/* Read and write the MII management registers using software-generated
702 serial MDIO protocol. Note that the command bits and data bits are
703 send out seperately */
704#define mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
inl(mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
705
706static void mdio_idle(long mdio_addr)
707{
708 outl(MDIO | MDDIR, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((MDIO | MDDIR),(mdio_addr)) : __outl((MDIO | MDDIR
),(mdio_addr)))
;
709 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
710 outl(MDIO | MDDIR | MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((MDIO | MDDIR | MDC),(mdio_addr)) : __outl((MDIO
| MDDIR | MDC),(mdio_addr)))
;
711}
712
713/* Syncronize the MII management interface by shifting 32 one bits out. */
714static void mdio_reset(long mdio_addr)
715{
716 int i;
717
718 for (i = 31; i >= 0; i--) {
719 outl(MDDIR | MDIO, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((MDDIR | MDIO),(mdio_addr)) : __outl((MDDIR |
MDIO),(mdio_addr)))
;
720 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
721 outl(MDDIR | MDIO | MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((MDDIR | MDIO | MDC),(mdio_addr)) : __outl((MDDIR
| MDIO | MDC),(mdio_addr)))
;
722 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
723 }
724 return;
725}
726
727static u16 mdio_read(struct devicelinux_device *net_dev, int phy_id, int location)
728{
729 long mdio_addr = net_dev->base_addr + mear;
730 int mii_cmd = MIIread0x6000|(phy_id<<MIIpmdShift7)|(location<<MIIregShift2);
731 u16 retval = 0;
732 int i;
733
734 mdio_reset(mdio_addr);
735 mdio_idle(mdio_addr);
736
737 for (i = 15; i >= 0; i--) {
738 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
739 outl(dataval, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((dataval),(mdio_addr)) : __outl((dataval),(mdio_addr
)))
;
740 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
741 outl(dataval | MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((dataval | MDC),(mdio_addr)) : __outl((dataval
| MDC),(mdio_addr)))
;
742 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
743 }
744
745 /* Read the 16 data bits. */
746 for (i = 16; i > 0; i--) {
747 outl(0, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((0),(mdio_addr)) : __outl((0),(mdio_addr)))
;
748 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
749 retval = (retval << 1) | ((inl(mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
& MDIO) ? 1 : 0);
750 outl(MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((MDC),(mdio_addr)) : __outl((MDC),(mdio_addr)
))
;
751 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
752 }
753 outl(0x00, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((0x00),(mdio_addr)) : __outl((0x00),(mdio_addr
)))
;
754
755 return retval;
756}
757
758static void mdio_write(struct devicelinux_device *net_dev, int phy_id, int location, int value)
759{
760 long mdio_addr = net_dev->base_addr + mear;
761 int mii_cmd = MIIwrite0x5002|(phy_id<<MIIpmdShift7)|(location<<MIIregShift2);
762 int i;
763
764 mdio_reset(mdio_addr);
765 mdio_idle(mdio_addr);
766
767 /* Shift the command bits out. */
768 for (i = 15; i >= 0; i--) {
769 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
770 outb(dataval, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outbc((dataval),(mdio_addr)) : __outb((dataval),(mdio_addr
)))
;
771 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
772 outb(dataval | MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outbc((dataval | MDC),(mdio_addr)) : __outb((dataval
| MDC),(mdio_addr)))
;
773 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
774 }
775 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
776
777 /* Shift the value bits out. */
778 for (i = 15; i >= 0; i--) {
779 int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
780 outl(dataval, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((dataval),(mdio_addr)) : __outl((dataval),(mdio_addr
)))
;
781 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
782 outl(dataval | MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((dataval | MDC),(mdio_addr)) : __outl((dataval
| MDC),(mdio_addr)))
;
783 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
784 }
785 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
786
787 /* Clear out extra bits. */
788 for (i = 2; i > 0; i--) {
789 outb(0, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outbc((0),(mdio_addr)) : __outb((0),(mdio_addr)))
;
790 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
791 outb(MDC, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outbc((MDC),(mdio_addr)) : __outb((MDC),(mdio_addr)
))
;
792 mdio_delay()((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __inlc(mdio_addr) : __inl(mdio_addr))
;
793 }
794 outl(0x00, mdio_addr)((__builtin_constant_p((mdio_addr)) && (mdio_addr) <
256) ? __outlc((0x00),(mdio_addr)) : __outl((0x00),(mdio_addr
)))
;
795
796 return;
797}
798
799static u16 sis900_reset_phy(struct devicelinux_device *net_dev, int phy_addr)
800{
801 int i = 0;
802 u16 status;
803
804 while (i++ < 2)
805 status = mdio_read(net_dev, phy_addr, MII_STATUS);
806
807 mdio_write( net_dev, phy_addr, MII_CONTROL, MII_CNTL_RESET );
808
809 return status;
810}
811
812static int
813sis900_open(struct devicelinux_device *net_dev)
814{
815 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
816 long ioaddr = net_dev->base_addr;
817 u8 revision;
818
819 /* Soft reset the chip. */
820 sis900_reset(net_dev);
821
822 /* Equalizer workaroung Rule */
823 pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
824 sis630_set_eq(net_dev, revision);
825
826 if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ0x04000000, net_dev->name, net_dev)) {
827 return -EAGAIN11;
828 }
829
830 MOD_INC_USE_COUNTdo { } while (0);
831
832 sis900_init_rxfilter(net_dev);
833
834 sis900_init_tx_ring(net_dev);
835 sis900_init_rx_ring(net_dev);
836
837 set_rx_mode(net_dev);
838
839 net_dev->tbusy = 0;
840 net_dev->interrupt = 0;
841 net_dev->start = 1;
842
843 /* Workaround for EDB */
844 sis900_set_mode(ioaddr, HW_SPEED_10_MBPS10, FDX_CAPABLE_HALF_SELECTED1);
845
846 /* Enable all known interrupts by setting the interrupt mask. */
847 outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr)((__builtin_constant_p((ioaddr + imr)) && (ioaddr + imr
) < 256) ? __outlc(((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE
)),(ioaddr + imr)) : __outl(((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR
|TxIDLE)),(ioaddr + imr)))
;
848 outl(RxENA | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((RxENA | ((__builtin_constant_p((ioaddr
+ cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr + cr
) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((RxENA | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)))
;
849 outl(IE, ioaddr + ier)((__builtin_constant_p((ioaddr + ier)) && (ioaddr + ier
) < 256) ? __outlc((IE),(ioaddr + ier)) : __outl((IE),(ioaddr
+ ier)))
;
850
851 sis900_check_mode(net_dev, sis_priv->mii);
852
853 /* Set the timer to switch to check for link beat and perhaps switch
854 to an alternate media type. */
855 init_timer(&sis_priv->timer);
856 sis_priv->timer.expires = jiffies + HZ100;
857 sis_priv->timer.data = (unsigned long)net_dev;
858 sis_priv->timer.function = &sis900_timer;
859 add_timer(&sis_priv->timer);
860
861 return 0;
862}
863
864/* set receive filter address to our MAC address */
865static void
866sis900_init_rxfilter (struct devicelinux_device * net_dev)
867{
868 long ioaddr = net_dev->base_addr;
869 u32 rfcrSave;
870 u32 i;
871
872 rfcrSave = inl(rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __inlc(rfcr + ioaddr) : __inl(rfcr + ioaddr))
;
873
874 /* disable packet filtering before setting filter */
875 outl(rfcrSave & ~RFEN, rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __outlc((rfcrSave & ~RFEN),(rfcr + ioaddr))
: __outl((rfcrSave & ~RFEN),(rfcr + ioaddr)))
;
876
877 /* load MAC addr to filter data register */
878 for (i = 0 ; i < 3 ; i++) {
879 u32 w;
880
881 w = (u32) *((u16 *)(net_dev->dev_addr)+i);
882 outl((i << RFADDR_shift), ioaddr + rfcr)((__builtin_constant_p((ioaddr + rfcr)) && (ioaddr + rfcr
) < 256) ? __outlc(((i << 16)),(ioaddr + rfcr)) : __outl
(((i << 16)),(ioaddr + rfcr)))
;
883 outl(w, ioaddr + rfdr)((__builtin_constant_p((ioaddr + rfdr)) && (ioaddr + rfdr
) < 256) ? __outlc((w),(ioaddr + rfdr)) : __outl((w),(ioaddr
+ rfdr)))
;
884
885 if (sis900_debugdebug > 2) {
886 printk(KERN_INFO"<6>" "%s: Receive Filter Addrss[%d]=%x\n",
887 net_dev->name, i, inl(ioaddr + rfdr)((__builtin_constant_p((ioaddr + rfdr)) && (ioaddr + rfdr
) < 256) ? __inlc(ioaddr + rfdr) : __inl(ioaddr + rfdr))
);
888 }
889 }
890
891 /* enable packet filitering */
892 outl(rfcrSave | RFEN, rfcr + ioaddr)((__builtin_constant_p((rfcr + ioaddr)) && (rfcr + ioaddr
) < 256) ? __outlc((rfcrSave | RFEN),(rfcr + ioaddr)) : __outl
((rfcrSave | RFEN),(rfcr + ioaddr)))
;
893}
894
895/* Initialize the Tx ring. */
896static void
897sis900_init_tx_ring(struct devicelinux_device *net_dev)
898{
899 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
900 long ioaddr = net_dev->base_addr;
901 int i;
902
903 sis_priv->tx_full = 0;
904 sis_priv->dirty_tx = sis_priv->cur_tx = 0;
905
906 for (i = 0; i < NUM_TX_DESC16; i++) {
907 sis_priv->tx_skbuff[i] = NULL((void *) 0);
908
909 sis_priv->tx_ring[i].link = (u32) virt_to_busvirt_to_phys(&sis_priv->tx_ring[i+1]);
910 sis_priv->tx_ring[i].cmdsts = 0;
911 sis_priv->tx_ring[i].bufptr = 0;
912 }
913 sis_priv->tx_ring[i-1].link = (u32) virt_to_busvirt_to_phys(&sis_priv->tx_ring[0]);
914
915 /* load Transmit Descriptor Register */
916 outl(virt_to_bus(&sis_priv->tx_ring[0]), ioaddr + txdp)((__builtin_constant_p((ioaddr + txdp)) && (ioaddr + txdp
) < 256) ? __outlc((virt_to_phys(&sis_priv->tx_ring
[0])),(ioaddr + txdp)) : __outl((virt_to_phys(&sis_priv->
tx_ring[0])),(ioaddr + txdp)))
;
917 if (sis900_debugdebug > 2)
918 printk(KERN_INFO"<6>" "%s: TX descriptor register loaded with: %8.8x\n",
919 net_dev->name, inl(ioaddr + txdp)((__builtin_constant_p((ioaddr + txdp)) && (ioaddr + txdp
) < 256) ? __inlc(ioaddr + txdp) : __inl(ioaddr + txdp))
);
920}
921
922/* Initialize the Rx descriptor ring, pre-allocate recevie buffers */
923static void
924sis900_init_rx_ring(struct devicelinux_device *net_dev)
925{
926 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
927 long ioaddr = net_dev->base_addr;
928 int i;
929
930 sis_priv->cur_rx = 0;
931 sis_priv->dirty_rx = 0;
932
933 /* init RX descriptor */
934 for (i = 0; i < NUM_RX_DESC16; i++) {
935 sis_priv->rx_skbuff[i] = NULL((void *) 0);
936
937 sis_priv->rx_ring[i].link = (u32) virt_to_busvirt_to_phys(&sis_priv->rx_ring[i+1]);
938 sis_priv->rx_ring[i].cmdsts = 0;
939 sis_priv->rx_ring[i].bufptr = 0;
940 }
941 sis_priv->rx_ring[i-1].link = (u32) virt_to_busvirt_to_phys(&sis_priv->rx_ring[0]);
942
943 /* allocate sock buffers */
944 for (i = 0; i < NUM_RX_DESC16; i++) {
945 struct sk_buff *skb;
946
947 if ((skb = dev_alloc_skb(RX_BUF_SIZE1536)) == NULL((void *) 0)) {
948 /* not enough memory for skbuff, this makes a "hole"
949 on the buffer ring, it is not clear how the
950 hardware will react to this kind of degenerated
951 buffer */
952 break;
953 }
954 skb->dev = net_dev;
955 sis_priv->rx_skbuff[i] = skb;
956 sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE1536;
957 sis_priv->rx_ring[i].bufptr = virt_to_busvirt_to_phys(skb->tail);
958 }
959 sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC16);
960
961 /* load Receive Descriptor Register */
962 outl(virt_to_bus(&sis_priv->rx_ring[0]), ioaddr + rxdp)((__builtin_constant_p((ioaddr + rxdp)) && (ioaddr + rxdp
) < 256) ? __outlc((virt_to_phys(&sis_priv->rx_ring
[0])),(ioaddr + rxdp)) : __outl((virt_to_phys(&sis_priv->
rx_ring[0])),(ioaddr + rxdp)))
;
963 if (sis900_debugdebug > 2)
964 printk(KERN_INFO"<6>" "%s: RX descriptor register loaded with: %8.8x\n",
965 net_dev->name, inl(ioaddr + rxdp)((__builtin_constant_p((ioaddr + rxdp)) && (ioaddr + rxdp
) < 256) ? __inlc(ioaddr + rxdp) : __inl(ioaddr + rxdp))
);
966}
967
968/**
969 * sis630_set_eq: - set phy equalizer value for 630 LAN
970 * @net_dev: the net device to set equalizer value
971 * @revision: 630 LAN revision number
972 *
973 * 630E equalizer workaround rule(Cyrus Huang 08/15)
974 * PHY register 14h(Test)
975 * Bit 14: 0 -- Automatically dectect (default)
976 * 1 -- Manually set Equalizer filter
977 * Bit 13: 0 -- (Default)
978 * 1 -- Speed up convergence of equalizer setting
979 * Bit 9 : 0 -- (Default)
980 * 1 -- Disable Baseline Wander
981 * Bit 3~7 -- Equalizer filter setting
982 * Link ON: Set Bit 9, 13 to 1, Bit 14 to 0
983 * Then calculate equalizer value
984 * Then set equalizer value, and set Bit 14 to 1, Bit 9 to 0
985 * Link Off:Set Bit 13 to 1, Bit 14 to 0
986 * Calculate Equalizer value:
987 * When Link is ON and Bit 14 is 0, SIS900PHY will auto-dectect proper equalizer value.
988 * When the equalizer is stable, this value is not a fixed value. It will be within
989 * a small range(eg. 7~9). Then we get a minimum and a maximum value(eg. min=7, max=9)
990 * 0 <= max <= 4 --> set equalizer to max
991 * 5 <= max <= 14 --> set equalizer to max+1 or set equalizer to max+2 if max == min
992 * max >= 15 --> set equalizer to max+5 or set equalizer to max+6 if max == min
993 */
994
995static void sis630_set_eq(struct devicelinux_device *net_dev, u8 revision)
996{
997 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
998 u16 reg14h, eq_value, max_value=0, min_value=0;
999 u8 host_bridge_rev;
1000 int i, maxcount=10;
1001 int not_found;
1002 u8 pci_bus, pci_device_fn;
1003
1004 if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
1005 revision == SIS630A_900_REV || revision == SIS630ET_900_REV) )
1006 return;
1007 not_found = pcibios_find_device(SIS630_VENDOR_ID0x1039, SIS630_DEVICE_ID0x0630,
1008 sis_priv->pci_index,
1009 &pci_bus,
1010 &pci_device_fn);
1011 if (not_found)
1012 pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION0x08, &host_bridge_rev);
1013
1014 if (sis_priv->LinkOn) {
1015 reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
1016 mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
1017 for (i=0; i < maxcount; i++) {
1018 eq_value=(0x00F8 & mdio_read(net_dev, sis_priv->cur_phy, MII_RESV)) >> 3;
1019 if (i == 0)
1020 max_value=min_value=eq_value;
1021 max_value=(eq_value > max_value) ? eq_value : max_value;
1022 min_value=(eq_value < min_value) ? eq_value : min_value;
1023 }
1024 /* 630E rule to determine the equalizer value */
1025 if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
1026 revision == SIS630ET_900_REV) {
1027 if (max_value < 5)
1028 eq_value=max_value;
1029 else if (max_value >= 5 && max_value < 15)
1030 eq_value=(max_value == min_value) ? max_value+2 : max_value+1;
1031 else if (max_value >= 15)
1032 eq_value=(max_value == min_value) ? max_value+6 : max_value+5;
1033 }
1034 /* 630B0&B1 rule to determine the equalizer value */
1035 if (revision == SIS630A_900_REV &&
1036 (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) {
1037 if (max_value == 0)
1038 eq_value=3;
1039 else
1040 eq_value=(max_value+min_value+1)/2;
1041 }
1042 /* write equalizer value and setting */
1043 reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
1044 reg14h=(reg14h & 0xFF07) | ((eq_value << 3) & 0x00F8);
1045 reg14h=(reg14h | 0x6000) & 0xFDFF;
1046 mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, reg14h);
1047 }
1048 else {
1049 reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
1050 if (revision == SIS630A_900_REV &&
1051 (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1))
1052 mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF);
1053 else
1054 mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF);
1055 }
1056 return;
1057}
1058
1059
1060/* on each timer ticks we check two things, Link Status (ON/OFF) and
1061 Link Mode (10/100/Full/Half)
1062*/
1063static void sis900_timer(unsigned long data)
1064{
1065 struct devicelinux_device *net_dev = (struct devicelinux_device *)data;
1066 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1067 struct mii_phy *mii_phy = sis_priv->mii;
1068 static int next_tick = 5*HZ100;
1069 u16 status;
1070 u8 revision;
1071
1072 if(!sis_priv->autong_complete){
1073 int speed, duplex = 0;
1074
1075 sis900_read_mode(net_dev, &speed, &duplex);
1076 if(duplex){
1077 sis900_set_mode(net_dev->base_addr, speed, duplex);
1078 pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
1079 sis630_set_eq(net_dev, revision);
1080 }
1081
1082 sis_priv->timer.expires = jiffies + HZ100;
1083 add_timer(&sis_priv->timer);
1084 return;
1085 }
1086
1087 status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
1088 status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
1089
1090 /* Link OFF -> ON */
1091 if ( !sis_priv->LinkOn ) {
1092LookForLink:
1093 /* Search for new PHY */
1094 status = sis900_default_phy( net_dev );
1095 mii_phy = sis_priv->mii;
1096
1097 if( status & MII_STAT_LINK ){
1098 sis900_check_mode(net_dev, mii_phy);
1099 sis_priv->LinkOn = TRUE1;
1100 }
1101 }
1102 /* Link ON -> OFF */
1103 else{
1104 if( !(status & MII_STAT_LINK) ){
1105 sis_priv->LinkOn = FALSE0;
1106 printk(KERN_INFO"<6>" "%s: Media Link Off\n", net_dev->name);
1107
1108 /* Change mode issue */
1109 if( (mii_phy->phy_id0 == 0x001D) &&
1110 ( (mii_phy->phy_id1 & 0xFFF0) == 0x8000 ))
1111 sis900_reset_phy( net_dev, sis_priv->cur_phy );
1112
1113 pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
1114 sis630_set_eq(net_dev, revision);
1115
1116 goto LookForLink;
1117 }
1118 }
1119
1120 sis_priv->timer.expires = jiffies + next_tick;
1121 add_timer(&sis_priv->timer);
1122}
1123
1124static void sis900_check_mode (struct devicelinux_device *net_dev, struct mii_phy *mii_phy)
1125{
1126 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1127 long ioaddr = net_dev->base_addr;
1128 int speed, duplex;
1129
1130 if( mii_phy->phy_types == LAN0x0002 ){
1131 outl( ~EXD & inl( ioaddr + cfg ), ioaddr + cfg)((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __outlc((~EXD & ((__builtin_constant_p((ioaddr
+ cfg)) && (ioaddr + cfg) < 256) ? __inlc(ioaddr +
cfg) : __inl(ioaddr + cfg))),(ioaddr + cfg)) : __outl((~EXD &
((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __inlc(ioaddr + cfg) : __inl(ioaddr + cfg))),(ioaddr
+ cfg)))
;
1132 sis900_set_capability(net_dev , mii_phy);
1133 sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
1134 }else{
1135 outl(EXD | inl( ioaddr + cfg ), ioaddr + cfg)((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __outlc((EXD | ((__builtin_constant_p((ioaddr +
cfg)) && (ioaddr + cfg) < 256) ? __inlc(ioaddr + cfg
) : __inl(ioaddr + cfg))),(ioaddr + cfg)) : __outl((EXD | ((__builtin_constant_p
((ioaddr + cfg)) && (ioaddr + cfg) < 256) ? __inlc
(ioaddr + cfg) : __inl(ioaddr + cfg))),(ioaddr + cfg)))
;
1136 speed = HW_SPEED_HOME1;
1137 duplex = FDX_CAPABLE_HALF_SELECTED1;
1138 sis900_set_mode(net_dev->base_addr, speed, duplex);
1139 sis_priv->autong_complete = 1;
1140 }
1141}
1142
1143static void sis900_set_mode (long ioaddr, int speed, int duplex)
1144{
1145 u32 tx_flags = 0, rx_flags = 0;
1146
1147 if( inl(ioaddr + cfg)((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __inlc(ioaddr + cfg) : __inl(ioaddr + cfg))
& EDB_MASTER_EN ){
1148 tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift20) | (TX_FILL_THRESH16 << TxFILLT_shift8);
1149 rx_flags = DMA_BURST_64 << RxMXDMA_shift20;
1150 }
1151 else{
1152 tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift20) | (TX_FILL_THRESH16 << TxFILLT_shift8);
1153 rx_flags = DMA_BURST_512 << RxMXDMA_shift20;
1154 }
1155
1156 if (speed == HW_SPEED_HOME1 || speed == HW_SPEED_10_MBPS10 ) {
1157 rx_flags |= (RxDRNT_1024 << RxDRNT_shift1);
1158 tx_flags |= (TxDRNT_1016 << TxDRNT_shift0);
1159 }
1160 else {
1161 rx_flags |= (RxDRNT_10016 << RxDRNT_shift1);
1162 tx_flags |= (TxDRNT_10048 << TxDRNT_shift0);
1163 }
1164
1165 if (duplex == FDX_CAPABLE_FULL_SELECTED2) {
1166 tx_flags |= (TxCSI | TxHBI);
1167 rx_flags |= RxATX;
1168 }
1169
1170 outl (tx_flags, ioaddr + txcfg)((__builtin_constant_p((ioaddr + txcfg)) && (ioaddr +
txcfg) < 256) ? __outlc((tx_flags),(ioaddr + txcfg)) : __outl
((tx_flags),(ioaddr + txcfg)))
;
1171 outl (rx_flags, ioaddr + rxcfg)((__builtin_constant_p((ioaddr + rxcfg)) && (ioaddr +
rxcfg) < 256) ? __outlc((rx_flags),(ioaddr + rxcfg)) : __outl
((rx_flags),(ioaddr + rxcfg)))
;
1172}
1173
1174
1175static void sis900_auto_negotiate(struct devicelinux_device *net_dev, int phy_addr)
1176{
1177 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1178 int i = 0;
1179 u32 status;
1180
1181 while (i++ < 2)
1182 status = mdio_read(net_dev, phy_addr, MII_STATUS);
1183
1184 if (!(status & MII_STAT_LINK)){
1185 printk(KERN_INFO"<6>" "%s: Media Link Off\n", net_dev->name);
1186 sis_priv->autong_complete = 1;
1187 sis_priv->LinkOn = FALSE0;
1188 return;
1189 }
1190
1191 /* (Re)start AutoNegotiate */
1192 mdio_write(net_dev, phy_addr, MII_CONTROL,
1193 MII_CNTL_AUTO | MII_CNTL_RST_AUTO);
1194 sis_priv->autong_complete = 0;
1195}
1196
1197
1198static void sis900_read_mode(struct devicelinux_device *net_dev, int *speed, int *duplex)
1199{
1200 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1201 struct mii_phy *phy = sis_priv->mii;
1202 int phy_addr = sis_priv->cur_phy;
1203 u32 status;
1204 u16 autoadv, autorec;
1205 int i = 0;
1206
1207 while (i++ < 2)
1208 status = mdio_read(net_dev, phy_addr, MII_STATUS);
1209
1210 if (!(status & MII_STAT_LINK)) return;
1211
1212 /* AutoNegotiate completed */
1213 autoadv = mdio_read(net_dev, phy_addr, MII_ANADV);
1214 autorec = mdio_read(net_dev, phy_addr, MII_ANLPAR);
1215 status = autoadv & autorec;
1216
1217 *speed = HW_SPEED_10_MBPS10;
1218 *duplex = FDX_CAPABLE_HALF_SELECTED1;
1219
1220 if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
1221 *speed = HW_SPEED_100_MBPS100;
1222 if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
1223 *duplex = FDX_CAPABLE_FULL_SELECTED2;
1224
1225 sis_priv->autong_complete = 1;
1226
1227 /* Workaround for Realtek RTL8201 PHY issue */
1228 if((phy->phy_id0 == 0x0000) && ((phy->phy_id1 & 0xFFF0) == 0x8200)){
1229 if(mdio_read(net_dev, phy_addr, MII_CONTROL) & MII_CNTL_FDX)
1230 *duplex = FDX_CAPABLE_FULL_SELECTED2;
1231 if(mdio_read(net_dev, phy_addr, 0x0019) & 0x01)
1232 *speed = HW_SPEED_100_MBPS100;
1233 }
1234
1235 printk(KERN_INFO"<6>" "%s: Media Link On %s %s-duplex \n",
1236 net_dev->name,
1237 *speed == HW_SPEED_100_MBPS100 ?
1238 "100mbps" : "10mbps",
1239 *duplex == FDX_CAPABLE_FULL_SELECTED2 ?
1240 "full" : "half");
1241}
1242
1243
1244static void sis900_tx_timeout(struct devicelinux_device *net_dev)
1245{
1246 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1247 long ioaddr = net_dev->base_addr;
1248 int i;
1249
1250 printk(KERN_INFO"<6>" "%s: Transmit timeout, status %8.8x %8.8x \n",
1251 net_dev->name, inl(ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __inlc(ioaddr + cr) : __inl(ioaddr + cr))
, inl(ioaddr + isr)((__builtin_constant_p((ioaddr + isr)) && (ioaddr + isr
) < 256) ? __inlc(ioaddr + isr) : __inl(ioaddr + isr))
);
1252
1253 /* Disable interrupts by clearing the interrupt mask. */
1254 outl(0x0000, ioaddr + imr)((__builtin_constant_p((ioaddr + imr)) && (ioaddr + imr
) < 256) ? __outlc((0x0000),(ioaddr + imr)) : __outl((0x0000
),(ioaddr + imr)))
;
1255
1256 /* discard unsent packets, should this code section be protected by
1257 cli(), sti() ?? */
1258 sis_priv->dirty_tx = sis_priv->cur_tx = 0;
1259 for (i = 0; i < NUM_TX_DESC16; i++) {
1260 if (sis_priv->tx_skbuff[i] != NULL((void *) 0)) {
1261 dev_free_skb(sis_priv->tx_skbuff[i])dev_kfree_skb (sis_priv->tx_skbuff[i], 0);;
1262 sis_priv->tx_skbuff[i] = 0;
1263 sis_priv->tx_ring[i].cmdsts = 0;
1264 sis_priv->tx_ring[i].bufptr = 0;
1265 sis_priv->stats.tx_dropped++;
1266 }
1267 }
1268 net_dev->trans_start = jiffies;
1269 net_dev->tbusy = sis_priv->tx_full = 0;
1270
1271 /* FIXME: Should we restart the transmission thread here ?? */
1272 outl(TxENA | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((TxENA | ((__builtin_constant_p((ioaddr
+ cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr + cr
) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((TxENA | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)))
;
1273
1274 /* Enable all known interrupts by setting the interrupt mask. */
1275 outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr)((__builtin_constant_p((ioaddr + imr)) && (ioaddr + imr
) < 256) ? __outlc(((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE
)),(ioaddr + imr)) : __outl(((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR
|TxIDLE)),(ioaddr + imr)))
;
1276 return;
1277}
1278
1279static int
1280sis900_start_xmit(struct sk_buff *skb, struct devicelinux_device *net_dev)
1281{
1282 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1283 long ioaddr = net_dev->base_addr;
1284 unsigned int entry;
1285
1286 /* test tbusy to see if we have timeout situation then set it */
1287 if (test_and_set_bit(0, (void*)&net_dev->tbusy) != 0) {
1288 if (jiffies - net_dev->trans_start > TX_TIMEOUT(4*100))
1289 sis900_tx_timeout(net_dev);
1290 return 1;
1291 }
1292
1293 /* Calculate the next Tx descriptor entry. */
1294 entry = sis_priv->cur_tx % NUM_TX_DESC16;
1295 sis_priv->tx_skbuff[entry] = skb;
1296
1297 /* set the transmit buffer descriptor and enable Transmit State Machine */
1298 sis_priv->tx_ring[entry].bufptr = virt_to_busvirt_to_phys(skb->data);
1299 sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
1300 outl(TxENA | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((TxENA | ((__builtin_constant_p((ioaddr
+ cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr + cr
) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((TxENA | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)))
;
1301
1302 if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC16) {
1303 /* Typical path, clear tbusy to indicate more
1304 transmission is possible */
1305 clear_bit(0, (void*)&net_dev->tbusy);
1306 } else {
1307 /* no more transmit descriptor avaiable, tbusy remain set */
1308 sis_priv->tx_full = 1;
1309 }
1310
1311 net_dev->trans_start = jiffies;
1312
1313 {
1314 int i;
1315 for (i = 0; i < 100000; i++); /* GRUIIIIIK */
1316 }
1317
1318 if (sis900_debugdebug > 3)
1319 printk(KERN_INFO"<6>" "%s: Queued Tx packet at %p size %d "
1320 "to slot %d.\n",
1321 net_dev->name, skb->data, (int)skb->len, entry);
1322
1323 return 0;
1324}
1325
1326/* The interrupt handler does all of the Rx thread work and cleans up
1327 after the Tx thread. */
1328static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1329{
1330 struct devicelinux_device *net_dev = (struct devicelinux_device *)dev_instance;
1331 int boguscnt = max_interrupt_work;
1332 long ioaddr = net_dev->base_addr;
1333 u32 status;
1334
1335#if defined(__i386__1)
1336 /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
1337 if (test_and_set_bit(0, (void*)&net_dev->interrupt)) {
1338 printk(KERN_INFO"<6>" "%s: SMP simultaneous entry of "
1339 "an interrupt handler.\n", net_dev->name);
1340 net_dev->interrupt = 0; /* Avoid halting machine. */
1341 return;
1342 }
1343#else
1344 if (net_dev->interrupt) {
1345 printk(KERN_INFO"<6>" "%s: Re-entering the interrupt handler.\n",
1346 net_dev->name);
1347 return;
1348 }
1349 net_dev->interrupt = 1;
1350#endif
1351
1352 do {
1353 status = inl(ioaddr + isr)((__builtin_constant_p((ioaddr + isr)) && (ioaddr + isr
) < 256) ? __inlc(ioaddr + isr) : __inl(ioaddr + isr))
;
1354
1355 if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
1356 /* nothing intresting happened */
1357 break;
1358
1359 /* why dow't we break after Tx/Rx case ?? keyword: full-duplex */
1360 if (status & (RxORN | RxERR | RxOK))
1361 /* Rx interrupt */
1362 sis900_rx(net_dev);
1363
1364 if (status & (TxURN | TxERR | TxIDLE))
1365 /* Tx interrupt */
1366 sis900_finish_xmit(net_dev);
1367
1368 /* something strange happened !!! */
1369 if (status & HIBERR) {
1370 printk(KERN_INFO"<6>" "%s: Abnormal interrupt,"
1371 "status %#8.8x.\n", net_dev->name, status);
1372 break;
1373 }
1374 if (--boguscnt < 0) {
1375 printk(KERN_INFO"<6>" "%s: Too much work at interrupt, "
1376 "interrupt status = %#8.8x.\n",
1377 net_dev->name, status);
1378 break;
1379 }
1380 } while (1);
1381
1382 if (sis900_debugdebug > 4)
1383 printk(KERN_INFO"<6>" "%s: exiting interrupt, "
1384 "interrupt status = 0x%#8.8x.\n",
1385 net_dev->name, inl(ioaddr + isr)((__builtin_constant_p((ioaddr + isr)) && (ioaddr + isr
) < 256) ? __inlc(ioaddr + isr) : __inl(ioaddr + isr))
);
1386
1387#if defined(__i386__1)
1388 clear_bit(0, (void*)&net_dev->interrupt);
1389#else
1390 net_dev->interrupt = 0;
1391#endif
1392 return;
1393}
1394
1395/* Process receive interrupt events, put buffer to higher layer and refill buffer pool
1396 Note: This fucntion is called by interrupt handler, don't do "too much" work here */
1397static int sis900_rx(struct devicelinux_device *net_dev)
1398{
1399 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1400 long ioaddr = net_dev->base_addr;
1401 unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC16;
1402 u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
1403
1404 if (sis900_debugdebug > 4)
1405 printk(KERN_INFO"<6>" "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
1406 "status:0x%8.8x\n",
1407 sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
1408
1409 while (rx_status & OWN) {
1410 unsigned int rx_size;
1411
1412 rx_size = (rx_status & DSIZE) - CRC_SIZE4;
1413
1414 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
1415 /* corrupted packet received */
1416 if (sis900_debugdebug > 4)
1417 printk(KERN_INFO"<6>" "%s: Corrupted packet "
1418 "received, buffer status = 0x%8.8x.\n",
1419 net_dev->name, rx_status);
1420 sis_priv->stats.rx_errors++;
1421 if (rx_status & OVERRUN)
1422 sis_priv->stats.rx_over_errors++;
1423 if (rx_status & (TOOLONG|RUNT))
1424 sis_priv->stats.rx_length_errors++;
1425 if (rx_status & (RXISERR | FAERR))
1426 sis_priv->stats.rx_frame_errors++;
1427 if (rx_status & CRCERR)
1428 sis_priv->stats.rx_crc_errors++;
1429 /* reset buffer descriptor state */
1430 sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE1536;
1431 } else {
1432 struct sk_buff * skb;
1433
1434 /* This situation should never happen, but due to
1435 some unknow bugs, it is possible that
1436 we are working on NULL sk_buff :-( */
1437 if (sis_priv->rx_skbuff[entry] == NULL((void *) 0)) {
1438 printk(KERN_INFO"<6>" "%s: NULL pointer "
1439 "encountered in Rx ring, skipping\n",
1440 net_dev->name);
1441 break;
1442 }
1443
1444 /* gvie the socket buffer to upper layers */
1445 skb = sis_priv->rx_skbuff[entry];
1446 skb_put(skb, rx_size);
1447 skb->protocol = eth_type_trans(skb, net_dev)((unsigned short)0);
1448 netif_rx(skb);
1449
1450 /* some network statistics */
1451 if ((rx_status & BCAST) == MCAST)
1452 sis_priv->stats.multicast++;
1453 net_dev->last_rx = jiffies;
1454 /* sis_priv->stats.rx_bytes += rx_size;*/
1455 sis_priv->stats.rx_packets++;
1456
1457 /* refill the Rx buffer, what if there is not enought memory for
1458 new socket buffer ?? */
1459 if ((skb = dev_alloc_skb(RX_BUF_SIZE1536)) == NULL((void *) 0)) {
1460 /* not enough memory for skbuff, this makes a "hole"
1461 on the buffer ring, it is not clear how the
1462 hardware will react to this kind of degenerated
1463 buffer */
1464 printk(KERN_INFO"<6>" "%s: Memory squeeze,"
1465 "deferring packet.\n",
1466 net_dev->name);
1467 sis_priv->rx_skbuff[entry] = NULL((void *) 0);
1468 /* reset buffer descriptor state */
1469 sis_priv->rx_ring[entry].cmdsts = 0;
1470 sis_priv->rx_ring[entry].bufptr = 0;
1471 sis_priv->stats.rx_dropped++;
1472 break;
1473 }
1474 skb->dev = net_dev;
1475 sis_priv->rx_skbuff[entry] = skb;
1476 sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE1536;
1477 sis_priv->rx_ring[entry].bufptr = virt_to_busvirt_to_phys(skb->tail);
1478 sis_priv->dirty_rx++;
1479 }
1480 sis_priv->cur_rx++;
1481 entry = sis_priv->cur_rx % NUM_RX_DESC16;
1482 rx_status = sis_priv->rx_ring[entry].cmdsts;
1483 } // while
1484
1485 /* refill the Rx buffer, what if the rate of refilling is slower than
1486 consuming ?? */
1487 for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
1488 struct sk_buff *skb;
1489
1490 entry = sis_priv->dirty_rx % NUM_RX_DESC16;
1491
1492 if (sis_priv->rx_skbuff[entry] == NULL((void *) 0)) {
1493 if ((skb = dev_alloc_skb(RX_BUF_SIZE1536)) == NULL((void *) 0)) {
1494 /* not enough memory for skbuff, this makes a "hole"
1495 on the buffer ring, it is not clear how the
1496 hardware will react to this kind of degenerated
1497 buffer */
1498 printk(KERN_INFO"<6>" "%s: Memory squeeze,"
1499 "deferring packet.\n",
1500 net_dev->name);
1501 sis_priv->stats.rx_dropped++;
1502 break;
1503 }
1504 skb->dev = net_dev;
1505 sis_priv->rx_skbuff[entry] = skb;
1506 sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE1536;
1507 sis_priv->rx_ring[entry].bufptr = virt_to_busvirt_to_phys(skb->tail);
1508 }
1509 }
1510
1511 /* re-enable the potentially idle receive state matchine */
1512 outl(RxENA | inl(ioaddr + cr), ioaddr + cr )((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((RxENA | ((__builtin_constant_p((ioaddr
+ cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr + cr
) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((RxENA | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)))
;
1513
1514 return 0;
1515}
1516
1517/* finish up transmission of packets, check for error condition and free skbuff etc.
1518 Note: This fucntion is called by interrupt handler, don't do "too much" work here */
1519static void sis900_finish_xmit (struct devicelinux_device *net_dev)
1520{
1521 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1522
1523 for (; sis_priv->dirty_tx < sis_priv->cur_tx; sis_priv->dirty_tx++) {
1524 unsigned int entry;
1525 u32 tx_status;
1526
1527 entry = sis_priv->dirty_tx % NUM_TX_DESC16;
1528 tx_status = sis_priv->tx_ring[entry].cmdsts;
1529
1530 if (tx_status & OWN) {
1531 /* The packet is not transmitted yet (owned by hardware) !
1532 Note: the interrupt is generated only when Tx Machine
1533 is idle, so this is an almost impossible case */
1534 break;
1535 }
1536
1537 if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
1538 /* packet unsuccessfully transmitted */
1539 if (sis900_debugdebug > 4)
1540 printk(KERN_INFO"<6>" "%s: Transmit "
1541 "error, Tx status %8.8x.\n",
1542 net_dev->name, tx_status);
1543 sis_priv->stats.tx_errors++;
1544 if (tx_status & UNDERRUN)
1545 sis_priv->stats.tx_fifo_errors++;
1546 if (tx_status & ABORT)
1547 sis_priv->stats.tx_aborted_errors++;
1548 if (tx_status & NOCARRIER)
1549 sis_priv->stats.tx_carrier_errors++;
1550 if (tx_status & OWCOLL)
1551 sis_priv->stats.tx_window_errors++;
1552 } else {
1553 /* packet successfully transmitted */
1554 sis_priv->stats.collisions += (tx_status & COLCNT) >> 16;
1555 /* sis_priv->stats.tx_bytes += tx_status & DSIZE;*/
1556 sis_priv->stats.tx_packets++;
1557 }
1558 /* Free the original skb. */
1559 dev_free_skb(sis_priv->tx_skbuff[entry])dev_kfree_skb (sis_priv->tx_skbuff[entry], 0);;
1560 sis_priv->tx_skbuff[entry] = NULL((void *) 0);
1561 sis_priv->tx_ring[entry].bufptr = 0;
1562 sis_priv->tx_ring[entry].cmdsts = 0;
1563 }
1564
1565 if (sis_priv->tx_full && net_dev->tbusy &&
1566 sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC16 - 4) {
1567 /* The ring is no longer full, clear tbusy, tx_full and
1568 schedule more transmission by marking NET_BH */
1569 sis_priv->tx_full = 0;
1570 clear_bit(0, (void *)&net_dev->tbusy);
1571 mark_bh(NET_BH);
1572 }
1573}
1574
1575static int
1576sis900_close(struct devicelinux_device *net_dev)
1577{
1578 long ioaddr = net_dev->base_addr;
1579 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1580 int i;
1581
1582 net_dev->start = 0;
1583 net_dev->tbusy = 1;
1584
1585 /* Disable interrupts by clearing the interrupt mask. */
1586 outl(0x0000, ioaddr + imr)((__builtin_constant_p((ioaddr + imr)) && (ioaddr + imr
) < 256) ? __outlc((0x0000),(ioaddr + imr)) : __outl((0x0000
),(ioaddr + imr)))
;
1587 outl(0x0000, ioaddr + ier)((__builtin_constant_p((ioaddr + ier)) && (ioaddr + ier
) < 256) ? __outlc((0x0000),(ioaddr + ier)) : __outl((0x0000
),(ioaddr + ier)))
;
1588
1589 /* Stop the chip's Tx and Rx Status Machine */
1590 outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((RxDIS | TxDIS | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((RxDIS |
TxDIS | ((__builtin_constant_p((ioaddr + cr)) && (ioaddr
+ cr) < 256) ? __inlc(ioaddr + cr) : __inl(ioaddr + cr)))
,(ioaddr + cr)))
;
1591
1592 del_timer(&sis_priv->timer);
1593
1594 free_irq(net_dev->irq, net_dev);
1595
1596 /* Free Tx and RX skbuff */
1597 for (i = 0; i < NUM_RX_DESC16; i++) {
1598 if (sis_priv->rx_skbuff[i] != NULL((void *) 0))
1599 dev_free_skb(sis_priv->rx_skbuff[i])dev_kfree_skb (sis_priv->rx_skbuff[i], 0);;
1600 sis_priv->rx_skbuff[i] = 0;
1601 }
1602 for (i = 0; i < NUM_TX_DESC16; i++) {
1603 if (sis_priv->tx_skbuff[i] != NULL((void *) 0))
1604 dev_free_skb(sis_priv->tx_skbuff[i])dev_kfree_skb (sis_priv->tx_skbuff[i], 0);;
1605 sis_priv->tx_skbuff[i] = 0;
1606 }
1607
1608 /* Green! Put the chip in low-power mode. */
1609
1610 MOD_DEC_USE_COUNTdo { } while (0);
1611
1612 return 0;
1613}
1614
1615static int mii_ioctl(struct devicelinux_device *net_dev, struct ifreq *rq, int cmd)
1616{
1617 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1618 u16 *data = (u16 *)&rq->ifr_dataifr_ifru.ifru_data;
1619
1620 switch(cmd) {
1621 case SIOCDEVPRIVATE0x89F0: /* Get the address of the PHY in use. */
1622 data[0] = sis_priv->mii->phy_addr;
1623 /* Fall Through */
1624 case SIOCDEVPRIVATE0x89F0+1: /* Read the specified MII register. */
1625 data[3] = mdio_read(net_dev, data[0] & 0x1f, data[1] & 0x1f);
1626 return 0;
1627 case SIOCDEVPRIVATE0x89F0+2: /* Write the specified MII register */
1628 if (!suser())
1629 return -EPERM1;
1630 mdio_write(net_dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
1631 return 0;
1632 default:
1633 return -EOPNOTSUPP95;
1634 }
1635}
1636
1637static struct enet_statistics *
1638sis900_get_stats(struct devicelinux_device *net_dev)
1639{
1640 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1641
1642 return &sis_priv->stats;
1643}
1644
1645
1646/* SiS 900 uses the most sigificant 7 bits to index a 128 bits multicast
1647 * hash table, which makes this function a little bit different from other drivers
1648 * SiS 900 B0 & 635 M/B uses the most significat 8 bits to index 256 bits
1649 * multicast hash table.
1650 */
1651static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision)
1652{
1653
1654/* what is the correct value of the POLYNOMIAL ??
1655 Donald Becker use 0x04C11DB7U
1656 Joseph Zbiciak im14u2c@primenet.com gives me the
1657 correct answer, thank you Joe !! */
1658#define POLYNOMIAL0x04C11DB7L 0x04C11DB7L
1659 u32 crc = 0xffffffff, msb;
1660 int i, j;
1661 u32 byte;
1662
1663 for (i = 0; i < 6; i++) {
1664 byte = *addr++;
1665 for (j = 0; j < 8; j++) {
1666 msb = crc >> 31;
1667 crc <<= 1;
1668 if (msb ^ (byte & 1)) {
1669 crc ^= POLYNOMIAL0x04C11DB7L;
1670 }
1671 byte >>= 1;
1672 }
1673 }
1674
1675 /* leave 8 or 7 most siginifant bits */
1676 if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
1677 return ((int)(crc >> 24));
1678 else
1679 return ((int)(crc >> 25));
1680}
1681
1682static void set_rx_mode(struct devicelinux_device *net_dev)
1683{
1684 long ioaddr = net_dev->base_addr;
1685 struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
1686 u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */
1687 int i, table_entries;
1688 u32 rx_mode;
1689 u8 revision;
1690
1691 /* 635 Hash Table entires = 256(2^16) */
1692 pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
1693 if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
1694 table_entries = 16;
1695 else
1696 table_entries = 8;
1697
1698 if (net_dev->flags & IFF_PROMISC0x100) {
1699 /* Accept any kinds of packets */
1700 rx_mode = RFPromiscuous;
1701 for (i = 0; i < table_entries; i++)
1702 mc_filter[i] = 0xffff;
1703 } else if ((net_dev->mc_count > multicast_filter_limit) ||
1704 (net_dev->flags & IFF_ALLMULTI0x200)) {
1705 /* too many multicast addresses or accept all multicast packets */
1706 rx_mode = RFAAB | RFAAM;
1707 for (i = 0; i < table_entries; i++)
1708 mc_filter[i] = 0xffff;
1709 } else {
1710 /* Accept Broadcast packets, destination addresses match our MAC address,
1711 use Receive Filter to reject unwanted MCAST packets */
1712 struct dev_mc_list *mclist;
1713 rx_mode = RFAAB;
1714 for (i = 0, mclist = net_dev->mc_list; mclist && i < net_dev->mc_count;
1715 i++, mclist = mclist->next)
1716 set_bit(sis900_compute_hashtable_index(mclist->dmi_addr, revision),
1717 mc_filter);
1718 }
1719
1720 /* update Multicast Hash Table in Receive Filter */
1721 for (i = 0; i < table_entries; i++) {
1722 /* why plus 0x04 ??, That makes the correct value for hash table. */
1723 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr)((__builtin_constant_p((ioaddr + rfcr)) && (ioaddr + rfcr
) < 256) ? __outlc(((u32)(0x00000004 +i) << 16),(ioaddr
+ rfcr)) : __outl(((u32)(0x00000004 +i) << 16),(ioaddr
+ rfcr)))
;
1724 outl(mc_filter[i], ioaddr + rfdr)((__builtin_constant_p((ioaddr + rfdr)) && (ioaddr + rfdr
) < 256) ? __outlc((mc_filter[i]),(ioaddr + rfdr)) : __outl
((mc_filter[i]),(ioaddr + rfdr)))
;
1725 }
1726
1727 outl(RFEN | rx_mode, ioaddr + rfcr)((__builtin_constant_p((ioaddr + rfcr)) && (ioaddr + rfcr
) < 256) ? __outlc((RFEN | rx_mode),(ioaddr + rfcr)) : __outl
((RFEN | rx_mode),(ioaddr + rfcr)))
;
1728
1729 /* sis900 is capatable of looping back packet at MAC level for debugging purpose */
1730 if (net_dev->flags & IFF_LOOPBACK0x8) {
1731 u32 cr_saved;
1732 /* We must disable Tx/Rx before setting loopback mode */
1733 cr_saved = inl(ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __inlc(ioaddr + cr) : __inl(ioaddr + cr))
;
1734 outl(cr_saved | TxDIS | RxDIS, ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((cr_saved | TxDIS | RxDIS),(ioaddr + cr
)) : __outl((cr_saved | TxDIS | RxDIS),(ioaddr + cr)))
;
1735 /* enable loopback */
1736 outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg)((__builtin_constant_p((ioaddr + txcfg)) && (ioaddr +
txcfg) < 256) ? __outlc((((__builtin_constant_p((ioaddr +
txcfg)) && (ioaddr + txcfg) < 256) ? __inlc(ioaddr
+ txcfg) : __inl(ioaddr + txcfg)) | TxMLB),(ioaddr + txcfg))
: __outl((((__builtin_constant_p((ioaddr + txcfg)) &&
(ioaddr + txcfg) < 256) ? __inlc(ioaddr + txcfg) : __inl(
ioaddr + txcfg)) | TxMLB),(ioaddr + txcfg)))
;
1737 outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg)((__builtin_constant_p((ioaddr + rxcfg)) && (ioaddr +
rxcfg) < 256) ? __outlc((((__builtin_constant_p((ioaddr +
rxcfg)) && (ioaddr + rxcfg) < 256) ? __inlc(ioaddr
+ rxcfg) : __inl(ioaddr + rxcfg)) | RxATX),(ioaddr + rxcfg))
: __outl((((__builtin_constant_p((ioaddr + rxcfg)) &&
(ioaddr + rxcfg) < 256) ? __inlc(ioaddr + rxcfg) : __inl(
ioaddr + rxcfg)) | RxATX),(ioaddr + rxcfg)))
;
1738 /* restore cr */
1739 outl(cr_saved, ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((cr_saved),(ioaddr + cr)) : __outl((cr_saved
),(ioaddr + cr)))
;
1740 }
1741
1742 return;
1743}
1744
1745static void sis900_reset(struct devicelinux_device *net_dev)
1746{
1747 long ioaddr = net_dev->base_addr;
1748 struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
1749 int i = 0;
1750 u8 revision;
1751 u32 status = TxRCMP | RxRCMP;
1752
1753 outl(0, ioaddr + ier)((__builtin_constant_p((ioaddr + ier)) && (ioaddr + ier
) < 256) ? __outlc((0),(ioaddr + ier)) : __outl((0),(ioaddr
+ ier)))
;
1754 outl(0, ioaddr + imr)((__builtin_constant_p((ioaddr + imr)) && (ioaddr + imr
) < 256) ? __outlc((0),(ioaddr + imr)) : __outl((0),(ioaddr
+ imr)))
;
1755 outl(0, ioaddr + rfcr)((__builtin_constant_p((ioaddr + rfcr)) && (ioaddr + rfcr
) < 256) ? __outlc((0),(ioaddr + rfcr)) : __outl((0),(ioaddr
+ rfcr)))
;
1756
1757 outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr)((__builtin_constant_p((ioaddr + cr)) && (ioaddr + cr
) < 256) ? __outlc((RxRESET | TxRESET | RESET | ((__builtin_constant_p
((ioaddr + cr)) && (ioaddr + cr) < 256) ? __inlc(ioaddr
+ cr) : __inl(ioaddr + cr))),(ioaddr + cr)) : __outl((RxRESET
| TxRESET | RESET | ((__builtin_constant_p((ioaddr + cr)) &&
(ioaddr + cr) < 256) ? __inlc(ioaddr + cr) : __inl(ioaddr
+ cr))),(ioaddr + cr)))
;
1758
1759 /* Check that the chip has finished the reset. */
1760 while (status && (i++ < 1000)) {
1761 status ^= (inl(isr + ioaddr)((__builtin_constant_p((isr + ioaddr)) && (isr + ioaddr
) < 256) ? __inlc(isr + ioaddr) : __inl(isr + ioaddr))
& status);
1762 }
1763
1764 pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION0x08, &revision);
1765 if( (revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV) )
1766 outl(PESEL | RND_CNT, ioaddr + cfg)((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __outlc((PESEL | RND_CNT),(ioaddr + cfg)) : __outl
((PESEL | RND_CNT),(ioaddr + cfg)))
;
1767 else
1768 outl(PESEL, ioaddr + cfg)((__builtin_constant_p((ioaddr + cfg)) && (ioaddr + cfg
) < 256) ? __outlc((PESEL),(ioaddr + cfg)) : __outl((PESEL
),(ioaddr + cfg)))
;
1769}
1770
1771#ifdef MODULE
1772int init_module(void)
1773{
1774 return sis900_probe(NULL((void *) 0));
1775}
1776
1777void
1778cleanup_module(void)
1779{
1780 /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
1781 while (root_sis900_dev) {
1782 struct sis900_private *sis_priv =
1783 (struct sis900_private *)root_sis900_dev->priv;
1784 struct devicelinux_device *next_dev = sis_priv->next_module;
1785 struct mii_phy *phy = NULL((void *) 0);
1786
1787 while(sis_priv->first_mii){
1788 phy = sis_priv->first_mii;
1789 sis_priv->first_mii = phy->next;
1790 kfreelinux_kfree(phy);
1791 }
1792
1793 unregister_netdev(root_sis900_dev);
1794 release_region(root_sis900_dev->base_addr,
1795 sis_priv->mac->io_size);
1796 kfreelinux_kfree(sis_priv);
1797 kfreelinux_kfree(root_sis900_dev);
1798
1799 root_sis900_dev = next_dev;
1800 }
1801}
1802
1803#endif /* MODULE */