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