00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 FILE_LICENCE ( GPL_ANY );
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "etherboot.h"
00049 #include <gpxe/pci.h>
00050 #include "nic.h"
00051
00052 #include "sis900.h"
00053
00054
00055
00056 static struct nic_operations sis900_operations;
00057
00058 static int sis900_debug = 0;
00059
00060 static unsigned short vendor, dev_id;
00061 static unsigned long ioaddr;
00062 static u8 pci_revision;
00063
00064 static unsigned int cur_phy;
00065
00066 static unsigned int cur_rx;
00067
00068 struct {
00069 BufferDesc txd;
00070 BufferDesc rxd[NUM_RX_DESC];
00071 unsigned char txb[TX_BUF_SIZE];
00072 unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
00073 } sis900_bufs __shared;
00074 #define txd sis900_bufs.txd
00075 #define rxd sis900_bufs.rxd
00076 #define txb sis900_bufs.txb
00077 #define rxb sis900_bufs.rxb
00078
00079 #if 0
00080 static struct mac_chip_info {
00081 const char *name;
00082 u16 vendor_id, device_id, flags;
00083 int io_size;
00084 } mac_chip_table[] = {
00085 { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
00086 PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
00087 { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
00088 PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
00089 {0,0,0,0,0}
00090 };
00091 #endif
00092
00093 static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
00094 static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
00095 static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
00096 static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
00097 static void vt6103_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
00098
00099 static struct mii_chip_info {
00100 const char * name;
00101 u16 phy_id0;
00102 u16 phy_id1;
00103 void (*read_mode) (struct nic *nic, int phy_addr, int *speed, int *duplex);
00104 } mii_chip_table[] = {
00105 {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode},
00106 {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode},
00107 {"SiS 900 on Foxconn 661 7MI", 0x0143, 0xBC70, sis900_read_mode},
00108 {"AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, amd79c901_read_mode},
00109 {"AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, amd79c901_read_mode},
00110 {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf440,ics1893_read_mode},
00111
00112 {"RTL 8201 10/100Mbps Phyceiver" , 0x0000, 0x8200,rtl8201_read_mode},
00113 {"VIA 6103 10/100Mbps Phyceiver", 0x0101, 0x8f20,vt6103_read_mode},
00114 {0,0,0,0}
00115 };
00116
00117 static struct mii_phy {
00118 struct mii_phy * next;
00119 struct mii_chip_info * chip_info;
00120 int phy_addr;
00121 u16 status;
00122 } mii;
00123
00124
00125
00126 #if 0
00127
00128 static struct pci_device_id pci_isa_bridge_list[] = {
00129 { .vendor = 0x1039, .device = 0x0008,
00130 .name = "SIS 85C503/5513 PCI to ISA bridge"},
00131 };
00132
00133 PCI_DRIVER( sis_bridge_pci_driver, pci_isa_bridge_list, PCI_NO_CLASS );
00134
00135 static struct device_driver sis_bridge_driver = {
00136 .name = "SIS ISA bridge",
00137 .bus_driver = &pci_driver,
00138 .bus_driver_info = ( struct bus_driver_info * ) &sis_bridge_pci_driver,
00139 };
00140 #endif
00141
00142
00143
00144 static int sis900_probe(struct nic *nic,struct pci_device *pci);
00145
00146 static u16 sis900_read_eeprom(int location);
00147 static void sis900_mdio_reset(long mdio_addr);
00148 static void sis900_mdio_idle(long mdio_addr);
00149 static u16 sis900_mdio_read(int phy_id, int location);
00150 #if 0
00151 static void sis900_mdio_write(int phy_id, int location, int val);
00152 #endif
00153 static void sis900_init(struct nic *nic);
00154
00155 static void sis900_reset(struct nic *nic);
00156
00157 static void sis900_init_rxfilter(struct nic *nic);
00158 static void sis900_init_txd(struct nic *nic);
00159 static void sis900_init_rxd(struct nic *nic);
00160 static void sis900_set_rx_mode(struct nic *nic);
00161 static void sis900_check_mode(struct nic *nic);
00162
00163 static void sis900_transmit(struct nic *nic, const char *d,
00164 unsigned int t, unsigned int s, const char *p);
00165 static int sis900_poll(struct nic *nic, int retrieve);
00166
00167 static void sis900_disable(struct nic *nic);
00168
00169 static void sis900_irq(struct nic *nic, irq_action_t action);
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 static int sis900_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
00181 {
00182 u16 signature;
00183 int i;
00184
00185
00186 signature = (u16) sis900_read_eeprom( EEPROMSignature);
00187 if (signature == 0xffff || signature == 0x0000) {
00188 printf ("sis900_probe: Error EERPOM read %hX\n", signature);
00189 return 0;
00190 }
00191
00192
00193 for (i = 0; i < 3; i++)
00194 ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
00195 return 1;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 static int sis96x_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
00215 {
00216
00217 long ee_addr = ioaddr + mear;
00218 u32 waittime = 0;
00219 int i;
00220
00221 printf("Alternate function\n");
00222
00223 outl(EEREQ, ee_addr);
00224 while(waittime < 2000) {
00225 if(inl(ee_addr) & EEGNT) {
00226
00227
00228 for (i = 0; i < 3; i++)
00229 ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
00230
00231 outl(EEDONE, ee_addr);
00232 return 1;
00233 } else {
00234 udelay(1);
00235 waittime ++;
00236 }
00237 }
00238 outl(EEDONE, ee_addr);
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 static int sis630e_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
00253 {
00254 #if 0
00255 u8 reg;
00256 int i;
00257 struct bus_loc bus_loc;
00258 union {
00259 struct bus_dev bus_dev;
00260 struct pci_device isa_bridge;
00261 } u;
00262
00263
00264 memset(&bus_loc, 0, sizeof(bus_loc));
00265 if ( ! find_by_driver ( &bus_loc, &u.bus_dev, &sis_bridge_driver, 0 ) )
00266 return 0;
00267
00268 pci_read_config_byte(&u.isa_bridge, 0x48, ®);
00269 pci_write_config_byte(&u.isa_bridge, 0x48, reg | 0x40);
00270
00271 for (i = 0; i < ETH_ALEN; i++)
00272 {
00273 outb(0x09 + i, 0x70);
00274 ((u8 *)(nic->node_addr))[i] = inb(0x71);
00275 }
00276 pci_write_config_byte(&u.isa_bridge, 0x48, reg & ~0x40);
00277
00278 return 1;
00279 #endif
00280
00281
00282 memset ( nic->node_addr, 0, sizeof ( nic->node_addr ) );
00283 return 0;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 static int sis635_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
00297 {
00298 u32 rfcrSave;
00299 u32 i;
00300
00301
00302 rfcrSave = inl(rfcr + ioaddr);
00303
00304 outl(rfcrSave | RELOAD, ioaddr + cr);
00305 outl(0, ioaddr + cr);
00306
00307
00308 outl(rfcrSave & ~RFEN, rfcr + ioaddr);
00309
00310
00311 for (i = 0 ; i < 3 ; i++) {
00312 outl((i << RFADDR_shift), ioaddr + rfcr);
00313 *( ((u16 *)nic->node_addr) + i) = inw(ioaddr + rfdr);
00314 }
00315
00316
00317 outl(rfcrSave | RFEN, rfcr + ioaddr);
00318
00319 return 1;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 static int sis900_probe ( struct nic *nic, struct pci_device *pci ) {
00337
00338 int i;
00339 int found=0;
00340 int phy_addr;
00341 u8 revision;
00342 int ret;
00343
00344 if (pci->ioaddr == 0)
00345 return 0;
00346
00347 nic->irqno = 0;
00348 nic->ioaddr = pci->ioaddr;
00349
00350 ioaddr = pci->ioaddr;
00351 vendor = pci->vendor;
00352 dev_id = pci->device;
00353
00354
00355 pci_write_config_dword(pci, 0x40, 0x00000000);
00356
00357 adjust_pci_device(pci);
00358
00359
00360 ret = 0;
00361 pci_read_config_byte(pci, PCI_REVISION, &revision);
00362
00363
00364 pci_revision = revision;
00365
00366 if (revision == SIS630E_900_REV)
00367 ret = sis630e_get_mac_addr(pci, nic);
00368 else if ((revision > 0x81) && (revision <= 0x90))
00369 ret = sis635_get_mac_addr(pci, nic);
00370 else if (revision == SIS96x_900_REV)
00371 ret = sis96x_get_mac_addr(pci, nic);
00372 else
00373 ret = sis900_get_mac_addr(pci, nic);
00374
00375 if (ret == 0)
00376 {
00377 printf ("sis900_probe: Error MAC address not found\n");
00378 return 0;
00379 }
00380
00381
00382 if (revision == SIS630ET_900_REV)
00383 outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
00384
00385 DBG( "sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id );
00386
00387
00388
00389
00390 found = 0;
00391 for (phy_addr = 0; phy_addr < 32; phy_addr++) {
00392 u16 mii_status;
00393 u16 phy_id0, phy_id1;
00394
00395 mii_status = sis900_mdio_read(phy_addr, MII_STATUS);
00396 if (mii_status == 0xffff || mii_status == 0x0000)
00397
00398 continue;
00399
00400 phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
00401 phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
00402
00403
00404 for (i = 0; mii_chip_table[i].phy_id1; i++) {
00405
00406 if ((phy_id0 == mii_chip_table[i].phy_id0) &&
00407 ((phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1)){
00408
00409 printf("sis900_probe: %s transceiver found at address %d.\n",
00410 mii_chip_table[i].name, phy_addr);
00411
00412 mii.chip_info = &mii_chip_table[i];
00413 mii.phy_addr = phy_addr;
00414 mii.status = sis900_mdio_read(phy_addr, MII_STATUS);
00415 mii.next = NULL;
00416
00417 found=1;
00418 break;
00419 }
00420 }
00421 }
00422
00423 if (found == 0) {
00424 printf("sis900_probe: No MII transceivers found!\n");
00425 return 0;
00426 }
00427
00428
00429 cur_phy = mii.phy_addr;
00430 printf("sis900_probe: Using %s as default\n", mii.chip_info->name);
00431
00432
00433 sis900_init(nic);
00434 nic->nic_op = &sis900_operations;
00435
00436 return 1;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 #define eeprom_delay() inl(ee_addr)
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 static u16 sis900_read_eeprom(int location)
00465 {
00466 int i;
00467 u16 retval = 0;
00468 long ee_addr = ioaddr + mear;
00469 u32 read_cmd = location | EEread;
00470
00471 outl(0, ee_addr);
00472 eeprom_delay();
00473 outl(EECS, ee_addr);
00474 eeprom_delay();
00475
00476
00477 for (i = 8; i >= 0; i--) {
00478 u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
00479 outl(dataval, ee_addr);
00480 eeprom_delay();
00481 outl(dataval | EECLK, ee_addr);
00482 eeprom_delay();
00483 }
00484 outl(EECS, ee_addr);
00485 eeprom_delay();
00486
00487
00488 for (i = 16; i > 0; i--) {
00489 outl(EECS, ee_addr);
00490 eeprom_delay();
00491 outl(EECS | EECLK, ee_addr);
00492 eeprom_delay();
00493 retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
00494 eeprom_delay();
00495 }
00496
00497
00498 outl(0, ee_addr);
00499 eeprom_delay();
00500
00501
00502 return (retval);
00503 }
00504
00505 #define sis900_mdio_delay() inl(mdio_addr)
00506
00507
00508
00509
00510
00511
00512
00513
00514 static void sis900_mdio_idle(long mdio_addr)
00515 {
00516 outl(MDIO | MDDIR, mdio_addr);
00517 sis900_mdio_delay();
00518 outl(MDIO | MDDIR | MDC, mdio_addr);
00519 }
00520
00521
00522 static void sis900_mdio_reset(long mdio_addr)
00523 {
00524 int i;
00525
00526 for (i = 31; i >= 0; i--) {
00527 outl(MDDIR | MDIO, mdio_addr);
00528 sis900_mdio_delay();
00529 outl(MDDIR | MDIO | MDC, mdio_addr);
00530 sis900_mdio_delay();
00531 }
00532 return;
00533 }
00534
00535 static u16 sis900_mdio_read(int phy_id, int location)
00536 {
00537 long mdio_addr = ioaddr + mear;
00538 int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
00539 u16 retval = 0;
00540 int i;
00541
00542 sis900_mdio_reset(mdio_addr);
00543 sis900_mdio_idle(mdio_addr);
00544
00545 for (i = 15; i >= 0; i--) {
00546 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
00547 outl(dataval, mdio_addr);
00548 sis900_mdio_delay();
00549 outl(dataval | MDC, mdio_addr);
00550 sis900_mdio_delay();
00551 }
00552
00553
00554 for (i = 16; i > 0; i--) {
00555 outl(0, mdio_addr);
00556 sis900_mdio_delay();
00557 retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
00558 outl(MDC, mdio_addr);
00559 sis900_mdio_delay();
00560 }
00561 outl(0x00, mdio_addr);
00562 return retval;
00563 }
00564
00565 #if 0
00566 static void sis900_mdio_write(int phy_id, int location, int value)
00567 {
00568 long mdio_addr = ioaddr + mear;
00569 int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
00570 int i;
00571
00572 sis900_mdio_reset(mdio_addr);
00573 sis900_mdio_idle(mdio_addr);
00574
00575
00576 for (i = 15; i >= 0; i--) {
00577 int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
00578 outb(dataval, mdio_addr);
00579 sis900_mdio_delay();
00580 outb(dataval | MDC, mdio_addr);
00581 sis900_mdio_delay();
00582 }
00583 sis900_mdio_delay();
00584
00585
00586 for (i = 15; i >= 0; i--) {
00587 int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
00588 outl(dataval, mdio_addr);
00589 sis900_mdio_delay();
00590 outl(dataval | MDC, mdio_addr);
00591 sis900_mdio_delay();
00592 }
00593 sis900_mdio_delay();
00594
00595
00596 for (i = 2; i > 0; i--) {
00597 outb(0, mdio_addr);
00598 sis900_mdio_delay();
00599 outb(MDC, mdio_addr);
00600 sis900_mdio_delay();
00601 }
00602 outl(0x00, mdio_addr);
00603 return;
00604 }
00605 #endif
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 static void
00619 sis900_init(struct nic *nic)
00620 {
00621
00622 sis900_reset(nic);
00623
00624 sis900_init_rxfilter(nic);
00625
00626 sis900_init_txd(nic);
00627 sis900_init_rxd(nic);
00628
00629 sis900_set_rx_mode(nic);
00630
00631 sis900_check_mode(nic);
00632
00633 outl(RxENA| inl(ioaddr + cr), ioaddr + cr);
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 static void
00648 sis900_reset(struct nic *nic __unused)
00649 {
00650 int i = 0;
00651 u32 status = TxRCMP | RxRCMP;
00652
00653 outl(0, ioaddr + ier);
00654 outl(0, ioaddr + imr);
00655 outl(0, ioaddr + rfcr);
00656
00657 outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
00658
00659
00660 while (status && (i++ < 1000)) {
00661 status ^= (inl(isr + ioaddr) & status);
00662 }
00663
00664 if( (pci_revision >= SIS635A_900_REV) || (pci_revision == SIS900B_900_REV) )
00665 outl(PESEL | RND_CNT, ioaddr + cfg);
00666 else
00667 outl(PESEL, ioaddr + cfg);
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 static void
00681 sis900_init_rxfilter(struct nic *nic)
00682 {
00683 u32 rfcrSave;
00684 int i;
00685
00686 rfcrSave = inl(rfcr + ioaddr);
00687
00688
00689 outl(rfcrSave & ~RFEN, rfcr + ioaddr);
00690
00691
00692 for (i = 0 ; i < 3 ; i++) {
00693 u32 w;
00694
00695 w = (u32) *((u16 *)(nic->node_addr)+i);
00696 outl((i << RFADDR_shift), ioaddr + rfcr);
00697 outl(w, ioaddr + rfdr);
00698
00699 if (sis900_debug > 0)
00700 printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%X\n",
00701 i, inl(ioaddr + rfdr));
00702 }
00703
00704
00705 outl(rfcrSave | RFEN, rfcr + ioaddr);
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 static void
00720 sis900_init_txd(struct nic *nic __unused)
00721 {
00722 txd.link = (u32) 0;
00723 txd.cmdsts = (u32) 0;
00724 txd.bufptr = virt_to_bus(&txb[0]);
00725
00726
00727 outl(virt_to_bus(&txd), ioaddr + txdp);
00728 if (sis900_debug > 0)
00729 printf("sis900_init_txd: TX descriptor register loaded with: %X\n",
00730 inl(ioaddr + txdp));
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 static void
00744 sis900_init_rxd(struct nic *nic __unused)
00745 {
00746 int i;
00747
00748 cur_rx = 0;
00749
00750
00751 for (i = 0; i < NUM_RX_DESC; i++) {
00752 rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
00753 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
00754 rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
00755 if (sis900_debug > 0)
00756 printf("sis900_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
00757 i, &rxd[i], (unsigned int) rxd[i].link, (unsigned int) rxd[i].cmdsts,
00758 (unsigned int) rxd[i].bufptr);
00759 }
00760
00761
00762 outl(virt_to_bus(&rxd[0]), ioaddr + rxdp);
00763
00764 if (sis900_debug > 0)
00765 printf("sis900_init_rxd: RX descriptor register loaded with: %X\n",
00766 inl(ioaddr + rxdp));
00767
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 static void sis900_set_rx_mode(struct nic *nic __unused)
00783 {
00784 int i, table_entries;
00785 u32 rx_mode;
00786 u16 mc_filter[16] = {0};
00787
00788 if((pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV))
00789 table_entries = 16;
00790 else
00791 table_entries = 8;
00792
00793
00794 rx_mode = RFAAB | RFAAM;
00795 for (i = 0; i < table_entries; i++)
00796 mc_filter[i] = 0xffff;
00797
00798
00799 for (i = 0; i < table_entries; i++) {
00800
00801 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
00802 outl(mc_filter[i], ioaddr + rfdr);
00803 }
00804
00805
00806
00807 outl(RFEN | rx_mode, ioaddr + rfcr);
00808
00809 return;
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 static void
00824 sis900_check_mode(struct nic *nic)
00825 {
00826 int speed, duplex;
00827 u32 tx_flags = 0, rx_flags = 0;
00828
00829 mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex);
00830
00831 if( inl(ioaddr + cfg) & EDB_MASTER_EN ) {
00832 tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
00833 rx_flags = DMA_BURST_64 << RxMXDMA_shift;
00834 }
00835 else {
00836 tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
00837 rx_flags = DMA_BURST_512 << RxMXDMA_shift;
00838 }
00839
00840 if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
00841 rx_flags |= (RxDRNT_10 << RxDRNT_shift);
00842 tx_flags |= (TxDRNT_10 << TxDRNT_shift);
00843 }
00844 else {
00845 rx_flags |= (RxDRNT_100 << RxDRNT_shift);
00846 tx_flags |= (TxDRNT_100 << TxDRNT_shift);
00847 }
00848
00849 if (duplex == FDX_CAPABLE_FULL_SELECTED) {
00850 tx_flags |= (TxCSI | TxHBI);
00851 rx_flags |= RxATX;
00852 }
00853
00854 outl (tx_flags, ioaddr + txcfg);
00855 outl (rx_flags, ioaddr + rxcfg);
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 static void
00870 sis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
00871 {
00872 int i = 0;
00873 u32 status;
00874 u16 phy_id0, phy_id1;
00875
00876
00877 do {
00878 status = sis900_mdio_read(phy_addr, MII_STSOUT);
00879 } while (i++ < 2);
00880
00881 *speed = HW_SPEED_10_MBPS;
00882 *duplex = FDX_CAPABLE_HALF_SELECTED;
00883
00884 if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
00885 *speed = HW_SPEED_100_MBPS;
00886 if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
00887 *duplex = FDX_CAPABLE_FULL_SELECTED;
00888
00889
00890 phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
00891 phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
00892 if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){
00893 if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX)
00894 *duplex = FDX_CAPABLE_FULL_SELECTED;
00895 if(sis900_mdio_read(phy_addr, 0x0019) & 0x01)
00896 *speed = HW_SPEED_100_MBPS;
00897 }
00898
00899 if (status & MII_STSOUT_LINK_FAIL)
00900 printf("sis900_read_mode: Media Link Off\n");
00901 else
00902 printf("sis900_read_mode: Media Link On %s %s-duplex \n",
00903 *speed == HW_SPEED_100_MBPS ?
00904 "100mbps" : "10mbps",
00905 *duplex == FDX_CAPABLE_FULL_SELECTED ?
00906 "full" : "half");
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 static void
00921 amd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
00922 {
00923 int i;
00924 u16 status;
00925
00926 for (i = 0; i < 2; i++)
00927 status = sis900_mdio_read(phy_addr, MII_STATUS);
00928
00929 if (status & MII_STAT_CAN_AUTO) {
00930
00931 for (i = 0; i < 2; i++)
00932 status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY);
00933 if (status & MII_STSSUM_SPD)
00934 *speed = HW_SPEED_100_MBPS;
00935 else
00936 *speed = HW_SPEED_10_MBPS;
00937 if (status & MII_STSSUM_DPLX)
00938 *duplex = FDX_CAPABLE_FULL_SELECTED;
00939 else
00940 *duplex = FDX_CAPABLE_HALF_SELECTED;
00941
00942 if (status & MII_STSSUM_LINK)
00943 printf("amd79c901_read_mode: Media Link On %s %s-duplex \n",
00944 *speed == HW_SPEED_100_MBPS ?
00945 "100mbps" : "10mbps",
00946 *duplex == FDX_CAPABLE_FULL_SELECTED ?
00947 "full" : "half");
00948 else
00949 printf("amd79c901_read_mode: Media Link Off\n");
00950 }
00951 else {
00952
00953 *speed = HW_SPEED_HOME;
00954 *duplex = FDX_CAPABLE_HALF_SELECTED;
00955 if (status & MII_STAT_LINK)
00956 printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");
00957 else
00958 printf("amd79c901_read_mode: Media Link Off\n");
00959 }
00960 }
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
00975 {
00976 int i = 0;
00977 u32 status;
00978
00979
00980 for (i = 0; i < 2; i++)
00981 status = sis900_mdio_read(phy_addr, MII_QPDSTS);
00982
00983 if (status & MII_STSICS_SPD)
00984 *speed = HW_SPEED_100_MBPS;
00985 else
00986 *speed = HW_SPEED_10_MBPS;
00987
00988 if (status & MII_STSICS_DPLX)
00989 *duplex = FDX_CAPABLE_FULL_SELECTED;
00990 else
00991 *duplex = FDX_CAPABLE_HALF_SELECTED;
00992
00993 if (status & MII_STSICS_LINKSTS)
00994 printf("ics1893_read_mode: Media Link On %s %s-duplex \n",
00995 *speed == HW_SPEED_100_MBPS ?
00996 "100mbps" : "10mbps",
00997 *duplex == FDX_CAPABLE_FULL_SELECTED ?
00998 "full" : "half");
00999 else
01000 printf("ics1893_read_mode: Media Link Off\n");
01001 }
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
01015 {
01016 u32 status;
01017
01018 status = sis900_mdio_read(phy_addr, MII_STATUS);
01019
01020 if (status & MII_STAT_CAN_TX_FDX) {
01021 *speed = HW_SPEED_100_MBPS;
01022 *duplex = FDX_CAPABLE_FULL_SELECTED;
01023 }
01024 else if (status & MII_STAT_CAN_TX) {
01025 *speed = HW_SPEED_100_MBPS;
01026 *duplex = FDX_CAPABLE_HALF_SELECTED;
01027 }
01028 else if (status & MII_STAT_CAN_T_FDX) {
01029 *speed = HW_SPEED_10_MBPS;
01030 *duplex = FDX_CAPABLE_FULL_SELECTED;
01031 }
01032 else if (status & MII_STAT_CAN_T) {
01033 *speed = HW_SPEED_10_MBPS;
01034 *duplex = FDX_CAPABLE_HALF_SELECTED;
01035 }
01036
01037 if (status & MII_STAT_LINK)
01038 printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",
01039 *speed == HW_SPEED_100_MBPS ?
01040 "100mbps" : "10mbps",
01041 *duplex == FDX_CAPABLE_FULL_SELECTED ?
01042 "full" : "half");
01043 else
01044 printf("rtl8201_read_config_mode: Media Link Off\n");
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
01059 {
01060 u32 status;
01061
01062 status = sis900_mdio_read(phy_addr, MII_STATUS);
01063
01064 if (status & MII_STAT_CAN_TX_FDX) {
01065 *speed = HW_SPEED_100_MBPS;
01066 *duplex = FDX_CAPABLE_FULL_SELECTED;
01067 }
01068 else if (status & MII_STAT_CAN_TX) {
01069 *speed = HW_SPEED_100_MBPS;
01070 *duplex = FDX_CAPABLE_HALF_SELECTED;
01071 }
01072 else if (status & MII_STAT_CAN_T_FDX) {
01073 *speed = HW_SPEED_10_MBPS;
01074 *duplex = FDX_CAPABLE_FULL_SELECTED;
01075 }
01076 else if (status & MII_STAT_CAN_T) {
01077 *speed = HW_SPEED_10_MBPS;
01078 *duplex = FDX_CAPABLE_HALF_SELECTED;
01079 }
01080
01081 if (status & MII_STAT_LINK)
01082 printf("vt6103_read_mode: Media Link On %s %s-duplex \n",
01083 *speed == HW_SPEED_100_MBPS ?
01084 "100mbps" : "10mbps",
01085 *duplex == FDX_CAPABLE_FULL_SELECTED ?
01086 "full" : "half");
01087 else
01088 printf("vt6103_read_config_mode: Media Link Off\n");
01089 }
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 static void
01104 sis900_transmit(struct nic *nic,
01105 const char *d,
01106 unsigned int t,
01107 unsigned int s,
01108 const char *p)
01109 {
01110 u32 to, nstype;
01111 volatile u32 tx_status;
01112
01113
01114 outl(TxDIS | inl(ioaddr + cr), ioaddr + cr);
01115
01116
01117 outl(virt_to_bus(&txd), ioaddr + txdp);
01118 if (sis900_debug > 1)
01119 printf("sis900_transmit: TX descriptor register loaded with: %X\n",
01120 inl(ioaddr + txdp));
01121
01122 memcpy(txb, d, ETH_ALEN);
01123 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
01124 nstype = htons(t);
01125 memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
01126 memcpy(txb + ETH_HLEN, p, s);
01127
01128 s += ETH_HLEN;
01129 s &= DSIZE;
01130
01131 if (sis900_debug > 1)
01132 printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
01133
01134
01135 while (s < ETH_ZLEN)
01136 txb[s++] = '\0';
01137
01138
01139 txd.bufptr = virt_to_bus(&txb[0]);
01140 txd.cmdsts = (u32) OWN | s;
01141
01142
01143 outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
01144
01145 if (sis900_debug > 1)
01146 printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);
01147
01148 to = currticks() + TX_TIMEOUT;
01149
01150 while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
01151 ;
01152
01153 if (currticks() >= to) {
01154 printf("sis900_transmit: TX Timeout! Tx status %X.\n",
01155 (unsigned int) tx_status);
01156 }
01157
01158 if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
01159
01160 printf("sis900_transmit: Transmit error, Tx status %X.\n",
01161 (unsigned int) tx_status);
01162 }
01163
01164 outl(0, ioaddr + imr);
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 static int
01183 sis900_poll(struct nic *nic, int retrieve)
01184 {
01185 u32 rx_status = rxd[cur_rx].cmdsts;
01186 u32 intr_status;
01187 int retstat = 0;
01188
01189
01190 intr_status = inl(ioaddr + isr);
01191
01192 if (sis900_debug > 2)
01193 printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx,
01194 (unsigned int) rx_status);
01195
01196 if (!(rx_status & OWN))
01197 return retstat;
01198
01199 if (sis900_debug > 1)
01200 printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
01201 cur_rx, (unsigned int) rx_status);
01202
01203 if ( ! retrieve ) return 1;
01204
01205 nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
01206
01207 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
01208
01209 printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
01210 (unsigned int) rx_status);
01211 retstat = 0;
01212 } else {
01213
01214 memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
01215 retstat = 1;
01216 }
01217
01218
01219 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
01220 rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
01221
01222 if (++cur_rx == NUM_RX_DESC)
01223 cur_rx = 0;
01224
01225
01226 outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
01227
01228 return retstat;
01229
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242 static void
01243 sis900_disable ( struct nic *nic ) {
01244
01245 sis900_init(nic);
01246
01247
01248 outl(0, ioaddr + imr);
01249 outl(0, ioaddr + ier);
01250
01251
01252 outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
01253 }
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 static void
01267 sis900_irq(struct nic *nic __unused, irq_action_t action __unused)
01268 {
01269 switch ( action ) {
01270 case DISABLE :
01271 outl(0, ioaddr + imr);
01272 break;
01273 case ENABLE :
01274 outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
01275 break;
01276 case FORCE :
01277 break;
01278 }
01279 }
01280
01281 static struct nic_operations sis900_operations = {
01282 .connect = dummy_connect,
01283 .poll = sis900_poll,
01284 .transmit = sis900_transmit,
01285 .irq = sis900_irq,
01286 };
01287
01288 static struct pci_device_id sis900_nics[] = {
01289 PCI_ROM(0x1039, 0x0900, "sis900", "SIS900", 0),
01290 PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016", 0),
01291 };
01292
01293 PCI_DRIVER ( sis900_driver, sis900_nics, PCI_NO_CLASS );
01294
01295 DRIVER ( "SIS900", nic_driver, pci_driver, sis900_driver,
01296 sis900_probe, sis900_disable );
01297
01298
01299
01300
01301
01302
01303
01304