iPXE
3c90x.h
Go to the documentation of this file.
00001 /*
00002  * 3c90x.c -- This file implements the 3c90x driver for etherboot.  Written
00003  * by Greg Beeley, Greg.Beeley@LightSys.org.  Modified by Steve Smith,
00004  * Steve.Smith@Juno.Com. Alignment bug fix Neil Newell (nn@icenoir.net).
00005  *
00006  * Port from etherboot to iPXE API, implementation of tx/rx ring support
00007  * by Thomas Miletich, thomas.miletich@gmail.com
00008  * Thanks to Marty Connor and Stefan Hajnoczi for their help and feedback.
00009  *
00010  * This program Copyright (C) 1999 LightSys Technology Services, Inc.
00011  * Portions Copyright (C) 1999 Steve Smith
00012  *
00013  * This program may be re-distributed in source or binary form, modified,
00014  * sold, or copied for any purpose, provided that the above copyright message
00015  * and this text are included with all source copies or derivative works, and
00016  * provided that the above copyright message and this text are included in the
00017  * documentation of any binary-only distributions.  This program is distributed
00018  * WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR
00019  * PURPOSE or MERCHANTABILITY.  Please read the associated documentation
00020  * "3c90x.txt" before compiling and using this driver.
00021  *
00022  * --------
00023  *
00024  * Program written with the assistance of the 3com documentation for
00025  * the 3c905B-TX card, as well as with some assistance from the 3c59x
00026  * driver Donald Becker wrote for the Linux kernel, and with some assistance
00027  * from the remainder of the Etherboot distribution.
00028  *
00029  * REVISION HISTORY:
00030  *
00031  * v0.10        1-26-1998       GRB     Initial implementation.
00032  * v0.90        1-27-1998       GRB     System works.
00033  * v1.00pre1    2-11-1998       GRB     Got prom boot issue fixed.
00034  * v2.0         9-24-1999       SCS     Modified for 3c905 (from 3c905b code)
00035  *                                      Re-wrote poll and transmit for
00036  *                                      better error recovery and heavy
00037  *                                      network traffic operation
00038  * v2.01    5-26-2003 NN Fixed driver alignment issue which
00039  *                  caused system lockups if driver structures
00040  *                  not 8-byte aligned.
00041  * v2.02   11-28-2007 GSt Got polling working again by replacing
00042  *                      "for(i=0;i<40000;i++);" with "mdelay(1);"
00043  *
00044  *
00045  * indent options: indent -kr -i8 3c90x.c
00046  */
00047 
00048 FILE_LICENCE ( BSD2 );
00049 
00050 #ifndef __3C90X_H_
00051 #define __3C90X_H_
00052 
00053 static struct net_device_operations a3c90x_operations;
00054 
00055 #define XCVR_MAGIC      (0x5A00)
00056 
00057 /* Register definitions for the 3c905 */
00058 enum Registers {
00059         regPowerMgmtCtrl_w = 0x7c,      /* 905B Revision Only                 */
00060         regUpMaxBurst_w = 0x7a, /* 905B Revision Only                 */
00061         regDnMaxBurst_w = 0x78, /* 905B Revision Only                 */
00062         regDebugControl_w = 0x74,       /* 905B Revision Only                 */
00063         regDebugData_l = 0x70,  /* 905B Revision Only                 */
00064         regRealTimeCnt_l = 0x40,        /* Universal                          */
00065         regUpBurstThresh_b = 0x3e,      /* 905B Revision Only                 */
00066         regUpPoll_b = 0x3d,     /* 905B Revision Only                 */
00067         regUpPriorityThresh_b = 0x3c,   /* 905B Revision Only                 */
00068         regUpListPtr_l = 0x38,  /* Universal                          */
00069         regCountdown_w = 0x36,  /* Universal                          */
00070         regFreeTimer_w = 0x34,  /* Universal                          */
00071         regUpPktStatus_l = 0x30,        /* Universal with Exception, pg 130   */
00072         regTxFreeThresh_b = 0x2f,       /* 90X Revision Only                  */
00073         regDnPoll_b = 0x2d,     /* 905B Revision Only                 */
00074         regDnPriorityThresh_b = 0x2c,   /* 905B Revision Only                 */
00075         regDnBurstThresh_b = 0x2a,      /* 905B Revision Only                 */
00076         regDnListPtr_l = 0x24,  /* Universal with Exception, pg 107   */
00077         regDmaCtrl_l = 0x20,    /* Universal with Exception, pg 106   */
00078         /*                                    */
00079         regIntStatusAuto_w = 0x1e,      /* 905B Revision Only                 */
00080         regTxStatus_b = 0x1b,   /* Universal with Exception, pg 113   */
00081         regTimer_b = 0x1a,      /* Universal                          */
00082         regTxPktId_b = 0x18,    /* 905B Revision Only                 */
00083         regCommandIntStatus_w = 0x0e,   /* Universal (Command Variations)     */
00084 };
00085 
00086 /* following are windowed registers */
00087 enum Registers7 {
00088         regPowerMgmtEvent_7_w = 0x0c,   /* 905B Revision Only                 */
00089         regVlanEtherType_7_w = 0x04,    /* 905B Revision Only                 */
00090         regVlanMask_7_w = 0x00, /* 905B Revision Only                 */
00091 };
00092 
00093 enum Registers6 {
00094         regBytesXmittedOk_6_w = 0x0c,   /* Universal                          */
00095         regBytesRcvdOk_6_w = 0x0a,      /* Universal                          */
00096         regUpperFramesOk_6_b = 0x09,    /* Universal                          */
00097         regFramesDeferred_6_b = 0x08,   /* Universal                          */
00098         regFramesRecdOk_6_b = 0x07,     /* Universal with Exceptions, pg 142  */
00099         regFramesXmittedOk_6_b = 0x06,  /* Universal                          */
00100         regRxOverruns_6_b = 0x05,       /* Universal                          */
00101         regLateCollisions_6_b = 0x04,   /* Universal                          */
00102         regSingleCollisions_6_b = 0x03, /* Universal                          */
00103         regMultipleCollisions_6_b = 0x02,       /* Universal                          */
00104         regSqeErrors_6_b = 0x01,        /* Universal                          */
00105         regCarrierLost_6_b = 0x00,      /* Universal                          */
00106 };
00107 
00108 enum Registers5 {
00109         regIndicationEnable_5_w = 0x0c, /* Universal                          */
00110         regInterruptEnable_5_w = 0x0a,  /* Universal                          */
00111         regTxReclaimThresh_5_b = 0x09,  /* 905B Revision Only                 */
00112         regRxFilter_5_b = 0x08, /* Universal                          */
00113         regRxEarlyThresh_5_w = 0x06,    /* Universal                          */
00114         regTxStartThresh_5_w = 0x00,    /* Universal                          */
00115 };
00116 
00117 enum Registers4 {
00118         regUpperBytesOk_4_b = 0x0d,     /* Universal                          */
00119         regBadSSD_4_b = 0x0c,   /* Universal                          */
00120         regMediaStatus_4_w = 0x0a,      /* Universal with Exceptions, pg 201  */
00121         regPhysicalMgmt_4_w = 0x08,     /* Universal                          */
00122         regNetworkDiagnostic_4_w = 0x06,        /* Universal with Exceptions, pg 203  */
00123         regFifoDiagnostic_4_w = 0x04,   /* Universal with Exceptions, pg 196  */
00124         regVcoDiagnostic_4_w = 0x02,    /* Undocumented?                      */
00125 };
00126 
00127 enum Registers3 {
00128         regTxFree_3_w = 0x0c,   /* Universal                          */
00129         regRxFree_3_w = 0x0a,   /* Universal with Exceptions, pg 125  */
00130         regResetMediaOptions_3_w = 0x08,        /* Media Options on B Revision,       */
00131         /* Reset Options on Non-B Revision    */
00132         regMacControl_3_w = 0x06,       /* Universal with Exceptions, pg 199  */
00133         regMaxPktSize_3_w = 0x04,       /* 905B Revision Only                 */
00134         regInternalConfig_3_l = 0x00,   /* Universal, different bit           */
00135         /* definitions, pg 59                 */
00136 };
00137 
00138 enum Registers2 {
00139         regResetOptions_2_w = 0x0c,     /* 905B Revision Only                 */
00140         regStationMask_2_3w = 0x06,     /* Universal with Exceptions, pg 127  */
00141         regStationAddress_2_3w = 0x00,  /* Universal with Exceptions, pg 127  */
00142 };
00143 
00144 enum Registers1 {
00145         regRxStatus_1_w = 0x0a, /* 90X Revision Only, Pg 126          */
00146 };
00147 
00148 enum Registers0 {
00149         regEepromData_0_w = 0x0c,       /* Universal                          */
00150         regEepromCommand_0_w = 0x0a,    /* Universal                          */
00151         regBiosRomData_0_b = 0x08,      /* 905B Revision Only                 */
00152         regBiosRomAddr_0_l = 0x04,      /* 905B Revision Only                 */
00153 };
00154 
00155 
00156 /* The names for the eight register windows */
00157 enum Windows {
00158         winNone = 0xff,
00159         winPowerVlan7 = 0x07,
00160         winStatistics6 = 0x06,
00161         winTxRxControl5 = 0x05,
00162         winDiagnostics4 = 0x04,
00163         winTxRxOptions3 = 0x03,
00164         winAddressing2 = 0x02,
00165         winUnused1 = 0x01,
00166         winEepromBios0 = 0x00,
00167 };
00168 
00169 
00170 /* Command definitions for the 3c90X */
00171 enum Commands {
00172         cmdGlobalReset = 0x00,  /* Universal with Exceptions, pg 151 */
00173         cmdSelectRegisterWindow = 0x01, /* Universal                         */
00174         cmdEnableDcConverter = 0x02,    /*                                   */
00175         cmdRxDisable = 0x03,    /*                                   */
00176         cmdRxEnable = 0x04,     /* Universal                         */
00177         cmdRxReset = 0x05,      /* Universal                         */
00178         cmdStallCtl = 0x06,     /* Universal                         */
00179         cmdTxEnable = 0x09,     /* Universal                         */
00180         cmdTxDisable = 0x0A,    /*                                   */
00181         cmdTxReset = 0x0B,      /* Universal                         */
00182         cmdRequestInterrupt = 0x0C,     /*                                   */
00183         cmdAcknowledgeInterrupt = 0x0D, /* Universal                         */
00184         cmdSetInterruptEnable = 0x0E,   /* Universal                         */
00185         cmdSetIndicationEnable = 0x0F,  /* Universal                         */
00186         cmdSetRxFilter = 0x10,  /* Universal                         */
00187         cmdSetRxEarlyThresh = 0x11,     /*                                   */
00188         cmdSetTxStartThresh = 0x13,     /*                                   */
00189         cmdStatisticsEnable = 0x15,     /*                                   */
00190         cmdStatisticsDisable = 0x16,    /*                                   */
00191         cmdDisableDcConverter = 0x17,   /*                                   */
00192         cmdSetTxReclaimThresh = 0x18,   /*                                   */
00193         cmdSetHashFilterBit = 0x19,     /*                                   */
00194 };
00195 
00196 enum GlobalResetParams {
00197         globalResetAll = 0,
00198         globalResetMaskNetwork = (1<<2),
00199         globalResetMaskAll = 0x1ff,
00200 };
00201 
00202 enum FrameStartHeader {
00203         fshTxIndicate = 0x8000,
00204         fshDnComplete = 0x10000,
00205         fshRndupDefeat = 0x10000000,
00206 };
00207 
00208 enum UpDownDesc {
00209         upLastFrag = (1 << 31),
00210         downLastFrag = (1 << 31),
00211 };
00212 
00213 enum UpPktStatus {
00214         upComplete = (1 << 15),
00215         upError = (1 << 14),
00216 };
00217 
00218 enum Stalls {
00219         upStall = 0x00,
00220         upUnStall = 0x01,
00221 
00222         dnStall = 0x02,
00223         dnUnStall = 0x03,
00224 };
00225 
00226 enum Resources {
00227         resRxRing = 0x00,
00228         resTxRing = 0x02,
00229         resRxIOBuf = 0x04
00230 };
00231 
00232 enum eeprom {
00233         eepromBusy = (1 << 15),
00234         eepromRead = ((0x02) << 6),
00235         eepromRead_556 = 0x230,
00236         eepromHwAddrOffset = 0x0a,
00237 };
00238 
00239 /* Bit 4 is only used in revison B and upwards */
00240 enum linktype {
00241         link10BaseT = 0x00,
00242         linkAUI = 0x01,
00243         link10Base2 = 0x03,
00244         link100BaseFX = 0x05,
00245         linkMII = 0x06,
00246         linkAutoneg = 0x08,
00247         linkExternalMII = 0x09,
00248 };
00249 
00250 /* Values for int status register bitmask */
00251 #define INT_INTERRUPTLATCH      (1<<0)
00252 #define INT_HOSTERROR           (1<<1)
00253 #define INT_TXCOMPLETE          (1<<2)
00254 #define INT_RXCOMPLETE          (1<<4)
00255 #define INT_RXEARLY             (1<<5)
00256 #define INT_INTREQUESTED        (1<<6)
00257 #define INT_UPDATESTATS         (1<<7)
00258 #define INT_LINKEVENT           (1<<8)
00259 #define INT_DNCOMPLETE          (1<<9)
00260 #define INT_UPCOMPLETE          (1<<10)
00261 #define INT_CMDINPROGRESS       (1<<12)
00262 #define INT_WINDOWNUMBER        (7<<13)
00263 
00264 /* Buffer sizes */
00265 #define TX_RING_SIZE 8
00266 #define RX_RING_SIZE 8
00267 #define TX_RING_ALIGN 16
00268 #define RX_RING_ALIGN 16
00269 #define RX_BUF_SIZE 1536
00270 
00271 /* Timeouts for eeprom and command completion */
00272 /* Timeout 1 second, to be save */
00273 #define EEPROM_TIMEOUT          1 * 1000 * 1000
00274 
00275 /* TX descriptor */
00276 struct TXD {
00277         volatile unsigned int DnNextPtr;
00278         volatile unsigned int FrameStartHeader;
00279         volatile unsigned int DataAddr;
00280         volatile unsigned int DataLength;
00281 } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
00282 
00283 /* RX descriptor */
00284 struct RXD {
00285         volatile unsigned int UpNextPtr;
00286         volatile unsigned int UpPktStatus;
00287         volatile unsigned int DataAddr;
00288         volatile unsigned int DataLength;
00289 } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
00290 
00291 /* Private NIC dats */
00292 struct INF_3C90X {
00293         unsigned int is3c556;
00294         unsigned char isBrev;
00295         unsigned char CurrentWindow;
00296         unsigned int IOAddr;
00297         unsigned short eeprom[0x21];
00298         unsigned int tx_cur;    /* current entry in tx_ring */
00299         unsigned int tx_cnt;    /* current number of used tx descriptors */
00300         unsigned int tx_tail;   /* entry of last finished packet */
00301         unsigned int rx_cur;
00302         struct TXD *tx_ring;
00303         struct RXD *rx_ring;
00304         struct io_buffer *tx_iobuf[TX_RING_SIZE];
00305         struct io_buffer *rx_iobuf[RX_RING_SIZE];
00306         struct nvs_device nvs;
00307 };
00308 
00309 #endif