|
|
1.1 ! root 1: /* ! 2: * 3c90x.c -- This file implements the 3c90x driver for etherboot. Written ! 3: * by Greg Beeley, [email protected]. Modified by Steve Smith, ! 4: * [email protected]. Alignment bug fix Neil Newell ([email protected]). ! 5: * ! 6: * Port from etherboot to iPXE API, implementation of tx/rx ring support ! 7: * by Thomas Miletich, [email protected] ! 8: * Thanks to Marty Connor and Stefan Hajnoczi for their help and feedback. ! 9: * ! 10: * This program Copyright (C) 1999 LightSys Technology Services, Inc. ! 11: * Portions Copyright (C) 1999 Steve Smith ! 12: * ! 13: * This program may be re-distributed in source or binary form, modified, ! 14: * sold, or copied for any purpose, provided that the above copyright message ! 15: * and this text are included with all source copies or derivative works, and ! 16: * provided that the above copyright message and this text are included in the ! 17: * documentation of any binary-only distributions. This program is distributed ! 18: * WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR ! 19: * PURPOSE or MERCHANTABILITY. Please read the associated documentation ! 20: * "3c90x.txt" before compiling and using this driver. ! 21: * ! 22: * -------- ! 23: * ! 24: * Program written with the assistance of the 3com documentation for ! 25: * the 3c905B-TX card, as well as with some assistance from the 3c59x ! 26: * driver Donald Becker wrote for the Linux kernel, and with some assistance ! 27: * from the remainder of the Etherboot distribution. ! 28: * ! 29: * REVISION HISTORY: ! 30: * ! 31: * v0.10 1-26-1998 GRB Initial implementation. ! 32: * v0.90 1-27-1998 GRB System works. ! 33: * v1.00pre1 2-11-1998 GRB Got prom boot issue fixed. ! 34: * v2.0 9-24-1999 SCS Modified for 3c905 (from 3c905b code) ! 35: * Re-wrote poll and transmit for ! 36: * better error recovery and heavy ! 37: * network traffic operation ! 38: * v2.01 5-26-2003 NN Fixed driver alignment issue which ! 39: * caused system lockups if driver structures ! 40: * not 8-byte aligned. ! 41: * v2.02 11-28-2007 GSt Got polling working again by replacing ! 42: * "for(i=0;i<40000;i++);" with "mdelay(1);" ! 43: * ! 44: * ! 45: * indent options: indent -kr -i8 3c90x.c ! 46: */ ! 47: ! 48: FILE_LICENCE ( BSD2 ); ! 49: ! 50: #ifndef __3C90X_H_ ! 51: #define __3C90X_H_ ! 52: ! 53: static struct net_device_operations a3c90x_operations; ! 54: ! 55: #define XCVR_MAGIC (0x5A00) ! 56: ! 57: /* Register definitions for the 3c905 */ ! 58: enum Registers { ! 59: regPowerMgmtCtrl_w = 0x7c, /* 905B Revision Only */ ! 60: regUpMaxBurst_w = 0x7a, /* 905B Revision Only */ ! 61: regDnMaxBurst_w = 0x78, /* 905B Revision Only */ ! 62: regDebugControl_w = 0x74, /* 905B Revision Only */ ! 63: regDebugData_l = 0x70, /* 905B Revision Only */ ! 64: regRealTimeCnt_l = 0x40, /* Universal */ ! 65: regUpBurstThresh_b = 0x3e, /* 905B Revision Only */ ! 66: regUpPoll_b = 0x3d, /* 905B Revision Only */ ! 67: regUpPriorityThresh_b = 0x3c, /* 905B Revision Only */ ! 68: regUpListPtr_l = 0x38, /* Universal */ ! 69: regCountdown_w = 0x36, /* Universal */ ! 70: regFreeTimer_w = 0x34, /* Universal */ ! 71: regUpPktStatus_l = 0x30, /* Universal with Exception, pg 130 */ ! 72: regTxFreeThresh_b = 0x2f, /* 90X Revision Only */ ! 73: regDnPoll_b = 0x2d, /* 905B Revision Only */ ! 74: regDnPriorityThresh_b = 0x2c, /* 905B Revision Only */ ! 75: regDnBurstThresh_b = 0x2a, /* 905B Revision Only */ ! 76: regDnListPtr_l = 0x24, /* Universal with Exception, pg 107 */ ! 77: regDmaCtrl_l = 0x20, /* Universal with Exception, pg 106 */ ! 78: /* */ ! 79: regIntStatusAuto_w = 0x1e, /* 905B Revision Only */ ! 80: regTxStatus_b = 0x1b, /* Universal with Exception, pg 113 */ ! 81: regTimer_b = 0x1a, /* Universal */ ! 82: regTxPktId_b = 0x18, /* 905B Revision Only */ ! 83: regCommandIntStatus_w = 0x0e, /* Universal (Command Variations) */ ! 84: }; ! 85: ! 86: /* following are windowed registers */ ! 87: enum Registers7 { ! 88: regPowerMgmtEvent_7_w = 0x0c, /* 905B Revision Only */ ! 89: regVlanEtherType_7_w = 0x04, /* 905B Revision Only */ ! 90: regVlanMask_7_w = 0x00, /* 905B Revision Only */ ! 91: }; ! 92: ! 93: enum Registers6 { ! 94: regBytesXmittedOk_6_w = 0x0c, /* Universal */ ! 95: regBytesRcvdOk_6_w = 0x0a, /* Universal */ ! 96: regUpperFramesOk_6_b = 0x09, /* Universal */ ! 97: regFramesDeferred_6_b = 0x08, /* Universal */ ! 98: regFramesRecdOk_6_b = 0x07, /* Universal with Exceptions, pg 142 */ ! 99: regFramesXmittedOk_6_b = 0x06, /* Universal */ ! 100: regRxOverruns_6_b = 0x05, /* Universal */ ! 101: regLateCollisions_6_b = 0x04, /* Universal */ ! 102: regSingleCollisions_6_b = 0x03, /* Universal */ ! 103: regMultipleCollisions_6_b = 0x02, /* Universal */ ! 104: regSqeErrors_6_b = 0x01, /* Universal */ ! 105: regCarrierLost_6_b = 0x00, /* Universal */ ! 106: }; ! 107: ! 108: enum Registers5 { ! 109: regIndicationEnable_5_w = 0x0c, /* Universal */ ! 110: regInterruptEnable_5_w = 0x0a, /* Universal */ ! 111: regTxReclaimThresh_5_b = 0x09, /* 905B Revision Only */ ! 112: regRxFilter_5_b = 0x08, /* Universal */ ! 113: regRxEarlyThresh_5_w = 0x06, /* Universal */ ! 114: regTxStartThresh_5_w = 0x00, /* Universal */ ! 115: }; ! 116: ! 117: enum Registers4 { ! 118: regUpperBytesOk_4_b = 0x0d, /* Universal */ ! 119: regBadSSD_4_b = 0x0c, /* Universal */ ! 120: regMediaStatus_4_w = 0x0a, /* Universal with Exceptions, pg 201 */ ! 121: regPhysicalMgmt_4_w = 0x08, /* Universal */ ! 122: regNetworkDiagnostic_4_w = 0x06, /* Universal with Exceptions, pg 203 */ ! 123: regFifoDiagnostic_4_w = 0x04, /* Universal with Exceptions, pg 196 */ ! 124: regVcoDiagnostic_4_w = 0x02, /* Undocumented? */ ! 125: }; ! 126: ! 127: enum Registers3 { ! 128: regTxFree_3_w = 0x0c, /* Universal */ ! 129: regRxFree_3_w = 0x0a, /* Universal with Exceptions, pg 125 */ ! 130: regResetMediaOptions_3_w = 0x08, /* Media Options on B Revision, */ ! 131: /* Reset Options on Non-B Revision */ ! 132: regMacControl_3_w = 0x06, /* Universal with Exceptions, pg 199 */ ! 133: regMaxPktSize_3_w = 0x04, /* 905B Revision Only */ ! 134: regInternalConfig_3_l = 0x00, /* Universal, different bit */ ! 135: /* definitions, pg 59 */ ! 136: }; ! 137: ! 138: enum Registers2 { ! 139: regResetOptions_2_w = 0x0c, /* 905B Revision Only */ ! 140: regStationMask_2_3w = 0x06, /* Universal with Exceptions, pg 127 */ ! 141: regStationAddress_2_3w = 0x00, /* Universal with Exceptions, pg 127 */ ! 142: }; ! 143: ! 144: enum Registers1 { ! 145: regRxStatus_1_w = 0x0a, /* 90X Revision Only, Pg 126 */ ! 146: }; ! 147: ! 148: enum Registers0 { ! 149: regEepromData_0_w = 0x0c, /* Universal */ ! 150: regEepromCommand_0_w = 0x0a, /* Universal */ ! 151: regBiosRomData_0_b = 0x08, /* 905B Revision Only */ ! 152: regBiosRomAddr_0_l = 0x04, /* 905B Revision Only */ ! 153: }; ! 154: ! 155: ! 156: /* The names for the eight register windows */ ! 157: enum Windows { ! 158: winNone = 0xff, ! 159: winPowerVlan7 = 0x07, ! 160: winStatistics6 = 0x06, ! 161: winTxRxControl5 = 0x05, ! 162: winDiagnostics4 = 0x04, ! 163: winTxRxOptions3 = 0x03, ! 164: winAddressing2 = 0x02, ! 165: winUnused1 = 0x01, ! 166: winEepromBios0 = 0x00, ! 167: }; ! 168: ! 169: ! 170: /* Command definitions for the 3c90X */ ! 171: enum Commands { ! 172: cmdGlobalReset = 0x00, /* Universal with Exceptions, pg 151 */ ! 173: cmdSelectRegisterWindow = 0x01, /* Universal */ ! 174: cmdEnableDcConverter = 0x02, /* */ ! 175: cmdRxDisable = 0x03, /* */ ! 176: cmdRxEnable = 0x04, /* Universal */ ! 177: cmdRxReset = 0x05, /* Universal */ ! 178: cmdStallCtl = 0x06, /* Universal */ ! 179: cmdTxEnable = 0x09, /* Universal */ ! 180: cmdTxDisable = 0x0A, /* */ ! 181: cmdTxReset = 0x0B, /* Universal */ ! 182: cmdRequestInterrupt = 0x0C, /* */ ! 183: cmdAcknowledgeInterrupt = 0x0D, /* Universal */ ! 184: cmdSetInterruptEnable = 0x0E, /* Universal */ ! 185: cmdSetIndicationEnable = 0x0F, /* Universal */ ! 186: cmdSetRxFilter = 0x10, /* Universal */ ! 187: cmdSetRxEarlyThresh = 0x11, /* */ ! 188: cmdSetTxStartThresh = 0x13, /* */ ! 189: cmdStatisticsEnable = 0x15, /* */ ! 190: cmdStatisticsDisable = 0x16, /* */ ! 191: cmdDisableDcConverter = 0x17, /* */ ! 192: cmdSetTxReclaimThresh = 0x18, /* */ ! 193: cmdSetHashFilterBit = 0x19, /* */ ! 194: }; ! 195: ! 196: enum GlobalResetParams { ! 197: globalResetAll = 0, ! 198: globalResetMaskNetwork = (1<<2), ! 199: globalResetMaskAll = 0x1ff, ! 200: }; ! 201: ! 202: enum FrameStartHeader { ! 203: fshTxIndicate = 0x8000, ! 204: fshDnComplete = 0x10000, ! 205: }; ! 206: ! 207: enum UpDownDesc { ! 208: upLastFrag = (1 << 31), ! 209: downLastFrag = (1 << 31), ! 210: }; ! 211: ! 212: enum UpPktStatus { ! 213: upComplete = (1 << 15), ! 214: upError = (1 << 14), ! 215: }; ! 216: ! 217: enum Stalls { ! 218: upStall = 0x00, ! 219: upUnStall = 0x01, ! 220: ! 221: dnStall = 0x02, ! 222: dnUnStall = 0x03, ! 223: }; ! 224: ! 225: enum Resources { ! 226: resRxRing = 0x00, ! 227: resTxRing = 0x02, ! 228: resRxIOBuf = 0x04 ! 229: }; ! 230: ! 231: enum eeprom { ! 232: eepromBusy = (1 << 15), ! 233: eepromRead = ((0x02) << 6), ! 234: eepromRead_556 = 0x230, ! 235: eepromHwAddrOffset = 0x0a, ! 236: }; ! 237: ! 238: /* Bit 4 is only used in revison B and upwards */ ! 239: enum linktype { ! 240: link10BaseT = 0x00, ! 241: linkAUI = 0x01, ! 242: link10Base2 = 0x03, ! 243: link100BaseFX = 0x05, ! 244: linkMII = 0x06, ! 245: linkAutoneg = 0x08, ! 246: linkExternalMII = 0x09, ! 247: }; ! 248: ! 249: /* Values for int status register bitmask */ ! 250: #define INT_INTERRUPTLATCH (1<<0) ! 251: #define INT_HOSTERROR (1<<1) ! 252: #define INT_TXCOMPLETE (1<<2) ! 253: #define INT_RXCOMPLETE (1<<4) ! 254: #define INT_RXEARLY (1<<5) ! 255: #define INT_INTREQUESTED (1<<6) ! 256: #define INT_UPDATESTATS (1<<7) ! 257: #define INT_LINKEVENT (1<<8) ! 258: #define INT_DNCOMPLETE (1<<9) ! 259: #define INT_UPCOMPLETE (1<<10) ! 260: #define INT_CMDINPROGRESS (1<<12) ! 261: #define INT_WINDOWNUMBER (7<<13) ! 262: ! 263: /* Buffer sizes */ ! 264: #define TX_RING_SIZE 8 ! 265: #define RX_RING_SIZE 8 ! 266: #define TX_RING_ALIGN 16 ! 267: #define RX_RING_ALIGN 16 ! 268: #define RX_BUF_SIZE 1536 ! 269: ! 270: /* Timeouts for eeprom and command completion */ ! 271: /* Timeout 1 second, to be save */ ! 272: #define EEPROM_TIMEOUT 1 * 1000 * 1000 ! 273: ! 274: /* TX descriptor */ ! 275: struct TXD { ! 276: volatile unsigned int DnNextPtr; ! 277: volatile unsigned int FrameStartHeader; ! 278: volatile unsigned int DataAddr; ! 279: volatile unsigned int DataLength; ! 280: } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */ ! 281: ! 282: /* RX descriptor */ ! 283: struct RXD { ! 284: volatile unsigned int UpNextPtr; ! 285: volatile unsigned int UpPktStatus; ! 286: volatile unsigned int DataAddr; ! 287: volatile unsigned int DataLength; ! 288: } __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */ ! 289: ! 290: /* Private NIC dats */ ! 291: struct INF_3C90X { ! 292: unsigned int is3c556; ! 293: unsigned char isBrev; ! 294: unsigned char CurrentWindow; ! 295: unsigned int IOAddr; ! 296: unsigned short eeprom[0x21]; ! 297: unsigned int tx_cur; /* current entry in tx_ring */ ! 298: unsigned int tx_cnt; /* current number of used tx descriptors */ ! 299: unsigned int tx_tail; /* entry of last finished packet */ ! 300: unsigned int rx_cur; ! 301: struct TXD *tx_ring; ! 302: struct RXD *rx_ring; ! 303: struct io_buffer *tx_iobuf[TX_RING_SIZE]; ! 304: struct io_buffer *rx_iobuf[RX_RING_SIZE]; ! 305: struct nvs_device nvs; ! 306: }; ! 307: ! 308: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.