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