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