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
27FILE_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
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
56static struct nic_operations sis900_operations;
57
58static int sis900_debug = 0;
59
60static unsigned short vendor, dev_id;
61static unsigned long ioaddr;
62static u8 pci_revision;
63
64static unsigned int cur_phy;
65
66static unsigned int cur_rx;
67
68struct {
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
80static 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
93static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
94static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
95static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
96static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
97static void vt6103_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
98
99static 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
117static 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
125
126#if 0
127// PCI to ISA bridge for SIS640E access
128static struct pci_device_id pci_isa_bridge_list[] = {
129	{ .vendor = 0x1039, .device = 0x0008,
130		.name = "SIS 85C503/5513 PCI to ISA bridge"},
131};
132
133PCI_DRIVER( sis_bridge_pci_driver, pci_isa_bridge_list, PCI_NO_CLASS );
134
135static 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
144static int sis900_probe(struct nic *nic,struct pci_device *pci);
145
146static u16  sis900_read_eeprom(int location);
147static void sis900_mdio_reset(long mdio_addr);
148static void sis900_mdio_idle(long mdio_addr);
149static u16  sis900_mdio_read(int phy_id, int location);
150#if 0
151static void sis900_mdio_write(int phy_id, int location, int val);
152#endif
153static void sis900_init(struct nic *nic);
154
155static void sis900_reset(struct nic *nic);
156
157static void sis900_init_rxfilter(struct nic *nic);
158static void sis900_init_txd(struct nic *nic);
159static void sis900_init_rxd(struct nic *nic);
160static void sis900_set_rx_mode(struct nic *nic);
161static void sis900_check_mode(struct nic *nic);
162
163static void sis900_transmit(struct nic *nic, const char *d,
164                            unsigned int t, unsigned int s, const char *p);
165static int  sis900_poll(struct nic *nic, int retrieve);
166
167static void sis900_disable(struct nic *nic);
168
169static 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
180static 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
214static 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
252static 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
296static 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
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
336static 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
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
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 */
464static 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
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
514static 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. */
522static 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
535static 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
566static 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
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
618static void
619sis900_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
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
647static void
648sis900_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
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
680static void
681sis900_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
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
719static void
720sis900_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
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
743static void
744sis900_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
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
782static 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
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
823static void
824sis900_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
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
869static void
870sis900_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
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
920static void
921amd79c901_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
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
974static 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
1014static 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
1058static 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
1103static void
1104sis900_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
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
1182static int
1183sis900_poll(struct nic *nic, int retrieve)
1184{
1185    u32 rx_status = rxd[cur_rx].cmdsts;
1186    u32 intr_status;
1187    int retstat = 0;
1188
1189     /* acknowledge interrupts by reading interrupt status register */
1190    intr_status = inl(ioaddr + isr);
1191
1192    if (sis900_debug > 2)
1193        printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx,
1194	       (unsigned int) rx_status);
1195
1196    if (!(rx_status & OWN))
1197        return retstat;
1198
1199    if (sis900_debug > 1)
1200        printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
1201               cur_rx, (unsigned int) rx_status);
1202
1203    if ( ! retrieve ) return 1;
1204
1205    nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
1206
1207    if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
1208        /* corrupted packet received */
1209        printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
1210               (unsigned int) rx_status);
1211        retstat = 0;
1212    } else {
1213        /* give packet to higher level routine */
1214        memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
1215        retstat = 1;
1216    }
1217
1218    /* return the descriptor and buffer to receive ring */
1219    rxd[cur_rx].cmdsts = RX_BUF_SIZE;
1220    rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
1221
1222    if (++cur_rx == NUM_RX_DESC)
1223        cur_rx = 0;
1224
1225    /* re-enable the potentially idle receive state machine */
1226    outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
1227
1228    return retstat;
1229
1230}
1231
1232
1233/* Function: sis900_disable
1234 *
1235 * Description: Turns off interrupts and stops Tx and Rx engines
1236 *
1237 * Arguments: struct nic *nic:          NIC data structure
1238 *
1239 * Returns:   void.
1240 */
1241
1242static void
1243sis900_disable ( struct nic *nic ) {
1244
1245    sis900_init(nic);
1246
1247    /* Disable interrupts by clearing the interrupt mask. */
1248    outl(0, ioaddr + imr);
1249    outl(0, ioaddr + ier);
1250
1251    /* Stop the chip's Tx and Rx Status Machine */
1252    outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
1253}
1254
1255
1256/* Function: sis900_irq
1257 *
1258 * Description: Enable, Disable, or Force, interrupts
1259 *
1260 * Arguments: struct nic *nic:          NIC data structure
1261 *            irq_action_t action:      Requested action
1262 *
1263 * Returns:   void.
1264 */
1265
1266static void
1267sis900_irq(struct nic *nic __unused, irq_action_t action __unused)
1268{
1269  switch ( action ) {
1270  case DISABLE :
1271    outl(0, ioaddr + imr);
1272    break;
1273  case ENABLE :
1274    outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
1275    break;
1276  case FORCE :
1277    break;
1278  }
1279}
1280
1281static struct nic_operations sis900_operations = {
1282	.connect	= dummy_connect,
1283	.poll		= sis900_poll,
1284	.transmit	= sis900_transmit,
1285	.irq		= sis900_irq,
1286};
1287
1288static struct pci_device_id sis900_nics[] = {
1289PCI_ROM(0x1039, 0x0900, "sis900",  "SIS900", 0),
1290PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016", 0),
1291};
1292
1293PCI_DRIVER ( sis900_driver, sis900_nics, PCI_NO_CLASS );
1294
1295DRIVER ( "SIS900", nic_driver, pci_driver, sis900_driver,
1296	 sis900_probe, sis900_disable );
1297
1298/*
1299 * Local variables:
1300 *  c-basic-offset: 8
1301 *  c-indent-level: 8
1302 *  tab-width: 8
1303 * End:
1304 */
1305