1 /* -*- Mode:C; c-basic-offset:4; -*- */
2 
3 /*
4    sis900.c: An SiS 900/7016 PCI Fast Ethernet driver for Etherboot
5    Copyright (C) 2001 Entity Cyber, Inc.
6 
7    Revision:	1.0	March 1, 2001
8 
9    Author: Marty Connor (mdc@etherboot.org)
10 
11    Adapted from a Linux driver which was written by Donald Becker
12    and modified by Ollie Lho and Chin-Shan Li of SiS Corporation.
13    Rewritten for Etherboot by Marty Connor.
14 
15    This software may be used and distributed according to the terms
16    of the GNU Public License (GPL), incorporated herein by reference.
17 
18    References:
19    SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
20    preliminary Rev. 1.0 Jan. 14, 1998
21    SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
22    preliminary Rev. 1.0 Nov. 10, 1998
23    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
24    preliminary Rev. 1.0 Jan. 18, 1998
25    http://www.sis.com.tw/support/databook.htm */
26 
27 FILE_LICENCE ( GPL_ANY );
28 
29 /* Revision History */
30 
31 /*
32   07 Dec 2003  timlegge - Enabled Multicast Support
33   06 Dec 2003  timlegge - Fixed relocation issue in 5.2
34   04 Jan 2002  Chien-Yu Chen, Doug Ambrisko, Marty Connor  Patch to Etherboot 5.0.5
35      Added support for the SiS 630ET plus various bug fixes from linux kernel
36      source 2.4.17.
37   01 March 2001  mdc     1.0
38      Initial Release.  Tested with PCI based sis900 card and ThinkNIC
39      computer.
40   20 March 2001 P.Koegel
41      added support for sis630e and PHY ICS1893 and RTL8201
42      Testet with SIS730S chipset + ICS1893
43 */
44 
45 
46 /* Includes */
47 
48 #include "etherboot.h"
49 #include <gpxe/pci.h>
50 #include "nic.h"
51 
52 #include "sis900.h"
53 
54 /* Globals */
55 
56 static struct nic_operations sis900_operations;
57 
58 static int sis900_debug = 0;
59 
60 static unsigned short vendor, dev_id;
61 static unsigned long ioaddr;
62 static u8 pci_revision;
63 
64 static unsigned int cur_phy;
65 
66 static unsigned int cur_rx;
67 
68 struct {
69     BufferDesc txd;
70     BufferDesc rxd[NUM_RX_DESC];
71     unsigned char txb[TX_BUF_SIZE];
72     unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
73 } sis900_bufs __shared;
74 #define txd sis900_bufs.txd
75 #define rxd sis900_bufs.rxd
76 #define txb sis900_bufs.txb
77 #define rxb sis900_bufs.rxb
78 
79 #if 0
80 static struct mac_chip_info {
81     const char *name;
82     u16 vendor_id, device_id, flags;
83     int io_size;
84 } mac_chip_table[] = {
85     { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
86       PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
87     { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
88       PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
89     {0,0,0,0,0} /* 0 terminated list. */
90 };
91 #endif
92 
93 static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
94 static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
95 static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
96 static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
97 static void vt6103_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
98 
99 static struct mii_chip_info {
100     const char * name;
101     u16 phy_id0;
102     u16 phy_id1;
103     void (*read_mode) (struct nic *nic, int phy_addr, int *speed, int *duplex);
104 } mii_chip_table[] = {
105     {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode},
106     {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode},
107     {"SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, sis900_read_mode},
108     {"AMD 79C901 10BASE-T PHY",  0x0000, 0x6B70, amd79c901_read_mode},
109     {"AMD 79C901 HomePNA PHY",   0x0000, 0x6B90, amd79c901_read_mode},
110     {"ICS 1893 Integrated PHYceiver"   , 0x0015, 0xf440,ics1893_read_mode},
111 //  {"NS 83851 PHY",0x2000, 0x5C20, MIX },
112     {"RTL 8201 10/100Mbps Phyceiver"   , 0x0000, 0x8200,rtl8201_read_mode},
113     {"VIA 6103 10/100Mbps Phyceiver", 0x0101, 0x8f20,vt6103_read_mode},
114     {0,0,0,0}
115 };
116 
117 static struct mii_phy {
118     struct mii_phy * next;
119     struct mii_chip_info * chip_info;
120     int phy_addr;
121     u16 status;
122 } mii;
123 
124 
125 
126 #if 0
127 // PCI to ISA bridge for SIS640E access
128 static struct pci_device_id pci_isa_bridge_list[] = {
129 	{ .vendor = 0x1039, .device = 0x0008,
130 		.name = "SIS 85C503/5513 PCI to ISA bridge"},
131 };
132 
133 PCI_DRIVER( sis_bridge_pci_driver, pci_isa_bridge_list, PCI_NO_CLASS );
134 
135 static struct device_driver sis_bridge_driver = {
136     .name = "SIS ISA bridge",
137     .bus_driver = &pci_driver,
138     .bus_driver_info = ( struct bus_driver_info * ) &sis_bridge_pci_driver,
139 };
140 #endif
141 
142 /* Function Prototypes */
143 
144 static int sis900_probe(struct nic *nic,struct pci_device *pci);
145 
146 static u16  sis900_read_eeprom(int location);
147 static void sis900_mdio_reset(long mdio_addr);
148 static void sis900_mdio_idle(long mdio_addr);
149 static u16  sis900_mdio_read(int phy_id, int location);
150 #if 0
151 static void sis900_mdio_write(int phy_id, int location, int val);
152 #endif
153 static void sis900_init(struct nic *nic);
154 
155 static void sis900_reset(struct nic *nic);
156 
157 static void sis900_init_rxfilter(struct nic *nic);
158 static void sis900_init_txd(struct nic *nic);
159 static void sis900_init_rxd(struct nic *nic);
160 static void sis900_set_rx_mode(struct nic *nic);
161 static void sis900_check_mode(struct nic *nic);
162 
163 static void sis900_transmit(struct nic *nic, const char *d,
164                             unsigned int t, unsigned int s, const char *p);
165 static int  sis900_poll(struct nic *nic, int retrieve);
166 
167 static void sis900_disable(struct nic *nic);
168 
169 static void sis900_irq(struct nic *nic, irq_action_t action);
170 
171 /**
172  *	sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
173  *	@pci_dev: the sis900 pci device
174  *	@net_dev: the net device to get address for
175  *
176  *	Older SiS900 and friends, use EEPROM to store MAC address.
177  *	MAC address is read from read_eeprom() into @net_dev->dev_addr.
178  */
179 
sis900_get_mac_addr(struct pci_device * pci_dev __unused,struct nic * nic)180 static int sis900_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
181 {
182 	u16 signature;
183 	int i;
184 
185 	/* check to see if we have sane EEPROM */
186 	signature = (u16) sis900_read_eeprom( EEPROMSignature);
187 	if (signature == 0xffff || signature == 0x0000) {
188 		printf ("sis900_probe: Error EERPOM read %hX\n", signature);
189 		return 0;
190 	}
191 
192 	/* get MAC address from EEPROM */
193 	for (i = 0; i < 3; i++)
194 			((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
195 	return 1;
196 }
197 
198 /**
199  *	sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
200  *	@pci_dev: the sis900 pci device
201  *	@net_dev: the net device to get address for
202  *
203  *	SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
204  *	is shared by
205  *	LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
206  *	and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
207  *	by LAN, otherwise is not. After MAC address is read from EEPROM, send
208  *	EEDONE signal to refuse EEPROM access by LAN.
209  *	The EEPROM map of SiS962 or SiS963 is different to SiS900.
210  *	The signature field in SiS962 or SiS963 spec is meaningless.
211  *	MAC address is read into @net_dev->dev_addr.
212  */
213 
sis96x_get_mac_addr(struct pci_device * pci_dev __unused,struct nic * nic)214 static int sis96x_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
215 {
216 /* 	long ioaddr = net_dev->base_addr; */
217 	long ee_addr = ioaddr + mear;
218 	u32 waittime = 0;
219 	int i;
220 
221 	printf("Alternate function\n");
222 
223 	outl(EEREQ, ee_addr);
224 	while(waittime < 2000) {
225 		if(inl(ee_addr) & EEGNT) {
226 
227 			/* get MAC address from EEPROM */
228 			for (i = 0; i < 3; i++)
229 			        ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
230 
231 			outl(EEDONE, ee_addr);
232 			return 1;
233 		} else {
234 			udelay(1);
235 			waittime ++;
236 		}
237 	}
238 	outl(EEDONE, ee_addr);
239 	return 0;
240 }
241 
242 /**
243  *	sis630e_get_mac_addr: - Get MAC address for SiS630E model
244  *	@pci_dev: the sis900 pci device
245  *	@net_dev: the net device to get address for
246  *
247  *	SiS630E model, use APC CMOS RAM to store MAC address.
248  *	APC CMOS RAM is accessed through ISA bridge.
249  *	MAC address is read into @net_dev->dev_addr.
250  */
251 
sis630e_get_mac_addr(struct pci_device * pci_dev __unused,struct nic * nic)252 static int sis630e_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
253 {
254 #if 0
255 	u8 reg;
256 	int i;
257 	struct bus_loc bus_loc;
258 	union {
259 	    struct bus_dev bus_dev;
260 	    struct pci_device isa_bridge;
261 	} u;
262 
263 	/* find PCI to ISA bridge */
264 	memset(&bus_loc, 0, sizeof(bus_loc));
265 	if ( ! find_by_driver ( &bus_loc, &u.bus_dev, &sis_bridge_driver, 0 ) )
266 	    return 0;
267 
268 	pci_read_config_byte(&u.isa_bridge, 0x48, &reg);
269 	pci_write_config_byte(&u.isa_bridge, 0x48, reg | 0x40);
270 
271 	for (i = 0; i < ETH_ALEN; i++)
272 	{
273 		outb(0x09 + i, 0x70);
274 		((u8 *)(nic->node_addr))[i] = inb(0x71);
275 	}
276 	pci_write_config_byte(&u.isa_bridge, 0x48, reg & ~0x40);
277 
278 	return 1;
279 #endif
280 
281 	/* Does not work with current bus/device model */
282 	memset ( nic->node_addr, 0, sizeof ( nic->node_addr ) );
283 	return 0;
284 }
285 
286 /**
287  *      sis630e_get_mac_addr: - Get MAC address for SiS630E model
288  *      @pci_dev: the sis900 pci device
289  *      @net_dev: the net device to get address for
290  *
291  *      SiS630E model, use APC CMOS RAM to store MAC address.
292  *      APC CMOS RAM is accessed through ISA bridge.
293  *      MAC address is read into @net_dev->dev_addr.
294  */
295 
sis635_get_mac_addr(struct pci_device * pci_dev __unused,struct nic * nic)296 static int sis635_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
297 {
298         u32 rfcrSave;
299         u32 i;
300 
301 
302         rfcrSave = inl(rfcr + ioaddr);
303 
304         outl(rfcrSave | RELOAD, ioaddr + cr);
305         outl(0, ioaddr + cr);
306 
307         /* disable packet filtering before setting filter */
308         outl(rfcrSave & ~RFEN, rfcr + ioaddr);
309 
310         /* load MAC addr to filter data register */
311         for (i = 0 ; i < 3 ; i++) {
312                 outl((i << RFADDR_shift), ioaddr + rfcr);
313                 *( ((u16 *)nic->node_addr) + i) = inw(ioaddr + rfdr);
314         }
315 
316         /* enable packet filitering */
317         outl(rfcrSave | RFEN, rfcr + ioaddr);
318 
319         return 1;
320 }
321 
322 /*
323  * Function: sis900_probe
324  *
325  * Description: initializes initializes the NIC, retrieves the
326  *    MAC address of the card, and sets up some globals required by
327  *    other routines.
328  *
329  * Side effects:
330  *            leaves the ioaddress of the sis900 chip in the variable ioaddr.
331  *            leaves the sis900 initialized, and ready to recieve packets.
332  *
333  * Returns:   struct nic *:          pointer to NIC data structure
334  */
335 
sis900_probe(struct nic * nic,struct pci_device * pci)336 static int sis900_probe ( struct nic *nic, struct pci_device *pci ) {
337 
338     int i;
339     int found=0;
340     int phy_addr;
341     u8 revision;
342     int ret;
343 
344     if (pci->ioaddr == 0)
345         return 0;
346 
347     nic->irqno  = 0;
348     nic->ioaddr = pci->ioaddr;
349 
350     ioaddr  = pci->ioaddr;
351     vendor  = pci->vendor;
352     dev_id  = pci->device;
353 
354     /* wakeup chip */
355     pci_write_config_dword(pci, 0x40, 0x00000000);
356 
357     adjust_pci_device(pci);
358 
359     /* get MAC address */
360     ret = 0;
361     pci_read_config_byte(pci, PCI_REVISION, &revision);
362 
363     /* save for use later in sis900_reset() */
364     pci_revision = revision;
365 
366     if (revision == SIS630E_900_REV)
367         ret = sis630e_get_mac_addr(pci, nic);
368     else if ((revision > 0x81) && (revision <= 0x90))
369         ret = sis635_get_mac_addr(pci, nic);
370     else if (revision == SIS96x_900_REV)
371 	ret = sis96x_get_mac_addr(pci, nic);
372     else
373         ret = sis900_get_mac_addr(pci, nic);
374 
375     if (ret == 0)
376     {
377         printf ("sis900_probe: Error MAC address not found\n");
378         return 0;
379     }
380 
381     /* 630ET : set the mii access mode as software-mode */
382     if (revision == SIS630ET_900_REV)
383 	outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
384 
385     DBG( "sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id );
386 
387     /* probe for mii transceiver */
388     /* search for total of 32 possible mii phy addresses */
389 
390     found = 0;
391     for (phy_addr = 0; phy_addr < 32; phy_addr++) {
392         u16 mii_status;
393         u16 phy_id0, phy_id1;
394 
395         mii_status = sis900_mdio_read(phy_addr, MII_STATUS);
396         if (mii_status == 0xffff || mii_status == 0x0000)
397             /* the mii is not accessable, try next one */
398             continue;
399 
400         phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
401         phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
402 
403         /* search our mii table for the current mii */
404         for (i = 0; mii_chip_table[i].phy_id1; i++) {
405 
406             if ((phy_id0 == mii_chip_table[i].phy_id0) &&
407                 ((phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1)){
408 
409                 printf("sis900_probe: %s transceiver found at address %d.\n",
410                        mii_chip_table[i].name, phy_addr);
411 
412                 mii.chip_info = &mii_chip_table[i];
413                 mii.phy_addr  = phy_addr;
414                 mii.status    = sis900_mdio_read(phy_addr, MII_STATUS);
415                 mii.next      = NULL;
416 
417                 found=1;
418                 break;
419             }
420         }
421     }
422 
423     if (found == 0) {
424         printf("sis900_probe: No MII transceivers found!\n");
425         return 0;
426     }
427 
428     /* Arbitrarily select the last PHY found as current PHY */
429     cur_phy = mii.phy_addr;
430     printf("sis900_probe: Using %s as default\n",  mii.chip_info->name);
431 
432     /* initialize device */
433     sis900_init(nic);
434     nic->nic_op	= &sis900_operations;
435 
436     return 1;
437 }
438 
439 
440 
441 
442 /*
443  * EEPROM Routines:  These functions read and write to EEPROM for
444  *    retrieving the MAC address and other configuration information about
445  *    the card.
446  */
447 
448 /* Delay between EEPROM clock transitions. */
449 #define eeprom_delay()  inl(ee_addr)
450 
451 
452 /* Function: sis900_read_eeprom
453  *
454  * Description: reads and returns a given location from EEPROM
455  *
456  * Arguments: int location:       requested EEPROM location
457  *
458  * Returns:   u16:                contents of requested EEPROM location
459  *
460  */
461 
462 /* Read Serial EEPROM through EEPROM Access Register, Note that location is
463    in word (16 bits) unit */
sis900_read_eeprom(int location)464 static u16 sis900_read_eeprom(int location)
465 {
466     int i;
467     u16 retval = 0;
468     long ee_addr = ioaddr + mear;
469     u32 read_cmd = location | EEread;
470 
471     outl(0, ee_addr);
472     eeprom_delay();
473     outl(EECS, ee_addr);
474     eeprom_delay();
475 
476     /* Shift the read command (9) bits out. */
477     for (i = 8; i >= 0; i--) {
478         u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
479         outl(dataval, ee_addr);
480         eeprom_delay();
481         outl(dataval | EECLK, ee_addr);
482         eeprom_delay();
483     }
484     outl(EECS, ee_addr);
485     eeprom_delay();
486 
487     /* read the 16-bits data in */
488     for (i = 16; i > 0; i--) {
489         outl(EECS, ee_addr);
490         eeprom_delay();
491         outl(EECS | EECLK, ee_addr);
492         eeprom_delay();
493         retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
494         eeprom_delay();
495     }
496 
497     /* Terminate the EEPROM access. */
498     outl(0, ee_addr);
499     eeprom_delay();
500 //  outl(EECLK, ee_addr);
501 
502     return (retval);
503 }
504 
505 #define sis900_mdio_delay()    inl(mdio_addr)
506 
507 
508 /*
509    Read and write the MII management registers using software-generated
510    serial MDIO protocol. Note that the command bits and data bits are
511    send out seperately
512 */
513 
sis900_mdio_idle(long mdio_addr)514 static void sis900_mdio_idle(long mdio_addr)
515 {
516     outl(MDIO | MDDIR, mdio_addr);
517     sis900_mdio_delay();
518     outl(MDIO | MDDIR | MDC, mdio_addr);
519 }
520 
521 /* Syncronize the MII management interface by shifting 32 one bits out. */
sis900_mdio_reset(long mdio_addr)522 static void sis900_mdio_reset(long mdio_addr)
523 {
524     int i;
525 
526     for (i = 31; i >= 0; i--) {
527         outl(MDDIR | MDIO, mdio_addr);
528         sis900_mdio_delay();
529         outl(MDDIR | MDIO | MDC, mdio_addr);
530         sis900_mdio_delay();
531     }
532     return;
533 }
534 
sis900_mdio_read(int phy_id,int location)535 static u16 sis900_mdio_read(int phy_id, int location)
536 {
537     long mdio_addr = ioaddr + mear;
538     int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
539     u16 retval = 0;
540     int i;
541 
542     sis900_mdio_reset(mdio_addr);
543     sis900_mdio_idle(mdio_addr);
544 
545     for (i = 15; i >= 0; i--) {
546         int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
547         outl(dataval, mdio_addr);
548         sis900_mdio_delay();
549         outl(dataval | MDC, mdio_addr);
550         sis900_mdio_delay();
551     }
552 
553     /* Read the 16 data bits. */
554     for (i = 16; i > 0; i--) {
555         outl(0, mdio_addr);
556         sis900_mdio_delay();
557         retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
558         outl(MDC, mdio_addr);
559         sis900_mdio_delay();
560     }
561     outl(0x00, mdio_addr);
562     return retval;
563 }
564 
565 #if 0
566 static void sis900_mdio_write(int phy_id, int location, int value)
567 {
568     long mdio_addr = ioaddr + mear;
569     int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
570     int i;
571 
572     sis900_mdio_reset(mdio_addr);
573     sis900_mdio_idle(mdio_addr);
574 
575     /* Shift the command bits out. */
576     for (i = 15; i >= 0; i--) {
577         int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
578         outb(dataval, mdio_addr);
579         sis900_mdio_delay();
580         outb(dataval | MDC, mdio_addr);
581         sis900_mdio_delay();
582     }
583     sis900_mdio_delay();
584 
585     /* Shift the value bits out. */
586     for (i = 15; i >= 0; i--) {
587         int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
588         outl(dataval, mdio_addr);
589         sis900_mdio_delay();
590         outl(dataval | MDC, mdio_addr);
591         sis900_mdio_delay();
592     }
593     sis900_mdio_delay();
594 
595     /* Clear out extra bits. */
596     for (i = 2; i > 0; i--) {
597         outb(0, mdio_addr);
598         sis900_mdio_delay();
599         outb(MDC, mdio_addr);
600         sis900_mdio_delay();
601     }
602     outl(0x00, mdio_addr);
603     return;
604 }
605 #endif
606 
607 
608 /* Function: sis900_init
609  *
610  * Description: resets the ethernet controller chip and various
611  *    data structures required for sending and receiving packets.
612  *
613  * Arguments: struct nic *nic:          NIC data structure
614  *
615  * returns:   void.
616  */
617 
618 static void
sis900_init(struct nic * nic)619 sis900_init(struct nic *nic)
620 {
621     /* Soft reset the chip. */
622     sis900_reset(nic);
623 
624     sis900_init_rxfilter(nic);
625 
626     sis900_init_txd(nic);
627     sis900_init_rxd(nic);
628 
629     sis900_set_rx_mode(nic);
630 
631     sis900_check_mode(nic);
632 
633     outl(RxENA| inl(ioaddr + cr), ioaddr + cr);
634 }
635 
636 
637 /*
638  * Function: sis900_reset
639  *
640  * Description: disables interrupts and soft resets the controller chip
641  *
642  * Arguments: struct nic *nic:          NIC data structure
643  *
644  * Returns:   void.
645  */
646 
647 static void
sis900_reset(struct nic * nic __unused)648 sis900_reset(struct nic *nic __unused)
649 {
650     int i = 0;
651     u32 status = TxRCMP | RxRCMP;
652 
653     outl(0, ioaddr + ier);
654     outl(0, ioaddr + imr);
655     outl(0, ioaddr + rfcr);
656 
657     outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
658 
659     /* Check that the chip has finished the reset. */
660     while (status && (i++ < 1000)) {
661         status ^= (inl(isr + ioaddr) & status);
662     }
663 
664     if( (pci_revision >= SIS635A_900_REV) || (pci_revision == SIS900B_900_REV) )
665             outl(PESEL | RND_CNT, ioaddr + cfg);
666     else
667             outl(PESEL, ioaddr + cfg);
668 }
669 
670 
671 /* Function: sis_init_rxfilter
672  *
673  * Description: sets receive filter address to our MAC address
674  *
675  * Arguments: struct nic *nic:          NIC data structure
676  *
677  * returns:   void.
678  */
679 
680 static void
sis900_init_rxfilter(struct nic * nic)681 sis900_init_rxfilter(struct nic *nic)
682 {
683     u32 rfcrSave;
684     int i;
685 
686     rfcrSave = inl(rfcr + ioaddr);
687 
688     /* disable packet filtering before setting filter */
689     outl(rfcrSave & ~RFEN, rfcr + ioaddr);
690 
691     /* load MAC addr to filter data register */
692     for (i = 0 ; i < 3 ; i++) {
693         u32 w;
694 
695         w = (u32) *((u16 *)(nic->node_addr)+i);
696         outl((i << RFADDR_shift), ioaddr + rfcr);
697         outl(w, ioaddr + rfdr);
698 
699         if (sis900_debug > 0)
700             printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%X\n",
701                    i, inl(ioaddr + rfdr));
702     }
703 
704     /* enable packet filitering */
705     outl(rfcrSave | RFEN, rfcr + ioaddr);
706 }
707 
708 
709 /*
710  * Function: sis_init_txd
711  *
712  * Description: initializes the Tx descriptor
713  *
714  * Arguments: struct nic *nic:          NIC data structure
715  *
716  * returns:   void.
717  */
718 
719 static void
sis900_init_txd(struct nic * nic __unused)720 sis900_init_txd(struct nic *nic __unused)
721 {
722     txd.link   = (u32) 0;
723     txd.cmdsts = (u32) 0;
724     txd.bufptr = virt_to_bus(&txb[0]);
725 
726     /* load Transmit Descriptor Register */
727     outl(virt_to_bus(&txd), ioaddr + txdp);
728     if (sis900_debug > 0)
729         printf("sis900_init_txd: TX descriptor register loaded with: %X\n",
730                inl(ioaddr + txdp));
731 }
732 
733 
734 /* Function: sis_init_rxd
735  *
736  * Description: initializes the Rx descriptor ring
737  *
738  * Arguments: struct nic *nic:          NIC data structure
739  *
740  * Returns:   void.
741  */
742 
743 static void
sis900_init_rxd(struct nic * nic __unused)744 sis900_init_rxd(struct nic *nic __unused)
745 {
746     int i;
747 
748     cur_rx = 0;
749 
750     /* init RX descriptor */
751     for (i = 0; i < NUM_RX_DESC; i++) {
752         rxd[i].link   = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
753         rxd[i].cmdsts = (u32) RX_BUF_SIZE;
754         rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
755         if (sis900_debug > 0)
756             printf("sis900_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
757                    i, &rxd[i], (unsigned int) rxd[i].link, (unsigned int) rxd[i].cmdsts,
758 		   (unsigned int) rxd[i].bufptr);
759     }
760 
761     /* load Receive Descriptor Register */
762     outl(virt_to_bus(&rxd[0]), ioaddr + rxdp);
763 
764     if (sis900_debug > 0)
765         printf("sis900_init_rxd: RX descriptor register loaded with: %X\n",
766                inl(ioaddr + rxdp));
767 
768 }
769 
770 
771 /* Function: sis_init_rxd
772  *
773  * Description:
774  *    sets the receive mode to accept all broadcast packets and packets
775  *    with our MAC address, and reject all multicast packets.
776  *
777  * Arguments: struct nic *nic:          NIC data structure
778  *
779  * Returns:   void.
780  */
781 
sis900_set_rx_mode(struct nic * nic __unused)782 static void sis900_set_rx_mode(struct nic *nic __unused)
783 {
784     int i, table_entries;
785     u32 rx_mode;
786     u16 mc_filter[16] = {0};	/* 256/128 bits multicast hash table */
787 
788     if((pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV))
789 	table_entries = 16;
790     else
791 	table_entries = 8;
792 
793     /* accept all multicast packet */
794     rx_mode = RFAAB | RFAAM;
795     for (i = 0; i < table_entries; i++)
796 		mc_filter[i] = 0xffff;
797 
798     /* update Multicast Hash Table in Receive Filter */
799     for (i = 0; i < table_entries; i++) {
800         /* why plus 0x04? That makes the correct value for hash table. */
801         outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
802         outl(mc_filter[i], ioaddr + rfdr);
803     }
804 
805     /* Accept Broadcast and multicast packets, destination addresses that match
806        our MAC address */
807     outl(RFEN | rx_mode, ioaddr + rfcr);
808 
809     return;
810 }
811 
812 
813 /* Function: sis900_check_mode
814  *
815  * Description: checks the state of transmit and receive
816  *    parameters on the NIC, and updates NIC registers to match
817  *
818  * Arguments: struct nic *nic:          NIC data structure
819  *
820  * Returns:   void.
821  */
822 
823 static void
sis900_check_mode(struct nic * nic)824 sis900_check_mode(struct nic *nic)
825 {
826     int speed, duplex;
827     u32 tx_flags = 0, rx_flags = 0;
828 
829     mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex);
830 
831     if( inl(ioaddr + cfg) & EDB_MASTER_EN ) {
832         tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
833 	rx_flags = DMA_BURST_64 << RxMXDMA_shift;
834     }
835     else {
836             tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
837             rx_flags = DMA_BURST_512 << RxMXDMA_shift;
838     }
839 
840     if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
841         rx_flags |= (RxDRNT_10 << RxDRNT_shift);
842         tx_flags |= (TxDRNT_10 << TxDRNT_shift);
843     }
844     else {
845         rx_flags |= (RxDRNT_100 << RxDRNT_shift);
846         tx_flags |= (TxDRNT_100 << TxDRNT_shift);
847     }
848 
849     if (duplex == FDX_CAPABLE_FULL_SELECTED) {
850         tx_flags |= (TxCSI | TxHBI);
851         rx_flags |= RxATX;
852     }
853 
854     outl (tx_flags, ioaddr + txcfg);
855     outl (rx_flags, ioaddr + rxcfg);
856 }
857 
858 
859 /* Function: sis900_read_mode
860  *
861  * Description: retrieves and displays speed and duplex
862  *    parameters from the NIC
863  *
864  * Arguments: struct nic *nic:          NIC data structure
865  *
866  * Returns:   void.
867  */
868 
869 static void
sis900_read_mode(struct nic * nic __unused,int phy_addr,int * speed,int * duplex)870 sis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
871 {
872     int i = 0;
873     u32 status;
874     u16 phy_id0, phy_id1;
875 
876     /* STSOUT register is Latched on Transition, read operation updates it */
877     do {
878         status = sis900_mdio_read(phy_addr, MII_STSOUT);
879     } while (i++ < 2);
880 
881     *speed = HW_SPEED_10_MBPS;
882     *duplex = FDX_CAPABLE_HALF_SELECTED;
883 
884     if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
885 	*speed = HW_SPEED_100_MBPS;
886     if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
887 	*duplex = FDX_CAPABLE_FULL_SELECTED;
888 
889     /* Workaround for Realtek RTL8201 PHY issue */
890     phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
891     phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
892     if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){
893 	if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX)
894 	    *duplex = FDX_CAPABLE_FULL_SELECTED;
895 	if(sis900_mdio_read(phy_addr, 0x0019) & 0x01)
896 	    *speed = HW_SPEED_100_MBPS;
897     }
898 
899     if (status & MII_STSOUT_LINK_FAIL)
900         printf("sis900_read_mode: Media Link Off\n");
901     else
902         printf("sis900_read_mode: Media Link On %s %s-duplex \n",
903                *speed == HW_SPEED_100_MBPS ?
904                "100mbps" : "10mbps",
905                *duplex == FDX_CAPABLE_FULL_SELECTED ?
906                "full" : "half");
907 }
908 
909 
910 /* Function: amd79c901_read_mode
911  *
912  * Description: retrieves and displays speed and duplex
913  *    parameters from the NIC
914  *
915  * Arguments: struct nic *nic:          NIC data structure
916  *
917  * Returns:   void.
918  */
919 
920 static void
amd79c901_read_mode(struct nic * nic __unused,int phy_addr,int * speed,int * duplex)921 amd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
922 {
923     int i;
924     u16 status;
925 
926     for (i = 0; i < 2; i++)
927         status = sis900_mdio_read(phy_addr, MII_STATUS);
928 
929     if (status & MII_STAT_CAN_AUTO) {
930         /* 10BASE-T PHY */
931         for (i = 0; i < 2; i++)
932             status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY);
933         if (status & MII_STSSUM_SPD)
934             *speed = HW_SPEED_100_MBPS;
935         else
936             *speed = HW_SPEED_10_MBPS;
937         if (status & MII_STSSUM_DPLX)
938             *duplex = FDX_CAPABLE_FULL_SELECTED;
939         else
940             *duplex = FDX_CAPABLE_HALF_SELECTED;
941 
942         if (status & MII_STSSUM_LINK)
943             printf("amd79c901_read_mode: Media Link On %s %s-duplex \n",
944                    *speed == HW_SPEED_100_MBPS ?
945                    "100mbps" : "10mbps",
946                    *duplex == FDX_CAPABLE_FULL_SELECTED ?
947                    "full" : "half");
948         else
949             printf("amd79c901_read_mode: Media Link Off\n");
950     }
951     else {
952         /* HomePNA */
953         *speed = HW_SPEED_HOME;
954         *duplex = FDX_CAPABLE_HALF_SELECTED;
955         if (status & MII_STAT_LINK)
956             printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");
957         else
958             printf("amd79c901_read_mode: Media Link Off\n");
959     }
960 }
961 
962 
963 /**
964  *	ics1893_read_mode: - read media mode for ICS1893 PHY
965  *	@net_dev: the net device to read mode for
966  *	@phy_addr: mii phy address
967  *	@speed: the transmit speed to be determined
968  *	@duplex: the duplex mode to be determined
969  *
970  *	ICS1893 PHY use Quick Poll Detailed Status register
971  *	to determine the speed and duplex mode for sis900
972  */
973 
ics1893_read_mode(struct nic * nic __unused,int phy_addr,int * speed,int * duplex)974 static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
975 {
976 	int i = 0;
977 	u32 status;
978 
979 	/* MII_QPDSTS is Latched, read twice in succession will reflect the current state */
980 	for (i = 0; i < 2; i++)
981 		status = sis900_mdio_read(phy_addr, MII_QPDSTS);
982 
983 	if (status & MII_STSICS_SPD)
984 		*speed = HW_SPEED_100_MBPS;
985 	else
986 		*speed = HW_SPEED_10_MBPS;
987 
988 	if (status & MII_STSICS_DPLX)
989 		*duplex = FDX_CAPABLE_FULL_SELECTED;
990 	else
991 		*duplex = FDX_CAPABLE_HALF_SELECTED;
992 
993 	if (status & MII_STSICS_LINKSTS)
994 		printf("ics1893_read_mode: Media Link On %s %s-duplex \n",
995 		       *speed == HW_SPEED_100_MBPS ?
996 		       "100mbps" : "10mbps",
997 		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
998 		       "full" : "half");
999 	else
1000 		printf("ics1893_read_mode: Media Link Off\n");
1001 }
1002 
1003 /**
1004  *	rtl8201_read_mode: - read media mode for rtl8201 phy
1005  *	@nic: the net device to read mode for
1006  *	@phy_addr: mii phy address
1007  *	@speed: the transmit speed to be determined
1008  *	@duplex: the duplex mode to be determined
1009  *
1010  *	read MII_STATUS register from rtl8201 phy
1011  *	to determine the speed and duplex mode for sis900
1012  */
1013 
rtl8201_read_mode(struct nic * nic __unused,int phy_addr,int * speed,int * duplex)1014 static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
1015 {
1016 	u32 status;
1017 
1018 	status = sis900_mdio_read(phy_addr, MII_STATUS);
1019 
1020 	if (status & MII_STAT_CAN_TX_FDX) {
1021 		*speed = HW_SPEED_100_MBPS;
1022 		*duplex = FDX_CAPABLE_FULL_SELECTED;
1023 	}
1024 	else if (status & MII_STAT_CAN_TX) {
1025 		*speed = HW_SPEED_100_MBPS;
1026 		*duplex = FDX_CAPABLE_HALF_SELECTED;
1027 	}
1028 	else if (status & MII_STAT_CAN_T_FDX) {
1029 		*speed = HW_SPEED_10_MBPS;
1030 		*duplex = FDX_CAPABLE_FULL_SELECTED;
1031 	}
1032 	else if (status & MII_STAT_CAN_T) {
1033 		*speed = HW_SPEED_10_MBPS;
1034 		*duplex = FDX_CAPABLE_HALF_SELECTED;
1035 	}
1036 
1037 	if (status & MII_STAT_LINK)
1038 		printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",
1039 		       *speed == HW_SPEED_100_MBPS ?
1040 		       "100mbps" : "10mbps",
1041 		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
1042 		       "full" : "half");
1043 	else
1044 		printf("rtl8201_read_config_mode: Media Link Off\n");
1045 }
1046 
1047 /**
1048  *	vt6103_read_mode: - read media mode for vt6103 phy
1049  *	@nic: the net device to read mode for
1050  *	@phy_addr: mii phy address
1051  *	@speed: the transmit speed to be determined
1052  *	@duplex: the duplex mode to be determined
1053  *
1054  *	read MII_STATUS register from rtl8201 phy
1055  *	to determine the speed and duplex mode for sis900
1056  */
1057 
vt6103_read_mode(struct nic * nic __unused,int phy_addr,int * speed,int * duplex)1058 static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
1059 {
1060 	u32 status;
1061 
1062 	status = sis900_mdio_read(phy_addr, MII_STATUS);
1063 
1064 	if (status & MII_STAT_CAN_TX_FDX) {
1065 		*speed = HW_SPEED_100_MBPS;
1066 		*duplex = FDX_CAPABLE_FULL_SELECTED;
1067 	}
1068 	else if (status & MII_STAT_CAN_TX) {
1069 		*speed = HW_SPEED_100_MBPS;
1070 		*duplex = FDX_CAPABLE_HALF_SELECTED;
1071 	}
1072 	else if (status & MII_STAT_CAN_T_FDX) {
1073 		*speed = HW_SPEED_10_MBPS;
1074 		*duplex = FDX_CAPABLE_FULL_SELECTED;
1075 	}
1076 	else if (status & MII_STAT_CAN_T) {
1077 		*speed = HW_SPEED_10_MBPS;
1078 		*duplex = FDX_CAPABLE_HALF_SELECTED;
1079 	}
1080 
1081 	if (status & MII_STAT_LINK)
1082 		printf("vt6103_read_mode: Media Link On %s %s-duplex \n",
1083 		       *speed == HW_SPEED_100_MBPS ?
1084 		       "100mbps" : "10mbps",
1085 		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
1086 		       "full" : "half");
1087 	else
1088 		printf("vt6103_read_config_mode: Media Link Off\n");
1089 }
1090 
1091 /* Function: sis900_transmit
1092  *
1093  * Description: transmits a packet and waits for completion or timeout.
1094  *
1095  * Arguments: char d[6]:          destination ethernet address.
1096  *            unsigned short t:   ethernet protocol type.
1097  *            unsigned short s:   size of the data-part of the packet.
1098  *            char *p:            the data for the packet.
1099  *
1100  * Returns:   void.
1101  */
1102 
1103 static void
sis900_transmit(struct nic * nic,const char * d,unsigned int t,unsigned int s,const char * p)1104 sis900_transmit(struct nic  *nic,
1105                 const char  *d,     /* Destination */
1106                 unsigned int t,     /* Type */
1107                 unsigned int s,     /* size */
1108                 const char  *p)     /* Packet */
1109 {
1110     u32 to, nstype;
1111     volatile u32 tx_status;
1112 
1113     /* Stop the transmitter */
1114     outl(TxDIS | inl(ioaddr + cr), ioaddr + cr);
1115 
1116     /* load Transmit Descriptor Register */
1117     outl(virt_to_bus(&txd), ioaddr + txdp);
1118     if (sis900_debug > 1)
1119         printf("sis900_transmit: TX descriptor register loaded with: %X\n",
1120                inl(ioaddr + txdp));
1121 
1122     memcpy(txb, d, ETH_ALEN);
1123     memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
1124     nstype = htons(t);
1125     memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
1126     memcpy(txb + ETH_HLEN, p, s);
1127 
1128     s += ETH_HLEN;
1129     s &= DSIZE;
1130 
1131     if (sis900_debug > 1)
1132         printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
1133 
1134     /* pad to minimum packet size */
1135     while (s < ETH_ZLEN)
1136         txb[s++] = '\0';
1137 
1138     /* set the transmit buffer descriptor and enable Transmit State Machine */
1139     txd.bufptr = virt_to_bus(&txb[0]);
1140     txd.cmdsts = (u32) OWN | s;
1141 
1142     /* restart the transmitter */
1143     outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
1144 
1145     if (sis900_debug > 1)
1146         printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);
1147 
1148     to = currticks() + TX_TIMEOUT;
1149 
1150     while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
1151         /* wait */ ;
1152 
1153     if (currticks() >= to) {
1154         printf("sis900_transmit: TX Timeout! Tx status %X.\n",
1155 	       (unsigned int) tx_status);
1156     }
1157 
1158     if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
1159         /* packet unsuccessfully transmited */
1160         printf("sis900_transmit: Transmit error, Tx status %X.\n",
1161 	       (unsigned int) tx_status);
1162     }
1163     /* Disable interrupts by clearing the interrupt mask. */
1164     outl(0, ioaddr + imr);
1165 }
1166 
1167 
1168 /* Function: sis900_poll
1169  *
1170  * Description: checks for a received packet and returns it if found.
1171  *
1172  * Arguments: struct nic *nic:          NIC data structure
1173  *
1174  * Returns:   1 if a packet was recieved.
1175  *            0 if no pacet was recieved.
1176  *
1177  * Side effects:
1178  *            Returns (copies) the packet to the array nic->packet.
1179  *            Returns the length of the packet in nic->packetlen.
1180  */
1181 
1182 static int
sis900_poll(struct nic * nic,int retrieve)1183 sis900_poll(struct nic *nic, int retrieve)
1184 {
1185     u32 rx_status = rxd[cur_rx].cmdsts;
1186     u32 intr_status;
1187     int retstat = 0;
1188 
1189      /* acknowledge interrupts by reading interrupt status register */
1190     intr_status = inl(ioaddr + isr);
1191 
1192     if (sis900_debug > 2)
1193         printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx,
1194 	       (unsigned int) rx_status);
1195 
1196     if (!(rx_status & OWN))
1197         return retstat;
1198 
1199     if (sis900_debug > 1)
1200         printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
1201                cur_rx, (unsigned int) rx_status);
1202 
1203     if ( ! retrieve ) return 1;
1204 
1205     nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
1206 
1207     if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
1208         /* corrupted packet received */
1209         printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
1210                (unsigned int) rx_status);
1211         retstat = 0;
1212     } else {
1213         /* give packet to higher level routine */
1214         memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
1215         retstat = 1;
1216     }
1217 
1218     /* return the descriptor and buffer to receive ring */
1219     rxd[cur_rx].cmdsts = RX_BUF_SIZE;
1220     rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
1221 
1222     if (++cur_rx == NUM_RX_DESC)
1223         cur_rx = 0;
1224 
1225     /* re-enable the potentially idle receive state machine */
1226     outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
1227 
1228     return retstat;
1229 
1230 }
1231 
1232 
1233 /* Function: sis900_disable
1234  *
1235  * Description: Turns off interrupts and stops Tx and Rx engines
1236  *
1237  * Arguments: struct nic *nic:          NIC data structure
1238  *
1239  * Returns:   void.
1240  */
1241 
1242 static void
sis900_disable(struct nic * nic)1243 sis900_disable ( struct nic *nic ) {
1244 
1245     sis900_init(nic);
1246 
1247     /* Disable interrupts by clearing the interrupt mask. */
1248     outl(0, ioaddr + imr);
1249     outl(0, ioaddr + ier);
1250 
1251     /* Stop the chip's Tx and Rx Status Machine */
1252     outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
1253 }
1254 
1255 
1256 /* Function: sis900_irq
1257  *
1258  * Description: Enable, Disable, or Force, interrupts
1259  *
1260  * Arguments: struct nic *nic:          NIC data structure
1261  *            irq_action_t action:      Requested action
1262  *
1263  * Returns:   void.
1264  */
1265 
1266 static void
sis900_irq(struct nic * nic __unused,irq_action_t action __unused)1267 sis900_irq(struct nic *nic __unused, irq_action_t action __unused)
1268 {
1269   switch ( action ) {
1270   case DISABLE :
1271     outl(0, ioaddr + imr);
1272     break;
1273   case ENABLE :
1274     outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
1275     break;
1276   case FORCE :
1277     break;
1278   }
1279 }
1280 
1281 static struct nic_operations sis900_operations = {
1282 	.connect	= dummy_connect,
1283 	.poll		= sis900_poll,
1284 	.transmit	= sis900_transmit,
1285 	.irq		= sis900_irq,
1286 };
1287 
1288 static struct pci_device_id sis900_nics[] = {
1289 PCI_ROM(0x1039, 0x0900, "sis900",  "SIS900", 0),
1290 PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016", 0),
1291 };
1292 
1293 PCI_DRIVER ( sis900_driver, sis900_nics, PCI_NO_CLASS );
1294 
1295 DRIVER ( "SIS900", nic_driver, pci_driver, sis900_driver,
1296 	 sis900_probe, sis900_disable );
1297 
1298 /*
1299  * Local variables:
1300  *  c-basic-offset: 8
1301  *  c-indent-level: 8
1302  *  tab-width: 8
1303  * End:
1304  */
1305