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