iPXE
smc9000.c
Go to the documentation of this file.
00001 #ifdef ALLMULTI
00002 #error multicast support is not yet implemented
00003 #endif
00004  /*------------------------------------------------------------------------
00005  * smc9000.c
00006  * This is a Etherboot driver for SMC's 9000 series of Ethernet cards.
00007  *
00008  * Copyright (C) 1998 Daniel Engström <daniel.engstrom@riksnett.no>
00009  * Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman
00010  * Copyright (C) 1996 by Erik Stahlman <eric@vt.edu>
00011  *
00012  * This software may be used and distributed according to the terms
00013  * of the GNU Public License, incorporated herein by reference.
00014  *
00015  * "Features" of the SMC chip:
00016  *   4608 byte packet memory. ( for the 91C92/4.  Others have more )
00017  *   EEPROM for configuration
00018  *   AUI/TP selection
00019  *
00020  * Authors
00021  *      Erik Stahlman                           <erik@vt.edu>
00022  *      Daniel Engström                         <daniel.engstrom@riksnett.no>
00023  *
00024  * History
00025  * 98-09-25              Daniel Engström Etherboot driver crated from Eric's
00026  *                                       Linux driver.
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 <ipxe/ethernet.h>
00042 #include <errno.h>
00043 #include "etherboot.h"
00044 #include "nic.h"
00045 #include <ipxe/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    /* 3 */ "SMC91C90/91C92",
00056    /* 4 */ "SMC91C94",
00057    /* 5 */ "SMC91C95",
00058    NULL,
00059    /* 7 */ "SMC91C100",
00060    /* 8 */ "SMC91C100FD",
00061    /* 9 */ "SMC91C11xFD",
00062    NULL, NULL,
00063    NULL, NULL, NULL
00064 };
00065 static const char      smc91c96_id[] = "SMC91C96";
00066 
00067 /*------------------------------------------------------------
00068  . Reads a register from the MII Management serial interface
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     // 32 consecutive ones on MDO to establish sync
00082     for (i = 0; i < 32; ++i)
00083         bits[clk_idx++] = MII_MDOE | MII_MDO;
00084 
00085     // Start code <01>
00086     bits[clk_idx++] = MII_MDOE;
00087     bits[clk_idx++] = MII_MDOE | MII_MDO;
00088 
00089     // Read command <10>
00090     bits[clk_idx++] = MII_MDOE | MII_MDO;
00091     bits[clk_idx++] = MII_MDOE;
00092 
00093     // Output the PHY address, msb first
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         // Shift to next lowest bit
00103         mask >>= 1;
00104     }
00105 
00106     // Output the phy register number, msb first
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         // Shift to next lowest bit
00116         mask >>= 1;
00117     }
00118 
00119     // Tristate and turnaround (2 bit times)
00120     bits[clk_idx++] = 0;
00121     //bits[clk_idx++] = 0;
00122 
00123     // Input starts at this bit time
00124     input_idx = clk_idx;
00125 
00126     // Will input 16 bits
00127     for (i = 0; i < 16; ++i)
00128         bits[clk_idx++] = 0;
00129 
00130     // Final clock bit
00131     bits[clk_idx++] = 0;
00132 
00133     // Save the current bank
00134     oldBank = inw( ioaddr+BANK_SELECT );
00135 
00136     // Select bank 3
00137     SMC_SELECT_BANK(ioaddr, 3);
00138 
00139     // Get the current MII register value
00140     mii_reg = inw( ioaddr+MII_REG );
00141 
00142     // Turn off all MII Interface bits
00143     mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
00144 
00145     // Clock all 64 cycles
00146     for (i = 0; i < sizeof(bits); ++i)
00147     {
00148         // Clock Low - output data
00149         outw( mii_reg | bits[i], ioaddr+MII_REG );
00150         udelay(50);
00151 
00152 
00153         // Clock Hi - input data
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     // Return to idle state
00160     // Set clock to low, data to low, and output tristated
00161     outw( mii_reg, ioaddr+MII_REG );
00162     udelay(50);
00163 
00164     // Restore original bank select
00165     SMC_SELECT_BANK(ioaddr, oldBank);
00166 
00167     // Recover input data
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  . Writes a register to the MII Management serial interface
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     // 32 consecutive ones on MDO to establish sync
00200     for (i = 0; i < 32; ++i)
00201         bits[clk_idx++] = MII_MDOE | MII_MDO;
00202 
00203     // Start code <01>
00204     bits[clk_idx++] = MII_MDOE;
00205     bits[clk_idx++] = MII_MDOE | MII_MDO;
00206 
00207     // Write command <01>
00208     bits[clk_idx++] = MII_MDOE;
00209     bits[clk_idx++] = MII_MDOE | MII_MDO;
00210 
00211     // Output the PHY address, msb first
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                 // Shift to next lowest bit
00221         mask >>= 1;
00222     }
00223 
00224     // Output the phy register number, msb first
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         // Shift to next lowest bit
00234         mask >>= 1;
00235     }
00236 
00237     // Tristate and turnaround (2 bit times)
00238     bits[clk_idx++] = 0;
00239     bits[clk_idx++] = 0;
00240 
00241     // Write out 16 bits of data, msb first
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         // Shift to next lowest bit
00251         mask >>= 1;
00252     }
00253 
00254     // Final clock bit (tristate)
00255     bits[clk_idx++] = 0;
00256 
00257     // Save the current bank
00258     oldBank = inw( ioaddr+BANK_SELECT );
00259 
00260     // Select bank 3
00261     SMC_SELECT_BANK(ioaddr, 3);
00262 
00263     // Get the current MII register value
00264     mii_reg = inw( ioaddr+MII_REG );
00265 
00266     // Turn off all MII Interface bits
00267     mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
00268 
00269     // Clock all cycles
00270     for (i = 0; i < sizeof(bits); ++i)
00271     {
00272         // Clock Low - output data
00273         outw( mii_reg | bits[i], ioaddr+MII_REG );
00274         udelay(50);
00275 
00276 
00277         // Clock Hi - input data
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     // Return to idle state
00284     // Set clock to low, data to low, and output tristated
00285     outw( mii_reg, ioaddr+MII_REG );
00286     udelay(50);
00287 
00288     // Restore original bank select
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  . Finds and reports the PHY address
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     // Scan all 32 PHY addresses if necessary
00309     for (phyaddr = 0; phyaddr < 32; ++phyaddr)
00310     {
00311         // Read the PHY identifiers
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         // Make sure it is a valid identifier
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                 // Save the PHY's address
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     // Set the PHY type
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  . Configures the specified PHY using Autonegotiation. Calls
00351  . smc_phy_fixed() if the user has requested a certain config.
00352  .-------------------------------------------------------------*/
00353 static void smc_phy_configure(int ioaddr)
00354 {
00355     int timeout;
00356     byte phyaddr;
00357     word my_phy_caps; // My PHY capabilities
00358     word my_ad_caps; // My Advertised capabilities
00359     word status;
00360     int rpc_cur_mode = RPC_DEFAULT;
00361     int lastPhy18;
00362 
00363     // Find the address and type of our phy
00364     if (!smc_detect_phy(ioaddr, &phyaddr))
00365     {
00366         return;
00367     }
00368 
00369     // Reset the PHY, setting all other bits to zero
00370     smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
00371 
00372     // Wait for the reset to complete, or time out
00373     timeout = 6; // Wait up to 3 seconds
00374     while (timeout--)
00375     {
00376         if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
00377               & PHY_CNTL_RST))
00378         {
00379             // reset complete
00380             break;
00381         }
00382 
00383         mdelay(500); // wait 500 millisecs
00384     }
00385 
00386     if (timeout < 1)
00387     {
00388         PRINTK2("PHY reset timed out\n");
00389         return;
00390     }
00391 
00392     // Read PHY Register 18, Status Output
00393     lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
00394 
00395     // Enable PHY Interrupts (for register 18)
00396     // Interrupts listed here are disabled
00397     smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG,
00398                            PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
00399                                    PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
00400                                    PHY_INT_SPDDET | PHY_INT_DPLXDET);
00401 
00402     /* Configure the Receive/Phy Control register */
00403     SMC_SELECT_BANK(ioaddr, 0);
00404     outw( rpc_cur_mode, ioaddr + RPC_REG );
00405 
00406     // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
00407     my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00408     my_ad_caps  = PHY_AD_CSMA; // I am CSMA capable
00409 
00410     if (my_phy_caps & PHY_STAT_CAP_T4)
00411         my_ad_caps |= PHY_AD_T4;
00412 
00413     if (my_phy_caps & PHY_STAT_CAP_TXF)
00414         my_ad_caps |= PHY_AD_TX_FDX;
00415 
00416     if (my_phy_caps & PHY_STAT_CAP_TXH)
00417         my_ad_caps |= PHY_AD_TX_HDX;
00418 
00419     if (my_phy_caps & PHY_STAT_CAP_TF)
00420         my_ad_caps |= PHY_AD_10_FDX;
00421 
00422     if (my_phy_caps & PHY_STAT_CAP_TH)
00423         my_ad_caps |= PHY_AD_10_HDX;
00424 
00425     // Update our Auto-Neg Advertisement Register
00426     smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
00427 
00428     PRINTK2("phy caps=%x\n", my_phy_caps);
00429     PRINTK2("phy advertised caps=%x\n", my_ad_caps);
00430 
00431     // Restart auto-negotiation process in order to advertise my caps
00432     smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
00433                             PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
00434 
00435     // Wait for the auto-negotiation to complete.  This may take from
00436     // 2 to 3 seconds.
00437     // Wait for the reset to complete, or time out
00438     timeout = 20; // Wait up to 10 seconds
00439     while (timeout--)
00440     {
00441         status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00442         if (status & PHY_STAT_ANEG_ACK)
00443         {
00444             // auto-negotiate complete
00445             break;
00446         }
00447 
00448         mdelay(500); // wait 500 millisecs
00449 
00450         // Restart auto-negotiation if remote fault
00451         if (status & PHY_STAT_REM_FLT)
00452         {
00453             PRINTK2("PHY remote fault detected\n");
00454 
00455             // Restart auto-negotiation
00456             PRINTK2("PHY restarting auto-negotiation\n");
00457             smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
00458                                     PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST |
00459                                     PHY_CNTL_SPEED | PHY_CNTL_DPLX);
00460         }
00461     }
00462 
00463     if (timeout < 1)
00464     {
00465         PRINTK2("PHY auto-negotiate timed out\n");
00466     }
00467 
00468     // Fail if we detected an auto-negotiate remote fault
00469     if (status & PHY_STAT_REM_FLT)
00470     {
00471         PRINTK2("PHY remote fault detected\n");
00472     }
00473 
00474     // Set our sysctl parameters to match auto-negotiation results
00475     if ( lastPhy18 & PHY_INT_SPDDET )
00476     {
00477         PRINTK2("PHY 100BaseT\n");
00478         rpc_cur_mode |= RPC_SPEED;
00479     }
00480     else
00481     {
00482         PRINTK2("PHY 10BaseT\n");
00483         rpc_cur_mode &= ~RPC_SPEED;
00484     }
00485 
00486     if ( lastPhy18 & PHY_INT_DPLXDET )
00487     {
00488         PRINTK2("PHY Full Duplex\n");
00489         rpc_cur_mode |= RPC_DPLX;
00490     }
00491     else
00492     {
00493         PRINTK2("PHY Half Duplex\n");
00494         rpc_cur_mode &= ~RPC_DPLX;
00495     }
00496 
00497     // Re-Configure the Receive/Phy Control register
00498     outw( rpc_cur_mode, ioaddr + RPC_REG );
00499 }
00500 
00501 /*
00502  * Function: smc_reset( int ioaddr )
00503  * Purpose:
00504  *      This sets the SMC91xx chip to its normal state, hopefully from whatever
00505  *      mess that any other DOS driver has put it in.
00506  *
00507  * Maybe I should reset more registers to defaults in here?  SOFTRESET  should
00508  * do that for me.
00509  *
00510  * Method:
00511  *      1.  send a SOFT RESET
00512  *      2.  wait for it to finish
00513  *      3.  reset the memory management unit
00514  *      4.  clear all interrupts
00515  *
00516 */
00517 static void smc_reset(int ioaddr)
00518 {
00519    /* This resets the registers mostly to defaults, but doesn't
00520     * affect EEPROM.  That seems unnecessary */
00521    SMC_SELECT_BANK(ioaddr, 0);
00522    _outw( RCR_SOFTRESET, ioaddr + RCR );
00523 
00524    /* this should pause enough for the chip to be happy */
00525    SMC_DELAY(ioaddr);
00526 
00527    /* Set the transmit and receive configuration registers to
00528     * default values */
00529    _outw(RCR_CLEAR, ioaddr + RCR);
00530    _outw(TCR_CLEAR, ioaddr + TCR);
00531 
00532    /* Reset the MMU */
00533    SMC_SELECT_BANK(ioaddr, 2);
00534    _outw( MC_RESET, ioaddr + MMU_CMD );
00535 
00536    /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
00537     * but this is a place where future chipsets _COULD_ break.  Be wary
00538     * of issuing another MMU command right after this */
00539    _outb(0, ioaddr + INT_MASK);
00540 }
00541 
00542 
00543 /*----------------------------------------------------------------------
00544  * Function: smc9000_probe_addr( int ioaddr )
00545  *
00546  * Purpose:
00547  *      Tests to see if a given ioaddr points to an SMC9xxx chip.
00548  *      Returns a 1 on success
00549  *
00550  * Algorithm:
00551  *      (1) see if the high byte of BANK_SELECT is 0x33
00552  *      (2) compare the ioaddr with the base register's address
00553  *      (3) see if I recognize the chip ID in the appropriate register
00554  *
00555  * ---------------------------------------------------------------------
00556  */
00557 static int smc9000_probe_addr( isa_probe_addr_t ioaddr )
00558 {
00559    word bank;
00560    word revision_register;
00561    word base_address_register;
00562 
00563    /* First, see if the high byte is 0x33 */
00564    bank = inw(ioaddr + BANK_SELECT);
00565    if ((bank & 0xFF00) != 0x3300) {
00566       return 0;
00567    }
00568    /* The above MIGHT indicate a device, but I need to write to further
00569     *   test this.  */
00570    _outw(0x0, ioaddr + BANK_SELECT);
00571    bank = inw(ioaddr + BANK_SELECT);
00572    if ((bank & 0xFF00) != 0x3300) {
00573       return 0;
00574    }
00575 
00576    /* well, we've already written once, so hopefully another time won't
00577     *  hurt.  This time, I need to switch the bank register to bank 1,
00578     *  so I can access the base address register */
00579    SMC_SELECT_BANK(ioaddr, 1);
00580    base_address_register = inw(ioaddr + BASE);
00581 
00582    if (ioaddr != (base_address_register >> 3 & 0x3E0))  {
00583       DBG("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
00584           "Probably not a SMC chip\n",
00585           ioaddr, base_address_register >> 3 & 0x3E0);
00586       /* well, the base address register didn't match.  Must not have
00587        * been a SMC chip after all. */
00588       return 0;
00589    }
00590 
00591 
00592    /* check if the revision register is something that I recognize.
00593     * These might need to be added to later, as future revisions
00594     * could be added.  */
00595    SMC_SELECT_BANK(ioaddr, 3);
00596    revision_register  = inw(ioaddr + REVISION);
00597    if (!chip_ids[(revision_register >> 4) & 0xF]) {
00598       /* I don't recognize this chip, so... */
00599       DBG( "SMC9000: IO %hX: Unrecognized revision register:"
00600            " %hX, Contact author.\n", ioaddr, revision_register );
00601       return 0;
00602    }
00603 
00604    /* at this point I'll assume that the chip is an SMC9xxx.
00605     * It might be prudent to check a listing of MAC addresses
00606     * against the hardware address, or do some other tests. */
00607    return 1;
00608 }
00609 
00610 
00611 /**************************************************************************
00612  * ETH_TRANSMIT - Transmit a frame
00613  ***************************************************************************/
00614 static void smc9000_transmit(
00615         struct nic *nic,
00616         const char *d,                  /* Destination */
00617         unsigned int t,                 /* Type */
00618         unsigned int s,                 /* size */
00619         const char *p)                  /* Packet */
00620 {
00621    word length; /* real, length incl. header */
00622    word numPages;
00623    unsigned long time_out;
00624    byte packet_no;
00625    word status;
00626    int i;
00627 
00628    /* We dont pad here since we can have the hardware doing it for us */
00629    length = (s + ETH_HLEN + 1)&~1;
00630 
00631    /* convert to MMU pages */
00632    numPages = length / 256;
00633 
00634    if (numPages > 7 ) {
00635       DBG("SMC9000: Far too big packet error. \n");
00636       return;
00637    }
00638 
00639    /* dont try more than, say 30 times */
00640    for (i=0;i<30;i++) {
00641       /* now, try to allocate the memory */
00642       SMC_SELECT_BANK(nic->ioaddr, 2);
00643       _outw(MC_ALLOC | numPages, nic->ioaddr + MMU_CMD);
00644 
00645       status = 0;
00646       /* wait for the memory allocation to finnish */
00647       for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
00648          status = inb(nic->ioaddr + INTERRUPT);
00649          if ( status & IM_ALLOC_INT ) {
00650             /* acknowledge the interrupt */
00651             _outb(IM_ALLOC_INT, nic->ioaddr + INTERRUPT);
00652             break;
00653          }
00654       }
00655 
00656       if ((status & IM_ALLOC_INT) != 0 ) {
00657          /* We've got the memory */
00658          break;
00659       } else {
00660          printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
00661          _outw(MC_RESET, nic->ioaddr + MMU_CMD);
00662       }
00663    }
00664 
00665    /* If I get here, I _know_ there is a packet slot waiting for me */
00666    packet_no = inb(nic->ioaddr + PNR_ARR + 1);
00667    if (packet_no & 0x80) {
00668       /* or isn't there?  BAD CHIP! */
00669       printf("SMC9000: Memory allocation failed. \n");
00670       return;
00671    }
00672 
00673    /* we have a packet address, so tell the card to use it */
00674    _outb(packet_no, nic->ioaddr + PNR_ARR);
00675 
00676    /* point to the beginning of the packet */
00677    _outw(PTR_AUTOINC, nic->ioaddr + POINTER);
00678 
00679 #if     SMC9000_DEBUG > 2
00680    printf("Trying to xmit packet of length %hX\n", length );
00681 #endif
00682 
00683    /* send the packet length ( +6 for status, length and ctl byte )
00684     * and the status word ( set to zeros ) */
00685    _outw(0, nic->ioaddr + DATA_1 );
00686 
00687    /* send the packet length ( +6 for status words, length, and ctl) */
00688    _outb((length+6) & 0xFF,  nic->ioaddr + DATA_1);
00689    _outb((length+6) >> 8 ,   nic->ioaddr + DATA_1);
00690 
00691    /* Write the contents of the packet */
00692 
00693    /* The ethernet header first... */
00694    outsw(nic->ioaddr + DATA_1, d, ETH_ALEN >> 1);
00695    outsw(nic->ioaddr + DATA_1, nic->node_addr, ETH_ALEN >> 1);
00696    _outw(htons(t), nic->ioaddr + DATA_1);
00697 
00698    /* ... the data ... */
00699    outsw(nic->ioaddr + DATA_1 , p, s >> 1);
00700 
00701    /* ... and the last byte, if there is one.   */
00702    if ((s & 1) == 0) {
00703       _outw(0, nic->ioaddr + DATA_1);
00704    } else {
00705       _outb(p[s-1], nic->ioaddr + DATA_1);
00706       _outb(0x20, nic->ioaddr + DATA_1);
00707    }
00708 
00709    /* and let the chipset deal with it */
00710    _outw(MC_ENQUEUE , nic->ioaddr + MMU_CMD);
00711 
00712    status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
00713    do {
00714       status = inb(nic->ioaddr + INTERRUPT);
00715 
00716       if ((status & IM_TX_INT ) != 0) {
00717          word tx_status;
00718 
00719          /* ack interrupt */
00720          _outb(IM_TX_INT, nic->ioaddr + INTERRUPT);
00721 
00722          packet_no = inw(nic->ioaddr + FIFO_PORTS);
00723          packet_no &= 0x7F;
00724 
00725          /* select this as the packet to read from */
00726          _outb( packet_no, nic->ioaddr + PNR_ARR );
00727 
00728          /* read the first word from this packet */
00729          _outw( PTR_AUTOINC | PTR_READ, nic->ioaddr + POINTER );
00730 
00731          tx_status = inw( nic->ioaddr + DATA_1 );
00732 
00733          if (0 == (tx_status & TS_SUCCESS)) {
00734             DBG("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
00735             /* re-enable transmit */
00736             SMC_SELECT_BANK(nic->ioaddr, 0);
00737             _outw(inw(nic->ioaddr + TCR ) | TCR_ENABLE, nic->ioaddr + TCR );
00738          }
00739 
00740          /* kill the packet */
00741          SMC_SELECT_BANK(nic->ioaddr, 2);
00742          _outw(MC_FREEPKT, nic->ioaddr + MMU_CMD);
00743 
00744          return;
00745       }
00746    }while(currticks() < time_out);
00747 
00748    printf("SMC9000: TX timed out, resetting board\n");
00749    smc_reset(nic->ioaddr);
00750    return;
00751 }
00752 
00753 /**************************************************************************
00754  * ETH_POLL - Wait for a frame
00755  ***************************************************************************/
00756 static int smc9000_poll(struct nic *nic, int retrieve)
00757 {
00758    SMC_SELECT_BANK(nic->ioaddr, 2);
00759    if (inw(nic->ioaddr + FIFO_PORTS) & FP_RXEMPTY)
00760      return 0;
00761    
00762    if ( ! retrieve ) return 1;
00763 
00764    /*  start reading from the start of the packet */
00765    _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, nic->ioaddr + POINTER);
00766 
00767    /* First read the status and check that we're ok */
00768    if (!(inw(nic->ioaddr + DATA_1) & RS_ERRORS)) {
00769       /* Next: read the packet length and mask off the top bits */
00770       nic->packetlen = (inw(nic->ioaddr + DATA_1) & 0x07ff);
00771 
00772       /* the packet length includes the 3 extra words */
00773       nic->packetlen -= 6;
00774 #if     SMC9000_DEBUG > 2
00775       printf(" Reading %d words (and %d byte(s))\n",
00776                (nic->packetlen >> 1), nic->packetlen & 1);
00777 #endif
00778       /* read the packet (and the last "extra" word) */
00779       insw(nic->ioaddr + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
00780       /* is there an odd last byte ? */
00781       if (nic->packet[nic->packetlen+1] & 0x20)
00782          nic->packetlen++;
00783 
00784       /*  error or good, tell the card to get rid of this packet */
00785       _outw(MC_RELEASE, nic->ioaddr + MMU_CMD);
00786       return 1;
00787    }
00788 
00789    printf("SMC9000: RX error\n");
00790    /*  error or good, tell the card to get rid of this packet */
00791    _outw(MC_RELEASE, nic->ioaddr + MMU_CMD);
00792    return 0;
00793 }
00794 
00795 static void smc9000_disable ( struct nic *nic, struct isa_device *isa __unused ) {
00796 
00797    smc_reset(nic->ioaddr);
00798 
00799    /* no more interrupts for me */
00800    SMC_SELECT_BANK(nic->ioaddr, 2);
00801    _outb( 0, nic->ioaddr + INT_MASK);
00802 
00803    /* and tell the card to stay away from that nasty outside world */
00804    SMC_SELECT_BANK(nic->ioaddr, 0);
00805    _outb( RCR_CLEAR, nic->ioaddr + RCR );
00806    _outb( TCR_CLEAR, nic->ioaddr + TCR );
00807 }
00808 
00809 static void smc9000_irq(struct nic *nic __unused, irq_action_t action __unused)
00810 {
00811   switch ( action ) {
00812   case DISABLE :
00813     break;
00814   case ENABLE :
00815     break;
00816   case FORCE :
00817     break;
00818   }
00819 }
00820 
00821 static struct nic_operations smc9000_operations = {
00822         .connect        = dummy_connect,
00823         .poll           = smc9000_poll,
00824         .transmit       = smc9000_transmit,
00825         .irq            = smc9000_irq,
00826 
00827 };
00828 
00829 /**************************************************************************
00830  * ETH_PROBE - Look for an adapter
00831  ***************************************************************************/
00832 
00833 static int smc9000_probe ( struct nic *nic, struct isa_device *isa ) {
00834 
00835    unsigned short   revision;
00836    int              memory;
00837    int              media;
00838    const char *     version_string;
00839    const char *     if_string;
00840    int              i;
00841 
00842    nic->irqno  = 0;
00843    nic->ioaddr = isa->ioaddr;
00844 
00845    /*
00846     * Get the MAC address ( bank 1, regs 4 - 9 )
00847     */
00848    SMC_SELECT_BANK(nic->ioaddr, 1);
00849    for ( i = 0; i < 6; i += 2 ) {
00850       word address;
00851 
00852       address = inw(nic->ioaddr + ADDR0 + i);
00853       nic->node_addr[i+1] = address >> 8;
00854       nic->node_addr[i] = address & 0xFF;
00855    }
00856 
00857    /* get the memory information */
00858    SMC_SELECT_BANK(nic->ioaddr, 0);
00859    memory = ( inw(nic->ioaddr + MCR) >> 9 )  & 0x7;  /* multiplier */
00860    memory *= 256 * (inw(nic->ioaddr + MIR) & 0xFF);
00861 
00862    /*
00863     * Now, I want to find out more about the chip.  This is sort of
00864     * redundant, but it's cleaner to have it in both, rather than having
00865     * one VERY long probe procedure.
00866     */
00867    SMC_SELECT_BANK(nic->ioaddr, 3);
00868    revision  = inw(nic->ioaddr + REVISION);
00869    version_string = chip_ids[(revision >> 4) & 0xF];
00870 
00871    if (((revision & 0xF0) >> 4 == CHIP_9196) &&
00872        ((revision & 0x0F) >= REV_9196)) {
00873       /* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
00874        * a revision starting at 6 */
00875       version_string = smc91c96_id;
00876    }
00877 
00878    if ( !version_string ) {
00879       /* I shouldn't get here because this call was done before.... */
00880       return 0;
00881    }
00882 
00883    /* is it using AUI or 10BaseT ? */
00884    SMC_SELECT_BANK(nic->ioaddr, 1);
00885    if (inw(nic->ioaddr + CFG) & CFG_AUI_SELECT)
00886      media = 2;
00887    else
00888      media = 1;
00889 
00890    if_string = interfaces[media - 1];
00891 
00892    /* now, reset the chip, and put it into a known state */
00893    smc_reset(nic->ioaddr);
00894 
00895    printf("SMC9000 %s\n", smc9000_version);
00896    DBG("Copyright (C) 1998 Daniel Engstr\x94m\n");
00897    DBG("Copyright (C) 1996 Eric Stahlman\n");
00898 
00899    printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
00900           version_string, revision & 0xF,
00901           nic->ioaddr, if_string, memory );
00902 
00903    DBG ( "Ethernet MAC address: %s\n", eth_ntoa ( nic->node_addr ) );
00904 
00905    SMC_SELECT_BANK(nic->ioaddr, 0);
00906 
00907    /* see the header file for options in TCR/RCR NORMAL*/
00908    _outw(TCR_NORMAL, nic->ioaddr + TCR);
00909    _outw(RCR_NORMAL, nic->ioaddr + RCR);
00910 
00911    /* Select which interface to use */
00912    SMC_SELECT_BANK(nic->ioaddr, 1);
00913    if ( media == 1 ) {
00914       _outw( inw( nic->ioaddr + CFG ) & ~CFG_AUI_SELECT,
00915            nic->ioaddr + CFG );
00916    }
00917    else if ( media == 2 ) {
00918       _outw( inw( nic->ioaddr + CFG ) | CFG_AUI_SELECT,
00919            nic->ioaddr + CFG );
00920    }
00921 
00922    smc_phy_configure(nic->ioaddr);
00923  
00924    nic->nic_op  = &smc9000_operations;
00925    return 1;
00926 }
00927 
00928 /*
00929  * The SMC9000 can be at any of the following port addresses.  To
00930  * change for a slightly different card, you can add it to the array.
00931  *
00932  */
00933 static isa_probe_addr_t smc9000_probe_addrs[] = {
00934    0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
00935    0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
00936 };
00937 
00938 ISA_DRIVER ( smc9000_driver, smc9000_probe_addrs, smc9000_probe_addr,
00939                      GENERIC_ISAPNP_VENDOR, 0x8228 );
00940 
00941 DRIVER ( "SMC9000", nic_driver, isa_driver, smc9000_driver,
00942          smc9000_probe, smc9000_disable );
00943 
00944 ISA_ROM ( "smc9000", "SMC9000" );
00945 
00946 /*
00947  * Local variables:
00948  *  c-basic-offset: 8
00949  *  c-indent-level: 8
00950  *  tab-width: 8
00951  * End:
00952  */