00001 #ifdef ALLMULTI
00002 #error multicast support is not yet implemented
00003 #endif
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 FILE_LICENCE ( GPL_ANY );
00031
00032 #define LINUX_OUT_MACROS 1
00033 #define SMC9000_DEBUG 0
00034
00035 #if SMC9000_DEBUG > 1
00036 #define PRINTK2 printf
00037 #else
00038 #define PRINTK2(args...)
00039 #endif
00040
00041 #include <gpxe/ethernet.h>
00042 #include <errno.h>
00043 #include "etherboot.h"
00044 #include "nic.h"
00045 #include <gpxe/isa.h>
00046 #include "smc9000.h"
00047
00048 # define _outb outb
00049 # define _outw outw
00050
00051 static const char smc9000_version[] = "Version 0.99 98-09-30";
00052 static const char *interfaces[ 2 ] = { "TP", "AUI" };
00053 static const char *chip_ids[ 15 ] = {
00054 NULL, NULL, NULL,
00055 "SMC91C90/91C92",
00056 "SMC91C94",
00057 "SMC91C95",
00058 NULL,
00059 "SMC91C100",
00060 "SMC91C100FD",
00061 "SMC91C11xFD",
00062 NULL, NULL,
00063 NULL, NULL, NULL
00064 };
00065 static const char smc91c96_id[] = "SMC91C96";
00066
00067
00068
00069
00070 static word smc_read_phy_register(int ioaddr, byte phyaddr, byte phyreg)
00071 {
00072 int oldBank;
00073 unsigned int i;
00074 byte mask;
00075 word mii_reg;
00076 byte bits[64];
00077 int clk_idx = 0;
00078 int input_idx;
00079 word phydata;
00080
00081
00082 for (i = 0; i < 32; ++i)
00083 bits[clk_idx++] = MII_MDOE | MII_MDO;
00084
00085
00086 bits[clk_idx++] = MII_MDOE;
00087 bits[clk_idx++] = MII_MDOE | MII_MDO;
00088
00089
00090 bits[clk_idx++] = MII_MDOE | MII_MDO;
00091 bits[clk_idx++] = MII_MDOE;
00092
00093
00094 mask = (byte)0x10;
00095 for (i = 0; i < 5; ++i)
00096 {
00097 if (phyaddr & mask)
00098 bits[clk_idx++] = MII_MDOE | MII_MDO;
00099 else
00100 bits[clk_idx++] = MII_MDOE;
00101
00102
00103 mask >>= 1;
00104 }
00105
00106
00107 mask = (byte)0x10;
00108 for (i = 0; i < 5; ++i)
00109 {
00110 if (phyreg & mask)
00111 bits[clk_idx++] = MII_MDOE | MII_MDO;
00112 else
00113 bits[clk_idx++] = MII_MDOE;
00114
00115
00116 mask >>= 1;
00117 }
00118
00119
00120 bits[clk_idx++] = 0;
00121
00122
00123
00124 input_idx = clk_idx;
00125
00126
00127 for (i = 0; i < 16; ++i)
00128 bits[clk_idx++] = 0;
00129
00130
00131 bits[clk_idx++] = 0;
00132
00133
00134 oldBank = inw( ioaddr+BANK_SELECT );
00135
00136
00137 SMC_SELECT_BANK(ioaddr, 3);
00138
00139
00140 mii_reg = inw( ioaddr+MII_REG );
00141
00142
00143 mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
00144
00145
00146 for (i = 0; i < sizeof(bits); ++i)
00147 {
00148
00149 outw( mii_reg | bits[i], ioaddr+MII_REG );
00150 udelay(50);
00151
00152
00153
00154 outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
00155 udelay(50);
00156 bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
00157 }
00158
00159
00160
00161 outw( mii_reg, ioaddr+MII_REG );
00162 udelay(50);
00163
00164
00165 SMC_SELECT_BANK(ioaddr, oldBank);
00166
00167
00168 phydata = 0;
00169 for (i = 0; i < 16; ++i)
00170 {
00171 phydata <<= 1;
00172
00173 if (bits[input_idx++] & MII_MDI)
00174 phydata |= 0x0001;
00175 }
00176
00177 #if (SMC_DEBUG > 2 )
00178 printf("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
00179 phyaddr, phyreg, phydata);
00180 #endif
00181
00182 return(phydata);
00183 }
00184
00185
00186
00187
00188
00189 static void smc_write_phy_register(int ioaddr,
00190 byte phyaddr, byte phyreg, word phydata)
00191 {
00192 int oldBank;
00193 unsigned int i;
00194 word mask;
00195 word mii_reg;
00196 byte bits[65];
00197 int clk_idx = 0;
00198
00199
00200 for (i = 0; i < 32; ++i)
00201 bits[clk_idx++] = MII_MDOE | MII_MDO;
00202
00203
00204 bits[clk_idx++] = MII_MDOE;
00205 bits[clk_idx++] = MII_MDOE | MII_MDO;
00206
00207
00208 bits[clk_idx++] = MII_MDOE;
00209 bits[clk_idx++] = MII_MDOE | MII_MDO;
00210
00211
00212 mask = (byte)0x10;
00213 for (i = 0; i < 5; ++i)
00214 {
00215 if (phyaddr & mask)
00216 bits[clk_idx++] = MII_MDOE | MII_MDO;
00217 else
00218 bits[clk_idx++] = MII_MDOE;
00219
00220
00221 mask >>= 1;
00222 }
00223
00224
00225 mask = (byte)0x10;
00226 for (i = 0; i < 5; ++i)
00227 {
00228 if (phyreg & mask)
00229 bits[clk_idx++] = MII_MDOE | MII_MDO;
00230 else
00231 bits[clk_idx++] = MII_MDOE;
00232
00233
00234 mask >>= 1;
00235 }
00236
00237
00238 bits[clk_idx++] = 0;
00239 bits[clk_idx++] = 0;
00240
00241
00242 mask = 0x8000;
00243 for (i = 0; i < 16; ++i)
00244 {
00245 if (phydata & mask)
00246 bits[clk_idx++] = MII_MDOE | MII_MDO;
00247 else
00248 bits[clk_idx++] = MII_MDOE;
00249
00250
00251 mask >>= 1;
00252 }
00253
00254
00255 bits[clk_idx++] = 0;
00256
00257
00258 oldBank = inw( ioaddr+BANK_SELECT );
00259
00260
00261 SMC_SELECT_BANK(ioaddr, 3);
00262
00263
00264 mii_reg = inw( ioaddr+MII_REG );
00265
00266
00267 mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
00268
00269
00270 for (i = 0; i < sizeof(bits); ++i)
00271 {
00272
00273 outw( mii_reg | bits[i], ioaddr+MII_REG );
00274 udelay(50);
00275
00276
00277
00278 outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
00279 udelay(50);
00280 bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
00281 }
00282
00283
00284
00285 outw( mii_reg, ioaddr+MII_REG );
00286 udelay(50);
00287
00288
00289 SMC_SELECT_BANK(ioaddr, oldBank);
00290
00291 #if (SMC_DEBUG > 2 )
00292 printf("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
00293 phyaddr, phyreg, phydata);
00294 #endif
00295 }
00296
00297
00298
00299
00300
00301 static int smc_detect_phy(int ioaddr, byte *pphyaddr)
00302 {
00303 word phy_id1;
00304 word phy_id2;
00305 int phyaddr;
00306 int found = 0;
00307
00308
00309 for (phyaddr = 0; phyaddr < 32; ++phyaddr)
00310 {
00311
00312 phy_id1 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG);
00313 phy_id2 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG);
00314
00315
00316 if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
00317 (phy_id1 > 0x0000) && (phy_id1 < 0xffff))
00318 {
00319 if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000))
00320 {
00321
00322 *pphyaddr = phyaddr;
00323 found = 1;
00324 break;
00325 }
00326 }
00327 }
00328
00329 if (!found)
00330 {
00331 printf("No PHY found\n");
00332 return(0);
00333 }
00334
00335
00336 if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) )
00337 {
00338 printf("PHY=LAN83C183 (LAN91C111 Internal)\n");
00339 }
00340
00341 if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) )
00342 {
00343 printf("PHY=LAN83C180\n");
00344 }
00345
00346 return(1);
00347 }
00348
00349
00350
00351
00352
00353 static void smc_phy_configure(int ioaddr)
00354 {
00355 int timeout;
00356 byte phyaddr;
00357 word my_phy_caps;
00358 word my_ad_caps;
00359 word status;
00360 int failed = 0;
00361 int rpc_cur_mode = RPC_DEFAULT;
00362 int lastPhy18;
00363
00364
00365 if (!smc_detect_phy(ioaddr, &phyaddr))
00366 {
00367 return;
00368 }
00369
00370
00371 smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
00372
00373
00374 timeout = 6;
00375 while (timeout--)
00376 {
00377 if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
00378 & PHY_CNTL_RST))
00379 {
00380
00381 break;
00382 }
00383
00384 mdelay(500);
00385 }
00386
00387 if (timeout < 1)
00388 {
00389 PRINTK2("PHY reset timed out\n");
00390 return;
00391 }
00392
00393
00394 lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
00395
00396
00397
00398 smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG,
00399 PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
00400 PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
00401 PHY_INT_SPDDET | PHY_INT_DPLXDET);
00402
00403
00404 SMC_SELECT_BANK(ioaddr, 0);
00405 outw( rpc_cur_mode, ioaddr + RPC_REG );
00406
00407
00408 my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00409 my_ad_caps = PHY_AD_CSMA;
00410
00411 if (my_phy_caps & PHY_STAT_CAP_T4)
00412 my_ad_caps |= PHY_AD_T4;
00413
00414 if (my_phy_caps & PHY_STAT_CAP_TXF)
00415 my_ad_caps |= PHY_AD_TX_FDX;
00416
00417 if (my_phy_caps & PHY_STAT_CAP_TXH)
00418 my_ad_caps |= PHY_AD_TX_HDX;
00419
00420 if (my_phy_caps & PHY_STAT_CAP_TF)
00421 my_ad_caps |= PHY_AD_10_FDX;
00422
00423 if (my_phy_caps & PHY_STAT_CAP_TH)
00424 my_ad_caps |= PHY_AD_10_HDX;
00425
00426
00427 smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
00428
00429 PRINTK2("phy caps=%x\n", my_phy_caps);
00430 PRINTK2("phy advertised caps=%x\n", my_ad_caps);
00431
00432
00433 smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
00434 PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
00435
00436
00437
00438
00439 timeout = 20;
00440 while (timeout--)
00441 {
00442 status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00443 if (status & PHY_STAT_ANEG_ACK)
00444 {
00445
00446 break;
00447 }
00448
00449 mdelay(500);
00450
00451
00452 if (status & PHY_STAT_REM_FLT)
00453 {
00454 PRINTK2("PHY remote fault detected\n");
00455
00456
00457 PRINTK2("PHY restarting auto-negotiation\n");
00458 smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
00459 PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST |
00460 PHY_CNTL_SPEED | PHY_CNTL_DPLX);
00461 }
00462 }
00463
00464 if (timeout < 1)
00465 {
00466 PRINTK2("PHY auto-negotiate timed out\n");
00467 failed = 1;
00468 }
00469
00470
00471 if (status & PHY_STAT_REM_FLT)
00472 {
00473 PRINTK2("PHY remote fault detected\n");
00474 failed = 1;
00475 }
00476
00477
00478 if ( lastPhy18 & PHY_INT_SPDDET )
00479 {
00480 PRINTK2("PHY 100BaseT\n");
00481 rpc_cur_mode |= RPC_SPEED;
00482 }
00483 else
00484 {
00485 PRINTK2("PHY 10BaseT\n");
00486 rpc_cur_mode &= ~RPC_SPEED;
00487 }
00488
00489 if ( lastPhy18 & PHY_INT_DPLXDET )
00490 {
00491 PRINTK2("PHY Full Duplex\n");
00492 rpc_cur_mode |= RPC_DPLX;
00493 }
00494 else
00495 {
00496 PRINTK2("PHY Half Duplex\n");
00497 rpc_cur_mode &= ~RPC_DPLX;
00498 }
00499
00500
00501 outw( rpc_cur_mode, ioaddr + RPC_REG );
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 static void smc_reset(int ioaddr)
00521 {
00522
00523
00524 SMC_SELECT_BANK(ioaddr, 0);
00525 _outw( RCR_SOFTRESET, ioaddr + RCR );
00526
00527
00528 SMC_DELAY(ioaddr);
00529
00530
00531
00532 _outw(RCR_CLEAR, ioaddr + RCR);
00533 _outw(TCR_CLEAR, ioaddr + TCR);
00534
00535
00536 SMC_SELECT_BANK(ioaddr, 2);
00537 _outw( MC_RESET, ioaddr + MMU_CMD );
00538
00539
00540
00541
00542 _outb(0, ioaddr + INT_MASK);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 static int smc9000_probe_addr( isa_probe_addr_t ioaddr )
00561 {
00562 word bank;
00563 word revision_register;
00564 word base_address_register;
00565
00566
00567 bank = inw(ioaddr + BANK_SELECT);
00568 if ((bank & 0xFF00) != 0x3300) {
00569 return 0;
00570 }
00571
00572
00573 _outw(0x0, ioaddr + BANK_SELECT);
00574 bank = inw(ioaddr + BANK_SELECT);
00575 if ((bank & 0xFF00) != 0x3300) {
00576 return 0;
00577 }
00578
00579
00580
00581
00582 SMC_SELECT_BANK(ioaddr, 1);
00583 base_address_register = inw(ioaddr + BASE);
00584
00585 if (ioaddr != (base_address_register >> 3 & 0x3E0)) {
00586 DBG("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
00587 "Probably not a SMC chip\n",
00588 ioaddr, base_address_register >> 3 & 0x3E0);
00589
00590
00591 return 0;
00592 }
00593
00594
00595
00596
00597
00598 SMC_SELECT_BANK(ioaddr, 3);
00599 revision_register = inw(ioaddr + REVISION);
00600 if (!chip_ids[(revision_register >> 4) & 0xF]) {
00601
00602 DBG( "SMC9000: IO %hX: Unrecognized revision register:"
00603 " %hX, Contact author.\n", ioaddr, revision_register );
00604 return 0;
00605 }
00606
00607
00608
00609
00610 return 1;
00611 }
00612
00613
00614
00615
00616
00617 static void smc9000_transmit(
00618 struct nic *nic,
00619 const char *d,
00620 unsigned int t,
00621 unsigned int s,
00622 const char *p)
00623 {
00624 word length;
00625 word numPages;
00626 unsigned long time_out;
00627 byte packet_no;
00628 word status;
00629 int i;
00630
00631
00632 length = (s + ETH_HLEN + 1)&~1;
00633
00634
00635 numPages = length / 256;
00636
00637 if (numPages > 7 ) {
00638 DBG("SMC9000: Far too big packet error. \n");
00639 return;
00640 }
00641
00642
00643 for (i=0;i<30;i++) {
00644
00645 SMC_SELECT_BANK(nic->ioaddr, 2);
00646 _outw(MC_ALLOC | numPages, nic->ioaddr + MMU_CMD);
00647
00648 status = 0;
00649
00650 for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
00651 status = inb(nic->ioaddr + INTERRUPT);
00652 if ( status & IM_ALLOC_INT ) {
00653
00654 _outb(IM_ALLOC_INT, nic->ioaddr + INTERRUPT);
00655 break;
00656 }
00657 }
00658
00659 if ((status & IM_ALLOC_INT) != 0 ) {
00660
00661 break;
00662 } else {
00663 printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
00664 _outw(MC_RESET, nic->ioaddr + MMU_CMD);
00665 }
00666 }
00667
00668
00669 packet_no = inb(nic->ioaddr + PNR_ARR + 1);
00670 if (packet_no & 0x80) {
00671
00672 printf("SMC9000: Memory allocation failed. \n");
00673 return;
00674 }
00675
00676
00677 _outb(packet_no, nic->ioaddr + PNR_ARR);
00678
00679
00680 _outw(PTR_AUTOINC, nic->ioaddr + POINTER);
00681
00682 #if SMC9000_DEBUG > 2
00683 printf("Trying to xmit packet of length %hX\n", length );
00684 #endif
00685
00686
00687
00688 _outw(0, nic->ioaddr + DATA_1 );
00689
00690
00691 _outb((length+6) & 0xFF, nic->ioaddr + DATA_1);
00692 _outb((length+6) >> 8 , nic->ioaddr + DATA_1);
00693
00694
00695
00696
00697 outsw(nic->ioaddr + DATA_1, d, ETH_ALEN >> 1);
00698 outsw(nic->ioaddr + DATA_1, nic->node_addr, ETH_ALEN >> 1);
00699 _outw(htons(t), nic->ioaddr + DATA_1);
00700
00701
00702 outsw(nic->ioaddr + DATA_1 , p, s >> 1);
00703
00704
00705 if ((s & 1) == 0) {
00706 _outw(0, nic->ioaddr + DATA_1);
00707 } else {
00708 _outb(p[s-1], nic->ioaddr + DATA_1);
00709 _outb(0x20, nic->ioaddr + DATA_1);
00710 }
00711
00712
00713 _outw(MC_ENQUEUE , nic->ioaddr + MMU_CMD);
00714
00715 status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
00716 do {
00717 status = inb(nic->ioaddr + INTERRUPT);
00718
00719 if ((status & IM_TX_INT ) != 0) {
00720 word tx_status;
00721
00722
00723 _outb(IM_TX_INT, nic->ioaddr + INTERRUPT);
00724
00725 packet_no = inw(nic->ioaddr + FIFO_PORTS);
00726 packet_no &= 0x7F;
00727
00728
00729 _outb( packet_no, nic->ioaddr + PNR_ARR );
00730
00731
00732 _outw( PTR_AUTOINC | PTR_READ, nic->ioaddr + POINTER );
00733
00734 tx_status = inw( nic->ioaddr + DATA_1 );
00735
00736 if (0 == (tx_status & TS_SUCCESS)) {
00737 DBG("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
00738
00739 SMC_SELECT_BANK(nic->ioaddr, 0);
00740 _outw(inw(nic->ioaddr + TCR ) | TCR_ENABLE, nic->ioaddr + TCR );
00741 }
00742
00743
00744 SMC_SELECT_BANK(nic->ioaddr, 2);
00745 _outw(MC_FREEPKT, nic->ioaddr + MMU_CMD);
00746
00747 return;
00748 }
00749 }while(currticks() < time_out);
00750
00751 printf("SMC9000: TX timed out, resetting board\n");
00752 smc_reset(nic->ioaddr);
00753 return;
00754 }
00755
00756
00757
00758
00759 static int smc9000_poll(struct nic *nic, int retrieve)
00760 {
00761 SMC_SELECT_BANK(nic->ioaddr, 2);
00762 if (inw(nic->ioaddr + FIFO_PORTS) & FP_RXEMPTY)
00763 return 0;
00764
00765 if ( ! retrieve ) return 1;
00766
00767
00768 _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, nic->ioaddr + POINTER);
00769
00770
00771 if (!(inw(nic->ioaddr + DATA_1) & RS_ERRORS)) {
00772
00773 nic->packetlen = (inw(nic->ioaddr + DATA_1) & 0x07ff);
00774
00775
00776 nic->packetlen -= 6;
00777 #if SMC9000_DEBUG > 2
00778 printf(" Reading %d words (and %d byte(s))\n",
00779 (nic->packetlen >> 1), nic->packetlen & 1);
00780 #endif
00781
00782 insw(nic->ioaddr + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
00783
00784 if (nic->packet[nic->packetlen+1] & 0x20)
00785 nic->packetlen++;
00786
00787
00788 _outw(MC_RELEASE, nic->ioaddr + MMU_CMD);
00789 return 1;
00790 }
00791
00792 printf("SMC9000: RX error\n");
00793
00794 _outw(MC_RELEASE, nic->ioaddr + MMU_CMD);
00795 return 0;
00796 }
00797
00798 static void smc9000_disable ( struct nic *nic, struct isa_device *isa __unused ) {
00799
00800 smc_reset(nic->ioaddr);
00801
00802
00803 SMC_SELECT_BANK(nic->ioaddr, 2);
00804 _outb( 0, nic->ioaddr + INT_MASK);
00805
00806
00807 SMC_SELECT_BANK(nic->ioaddr, 0);
00808 _outb( RCR_CLEAR, nic->ioaddr + RCR );
00809 _outb( TCR_CLEAR, nic->ioaddr + TCR );
00810 }
00811
00812 static void smc9000_irq(struct nic *nic __unused, irq_action_t action __unused)
00813 {
00814 switch ( action ) {
00815 case DISABLE :
00816 break;
00817 case ENABLE :
00818 break;
00819 case FORCE :
00820 break;
00821 }
00822 }
00823
00824 static struct nic_operations smc9000_operations = {
00825 .connect = dummy_connect,
00826 .poll = smc9000_poll,
00827 .transmit = smc9000_transmit,
00828 .irq = smc9000_irq,
00829
00830 };
00831
00832
00833
00834
00835
00836 static int smc9000_probe ( struct nic *nic, struct isa_device *isa ) {
00837
00838 unsigned short revision;
00839 int memory;
00840 int media;
00841 const char * version_string;
00842 const char * if_string;
00843 int i;
00844
00845 nic->irqno = 0;
00846 nic->ioaddr = isa->ioaddr;
00847
00848
00849
00850
00851 SMC_SELECT_BANK(nic->ioaddr, 1);
00852 for ( i = 0; i < 6; i += 2 ) {
00853 word address;
00854
00855 address = inw(nic->ioaddr + ADDR0 + i);
00856 nic->node_addr[i+1] = address >> 8;
00857 nic->node_addr[i] = address & 0xFF;
00858 }
00859
00860
00861 SMC_SELECT_BANK(nic->ioaddr, 0);
00862 memory = ( inw(nic->ioaddr + MCR) >> 9 ) & 0x7;
00863 memory *= 256 * (inw(nic->ioaddr + MIR) & 0xFF);
00864
00865
00866
00867
00868
00869
00870 SMC_SELECT_BANK(nic->ioaddr, 3);
00871 revision = inw(nic->ioaddr + REVISION);
00872 version_string = chip_ids[(revision >> 4) & 0xF];
00873
00874 if (((revision & 0xF0) >> 4 == CHIP_9196) &&
00875 ((revision & 0x0F) >= REV_9196)) {
00876
00877
00878 version_string = smc91c96_id;
00879 }
00880
00881 if ( !version_string ) {
00882
00883 return 0;
00884 }
00885
00886
00887 SMC_SELECT_BANK(nic->ioaddr, 1);
00888 if (inw(nic->ioaddr + CONFIG) & CFG_AUI_SELECT)
00889 media = 2;
00890 else
00891 media = 1;
00892
00893 if_string = interfaces[media - 1];
00894
00895
00896 smc_reset(nic->ioaddr);
00897
00898 printf("SMC9000 %s\n", smc9000_version);
00899 DBG("Copyright (C) 1998 Daniel Engstr\x94m\n");
00900 DBG("Copyright (C) 1996 Eric Stahlman\n");
00901
00902 printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
00903 version_string, revision & 0xF,
00904 nic->ioaddr, if_string, memory );
00905
00906 DBG ( "Ethernet MAC address: %s\n", eth_ntoa ( nic->node_addr ) );
00907
00908 SMC_SELECT_BANK(nic->ioaddr, 0);
00909
00910
00911 _outw(TCR_NORMAL, nic->ioaddr + TCR);
00912 _outw(RCR_NORMAL, nic->ioaddr + RCR);
00913
00914
00915 SMC_SELECT_BANK(nic->ioaddr, 1);
00916 if ( media == 1 ) {
00917 _outw( inw( nic->ioaddr + CONFIG ) & ~CFG_AUI_SELECT,
00918 nic->ioaddr + CONFIG );
00919 }
00920 else if ( media == 2 ) {
00921 _outw( inw( nic->ioaddr + CONFIG ) | CFG_AUI_SELECT,
00922 nic->ioaddr + CONFIG );
00923 }
00924
00925 smc_phy_configure(nic->ioaddr);
00926
00927 nic->nic_op = &smc9000_operations;
00928 return 1;
00929 }
00930
00931
00932
00933
00934
00935
00936 static isa_probe_addr_t smc9000_probe_addrs[] = {
00937 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
00938 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
00939 };
00940
00941 ISA_DRIVER ( smc9000_driver, smc9000_probe_addrs, smc9000_probe_addr,
00942 GENERIC_ISAPNP_VENDOR, 0x8228 );
00943
00944 DRIVER ( "SMC9000", nic_driver, isa_driver, smc9000_driver,
00945 smc9000_probe, smc9000_disable );
00946
00947 ISA_ROM ( "smc9000", "SMC9000" );
00948
00949
00950
00951
00952
00953
00954
00955