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