1 /* -*- Mode:C; c-basic-offset:4; -*- */
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.
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
36 Initial Release. Tested with PCI based sis900 card and ThinkNIC
38 20 March 2001 P.Koegel
39 added support for sis630e and PHY ICS1893 and RTL8201
40 Testet with SIS730S chipset + ICS1893
46 #include "etherboot.h"
54 static struct nic_operations sis900_operations
;
56 static int sis900_debug
= 0;
58 static unsigned short vendor
, dev_id
;
59 static unsigned long ioaddr
;
60 static u8 pci_revision
;
62 static unsigned int cur_phy
;
64 static unsigned int cur_rx
;
68 BufferDesc rxd
[NUM_RX_DESC
];
69 unsigned char txb
[TX_BUF_SIZE
];
70 unsigned char rxb
[NUM_RX_DESC
* RX_BUF_SIZE
];
71 } sis900_bufs __shared
;
72 #define txd sis900_bufs.txd
73 #define rxd sis900_bufs.rxd
74 #define txb sis900_bufs.txb
75 #define rxb sis900_bufs.rxb
78 static struct mac_chip_info
{
80 u16 vendor_id
, device_id
, flags
;
82 } mac_chip_table
[] = {
83 { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS
, PCI_DEVICE_ID_SIS900
,
84 PCI_COMMAND_IO
|PCI_COMMAND_MASTER
, SIS900_TOTAL_SIZE
},
85 { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS
, PCI_DEVICE_ID_SIS7016
,
86 PCI_COMMAND_IO
|PCI_COMMAND_MASTER
, SIS900_TOTAL_SIZE
},
87 {0,0,0,0,0} /* 0 terminated list. */
91 static void sis900_read_mode(struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
92 static void amd79c901_read_mode(struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
93 static void ics1893_read_mode(struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
94 static void rtl8201_read_mode(struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
95 static void vt6103_read_mode(struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
97 static struct mii_chip_info
{
101 void (*read_mode
) (struct nic
*nic
, int phy_addr
, int *speed
, int *duplex
);
102 } mii_chip_table
[] = {
103 {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode
},
104 {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode
},
105 {"SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, sis900_read_mode
},
106 {"AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, amd79c901_read_mode
},
107 {"AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, amd79c901_read_mode
},
108 {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf440,ics1893_read_mode
},
109 // {"NS 83851 PHY",0x2000, 0x5C20, MIX },
110 {"RTL 8201 10/100Mbps Phyceiver" , 0x0000, 0x8200,rtl8201_read_mode
},
111 {"VIA 6103 10/100Mbps Phyceiver", 0x0101, 0x8f20,vt6103_read_mode
},
115 static struct mii_phy
{
116 struct mii_phy
* next
;
117 struct mii_chip_info
* chip_info
;
125 // PCI to ISA bridge for SIS640E access
126 static struct pci_device_id pci_isa_bridge_list
[] = {
127 { .vendor
= 0x1039, .device
= 0x0008,
128 .name
= "SIS 85C503/5513 PCI to ISA bridge"},
131 PCI_DRIVER( sis_bridge_pci_driver
, pci_isa_bridge_list
, PCI_NO_CLASS
);
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
,
140 /* Function Prototypes */
142 static int sis900_probe(struct nic
*nic
,struct pci_device
*pci
);
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
);
149 static void sis900_mdio_write(int phy_id
, int location
, int val
);
151 static void sis900_init(struct nic
*nic
);
153 static void sis900_reset(struct nic
*nic
);
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
);
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
);
165 static void sis900_disable(struct nic
*nic
);
167 static void sis900_irq(struct nic
*nic
, irq_action_t action
);
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
174 * Older SiS900 and friends, use EEPROM to store MAC address.
175 * MAC address is read from read_eeprom() into @net_dev->dev_addr.
178 static int sis900_get_mac_addr(struct pci_device
* pci_dev __unused
, struct nic
*nic
)
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
);
190 /* get MAC address from EEPROM */
191 for (i
= 0; i
< 3; i
++)
192 ((u16
*)(nic
->node_addr
))[i
] = sis900_read_eeprom(i
+EEPROMMACAddr
);
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
201 * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
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.
212 static int sis96x_get_mac_addr(struct pci_device
* pci_dev __unused
, struct nic
*nic
)
214 /* long ioaddr = net_dev->base_addr; */
215 long ee_addr
= ioaddr
+ mear
;
219 printf("Alternate function\n");
221 outl(EEREQ
, ee_addr
);
222 while(waittime
< 2000) {
223 if(inl(ee_addr
) & EEGNT
) {
225 /* get MAC address from EEPROM */
226 for (i
= 0; i
< 3; i
++)
227 ((u16
*)(nic
->node_addr
))[i
] = sis900_read_eeprom(i
+EEPROMMACAddr
);
229 outl(EEDONE
, ee_addr
);
236 outl(EEDONE
, ee_addr
);
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
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.
250 static int sis630e_get_mac_addr(struct pci_device
* pci_dev __unused
, struct nic
*nic
)
255 struct bus_loc bus_loc
;
257 struct bus_dev bus_dev
;
258 struct pci_device isa_bridge
;
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 ) )
266 pci_read_config_byte(&u
.isa_bridge
, 0x48, ®
);
267 pci_write_config_byte(&u
.isa_bridge
, 0x48, reg
| 0x40);
269 for (i
= 0; i
< ETH_ALEN
; i
++)
271 outb(0x09 + i
, 0x70);
272 ((u8
*)(nic
->node_addr
))[i
] = inb(0x71);
274 pci_write_config_byte(&u
.isa_bridge
, 0x48, reg
& ~0x40);
279 /* Does not work with current bus/device model */
280 memset ( nic
->node_addr
, 0, sizeof ( nic
->node_addr
) );
285 * sis630e_get_mac_addr: - Get MAC address for SiS630E model
286 * @pci_dev: the sis900 pci device
287 * @net_dev: the net device to get address for
289 * SiS630E model, use APC CMOS RAM to store MAC address.
290 * APC CMOS RAM is accessed through ISA bridge.
291 * MAC address is read into @net_dev->dev_addr.
294 static int sis635_get_mac_addr(struct pci_device
* pci_dev __unused
, struct nic
*nic
)
300 rfcrSave
= inl(rfcr
+ ioaddr
);
302 outl(rfcrSave
| RELOAD
, ioaddr
+ cr
);
303 outl(0, ioaddr
+ cr
);
305 /* disable packet filtering before setting filter */
306 outl(rfcrSave
& ~RFEN
, rfcr
+ ioaddr
);
308 /* load MAC addr to filter data register */
309 for (i
= 0 ; i
< 3 ; i
++) {
310 outl((i
<< RFADDR_shift
), ioaddr
+ rfcr
);
311 *( ((u16
*)nic
->node_addr
) + i
) = inw(ioaddr
+ rfdr
);
314 /* enable packet filitering */
315 outl(rfcrSave
| RFEN
, rfcr
+ ioaddr
);
321 * Function: sis900_probe
323 * Description: initializes initializes the NIC, retrieves the
324 * MAC address of the card, and sets up some globals required by
328 * leaves the ioaddress of the sis900 chip in the variable ioaddr.
329 * leaves the sis900 initialized, and ready to recieve packets.
331 * Returns: struct nic *: pointer to NIC data structure
334 static int sis900_probe ( struct nic
*nic
, struct pci_device
*pci
) {
342 if (pci
->ioaddr
== 0)
346 nic
->ioaddr
= pci
->ioaddr
;
348 ioaddr
= pci
->ioaddr
;
349 vendor
= pci
->vendor
;
350 dev_id
= pci
->device
;
353 pci_write_config_dword(pci
, 0x40, 0x00000000);
355 adjust_pci_device(pci
);
357 /* get MAC address */
359 pci_read_config_byte(pci
, PCI_REVISION
, &revision
);
361 /* save for use later in sis900_reset() */
362 pci_revision
= revision
;
364 if (revision
== SIS630E_900_REV
)
365 ret
= sis630e_get_mac_addr(pci
, nic
);
366 else if ((revision
> 0x81) && (revision
<= 0x90))
367 ret
= sis635_get_mac_addr(pci
, nic
);
368 else if (revision
== SIS96x_900_REV
)
369 ret
= sis96x_get_mac_addr(pci
, nic
);
371 ret
= sis900_get_mac_addr(pci
, nic
);
375 printf ("sis900_probe: Error MAC address not found\n");
379 /* 630ET : set the mii access mode as software-mode */
380 if (revision
== SIS630ET_900_REV
)
381 outl(ACCESSMODE
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
383 DBG( "sis900_probe: Vendor:%#hX Device:%#hX\n", vendor
, dev_id
);
385 /* probe for mii transceiver */
386 /* search for total of 32 possible mii phy addresses */
389 for (phy_addr
= 0; phy_addr
< 32; phy_addr
++) {
391 u16 phy_id0
, phy_id1
;
393 mii_status
= sis900_mdio_read(phy_addr
, MII_STATUS
);
394 if (mii_status
== 0xffff || mii_status
== 0x0000)
395 /* the mii is not accessable, try next one */
398 phy_id0
= sis900_mdio_read(phy_addr
, MII_PHY_ID0
);
399 phy_id1
= sis900_mdio_read(phy_addr
, MII_PHY_ID1
);
401 /* search our mii table for the current mii */
402 for (i
= 0; mii_chip_table
[i
].phy_id1
; i
++) {
404 if ((phy_id0
== mii_chip_table
[i
].phy_id0
) &&
405 ((phy_id1
& 0xFFF0) == mii_chip_table
[i
].phy_id1
)){
407 printf("sis900_probe: %s transceiver found at address %d.\n",
408 mii_chip_table
[i
].name
, phy_addr
);
410 mii
.chip_info
= &mii_chip_table
[i
];
411 mii
.phy_addr
= phy_addr
;
412 mii
.status
= sis900_mdio_read(phy_addr
, MII_STATUS
);
422 printf("sis900_probe: No MII transceivers found!\n");
426 /* Arbitrarily select the last PHY found as current PHY */
427 cur_phy
= mii
.phy_addr
;
428 printf("sis900_probe: Using %s as default\n", mii
.chip_info
->name
);
430 /* initialize device */
432 nic
->nic_op
= &sis900_operations
;
441 * EEPROM Routines: These functions read and write to EEPROM for
442 * retrieving the MAC address and other configuration information about
446 /* Delay between EEPROM clock transitions. */
447 #define eeprom_delay() inl(ee_addr)
450 /* Function: sis900_read_eeprom
452 * Description: reads and returns a given location from EEPROM
454 * Arguments: int location: requested EEPROM location
456 * Returns: u16: contents of requested EEPROM location
460 /* Read Serial EEPROM through EEPROM Access Register, Note that location is
461 in word (16 bits) unit */
462 static u16
sis900_read_eeprom(int location
)
466 long ee_addr
= ioaddr
+ mear
;
467 u32 read_cmd
= location
| EEread
;
474 /* Shift the read command (9) bits out. */
475 for (i
= 8; i
>= 0; i
--) {
476 u32 dataval
= (read_cmd
& (1 << i
)) ? EEDI
| EECS
: EECS
;
477 outl(dataval
, ee_addr
);
479 outl(dataval
| EECLK
, ee_addr
);
485 /* read the 16-bits data in */
486 for (i
= 16; i
> 0; i
--) {
489 outl(EECS
| EECLK
, ee_addr
);
491 retval
= (retval
<< 1) | ((inl(ee_addr
) & EEDO
) ? 1 : 0);
495 /* Terminate the EEPROM access. */
498 // outl(EECLK, ee_addr);
503 #define sis900_mdio_delay() inl(mdio_addr)
507 Read and write the MII management registers using software-generated
508 serial MDIO protocol. Note that the command bits and data bits are
512 static void sis900_mdio_idle(long mdio_addr
)
514 outl(MDIO
| MDDIR
, mdio_addr
);
516 outl(MDIO
| MDDIR
| MDC
, mdio_addr
);
519 /* Syncronize the MII management interface by shifting 32 one bits out. */
520 static void sis900_mdio_reset(long mdio_addr
)
524 for (i
= 31; i
>= 0; i
--) {
525 outl(MDDIR
| MDIO
, mdio_addr
);
527 outl(MDDIR
| MDIO
| MDC
, mdio_addr
);
533 static u16
sis900_mdio_read(int phy_id
, int location
)
535 long mdio_addr
= ioaddr
+ mear
;
536 int mii_cmd
= MIIread
|(phy_id
<<MIIpmdShift
)|(location
<<MIIregShift
);
540 sis900_mdio_reset(mdio_addr
);
541 sis900_mdio_idle(mdio_addr
);
543 for (i
= 15; i
>= 0; i
--) {
544 int dataval
= (mii_cmd
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
545 outl(dataval
, mdio_addr
);
547 outl(dataval
| MDC
, mdio_addr
);
551 /* Read the 16 data bits. */
552 for (i
= 16; i
> 0; i
--) {
555 retval
= (retval
<< 1) | ((inl(mdio_addr
) & MDIO
) ? 1 : 0);
556 outl(MDC
, mdio_addr
);
559 outl(0x00, mdio_addr
);
564 static void sis900_mdio_write(int phy_id
, int location
, int value
)
566 long mdio_addr
= ioaddr
+ mear
;
567 int mii_cmd
= MIIwrite
|(phy_id
<<MIIpmdShift
)|(location
<<MIIregShift
);
570 sis900_mdio_reset(mdio_addr
);
571 sis900_mdio_idle(mdio_addr
);
573 /* Shift the command bits out. */
574 for (i
= 15; i
>= 0; i
--) {
575 int dataval
= (mii_cmd
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
576 outb(dataval
, mdio_addr
);
578 outb(dataval
| MDC
, mdio_addr
);
583 /* Shift the value bits out. */
584 for (i
= 15; i
>= 0; i
--) {
585 int dataval
= (value
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
586 outl(dataval
, mdio_addr
);
588 outl(dataval
| MDC
, mdio_addr
);
593 /* Clear out extra bits. */
594 for (i
= 2; i
> 0; i
--) {
597 outb(MDC
, mdio_addr
);
600 outl(0x00, mdio_addr
);
606 /* Function: sis900_init
608 * Description: resets the ethernet controller chip and various
609 * data structures required for sending and receiving packets.
611 * Arguments: struct nic *nic: NIC data structure
617 sis900_init(struct nic
*nic
)
619 /* Soft reset the chip. */
622 sis900_init_rxfilter(nic
);
624 sis900_init_txd(nic
);
625 sis900_init_rxd(nic
);
627 sis900_set_rx_mode(nic
);
629 sis900_check_mode(nic
);
631 outl(RxENA
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
636 * Function: sis900_reset
638 * Description: disables interrupts and soft resets the controller chip
640 * Arguments: struct nic *nic: NIC data structure
646 sis900_reset(struct nic
*nic __unused
)
649 u32 status
= TxRCMP
| RxRCMP
;
651 outl(0, ioaddr
+ ier
);
652 outl(0, ioaddr
+ imr
);
653 outl(0, ioaddr
+ rfcr
);
655 outl(RxRESET
| TxRESET
| RESET
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
657 /* Check that the chip has finished the reset. */
658 while (status
&& (i
++ < 1000)) {
659 status
^= (inl(isr
+ ioaddr
) & status
);
662 if( (pci_revision
>= SIS635A_900_REV
) || (pci_revision
== SIS900B_900_REV
) )
663 outl(PESEL
| RND_CNT
, ioaddr
+ cfg
);
665 outl(PESEL
, ioaddr
+ cfg
);
669 /* Function: sis_init_rxfilter
671 * Description: sets receive filter address to our MAC address
673 * Arguments: struct nic *nic: NIC data structure
679 sis900_init_rxfilter(struct nic
*nic
)
684 rfcrSave
= inl(rfcr
+ ioaddr
);
686 /* disable packet filtering before setting filter */
687 outl(rfcrSave
& ~RFEN
, rfcr
+ ioaddr
);
689 /* load MAC addr to filter data register */
690 for (i
= 0 ; i
< 3 ; i
++) {
693 w
= (u32
) *((u16
*)(nic
->node_addr
)+i
);
694 outl((i
<< RFADDR_shift
), ioaddr
+ rfcr
);
695 outl(w
, ioaddr
+ rfdr
);
697 if (sis900_debug
> 0)
698 printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%lX\n",
699 i
, inl(ioaddr
+ rfdr
));
702 /* enable packet filitering */
703 outl(rfcrSave
| RFEN
, rfcr
+ ioaddr
);
708 * Function: sis_init_txd
710 * Description: initializes the Tx descriptor
712 * Arguments: struct nic *nic: NIC data structure
718 sis900_init_txd(struct nic
*nic __unused
)
721 txd
.cmdsts
= (u32
) 0;
722 txd
.bufptr
= virt_to_bus(&txb
[0]);
724 /* load Transmit Descriptor Register */
725 outl(virt_to_bus(&txd
), ioaddr
+ txdp
);
726 if (sis900_debug
> 0)
727 printf("sis900_init_txd: TX descriptor register loaded with: %lX\n",
732 /* Function: sis_init_rxd
734 * Description: initializes the Rx descriptor ring
736 * Arguments: struct nic *nic: NIC data structure
742 sis900_init_rxd(struct nic
*nic __unused
)
748 /* init RX descriptor */
749 for (i
= 0; i
< NUM_RX_DESC
; i
++) {
750 rxd
[i
].link
= virt_to_bus((i
+1 < NUM_RX_DESC
) ? &rxd
[i
+1] : &rxd
[0]);
751 rxd
[i
].cmdsts
= (u32
) RX_BUF_SIZE
;
752 rxd
[i
].bufptr
= virt_to_bus(&rxb
[i
*RX_BUF_SIZE
]);
753 if (sis900_debug
> 0)
754 printf("sis900_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
755 i
, &rxd
[i
], (unsigned int) rxd
[i
].link
, (unsigned int) rxd
[i
].cmdsts
,
756 (unsigned int) rxd
[i
].bufptr
);
759 /* load Receive Descriptor Register */
760 outl(virt_to_bus(&rxd
[0]), ioaddr
+ rxdp
);
762 if (sis900_debug
> 0)
763 printf("sis900_init_rxd: RX descriptor register loaded with: %lX\n",
769 /* Function: sis_init_rxd
772 * sets the receive mode to accept all broadcast packets and packets
773 * with our MAC address, and reject all multicast packets.
775 * Arguments: struct nic *nic: NIC data structure
780 static void sis900_set_rx_mode(struct nic
*nic __unused
)
782 int i
, table_entries
;
784 u16 mc_filter
[16] = {0}; /* 256/128 bits multicast hash table */
786 if((pci_revision
== SIS635A_900_REV
) || (pci_revision
== SIS900B_900_REV
))
791 /* accept all multicast packet */
792 rx_mode
= RFAAB
| RFAAM
;
793 for (i
= 0; i
< table_entries
; i
++)
794 mc_filter
[i
] = 0xffff;
796 /* update Multicast Hash Table in Receive Filter */
797 for (i
= 0; i
< table_entries
; i
++) {
798 /* why plus 0x04? That makes the correct value for hash table. */
799 outl((u32
)(0x00000004+i
) << RFADDR_shift
, ioaddr
+ rfcr
);
800 outl(mc_filter
[i
], ioaddr
+ rfdr
);
803 /* Accept Broadcast and multicast packets, destination addresses that match
805 outl(RFEN
| rx_mode
, ioaddr
+ rfcr
);
811 /* Function: sis900_check_mode
813 * Description: checks the state of transmit and receive
814 * parameters on the NIC, and updates NIC registers to match
816 * Arguments: struct nic *nic: NIC data structure
822 sis900_check_mode(struct nic
*nic
)
825 u32 tx_flags
= 0, rx_flags
= 0;
827 mii
.chip_info
->read_mode(nic
, cur_phy
, &speed
, &duplex
);
829 if( inl(ioaddr
+ cfg
) & EDB_MASTER_EN
) {
830 tx_flags
= TxATP
| (DMA_BURST_64
<< TxMXDMA_shift
) | (TX_FILL_THRESH
<< TxFILLT_shift
);
831 rx_flags
= DMA_BURST_64
<< RxMXDMA_shift
;
834 tx_flags
= TxATP
| (DMA_BURST_512
<< TxMXDMA_shift
) | (TX_FILL_THRESH
<< TxFILLT_shift
);
835 rx_flags
= DMA_BURST_512
<< RxMXDMA_shift
;
838 if (speed
== HW_SPEED_HOME
|| speed
== HW_SPEED_10_MBPS
) {
839 rx_flags
|= (RxDRNT_10
<< RxDRNT_shift
);
840 tx_flags
|= (TxDRNT_10
<< TxDRNT_shift
);
843 rx_flags
|= (RxDRNT_100
<< RxDRNT_shift
);
844 tx_flags
|= (TxDRNT_100
<< TxDRNT_shift
);
847 if (duplex
== FDX_CAPABLE_FULL_SELECTED
) {
848 tx_flags
|= (TxCSI
| TxHBI
);
852 outl (tx_flags
, ioaddr
+ txcfg
);
853 outl (rx_flags
, ioaddr
+ rxcfg
);
857 /* Function: sis900_read_mode
859 * Description: retrieves and displays speed and duplex
860 * parameters from the NIC
862 * Arguments: struct nic *nic: NIC data structure
868 sis900_read_mode(struct nic
*nic __unused
, int phy_addr
, int *speed
, int *duplex
)
872 u16 phy_id0
, phy_id1
;
874 /* STSOUT register is Latched on Transition, read operation updates it */
876 status
= sis900_mdio_read(phy_addr
, MII_STSOUT
);
879 *speed
= HW_SPEED_10_MBPS
;
880 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
882 if (status
& (MII_NWAY_TX
| MII_NWAY_TX_FDX
))
883 *speed
= HW_SPEED_100_MBPS
;
884 if (status
& ( MII_NWAY_TX_FDX
| MII_NWAY_T_FDX
))
885 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
887 /* Workaround for Realtek RTL8201 PHY issue */
888 phy_id0
= sis900_mdio_read(phy_addr
, MII_PHY_ID0
);
889 phy_id1
= sis900_mdio_read(phy_addr
, MII_PHY_ID1
);
890 if((phy_id0
== 0x0000) && ((phy_id1
& 0xFFF0) == 0x8200)){
891 if(sis900_mdio_read(phy_addr
, MII_CONTROL
) & MII_CNTL_FDX
)
892 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
893 if(sis900_mdio_read(phy_addr
, 0x0019) & 0x01)
894 *speed
= HW_SPEED_100_MBPS
;
897 if (status
& MII_STSOUT_LINK_FAIL
)
898 printf("sis900_read_mode: Media Link Off\n");
900 printf("sis900_read_mode: Media Link On %s %s-duplex \n",
901 *speed
== HW_SPEED_100_MBPS
?
902 "100mbps" : "10mbps",
903 *duplex
== FDX_CAPABLE_FULL_SELECTED
?
908 /* Function: amd79c901_read_mode
910 * Description: retrieves and displays speed and duplex
911 * parameters from the NIC
913 * Arguments: struct nic *nic: NIC data structure
919 amd79c901_read_mode(struct nic
*nic __unused
, int phy_addr
, int *speed
, int *duplex
)
924 for (i
= 0; i
< 2; i
++)
925 status
= sis900_mdio_read(phy_addr
, MII_STATUS
);
927 if (status
& MII_STAT_CAN_AUTO
) {
929 for (i
= 0; i
< 2; i
++)
930 status
= sis900_mdio_read(phy_addr
, MII_STATUS_SUMMARY
);
931 if (status
& MII_STSSUM_SPD
)
932 *speed
= HW_SPEED_100_MBPS
;
934 *speed
= HW_SPEED_10_MBPS
;
935 if (status
& MII_STSSUM_DPLX
)
936 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
938 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
940 if (status
& MII_STSSUM_LINK
)
941 printf("amd79c901_read_mode: Media Link On %s %s-duplex \n",
942 *speed
== HW_SPEED_100_MBPS
?
943 "100mbps" : "10mbps",
944 *duplex
== FDX_CAPABLE_FULL_SELECTED
?
947 printf("amd79c901_read_mode: Media Link Off\n");
951 *speed
= HW_SPEED_HOME
;
952 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
953 if (status
& MII_STAT_LINK
)
954 printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");
956 printf("amd79c901_read_mode: Media Link Off\n");
962 * ics1893_read_mode: - read media mode for ICS1893 PHY
963 * @net_dev: the net device to read mode for
964 * @phy_addr: mii phy address
965 * @speed: the transmit speed to be determined
966 * @duplex: the duplex mode to be determined
968 * ICS1893 PHY use Quick Poll Detailed Status register
969 * to determine the speed and duplex mode for sis900
972 static void ics1893_read_mode(struct nic
*nic __unused
, int phy_addr
, int *speed
, int *duplex
)
977 /* MII_QPDSTS is Latched, read twice in succession will reflect the current state */
978 for (i
= 0; i
< 2; i
++)
979 status
= sis900_mdio_read(phy_addr
, MII_QPDSTS
);
981 if (status
& MII_STSICS_SPD
)
982 *speed
= HW_SPEED_100_MBPS
;
984 *speed
= HW_SPEED_10_MBPS
;
986 if (status
& MII_STSICS_DPLX
)
987 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
989 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
991 if (status
& MII_STSICS_LINKSTS
)
992 printf("ics1893_read_mode: Media Link On %s %s-duplex \n",
993 *speed
== HW_SPEED_100_MBPS
?
994 "100mbps" : "10mbps",
995 *duplex
== FDX_CAPABLE_FULL_SELECTED
?
998 printf("ics1893_read_mode: Media Link Off\n");
1002 * rtl8201_read_mode: - read media mode for rtl8201 phy
1003 * @nic: the net device to read mode for
1004 * @phy_addr: mii phy address
1005 * @speed: the transmit speed to be determined
1006 * @duplex: the duplex mode to be determined
1008 * read MII_STATUS register from rtl8201 phy
1009 * to determine the speed and duplex mode for sis900
1012 static void rtl8201_read_mode(struct nic
*nic __unused
, int phy_addr
, int *speed
, int *duplex
)
1016 status
= sis900_mdio_read(phy_addr
, MII_STATUS
);
1018 if (status
& MII_STAT_CAN_TX_FDX
) {
1019 *speed
= HW_SPEED_100_MBPS
;
1020 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
1022 else if (status
& MII_STAT_CAN_TX
) {
1023 *speed
= HW_SPEED_100_MBPS
;
1024 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
1026 else if (status
& MII_STAT_CAN_T_FDX
) {
1027 *speed
= HW_SPEED_10_MBPS
;
1028 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
1030 else if (status
& MII_STAT_CAN_T
) {
1031 *speed
= HW_SPEED_10_MBPS
;
1032 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
1035 if (status
& MII_STAT_LINK
)
1036 printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",
1037 *speed
== HW_SPEED_100_MBPS
?
1038 "100mbps" : "10mbps",
1039 *duplex
== FDX_CAPABLE_FULL_SELECTED
?
1042 printf("rtl8201_read_config_mode: Media Link Off\n");
1046 * vt6103_read_mode: - read media mode for vt6103 phy
1047 * @nic: the net device to read mode for
1048 * @phy_addr: mii phy address
1049 * @speed: the transmit speed to be determined
1050 * @duplex: the duplex mode to be determined
1052 * read MII_STATUS register from rtl8201 phy
1053 * to determine the speed and duplex mode for sis900
1056 static void vt6103_read_mode(struct nic
*nic __unused
, int phy_addr
, int *speed
, int *duplex
)
1060 status
= sis900_mdio_read(phy_addr
, MII_STATUS
);
1062 if (status
& MII_STAT_CAN_TX_FDX
) {
1063 *speed
= HW_SPEED_100_MBPS
;
1064 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
1066 else if (status
& MII_STAT_CAN_TX
) {
1067 *speed
= HW_SPEED_100_MBPS
;
1068 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
1070 else if (status
& MII_STAT_CAN_T_FDX
) {
1071 *speed
= HW_SPEED_10_MBPS
;
1072 *duplex
= FDX_CAPABLE_FULL_SELECTED
;
1074 else if (status
& MII_STAT_CAN_T
) {
1075 *speed
= HW_SPEED_10_MBPS
;
1076 *duplex
= FDX_CAPABLE_HALF_SELECTED
;
1079 if (status
& MII_STAT_LINK
)
1080 printf("vt6103_read_mode: Media Link On %s %s-duplex \n",
1081 *speed
== HW_SPEED_100_MBPS
?
1082 "100mbps" : "10mbps",
1083 *duplex
== FDX_CAPABLE_FULL_SELECTED
?
1086 printf("vt6103_read_config_mode: Media Link Off\n");
1089 /* Function: sis900_transmit
1091 * Description: transmits a packet and waits for completion or timeout.
1093 * Arguments: char d[6]: destination ethernet address.
1094 * unsigned short t: ethernet protocol type.
1095 * unsigned short s: size of the data-part of the packet.
1096 * char *p: the data for the packet.
1102 sis900_transmit(struct nic
*nic
,
1103 const char *d
, /* Destination */
1104 unsigned int t
, /* Type */
1105 unsigned int s
, /* size */
1106 const char *p
) /* Packet */
1109 volatile u32 tx_status
;
1111 /* Stop the transmitter */
1112 outl(TxDIS
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
1114 /* load Transmit Descriptor Register */
1115 outl(virt_to_bus(&txd
), ioaddr
+ txdp
);
1116 if (sis900_debug
> 1)
1117 printf("sis900_transmit: TX descriptor register loaded with: %lX\n",
1118 inl(ioaddr
+ txdp
));
1120 memcpy(txb
, d
, ETH_ALEN
);
1121 memcpy(txb
+ ETH_ALEN
, nic
->node_addr
, ETH_ALEN
);
1123 memcpy(txb
+ 2 * ETH_ALEN
, (char*)&nstype
, 2);
1124 memcpy(txb
+ ETH_HLEN
, p
, s
);
1129 if (sis900_debug
> 1)
1130 printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s
, t
);
1132 /* pad to minimum packet size */
1133 while (s
< ETH_ZLEN
)
1136 /* set the transmit buffer descriptor and enable Transmit State Machine */
1137 txd
.bufptr
= virt_to_bus(&txb
[0]);
1138 txd
.cmdsts
= (u32
) OWN
| s
;
1140 /* restart the transmitter */
1141 outl(TxENA
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
1143 if (sis900_debug
> 1)
1144 printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s
);
1146 to
= currticks() + TX_TIMEOUT
;
1148 while (((tx_status
=txd
.cmdsts
) & OWN
) && (currticks() < to
))
1151 if (currticks() >= to
) {
1152 printf("sis900_transmit: TX Timeout! Tx status %X.\n",
1153 (unsigned int) tx_status
);
1156 if (tx_status
& (ABORT
| UNDERRUN
| OWCOLL
)) {
1157 /* packet unsuccessfully transmited */
1158 printf("sis900_transmit: Transmit error, Tx status %X.\n",
1159 (unsigned int) tx_status
);
1161 /* Disable interrupts by clearing the interrupt mask. */
1162 outl(0, ioaddr
+ imr
);
1166 /* Function: sis900_poll
1168 * Description: checks for a received packet and returns it if found.
1170 * Arguments: struct nic *nic: NIC data structure
1172 * Returns: 1 if a packet was recieved.
1173 * 0 if no pacet was recieved.
1176 * Returns (copies) the packet to the array nic->packet.
1177 * Returns the length of the packet in nic->packetlen.
1181 sis900_poll(struct nic
*nic
, int retrieve
)
1183 u32 rx_status
= rxd
[cur_rx
].cmdsts
;
1186 if (sis900_debug
> 2)
1187 printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx
,
1188 (unsigned int) rx_status
);
1190 if (!(rx_status
& OWN
))
1193 if (sis900_debug
> 1)
1194 printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
1195 cur_rx
, (unsigned int) rx_status
);
1197 if ( ! retrieve
) return 1;
1199 nic
->packetlen
= (rx_status
& DSIZE
) - CRC_SIZE
;
1201 if (rx_status
& (ABORT
|OVERRUN
|TOOLONG
|RUNT
|RXISERR
|CRCERR
|FAERR
)) {
1202 /* corrupted packet received */
1203 printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
1204 (unsigned int) rx_status
);
1207 /* give packet to higher level routine */
1208 memcpy(nic
->packet
, (rxb
+ cur_rx
*RX_BUF_SIZE
), nic
->packetlen
);
1212 /* return the descriptor and buffer to receive ring */
1213 rxd
[cur_rx
].cmdsts
= RX_BUF_SIZE
;
1214 rxd
[cur_rx
].bufptr
= virt_to_bus(&rxb
[cur_rx
*RX_BUF_SIZE
]);
1216 if (++cur_rx
== NUM_RX_DESC
)
1219 /* re-enable the potentially idle receive state machine */
1220 outl(RxENA
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
1227 /* Function: sis900_disable
1229 * Description: Turns off interrupts and stops Tx and Rx engines
1231 * Arguments: struct nic *nic: NIC data structure
1237 sis900_disable ( struct nic
*nic
) {
1241 /* Disable interrupts by clearing the interrupt mask. */
1242 outl(0, ioaddr
+ imr
);
1243 outl(0, ioaddr
+ ier
);
1245 /* Stop the chip's Tx and Rx Status Machine */
1246 outl(RxDIS
| TxDIS
| inl(ioaddr
+ cr
), ioaddr
+ cr
);
1250 /* Function: sis900_irq
1252 * Description: Enable, Disable, or Force, interrupts
1254 * Arguments: struct nic *nic: NIC data structure
1255 * irq_action_t action: Requested action
1261 sis900_irq(struct nic
*nic __unused
, irq_action_t action __unused
)
1273 static struct nic_operations sis900_operations
= {
1274 .connect
= dummy_connect
,
1275 .poll
= sis900_poll
,
1276 .transmit
= sis900_transmit
,
1280 static struct pci_device_id sis900_nics
[] = {
1281 PCI_ROM(0x1039, 0x0900, "sis900", "SIS900"),
1282 PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016"),
1285 PCI_DRIVER ( sis900_driver
, sis900_nics
, PCI_NO_CLASS
);
1287 DRIVER ( "SIS900", nic_driver
, pci_driver
, sis900_driver
,
1288 sis900_probe
, sis900_disable
);