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 <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    /* 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 failed = 0;
00361     int rpc_cur_mode = RPC_DEFAULT;
00362     int lastPhy18;
00363 
00364     // Find the address and type of our phy
00365     if (!smc_detect_phy(ioaddr, &phyaddr))
00366     {
00367         return;
00368     }
00369 
00370     // Reset the PHY, setting all other bits to zero
00371     smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
00372 
00373     // Wait for the reset to complete, or time out
00374     timeout = 6; // Wait up to 3 seconds
00375     while (timeout--)
00376     {
00377         if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
00378               & PHY_CNTL_RST))
00379         {
00380             // reset complete
00381             break;
00382         }
00383 
00384         mdelay(500); // wait 500 millisecs
00385     }
00386 
00387     if (timeout < 1)
00388     {
00389         PRINTK2("PHY reset timed out\n");
00390         return;
00391     }
00392 
00393     // Read PHY Register 18, Status Output
00394     lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
00395 
00396     // Enable PHY Interrupts (for register 18)
00397     // Interrupts listed here are disabled
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     /* Configure the Receive/Phy Control register */
00404     SMC_SELECT_BANK(ioaddr, 0);
00405     outw( rpc_cur_mode, ioaddr + RPC_REG );
00406 
00407     // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
00408     my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00409     my_ad_caps  = PHY_AD_CSMA; // I am CSMA capable
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     // Update our Auto-Neg Advertisement Register
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     // Restart auto-negotiation process in order to advertise my caps
00433     smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
00434                             PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
00435 
00436     // Wait for the auto-negotiation to complete.  This may take from
00437     // 2 to 3 seconds.
00438     // Wait for the reset to complete, or time out
00439     timeout = 20; // Wait up to 10 seconds
00440     while (timeout--)
00441     {
00442         status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
00443         if (status & PHY_STAT_ANEG_ACK)
00444         {
00445             // auto-negotiate complete
00446             break;
00447         }
00448 
00449         mdelay(500); // wait 500 millisecs
00450 
00451         // Restart auto-negotiation if remote fault
00452         if (status & PHY_STAT_REM_FLT)
00453         {
00454             PRINTK2("PHY remote fault detected\n");
00455 
00456             // Restart auto-negotiation
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     // Fail if we detected an auto-negotiate remote fault
00471     if (status & PHY_STAT_REM_FLT)
00472     {
00473         PRINTK2("PHY remote fault detected\n");
00474         failed = 1;
00475     }
00476 
00477     // Set our sysctl parameters to match auto-negotiation results
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     // Re-Configure the Receive/Phy Control register
00501     outw( rpc_cur_mode, ioaddr + RPC_REG );
00502 }
00503 
00504 /*
00505  * Function: smc_reset( int ioaddr )
00506  * Purpose:
00507  *      This sets the SMC91xx chip to its normal state, hopefully from whatever
00508  *      mess that any other DOS driver has put it in.
00509  *
00510  * Maybe I should reset more registers to defaults in here?  SOFTRESET  should
00511  * do that for me.
00512  *
00513  * Method:
00514  *      1.  send a SOFT RESET
00515  *      2.  wait for it to finish
00516  *      3.  reset the memory management unit
00517  *      4.  clear all interrupts
00518  *
00519 */
00520 static void smc_reset(int ioaddr)
00521 {
00522    /* This resets the registers mostly to defaults, but doesn't
00523     * affect EEPROM.  That seems unnecessary */
00524    SMC_SELECT_BANK(ioaddr, 0);
00525    _outw( RCR_SOFTRESET, ioaddr + RCR );
00526 
00527    /* this should pause enough for the chip to be happy */
00528    SMC_DELAY(ioaddr);
00529 
00530    /* Set the transmit and receive configuration registers to
00531     * default values */
00532    _outw(RCR_CLEAR, ioaddr + RCR);
00533    _outw(TCR_CLEAR, ioaddr + TCR);
00534 
00535    /* Reset the MMU */
00536    SMC_SELECT_BANK(ioaddr, 2);
00537    _outw( MC_RESET, ioaddr + MMU_CMD );
00538 
00539    /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
00540     * but this is a place where future chipsets _COULD_ break.  Be wary
00541     * of issuing another MMU command right after this */
00542    _outb(0, ioaddr + INT_MASK);
00543 }
00544 
00545 
00546 /*----------------------------------------------------------------------
00547  * Function: smc9000_probe_addr( int ioaddr )
00548  *
00549  * Purpose:
00550  *      Tests to see if a given ioaddr points to an SMC9xxx chip.
00551  *      Returns a 1 on success
00552  *
00553  * Algorithm:
00554  *      (1) see if the high byte of BANK_SELECT is 0x33
00555  *      (2) compare the ioaddr with the base register's address
00556  *      (3) see if I recognize the chip ID in the appropriate register
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    /* First, see if the high byte is 0x33 */
00567    bank = inw(ioaddr + BANK_SELECT);
00568    if ((bank & 0xFF00) != 0x3300) {
00569       return 0;
00570    }
00571    /* The above MIGHT indicate a device, but I need to write to further
00572     *   test this.  */
00573    _outw(0x0, ioaddr + BANK_SELECT);
00574    bank = inw(ioaddr + BANK_SELECT);
00575    if ((bank & 0xFF00) != 0x3300) {
00576       return 0;
00577    }
00578 
00579    /* well, we've already written once, so hopefully another time won't
00580     *  hurt.  This time, I need to switch the bank register to bank 1,
00581     *  so I can access the base address register */
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       /* well, the base address register didn't match.  Must not have
00590        * been a SMC chip after all. */
00591       return 0;
00592    }
00593 
00594 
00595    /* check if the revision register is something that I recognize.
00596     * These might need to be added to later, as future revisions
00597     * could be added.  */
00598    SMC_SELECT_BANK(ioaddr, 3);
00599    revision_register  = inw(ioaddr + REVISION);
00600    if (!chip_ids[(revision_register >> 4) & 0xF]) {
00601       /* I don't recognize this chip, so... */
00602       DBG( "SMC9000: IO %hX: Unrecognized revision register:"
00603            " %hX, Contact author.\n", ioaddr, revision_register );
00604       return 0;
00605    }
00606 
00607    /* at this point I'll assume that the chip is an SMC9xxx.
00608     * It might be prudent to check a listing of MAC addresses
00609     * against the hardware address, or do some other tests. */
00610    return 1;
00611 }
00612 
00613 
00614 /**************************************************************************
00615  * ETH_TRANSMIT - Transmit a frame
00616  ***************************************************************************/
00617 static void smc9000_transmit(
00618         struct nic *nic,
00619         const char *d,                  /* Destination */
00620         unsigned int t,                 /* Type */
00621         unsigned int s,                 /* size */
00622         const char *p)                  /* Packet */
00623 {
00624    word length; /* real, length incl. header */
00625    word numPages;
00626    unsigned long time_out;
00627    byte packet_no;
00628    word status;
00629    int i;
00630 
00631    /* We dont pad here since we can have the hardware doing it for us */
00632    length = (s + ETH_HLEN + 1)&~1;
00633 
00634    /* convert to MMU pages */
00635    numPages = length / 256;
00636 
00637    if (numPages > 7 ) {
00638       DBG("SMC9000: Far too big packet error. \n");
00639       return;
00640    }
00641 
00642    /* dont try more than, say 30 times */
00643    for (i=0;i<30;i++) {
00644       /* now, try to allocate the memory */
00645       SMC_SELECT_BANK(nic->ioaddr, 2);
00646       _outw(MC_ALLOC | numPages, nic->ioaddr + MMU_CMD);
00647 
00648       status = 0;
00649       /* wait for the memory allocation to finnish */
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             /* acknowledge the interrupt */
00654             _outb(IM_ALLOC_INT, nic->ioaddr + INTERRUPT);
00655             break;
00656          }
00657       }
00658 
00659       if ((status & IM_ALLOC_INT) != 0 ) {
00660          /* We've got the memory */
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    /* If I get here, I _know_ there is a packet slot waiting for me */
00669    packet_no = inb(nic->ioaddr + PNR_ARR + 1);
00670    if (packet_no & 0x80) {
00671       /* or isn't there?  BAD CHIP! */
00672       printf("SMC9000: Memory allocation failed. \n");
00673       return;
00674    }
00675 
00676    /* we have a packet address, so tell the card to use it */
00677    _outb(packet_no, nic->ioaddr + PNR_ARR);
00678 
00679    /* point to the beginning of the packet */
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    /* send the packet length ( +6 for status, length and ctl byte )
00687     * and the status word ( set to zeros ) */
00688    _outw(0, nic->ioaddr + DATA_1 );
00689 
00690    /* send the packet length ( +6 for status words, length, and ctl) */
00691    _outb((length+6) & 0xFF,  nic->ioaddr + DATA_1);
00692    _outb((length+6) >> 8 ,   nic->ioaddr + DATA_1);
00693 
00694    /* Write the contents of the packet */
00695 
00696    /* The ethernet header first... */
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    /* ... the data ... */
00702    outsw(nic->ioaddr + DATA_1 , p, s >> 1);
00703 
00704    /* ... and the last byte, if there is one.   */
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    /* and let the chipset deal with it */
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          /* ack interrupt */
00723          _outb(IM_TX_INT, nic->ioaddr + INTERRUPT);
00724 
00725          packet_no = inw(nic->ioaddr + FIFO_PORTS);
00726          packet_no &= 0x7F;
00727 
00728          /* select this as the packet to read from */
00729          _outb( packet_no, nic->ioaddr + PNR_ARR );
00730 
00731          /* read the first word from this packet */
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             /* re-enable transmit */
00739             SMC_SELECT_BANK(nic->ioaddr, 0);
00740             _outw(inw(nic->ioaddr + TCR ) | TCR_ENABLE, nic->ioaddr + TCR );
00741          }
00742 
00743          /* kill the packet */
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  * ETH_POLL - Wait for a frame
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    /*  start reading from the start of the packet */
00768    _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, nic->ioaddr + POINTER);
00769 
00770    /* First read the status and check that we're ok */
00771    if (!(inw(nic->ioaddr + DATA_1) & RS_ERRORS)) {
00772       /* Next: read the packet length and mask off the top bits */
00773       nic->packetlen = (inw(nic->ioaddr + DATA_1) & 0x07ff);
00774 
00775       /* the packet length includes the 3 extra words */
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       /* read the packet (and the last "extra" word) */
00782       insw(nic->ioaddr + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
00783       /* is there an odd last byte ? */
00784       if (nic->packet[nic->packetlen+1] & 0x20)
00785          nic->packetlen++;
00786 
00787       /*  error or good, tell the card to get rid of this packet */
00788       _outw(MC_RELEASE, nic->ioaddr + MMU_CMD);
00789       return 1;
00790    }
00791 
00792    printf("SMC9000: RX error\n");
00793    /*  error or good, tell the card to get rid of this packet */
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    /* no more interrupts for me */
00803    SMC_SELECT_BANK(nic->ioaddr, 2);
00804    _outb( 0, nic->ioaddr + INT_MASK);
00805 
00806    /* and tell the card to stay away from that nasty outside world */
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  * ETH_PROBE - Look for an adapter
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     * Get the MAC address ( bank 1, regs 4 - 9 )
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    /* get the memory information */
00861    SMC_SELECT_BANK(nic->ioaddr, 0);
00862    memory = ( inw(nic->ioaddr + MCR) >> 9 )  & 0x7;  /* multiplier */
00863    memory *= 256 * (inw(nic->ioaddr + MIR) & 0xFF);
00864 
00865    /*
00866     * Now, I want to find out more about the chip.  This is sort of
00867     * redundant, but it's cleaner to have it in both, rather than having
00868     * one VERY long probe procedure.
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       /* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
00877        * a revision starting at 6 */
00878       version_string = smc91c96_id;
00879    }
00880 
00881    if ( !version_string ) {
00882       /* I shouldn't get here because this call was done before.... */
00883       return 0;
00884    }
00885 
00886    /* is it using AUI or 10BaseT ? */
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    /* now, reset the chip, and put it into a known state */
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    /* see the header file for options in TCR/RCR NORMAL*/
00911    _outw(TCR_NORMAL, nic->ioaddr + TCR);
00912    _outw(RCR_NORMAL, nic->ioaddr + RCR);
00913 
00914    /* Select which interface to use */
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  * The SMC9000 can be at any of the following port addresses.  To
00933  * change for a slightly different card, you can add it to the array.
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  * Local variables:
00951  *  c-basic-offset: 8
00952  *  c-indent-level: 8
00953  *  tab-width: 8
00954  * End:
00955  */

Generated on Tue Apr 6 20:01:04 2010 for gPXE by  doxygen 1.5.7.1