2
* 3c90x.c -- This file implements the 3c90x driver for etherboot. Written
3
* by Greg Beeley, Greg.Beeley@LightSys.org. Modified by Steve Smith,
4
* Steve.Smith@Juno.Com. Alignment bug fix Neil Newell (nn@icenoir.net).
6
* Port from etherboot to iPXE API, implementation of tx/rx ring support
7
* by Thomas Miletich, thomas.miletich@gmail.com
8
* Thanks to Marty Connor and Stefan Hajnoczi for their help and feedback.
10
* This program Copyright (C) 1999 LightSys Technology Services, Inc.
11
* Portions Copyright (C) 1999 Steve Smith
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.
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.
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
41
* v2.02 11-28-2007 GSt Got polling working again by replacing
42
* "for(i=0;i<40000;i++);" with "mdelay(1);"
45
* indent options: indent -kr -i8 3c90x.c
48
FILE_LICENCE ( BSD2 );
53
static struct net_device_operations a3c90x_operations;
55
#define XCVR_MAGIC (0x5A00)
57
/* Register definitions for the 3c905 */
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 */
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) */
86
/* following are windowed registers */
88
regPowerMgmtEvent_7_w = 0x0c, /* 905B Revision Only */
89
regVlanEtherType_7_w = 0x04, /* 905B Revision Only */
90
regVlanMask_7_w = 0x00, /* 905B Revision Only */
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 */
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 */
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? */
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 */
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 */
145
regRxStatus_1_w = 0x0a, /* 90X Revision Only, Pg 126 */
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 */
156
/* The names for the eight register windows */
159
winPowerVlan7 = 0x07,
160
winStatistics6 = 0x06,
161
winTxRxControl5 = 0x05,
162
winDiagnostics4 = 0x04,
163
winTxRxOptions3 = 0x03,
164
winAddressing2 = 0x02,
166
winEepromBios0 = 0x00,
170
/* Command definitions for the 3c90X */
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, /* */
196
enum GlobalResetParams {
198
globalResetMaskNetwork = (1<<2),
199
globalResetMaskAll = 0x1ff,
202
enum FrameStartHeader {
203
fshTxIndicate = 0x8000,
204
fshDnComplete = 0x10000,
205
fshRndupDefeat = 0x10000000,
209
upLastFrag = (1 << 31),
210
downLastFrag = (1 << 31),
214
upComplete = (1 << 15),
233
eepromBusy = (1 << 15),
234
eepromRead = ((0x02) << 6),
235
eepromRead_556 = 0x230,
236
eepromHwAddrOffset = 0x0a,
239
/* Bit 4 is only used in revison B and upwards */
244
link100BaseFX = 0x05,
247
linkExternalMII = 0x09,
250
/* Values for int status register bitmask */
251
#define INT_INTERRUPTLATCH (1<<0)
252
#define INT_HOSTERROR (1<<1)
253
#define INT_TXCOMPLETE (1<<2)
254
#define INT_RXCOMPLETE (1<<4)
255
#define INT_RXEARLY (1<<5)
256
#define INT_INTREQUESTED (1<<6)
257
#define INT_UPDATESTATS (1<<7)
258
#define INT_LINKEVENT (1<<8)
259
#define INT_DNCOMPLETE (1<<9)
260
#define INT_UPCOMPLETE (1<<10)
261
#define INT_CMDINPROGRESS (1<<12)
262
#define INT_WINDOWNUMBER (7<<13)
265
#define TX_RING_SIZE 8
266
#define RX_RING_SIZE 8
267
#define TX_RING_ALIGN 16
268
#define RX_RING_ALIGN 16
269
#define RX_BUF_SIZE 1536
271
/* Timeouts for eeprom and command completion */
272
/* Timeout 1 second, to be save */
273
#define EEPROM_TIMEOUT 1 * 1000 * 1000
277
volatile unsigned int DnNextPtr;
278
volatile unsigned int FrameStartHeader;
279
volatile unsigned int DataAddr;
280
volatile unsigned int DataLength;
281
} __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
285
volatile unsigned int UpNextPtr;
286
volatile unsigned int UpPktStatus;
287
volatile unsigned int DataAddr;
288
volatile unsigned int DataLength;
289
} __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
291
/* Private NIC dats */
293
unsigned int is3c556;
294
unsigned char isBrev;
295
unsigned char CurrentWindow;
297
unsigned short eeprom[0x21];
298
unsigned int tx_cur; /* current entry in tx_ring */
299
unsigned int tx_cnt; /* current number of used tx descriptors */
300
unsigned int tx_tail; /* entry of last finished packet */
304
struct io_buffer *tx_iobuf[TX_RING_SIZE];
305
struct io_buffer *rx_iobuf[RX_RING_SIZE];
306
struct nvs_device nvs;