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