|
|
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.