Warnings purge of drivers (continued)
[gpxe.git] / src / drivers / net / sis900.c
blob7e15f6d0b5bd8a5100ee099c154f817f2481f326
1 /* -*- Mode:C; c-basic-offset:4; -*- */
3 /*
4 sis900.c: An SiS 900/7016 PCI Fast Ethernet driver for Etherboot
5 Copyright (C) 2001 Entity Cyber, Inc.
7 Revision: 1.0 March 1, 2001
9 Author: Marty Connor (mdc@etherboot.org)
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.
15 This software may be used and distributed according to the terms
16 of the GNU Public License (GPL), incorporated herein by reference.
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 */
27 /* Revision History */
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
44 /* Includes */
46 #include "etherboot.h"
47 #include "dev.h"
48 #include <gpxe/pci.h>
49 #include "nic.h"
50 #include "timer.h"
52 #include "sis900.h"
54 /* Globals */
56 static struct nic_operations sis900_operations;
58 static int sis900_debug = 0;
60 static unsigned short vendor, dev_id;
61 static unsigned long ioaddr;
62 static u8 pci_revision;
64 static unsigned int cur_phy;
66 static unsigned int cur_rx;
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
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. */
91 #endif
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);
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}
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;
125 #if 0
126 // PCI to ISA bridge for SIS640E access
127 static struct pci_device_id pci_isa_bridge_list[] = {
128 { .vendor = 0x1039, .device = 0x0008,
129 .name = "SIS 85C503/5513 PCI to ISA bridge"},
132 PCI_DRIVER( sis_bridge_pci_driver, pci_isa_bridge_list, PCI_NO_CLASS );
134 static struct device_driver sis_bridge_driver = {
135 .name = "SIS ISA bridge",
136 .bus_driver = &pci_driver,
137 .bus_driver_info = ( struct bus_driver_info * ) &sis_bridge_pci_driver,
139 #endif
141 /* Function Prototypes */
143 static int sis900_probe(struct nic *nic,struct pci_device *pci);
145 static u16 sis900_read_eeprom(int location);
146 static void sis900_mdio_reset(long mdio_addr);
147 static void sis900_mdio_idle(long mdio_addr);
148 static u16 sis900_mdio_read(int phy_id, int location);
149 #if 0
150 static void sis900_mdio_write(int phy_id, int location, int val);
151 #endif
152 static void sis900_init(struct nic *nic);
154 static void sis900_reset(struct nic *nic);
156 static void sis900_init_rxfilter(struct nic *nic);
157 static void sis900_init_txd(struct nic *nic);
158 static void sis900_init_rxd(struct nic *nic);
159 static void sis900_set_rx_mode(struct nic *nic);
160 static void sis900_check_mode(struct nic *nic);
162 static void sis900_transmit(struct nic *nic, const char *d,
163 unsigned int t, unsigned int s, const char *p);
164 static int sis900_poll(struct nic *nic, int retrieve);
166 static void sis900_disable(struct nic *nic);
168 static void sis900_irq(struct nic *nic, irq_action_t action);
171 * sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
172 * @pci_dev: the sis900 pci device
173 * @net_dev: the net device to get address for
175 * Older SiS900 and friends, use EEPROM to store MAC address.
176 * MAC address is read from read_eeprom() into @net_dev->dev_addr.
179 static int sis900_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
181 u16 signature;
182 int i;
184 /* check to see if we have sane EEPROM */
185 signature = (u16) sis900_read_eeprom( EEPROMSignature);
186 if (signature == 0xffff || signature == 0x0000) {
187 printf ("sis900_probe: Error EERPOM read %hX\n", signature);
188 return 0;
191 /* get MAC address from EEPROM */
192 for (i = 0; i < 3; i++)
193 ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
194 return 1;
198 * sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
199 * @pci_dev: the sis900 pci device
200 * @net_dev: the net device to get address for
202 * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
203 * is shared by
204 * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
205 * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
206 * by LAN, otherwise is not. After MAC address is read from EEPROM, send
207 * EEDONE signal to refuse EEPROM access by LAN.
208 * The EEPROM map of SiS962 or SiS963 is different to SiS900.
209 * The signature field in SiS962 or SiS963 spec is meaningless.
210 * MAC address is read into @net_dev->dev_addr.
213 static int sis96x_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
215 /* long ioaddr = net_dev->base_addr; */
216 long ee_addr = ioaddr + mear;
217 u32 waittime = 0;
218 int i;
220 printf("Alternate function\n");
222 outl(EEREQ, ee_addr);
223 while(waittime < 2000) {
224 if(inl(ee_addr) & EEGNT) {
226 /* get MAC address from EEPROM */
227 for (i = 0; i < 3; i++)
228 ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
230 outl(EEDONE, ee_addr);
231 return 1;
232 } else {
233 udelay(1);
234 waittime ++;
237 outl(EEDONE, ee_addr);
238 return 0;
242 * sis630e_get_mac_addr: - Get MAC address for SiS630E model
243 * @pci_dev: the sis900 pci device
244 * @net_dev: the net device to get address for
246 * SiS630E model, use APC CMOS RAM to store MAC address.
247 * APC CMOS RAM is accessed through ISA bridge.
248 * MAC address is read into @net_dev->dev_addr.
251 static int sis630e_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
253 u8 reg;
254 int i;
255 #if 0
256 struct bus_loc bus_loc;
257 #endif
258 union {
259 struct bus_dev bus_dev;
260 struct pci_device isa_bridge;
261 } u;
263 #if 0
264 /* find PCI to ISA bridge */
265 memset(&bus_loc, 0, sizeof(bus_loc));
266 if ( ! find_by_driver ( &bus_loc, &u.bus_dev, &sis_bridge_driver, 0 ) )
267 return 0;
268 #endif
270 pci_read_config_byte(&u.isa_bridge, 0x48, &reg);
271 pci_write_config_byte(&u.isa_bridge, 0x48, reg | 0x40);
273 for (i = 0; i < ETH_ALEN; i++)
275 outb(0x09 + i, 0x70);
276 ((u8 *)(nic->node_addr))[i] = inb(0x71);
278 pci_write_config_byte(&u.isa_bridge, 0x48, reg & ~0x40);
280 return 1;
284 * sis630e_get_mac_addr: - Get MAC address for SiS630E model
285 * @pci_dev: the sis900 pci device
286 * @net_dev: the net device to get address for
288 * SiS630E model, use APC CMOS RAM to store MAC address.
289 * APC CMOS RAM is accessed through ISA bridge.
290 * MAC address is read into @net_dev->dev_addr.
293 static int sis635_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
295 u32 rfcrSave;
296 u32 i;
299 rfcrSave = inl(rfcr + ioaddr);
301 outl(rfcrSave | RELOAD, ioaddr + cr);
302 outl(0, ioaddr + cr);
304 /* disable packet filtering before setting filter */
305 outl(rfcrSave & ~RFEN, rfcr + ioaddr);
307 /* load MAC addr to filter data register */
308 for (i = 0 ; i < 3 ; i++) {
309 outl((i << RFADDR_shift), ioaddr + rfcr);
310 *( ((u16 *)nic->node_addr) + i) = inw(ioaddr + rfdr);
313 /* enable packet filitering */
314 outl(rfcrSave | RFEN, rfcr + ioaddr);
316 return 1;
320 * Function: sis900_probe
322 * Description: initializes initializes the NIC, retrieves the
323 * MAC address of the card, and sets up some globals required by
324 * other routines.
326 * Side effects:
327 * leaves the ioaddress of the sis900 chip in the variable ioaddr.
328 * leaves the sis900 initialized, and ready to recieve packets.
330 * Returns: struct nic *: pointer to NIC data structure
333 static int sis900_probe ( struct nic *nic, struct pci_device *pci ) {
335 int i;
336 int found=0;
337 int phy_addr;
338 u8 revision;
339 int ret;
341 if (pci->ioaddr == 0)
342 return 0;
344 nic->irqno = 0;
345 pci_fill_nic ( nic, pci );
346 nic->ioaddr = pci->ioaddr;
347 ioaddr = pci->ioaddr;
348 vendor = pci->vendor;
349 dev_id = pci->device;
351 /* wakeup chip */
352 pci_write_config_dword(pci, 0x40, 0x00000000);
354 adjust_pci_device(pci);
356 /* get MAC address */
357 ret = 0;
358 pci_read_config_byte(pci, PCI_REVISION, &revision);
360 /* save for use later in sis900_reset() */
361 pci_revision = revision;
363 if (revision == SIS630E_900_REV)
364 ret = sis630e_get_mac_addr(pci, nic);
365 else if ((revision > 0x81) && (revision <= 0x90))
366 ret = sis635_get_mac_addr(pci, nic);
367 else if (revision == SIS96x_900_REV)
368 ret = sis96x_get_mac_addr(pci, nic);
369 else
370 ret = sis900_get_mac_addr(pci, nic);
372 if (ret == 0)
374 printf ("sis900_probe: Error MAC address not found\n");
375 return 0;
378 /* 630ET : set the mii access mode as software-mode */
379 if (revision == SIS630ET_900_REV)
380 outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
382 DBG( "sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id );
384 /* probe for mii transceiver */
385 /* search for total of 32 possible mii phy addresses */
387 found = 0;
388 for (phy_addr = 0; phy_addr < 32; phy_addr++) {
389 u16 mii_status;
390 u16 phy_id0, phy_id1;
392 mii_status = sis900_mdio_read(phy_addr, MII_STATUS);
393 if (mii_status == 0xffff || mii_status == 0x0000)
394 /* the mii is not accessable, try next one */
395 continue;
397 phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
398 phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
400 /* search our mii table for the current mii */
401 for (i = 0; mii_chip_table[i].phy_id1; i++) {
403 if ((phy_id0 == mii_chip_table[i].phy_id0) &&
404 ((phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1)){
406 printf("sis900_probe: %s transceiver found at address %d.\n",
407 mii_chip_table[i].name, phy_addr);
409 mii.chip_info = &mii_chip_table[i];
410 mii.phy_addr = phy_addr;
411 mii.status = sis900_mdio_read(phy_addr, MII_STATUS);
412 mii.next = NULL;
414 found=1;
415 break;
420 if (found == 0) {
421 printf("sis900_probe: No MII transceivers found!\n");
422 return 0;
425 /* Arbitrarily select the last PHY found as current PHY */
426 cur_phy = mii.phy_addr;
427 printf("sis900_probe: Using %s as default\n", mii.chip_info->name);
429 /* initialize device */
430 sis900_init(nic);
431 nic->nic_op = &sis900_operations;
433 return 1;
440 * EEPROM Routines: These functions read and write to EEPROM for
441 * retrieving the MAC address and other configuration information about
442 * the card.
445 /* Delay between EEPROM clock transitions. */
446 #define eeprom_delay() inl(ee_addr)
449 /* Function: sis900_read_eeprom
451 * Description: reads and returns a given location from EEPROM
453 * Arguments: int location: requested EEPROM location
455 * Returns: u16: contents of requested EEPROM location
459 /* Read Serial EEPROM through EEPROM Access Register, Note that location is
460 in word (16 bits) unit */
461 static u16 sis900_read_eeprom(int location)
463 int i;
464 u16 retval = 0;
465 long ee_addr = ioaddr + mear;
466 u32 read_cmd = location | EEread;
468 outl(0, ee_addr);
469 eeprom_delay();
470 outl(EECS, ee_addr);
471 eeprom_delay();
473 /* Shift the read command (9) bits out. */
474 for (i = 8; i >= 0; i--) {
475 u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
476 outl(dataval, ee_addr);
477 eeprom_delay();
478 outl(dataval | EECLK, ee_addr);
479 eeprom_delay();
481 outl(EECS, ee_addr);
482 eeprom_delay();
484 /* read the 16-bits data in */
485 for (i = 16; i > 0; i--) {
486 outl(EECS, ee_addr);
487 eeprom_delay();
488 outl(EECS | EECLK, ee_addr);
489 eeprom_delay();
490 retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
491 eeprom_delay();
494 /* Terminate the EEPROM access. */
495 outl(0, ee_addr);
496 eeprom_delay();
497 // outl(EECLK, ee_addr);
499 return (retval);
502 #define sis900_mdio_delay() inl(mdio_addr)
506 Read and write the MII management registers using software-generated
507 serial MDIO protocol. Note that the command bits and data bits are
508 send out seperately
511 static void sis900_mdio_idle(long mdio_addr)
513 outl(MDIO | MDDIR, mdio_addr);
514 sis900_mdio_delay();
515 outl(MDIO | MDDIR | MDC, mdio_addr);
518 /* Syncronize the MII management interface by shifting 32 one bits out. */
519 static void sis900_mdio_reset(long mdio_addr)
521 int i;
523 for (i = 31; i >= 0; i--) {
524 outl(MDDIR | MDIO, mdio_addr);
525 sis900_mdio_delay();
526 outl(MDDIR | MDIO | MDC, mdio_addr);
527 sis900_mdio_delay();
529 return;
532 static u16 sis900_mdio_read(int phy_id, int location)
534 long mdio_addr = ioaddr + mear;
535 int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
536 u16 retval = 0;
537 int i;
539 sis900_mdio_reset(mdio_addr);
540 sis900_mdio_idle(mdio_addr);
542 for (i = 15; i >= 0; i--) {
543 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
544 outl(dataval, mdio_addr);
545 sis900_mdio_delay();
546 outl(dataval | MDC, mdio_addr);
547 sis900_mdio_delay();
550 /* Read the 16 data bits. */
551 for (i = 16; i > 0; i--) {
552 outl(0, mdio_addr);
553 sis900_mdio_delay();
554 retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
555 outl(MDC, mdio_addr);
556 sis900_mdio_delay();
558 outl(0x00, mdio_addr);
559 return retval;
562 #if 0
563 static void sis900_mdio_write(int phy_id, int location, int value)
565 long mdio_addr = ioaddr + mear;
566 int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
567 int i;
569 sis900_mdio_reset(mdio_addr);
570 sis900_mdio_idle(mdio_addr);
572 /* Shift the command bits out. */
573 for (i = 15; i >= 0; i--) {
574 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
575 outb(dataval, mdio_addr);
576 sis900_mdio_delay();
577 outb(dataval | MDC, mdio_addr);
578 sis900_mdio_delay();
580 sis900_mdio_delay();
582 /* Shift the value bits out. */
583 for (i = 15; i >= 0; i--) {
584 int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
585 outl(dataval, mdio_addr);
586 sis900_mdio_delay();
587 outl(dataval | MDC, mdio_addr);
588 sis900_mdio_delay();
590 sis900_mdio_delay();
592 /* Clear out extra bits. */
593 for (i = 2; i > 0; i--) {
594 outb(0, mdio_addr);
595 sis900_mdio_delay();
596 outb(MDC, mdio_addr);
597 sis900_mdio_delay();
599 outl(0x00, mdio_addr);
600 return;
602 #endif
605 /* Function: sis900_init
607 * Description: resets the ethernet controller chip and various
608 * data structures required for sending and receiving packets.
610 * Arguments: struct nic *nic: NIC data structure
612 * returns: void.
615 static void
616 sis900_init(struct nic *nic)
618 /* Soft reset the chip. */
619 sis900_reset(nic);
621 sis900_init_rxfilter(nic);
623 sis900_init_txd(nic);
624 sis900_init_rxd(nic);
626 sis900_set_rx_mode(nic);
628 sis900_check_mode(nic);
630 outl(RxENA| inl(ioaddr + cr), ioaddr + cr);
635 * Function: sis900_reset
637 * Description: disables interrupts and soft resets the controller chip
639 * Arguments: struct nic *nic: NIC data structure
641 * Returns: void.
644 static void
645 sis900_reset(struct nic *nic __unused)
647 int i = 0;
648 u32 status = TxRCMP | RxRCMP;
650 outl(0, ioaddr + ier);
651 outl(0, ioaddr + imr);
652 outl(0, ioaddr + rfcr);
654 outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
656 /* Check that the chip has finished the reset. */
657 while (status && (i++ < 1000)) {
658 status ^= (inl(isr + ioaddr) & status);
661 if( (pci_revision >= SIS635A_900_REV) || (pci_revision == SIS900B_900_REV) )
662 outl(PESEL | RND_CNT, ioaddr + cfg);
663 else
664 outl(PESEL, ioaddr + cfg);
668 /* Function: sis_init_rxfilter
670 * Description: sets receive filter address to our MAC address
672 * Arguments: struct nic *nic: NIC data structure
674 * returns: void.
677 static void
678 sis900_init_rxfilter(struct nic *nic)
680 u32 rfcrSave;
681 int i;
683 rfcrSave = inl(rfcr + ioaddr);
685 /* disable packet filtering before setting filter */
686 outl(rfcrSave & ~RFEN, rfcr + ioaddr);
688 /* load MAC addr to filter data register */
689 for (i = 0 ; i < 3 ; i++) {
690 u32 w;
692 w = (u32) *((u16 *)(nic->node_addr)+i);
693 outl((i << RFADDR_shift), ioaddr + rfcr);
694 outl(w, ioaddr + rfdr);
696 if (sis900_debug > 0)
697 printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%lX\n",
698 i, inl(ioaddr + rfdr));
701 /* enable packet filitering */
702 outl(rfcrSave | RFEN, rfcr + ioaddr);
707 * Function: sis_init_txd
709 * Description: initializes the Tx descriptor
711 * Arguments: struct nic *nic: NIC data structure
713 * returns: void.
716 static void
717 sis900_init_txd(struct nic *nic __unused)
719 txd.link = (u32) 0;
720 txd.cmdsts = (u32) 0;
721 txd.bufptr = virt_to_bus(&txb[0]);
723 /* load Transmit Descriptor Register */
724 outl(virt_to_bus(&txd), ioaddr + txdp);
725 if (sis900_debug > 0)
726 printf("sis900_init_txd: TX descriptor register loaded with: %lX\n",
727 inl(ioaddr + txdp));
731 /* Function: sis_init_rxd
733 * Description: initializes the Rx descriptor ring
735 * Arguments: struct nic *nic: NIC data structure
737 * Returns: void.
740 static void
741 sis900_init_rxd(struct nic *nic __unused)
743 int i;
745 cur_rx = 0;
747 /* init RX descriptor */
748 for (i = 0; i < NUM_RX_DESC; i++) {
749 rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
750 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
751 rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
752 if (sis900_debug > 0)
753 printf("sis900_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
754 i, &rxd[i], (unsigned int) rxd[i].link, (unsigned int) rxd[i].cmdsts,
755 (unsigned int) rxd[i].bufptr);
758 /* load Receive Descriptor Register */
759 outl(virt_to_bus(&rxd[0]), ioaddr + rxdp);
761 if (sis900_debug > 0)
762 printf("sis900_init_rxd: RX descriptor register loaded with: %lX\n",
763 inl(ioaddr + rxdp));
768 /* Function: sis_init_rxd
770 * Description:
771 * sets the receive mode to accept all broadcast packets and packets
772 * with our MAC address, and reject all multicast packets.
774 * Arguments: struct nic *nic: NIC data structure
776 * Returns: void.
779 static void sis900_set_rx_mode(struct nic *nic __unused)
781 int i, table_entries;
782 u32 rx_mode;
783 u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */
785 if((pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV))
786 table_entries = 16;
787 else
788 table_entries = 8;
790 /* accept all multicast packet */
791 rx_mode = RFAAB | RFAAM;
792 for (i = 0; i < table_entries; i++)
793 mc_filter[i] = 0xffff;
795 /* update Multicast Hash Table in Receive Filter */
796 for (i = 0; i < table_entries; i++) {
797 /* why plus 0x04? That makes the correct value for hash table. */
798 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
799 outl(mc_filter[i], ioaddr + rfdr);
802 /* Accept Broadcast and multicast packets, destination addresses that match
803 our MAC address */
804 outl(RFEN | rx_mode, ioaddr + rfcr);
806 return;
810 /* Function: sis900_check_mode
812 * Description: checks the state of transmit and receive
813 * parameters on the NIC, and updates NIC registers to match
815 * Arguments: struct nic *nic: NIC data structure
817 * Returns: void.
820 static void
821 sis900_check_mode(struct nic *nic)
823 int speed, duplex;
824 u32 tx_flags = 0, rx_flags = 0;
826 mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex);
828 if( inl(ioaddr + cfg) & EDB_MASTER_EN ) {
829 tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
830 rx_flags = DMA_BURST_64 << RxMXDMA_shift;
832 else {
833 tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
834 rx_flags = DMA_BURST_512 << RxMXDMA_shift;
837 if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
838 rx_flags |= (RxDRNT_10 << RxDRNT_shift);
839 tx_flags |= (TxDRNT_10 << TxDRNT_shift);
841 else {
842 rx_flags |= (RxDRNT_100 << RxDRNT_shift);
843 tx_flags |= (TxDRNT_100 << TxDRNT_shift);
846 if (duplex == FDX_CAPABLE_FULL_SELECTED) {
847 tx_flags |= (TxCSI | TxHBI);
848 rx_flags |= RxATX;
851 outl (tx_flags, ioaddr + txcfg);
852 outl (rx_flags, ioaddr + rxcfg);
856 /* Function: sis900_read_mode
858 * Description: retrieves and displays speed and duplex
859 * parameters from the NIC
861 * Arguments: struct nic *nic: NIC data structure
863 * Returns: void.
866 static void
867 sis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
869 int i = 0;
870 u32 status;
871 u16 phy_id0, phy_id1;
873 /* STSOUT register is Latched on Transition, read operation updates it */
874 while (i++ < 2)
875 status = sis900_mdio_read(phy_addr, MII_STSOUT);
877 *speed = HW_SPEED_10_MBPS;
878 *duplex = FDX_CAPABLE_HALF_SELECTED;
880 if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
881 *speed = HW_SPEED_100_MBPS;
882 if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
883 *duplex = FDX_CAPABLE_FULL_SELECTED;
885 /* Workaround for Realtek RTL8201 PHY issue */
886 phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
887 phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
888 if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){
889 if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX)
890 *duplex = FDX_CAPABLE_FULL_SELECTED;
891 if(sis900_mdio_read(phy_addr, 0x0019) & 0x01)
892 *speed = HW_SPEED_100_MBPS;
895 if (status & MII_STSOUT_LINK_FAIL)
896 printf("sis900_read_mode: Media Link Off\n");
897 else
898 printf("sis900_read_mode: Media Link On %s %s-duplex \n",
899 *speed == HW_SPEED_100_MBPS ?
900 "100mbps" : "10mbps",
901 *duplex == FDX_CAPABLE_FULL_SELECTED ?
902 "full" : "half");
906 /* Function: amd79c901_read_mode
908 * Description: retrieves and displays speed and duplex
909 * parameters from the NIC
911 * Arguments: struct nic *nic: NIC data structure
913 * Returns: void.
916 static void
917 amd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
919 int i;
920 u16 status;
922 for (i = 0; i < 2; i++)
923 status = sis900_mdio_read(phy_addr, MII_STATUS);
925 if (status & MII_STAT_CAN_AUTO) {
926 /* 10BASE-T PHY */
927 for (i = 0; i < 2; i++)
928 status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY);
929 if (status & MII_STSSUM_SPD)
930 *speed = HW_SPEED_100_MBPS;
931 else
932 *speed = HW_SPEED_10_MBPS;
933 if (status & MII_STSSUM_DPLX)
934 *duplex = FDX_CAPABLE_FULL_SELECTED;
935 else
936 *duplex = FDX_CAPABLE_HALF_SELECTED;
938 if (status & MII_STSSUM_LINK)
939 printf("amd79c901_read_mode: Media Link On %s %s-duplex \n",
940 *speed == HW_SPEED_100_MBPS ?
941 "100mbps" : "10mbps",
942 *duplex == FDX_CAPABLE_FULL_SELECTED ?
943 "full" : "half");
944 else
945 printf("amd79c901_read_mode: Media Link Off\n");
947 else {
948 /* HomePNA */
949 *speed = HW_SPEED_HOME;
950 *duplex = FDX_CAPABLE_HALF_SELECTED;
951 if (status & MII_STAT_LINK)
952 printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");
953 else
954 printf("amd79c901_read_mode: Media Link Off\n");
960 * ics1893_read_mode: - read media mode for ICS1893 PHY
961 * @net_dev: the net device to read mode for
962 * @phy_addr: mii phy address
963 * @speed: the transmit speed to be determined
964 * @duplex: the duplex mode to be determined
966 * ICS1893 PHY use Quick Poll Detailed Status register
967 * to determine the speed and duplex mode for sis900
970 static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
972 int i = 0;
973 u32 status;
975 /* MII_QPDSTS is Latched, read twice in succession will reflect the current state */
976 for (i = 0; i < 2; i++)
977 status = sis900_mdio_read(phy_addr, MII_QPDSTS);
979 if (status & MII_STSICS_SPD)
980 *speed = HW_SPEED_100_MBPS;
981 else
982 *speed = HW_SPEED_10_MBPS;
984 if (status & MII_STSICS_DPLX)
985 *duplex = FDX_CAPABLE_FULL_SELECTED;
986 else
987 *duplex = FDX_CAPABLE_HALF_SELECTED;
989 if (status & MII_STSICS_LINKSTS)
990 printf("ics1893_read_mode: Media Link On %s %s-duplex \n",
991 *speed == HW_SPEED_100_MBPS ?
992 "100mbps" : "10mbps",
993 *duplex == FDX_CAPABLE_FULL_SELECTED ?
994 "full" : "half");
995 else
996 printf("ics1893_read_mode: Media Link Off\n");
1000 * rtl8201_read_mode: - read media mode for rtl8201 phy
1001 * @nic: the net device to read mode for
1002 * @phy_addr: mii phy address
1003 * @speed: the transmit speed to be determined
1004 * @duplex: the duplex mode to be determined
1006 * read MII_STATUS register from rtl8201 phy
1007 * to determine the speed and duplex mode for sis900
1010 static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
1012 u32 status;
1014 status = sis900_mdio_read(phy_addr, MII_STATUS);
1016 if (status & MII_STAT_CAN_TX_FDX) {
1017 *speed = HW_SPEED_100_MBPS;
1018 *duplex = FDX_CAPABLE_FULL_SELECTED;
1020 else if (status & MII_STAT_CAN_TX) {
1021 *speed = HW_SPEED_100_MBPS;
1022 *duplex = FDX_CAPABLE_HALF_SELECTED;
1024 else if (status & MII_STAT_CAN_T_FDX) {
1025 *speed = HW_SPEED_10_MBPS;
1026 *duplex = FDX_CAPABLE_FULL_SELECTED;
1028 else if (status & MII_STAT_CAN_T) {
1029 *speed = HW_SPEED_10_MBPS;
1030 *duplex = FDX_CAPABLE_HALF_SELECTED;
1033 if (status & MII_STAT_LINK)
1034 printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",
1035 *speed == HW_SPEED_100_MBPS ?
1036 "100mbps" : "10mbps",
1037 *duplex == FDX_CAPABLE_FULL_SELECTED ?
1038 "full" : "half");
1039 else
1040 printf("rtl8201_read_config_mode: Media Link Off\n");
1044 * vt6103_read_mode: - read media mode for vt6103 phy
1045 * @nic: the net device to read mode for
1046 * @phy_addr: mii phy address
1047 * @speed: the transmit speed to be determined
1048 * @duplex: the duplex mode to be determined
1050 * read MII_STATUS register from rtl8201 phy
1051 * to determine the speed and duplex mode for sis900
1054 static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
1056 u32 status;
1058 status = sis900_mdio_read(phy_addr, MII_STATUS);
1060 if (status & MII_STAT_CAN_TX_FDX) {
1061 *speed = HW_SPEED_100_MBPS;
1062 *duplex = FDX_CAPABLE_FULL_SELECTED;
1064 else if (status & MII_STAT_CAN_TX) {
1065 *speed = HW_SPEED_100_MBPS;
1066 *duplex = FDX_CAPABLE_HALF_SELECTED;
1068 else if (status & MII_STAT_CAN_T_FDX) {
1069 *speed = HW_SPEED_10_MBPS;
1070 *duplex = FDX_CAPABLE_FULL_SELECTED;
1072 else if (status & MII_STAT_CAN_T) {
1073 *speed = HW_SPEED_10_MBPS;
1074 *duplex = FDX_CAPABLE_HALF_SELECTED;
1077 if (status & MII_STAT_LINK)
1078 printf("vt6103_read_mode: Media Link On %s %s-duplex \n",
1079 *speed == HW_SPEED_100_MBPS ?
1080 "100mbps" : "10mbps",
1081 *duplex == FDX_CAPABLE_FULL_SELECTED ?
1082 "full" : "half");
1083 else
1084 printf("vt6103_read_config_mode: Media Link Off\n");
1087 /* Function: sis900_transmit
1089 * Description: transmits a packet and waits for completion or timeout.
1091 * Arguments: char d[6]: destination ethernet address.
1092 * unsigned short t: ethernet protocol type.
1093 * unsigned short s: size of the data-part of the packet.
1094 * char *p: the data for the packet.
1096 * Returns: void.
1099 static void
1100 sis900_transmit(struct nic *nic,
1101 const char *d, /* Destination */
1102 unsigned int t, /* Type */
1103 unsigned int s, /* size */
1104 const char *p) /* Packet */
1106 u32 to, nstype;
1107 volatile u32 tx_status;
1109 /* Stop the transmitter */
1110 outl(TxDIS | inl(ioaddr + cr), ioaddr + cr);
1112 /* load Transmit Descriptor Register */
1113 outl(virt_to_bus(&txd), ioaddr + txdp);
1114 if (sis900_debug > 1)
1115 printf("sis900_transmit: TX descriptor register loaded with: %lX\n",
1116 inl(ioaddr + txdp));
1118 memcpy(txb, d, ETH_ALEN);
1119 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
1120 nstype = htons(t);
1121 memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
1122 memcpy(txb + ETH_HLEN, p, s);
1124 s += ETH_HLEN;
1125 s &= DSIZE;
1127 if (sis900_debug > 1)
1128 printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
1130 /* pad to minimum packet size */
1131 while (s < ETH_ZLEN)
1132 txb[s++] = '\0';
1134 /* set the transmit buffer descriptor and enable Transmit State Machine */
1135 txd.bufptr = virt_to_bus(&txb[0]);
1136 txd.cmdsts = (u32) OWN | s;
1138 /* restart the transmitter */
1139 outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
1141 if (sis900_debug > 1)
1142 printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);
1144 to = currticks() + TX_TIMEOUT;
1146 while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
1147 /* wait */ ;
1149 if (currticks() >= to) {
1150 printf("sis900_transmit: TX Timeout! Tx status %X.\n",
1151 (unsigned int) tx_status);
1154 if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
1155 /* packet unsuccessfully transmited */
1156 printf("sis900_transmit: Transmit error, Tx status %X.\n",
1157 (unsigned int) tx_status);
1159 /* Disable interrupts by clearing the interrupt mask. */
1160 outl(0, ioaddr + imr);
1164 /* Function: sis900_poll
1166 * Description: checks for a received packet and returns it if found.
1168 * Arguments: struct nic *nic: NIC data structure
1170 * Returns: 1 if a packet was recieved.
1171 * 0 if no pacet was recieved.
1173 * Side effects:
1174 * Returns (copies) the packet to the array nic->packet.
1175 * Returns the length of the packet in nic->packetlen.
1178 static int
1179 sis900_poll(struct nic *nic, int retrieve)
1181 u32 rx_status = rxd[cur_rx].cmdsts;
1182 int retstat = 0;
1184 if (sis900_debug > 2)
1185 printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx,
1186 (unsigned int) rx_status);
1188 if (!(rx_status & OWN))
1189 return retstat;
1191 if (sis900_debug > 1)
1192 printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
1193 cur_rx, (unsigned int) rx_status);
1195 if ( ! retrieve ) return 1;
1197 nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
1199 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
1200 /* corrupted packet received */
1201 printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
1202 (unsigned int) rx_status);
1203 retstat = 0;
1204 } else {
1205 /* give packet to higher level routine */
1206 memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
1207 retstat = 1;
1210 /* return the descriptor and buffer to receive ring */
1211 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
1212 rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
1214 if (++cur_rx == NUM_RX_DESC)
1215 cur_rx = 0;
1217 /* re-enable the potentially idle receive state machine */
1218 outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
1220 return retstat;
1225 /* Function: sis900_disable
1227 * Description: Turns off interrupts and stops Tx and Rx engines
1229 * Arguments: struct nic *nic: NIC data structure
1231 * Returns: void.
1234 static void
1235 sis900_disable ( struct nic *nic ) {
1237 sis900_init(nic);
1239 /* Disable interrupts by clearing the interrupt mask. */
1240 outl(0, ioaddr + imr);
1241 outl(0, ioaddr + ier);
1243 /* Stop the chip's Tx and Rx Status Machine */
1244 outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
1248 /* Function: sis900_irq
1250 * Description: Enable, Disable, or Force, interrupts
1252 * Arguments: struct nic *nic: NIC data structure
1253 * irq_action_t action: Requested action
1255 * Returns: void.
1258 static void
1259 sis900_irq(struct nic *nic __unused, irq_action_t action __unused)
1261 switch ( action ) {
1262 case DISABLE :
1263 break;
1264 case ENABLE :
1265 break;
1266 case FORCE :
1267 break;
1271 static struct nic_operations sis900_operations = {
1272 .connect = dummy_connect,
1273 .poll = sis900_poll,
1274 .transmit = sis900_transmit,
1275 .irq = sis900_irq,
1278 static struct pci_device_id sis900_nics[] = {
1279 PCI_ROM(0x1039, 0x0900, "sis900", "SIS900"),
1280 PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016"),
1283 PCI_DRIVER ( sis900_driver, sis900_nics, PCI_NO_CLASS );
1285 DRIVER ( "SIS900", nic_driver, pci_driver, sis900_driver,
1286 sis900_probe, sis900_disable );