1 #if defined(CONFIG_WAVELAN)
2 /*
3 * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
4 *
5 * See:
6 * Intel Microcommunications 1991
7 * p1-1 to p1-37
8 * Intel order No. 231658
9 * ISBN 1-55512-119-5
10 *
11 * Unfortunately, the above chapter mentions neither
12 * the System Configuration Pointer (SCP) nor the
13 * Intermediate System Configuration Pointer (ISCP),
14 * so we probably need to look elsewhere for the
15 * whole story -- some recommend the "Intel LAN
16 * Components manual" but I have neither a copy
17 * nor a full reference. But "elsewhere" may be
18 * in the same publication...
19 * The description of a later device, the
20 * "82596CA High-Performance 32-Bit Local Area Network
21 * Coprocessor", (ibid. p1-38 to p1-109) does mention
22 * the SCP and ISCP and also has an i82586 compatibility
23 * mode. Even more useful is "AP-235 An 82586 Data Link
24 * Driver" (ibid. p1-337 to p1-417).
25 */
26
27 #define I82586_MEMZ (64 * 1024)
28
29 #define I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t))
30
31 #define ADDR_LEN 6
32 #define I82586NULL 0xFFFF
33
34 #define toff(t,p,f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
35
36 /*
37 * System Configuration Pointer (SCP).
38 */
39 typedef struct scp_t scp_t;
40 struct scp_t
41 {
42 unsigned short scp_sysbus; /* 82586 bus width: */
43 #define SCP_SY_16BBUS (0x0 << 0) /* 16 bits */
44 #define SCP_SY_8BBUS (0x1 << 0) /* 8 bits. */
45 unsigned short scp_junk[2]; /* Unused */
46 unsigned short scp_iscpl; /* lower 16 bits of ISCP_ADDR */
47 unsigned short scp_iscph; /* upper 16 bits of ISCP_ADDR */
48 };
49
50 /*
51 * Intermediate System Configuration Pointer (ISCP).
52 */
53 typedef struct iscp_t iscp_t;
54 struct iscp_t
55 {
56 unsigned short iscp_busy; /* set by CPU before first CA, */
57 /* cleared by 82586 after read. */
58 unsigned short iscp_offset; /* offset of SCB */
59 unsigned short iscp_basel; /* base of SCB */
60 unsigned short iscp_baseh; /* " */
61 };
62
63 /*
64 * System Control Block (SCB).
65 * The 82586 writes its status to scb_status and then
66 * raises an interrupt to alert the CPU.
67 * The CPU writes a command to scb_command and
68 * then issues a Channel Attention (CA) to alert the 82586.
69 */
70 typedef struct scb_t scb_t;
71 struct scb_t
72 {
73 unsigned short scb_status; /* Status of 82586 */
74 #define SCB_ST_INT (0xF << 12) /* Some of: */
75 #define SCB_ST_CX (0x1 << 15) /* Cmd completed */
76 #define SCB_ST_FR (0x1 << 14) /* Frame received */
77 #define SCB_ST_CNA (0x1 << 13) /* Cmd unit not active */
78 #define SCB_ST_RNR (0x1 << 12) /* Rcv unit not ready */
79 #define SCB_ST_JUNK0 (0x1 << 11) /* 0 */
80 #define SCB_ST_CUS (0x7 << 8) /* Cmd unit status */
81 #define SCB_ST_CUS_IDLE (0 << 8) /* Idle */
82 #define SCB_ST_CUS_SUSP (1 << 8) /* Suspended */
83 #define SCB_ST_CUS_ACTV (2 << 8) /* Active */
84 #define SCB_ST_JUNK1 (0x1 << 7) /* 0 */
85 #define SCB_ST_RUS (0x7 << 4) /* Rcv unit status */
86 #define SCB_ST_RUS_IDLE (0 << 4) /* Idle */
87 #define SCB_ST_RUS_SUSP (1 << 4) /* Suspended */
88 #define SCB_ST_RUS_NRES (2 << 4) /* No resources */
89 #define SCB_ST_RUS_RDY (4 << 4) /* Ready */
90 unsigned short scb_command; /* Next command */
91 #define SCB_CMD_ACK_CX (0x1 << 15) /* Ack cmd completion */
92 #define SCB_CMD_ACK_FR (0x1 << 14) /* Ack frame received */
93 #define SCB_CMD_ACK_CNA (0x1 << 13) /* Ack CU not active */
94 #define SCB_CMD_ACK_RNR (0x1 << 12) /* Ack RU not ready */
95 #define SCB_CMD_JUNKX (0x1 << 11) /* Unused */
96 #define SCB_CMD_CUC (0x7 << 8) /* Command Unit command */
97 #define SCB_CMD_CUC_NOP (0 << 8) /* Nop */
98 #define SCB_CMD_CUC_GO (1 << 8) /* Start cbl_offset */
99 #define SCB_CMD_CUC_RES (2 << 8) /* Resume execution */
100 #define SCB_CMD_CUC_SUS (3 << 8) /* Suspend " */
101 #define SCB_CMD_CUC_ABT (4 << 8) /* Abort " */
102 #define SCB_CMD_RESET (0x1 << 7) /* Reset chip (hardware) */
103 #define SCB_CMD_RUC (0x7 << 4) /* Receive Unit command */
104 #define SCB_CMD_RUC_NOP (0 << 4) /* Nop */
105 #define SCB_CMD_RUC_GO (1 << 4) /* Start rfa_offset */
106 #define SCB_CMD_RUC_RES (2 << 4) /* Resume reception */
107 #define SCB_CMD_RUC_SUS (3 << 4) /* Suspend " */
108 #define SCB_CMD_RUC_ABT (4 << 4) /* Abort " */
109 unsigned short scb_cbl_offset; /* Offset of first command unit */
110 /* Action Command */
111 unsigned short scb_rfa_offset; /* Offset of first Receive */
112 /* Frame Descriptor in the */
113 /* Receive Frame Area */
114 unsigned short scb_crcerrs; /* Properly aligned frames */
115 /* received with a CRC error */
116 unsigned short scb_alnerrs; /* Misaligned frames received */
117 /* with a CRC error */
118 unsigned short scb_rscerrs; /* Frames lost due to no space */
119 unsigned short scb_ovrnerrs; /* Frames lost due to slow bus */
120 };
121
122 #define scboff(p,f) toff(scb_t, p, f)
123
124 /*
125 * The eight Action Commands.
126 */
127 typedef enum acmd_e acmd_e;
128 enum acmd_e
129 {
130 acmd_nop = 0, /* Do nothing */
131 acmd_ia_setup = 1, /* Load an (ethernet) address into the */
132 /* 82586 */
133 acmd_configure = 2, /* Update the 82586 operating parameters */
134 acmd_mc_setup = 3, /* Load a list of (ethernet) multicast */
135 /* addresses into the 82586 */
136 acmd_transmit = 4, /* Transmit a frame */
137 acmd_tdr = 5, /* Perform a Time Domain Reflectometer */
138 /* test on the serial link */
139 acmd_dump = 6, /* Copy 82586 registers to memory */
140 acmd_diagnose = 7, /* Run an internal self test */
141 };
142
143 /*
144 * Generic Action Command header.
145 */
146 typedef struct ach_t ach_t;
147 struct ach_t
148 {
149 unsigned short ac_status; /* Command status: */
150 #define AC_SFLD_C (0x1 << 15) /* Command completed */
151 #define AC_SFLD_B (0x1 << 14) /* Busy executing */
152 #define AC_SFLD_OK (0x1 << 13) /* Completed error free */
153 #define AC_SFLD_A (0x1 << 12) /* Command aborted */
154 #define AC_SFLD_FAIL (0x1 << 11) /* Selftest failed */
155 #define AC_SFLD_S10 (0x1 << 10) /* No carrier sense */
156 /* during transmission */
157 #define AC_SFLD_S9 (0x1 << 9) /* Tx unsuccessful: */
158 /* (stopped) lost CTS */
159 #define AC_SFLD_S8 (0x1 << 8) /* Tx unsuccessful: */
160 /* (stopped) slow DMA */
161 #define AC_SFLD_S7 (0x1 << 7) /* Tx deferred: */
162 /* other link traffic */
163 #define AC_SFLD_S6 (0x1 << 6) /* Heart Beat: collision */
164 /* detect after last tx */
165 #define AC_SFLD_S5 (0x1 << 5) /* Tx stopped: */
166 /* excessive collisions */
167 #define AC_SFLD_MAXCOL (0xF << 0) /* Collision count */
168 unsigned short ac_command; /* Command specifier: */
169 #define AC_CFLD_EL (0x1 << 15) /* End of command list */
170 #define AC_CFLD_S (0x1 << 14) /* Suspend on completion */
171 #define AC_CFLD_I (0x1 << 13) /* Interrupt on completion */
172 #define AC_CFLD_CMD (0x7 << 0) /* acmd_e */
173 unsigned short ac_link; /* Next Action Command */
174 };
175
176 #define acoff(p,f) toff(ach_t, p, f)
177
178 /*
179 * The Nop Action Command.
180 */
181 typedef struct ac_nop_t ac_nop_t;
182 struct ac_nop_t
183 {
184 ach_t nop_h;
185 };
186
187 /*
188 * The IA-Setup Action Command.
189 */
190 typedef struct ac_ias_t ac_ias_t;
191 struct ac_ias_t
192 {
193 ach_t ias_h;
194 unsigned char ias_addr[ADDR_LEN]; /* The (ethernet) address */
195 };
196
197 /*
198 * The Configure Action Command.
199 */
200 typedef struct ac_cfg_t ac_cfg_t;
201 struct ac_cfg_t
202 {
203 ach_t cfg_h;
204 unsigned char cfg_byte_cnt; /* Size foll data: 4-12 */
205 #define AC_CFG_BYTE_CNT(v) (((v) & 0xF) << 0)
206 unsigned char cfg_fifolim; /* FIFO threshold */
207 #define AC_CFG_FIFOLIM(v) (((v) & 0xF) << 0)
208 unsigned char cfg_byte8;
209 #define AC_CFG_SAV_BF(v) (((v) & 0x1) << 7) /* Save rxd bad frames */
210 #define AC_CFG_SRDY(v) (((v) & 0x1) << 6) /* SRDY/ARDY pin means */
211 /* external sync. */
212 unsigned char cfg_byte9;
213 #define AC_CFG_ELPBCK(v) (((v) & 0x1) << 7) /* External loopback */
214 #define AC_CFG_ILPBCK(v) (((v) & 0x1) << 6) /* Internal loopback */
215 #define AC_CFG_PRELEN(v) (((v) & 0x3) << 4) /* Preamble length */
216 #define AC_CFG_PLEN_2 0 /* 2 bytes */
217 #define AC_CFG_PLEN_4 1 /* 4 bytes */
218 #define AC_CFG_PLEN_8 2 /* 8 bytes */
219 #define AC_CFG_PLEN_16 3 /* 16 bytes */
220 #define AC_CFG_ALOC(v) (((v) & 0x1) << 3) /* Addr/len data is */
221 /* explicit in buffers */
222 #define AC_CFG_ADDRLEN(v) (((v) & 0x7) << 0) /* Bytes per address */
223 unsigned char cfg_byte10;
224 #define AC_CFG_BOFMET(v) (((v) & 0x1) << 7) /* Use alternate expo. */
225 /* backoff method */
226 #define AC_CFG_ACR(v) (((v) & 0x7) << 4) /* Accelerated cont. res. */
227 #define AC_CFG_LINPRIO(v) (((v) & 0x7) << 0) /* Linear priority */
228 unsigned char cfg_ifs; /* Interframe spacing */
229 unsigned char cfg_slotl; /* Slot time (low byte) */
230 unsigned char cfg_byte13;
231 #define AC_CFG_RETRYNUM(v) (((v) & 0xF) << 4) /* Max. collision retry */
232 #define AC_CFG_SLTTMHI(v) (((v) & 0x7) << 0) /* Slot time (high bits) */
233 unsigned char cfg_byte14;
234 #define AC_CFG_FLGPAD(v) (((v) & 0x1) << 7) /* Pad with HDLC flags */
235 #define AC_CFG_BTSTF(v) (((v) & 0x1) << 6) /* Do HDLC bitstuffing */
236 #define AC_CFG_CRC16(v) (((v) & 0x1) << 5) /* 16 bit CCITT CRC */
237 #define AC_CFG_NCRC(v) (((v) & 0x1) << 4) /* Insert no CRC */
238 #define AC_CFG_TNCRS(v) (((v) & 0x1) << 3) /* Tx even if no carrier */
239 #define AC_CFG_MANCH(v) (((v) & 0x1) << 2) /* Manchester coding */
240 #define AC_CFG_BCDIS(v) (((v) & 0x1) << 1) /* Disable broadcast */
241 #define AC_CFG_PRM(v) (((v) & 0x1) << 0) /* Promiscuous mode */
242 unsigned char cfg_byte15;
243 #define AC_CFG_ICDS(v) (((v) & 0x1) << 7) /* Internal collision */
244 /* detect source */
245 #define AC_CFG_CDTF(v) (((v) & 0x7) << 4) /* Collision detect */
246 /* filter in bit times */
247 #define AC_CFG_ICSS(v) (((v) & 0x1) << 3) /* Internal carrier */
248 /* sense source */
249 #define AC_CFG_CSTF(v) (((v) & 0x7) << 0) /* Carrier sense */
250 /* filter in bit times */
251 unsigned short cfg_min_frm_len;
252 #define AC_CFG_MNFRM(v) (((v) & 0xFF) << 0) /* Min. bytes/frame (<= 255) */
253 };
254
255 /*
256 * The MC-Setup Action Command.
257 */
258 typedef struct ac_mcs_t ac_mcs_t;
259 struct ac_mcs_t
260 {
261 ach_t mcs_h;
262 unsigned short mcs_cnt; /* No. of bytes of MC addresses */
263 unsigned short mcs_data[3]; /* The first MC address .. */
264 };
265
266 /*
267 * The Transmit Action Command.
268 */
269 typedef struct ac_tx_t ac_tx_t;
270 struct ac_tx_t
271 {
272 ach_t tx_h;
273 unsigned short tx_tbd_offset; /* Address of list of buffers. */
274 #if 0
275 Linux packets are passed down with the destination MAC address
276 and length/type field already prepended to the data,
277 so we do not need to insert it. Consistent with this
278 we must also set the AC_CFG_ALOC(..) flag during the
279 ac_cfg_t action command.
280 unsigned char tx_addr[ADDR_LEN]; /* The frame dest. address */
281 unsigned short tx_length; /* The frame length */
282 #endif /* 0 */
283 };
284
285 /*
286 * The Time Domain Reflectometer Action Command.
287 */
288 typedef struct ac_tdr_t ac_tdr_t;
289 struct ac_tdr_t
290 {
291 ach_t tdr_h;
292 unsigned short tdr_result; /* Result. */
293 #define AC_TDR_LNK_OK (0x1 << 15) /* No link problem */
294 #define AC_TDR_XCVR_PRB (0x1 << 14) /* Txcvr cable problem */
295 #define AC_TDR_ET_OPN (0x1 << 13) /* Open on the link */
296 #define AC_TDR_ET_SRT (0x1 << 12) /* Short on the link */
297 #define AC_TDR_TIME (0x7FF << 0) /* Distance to problem */
298 /* site in transmit */
299 /* clock cycles */
300 };
301
302 /*
303 * The Dump Action Command.
304 */
305 typedef struct ac_dmp_t ac_dmp_t;
306 struct ac_dmp_t
307 {
308 ach_t dmp_h;
309 unsigned short dmp_offset; /* Result. */
310 };
311
312 /*
313 * Size of the result of the dump command.
314 */
315 #define DUMPBYTES 170
316
317 /*
318 * The Diagnose Action Command.
319 */
320 typedef struct ac_dgn_t ac_dgn_t;
321 struct ac_dgn_t
322 {
323 ach_t dgn_h;
324 };
325
326 /*
327 * Transmit Buffer Descriptor (TBD).
328 */
329 typedef struct tbd_t tbd_t;
330 struct tbd_t
331 {
332 unsigned short tbd_status; /* Written by the CPU */
333 #define TBD_STATUS_EOF (0x1 << 15) /* This TBD is the */
334 /* last for this frame */
335 #define TBD_STATUS_ACNT (0x3FFF << 0) /* Actual count of data */
336 /* bytes in this buffer */
337 unsigned short tbd_next_bd_offset; /* Next in list */
338 unsigned short tbd_bufl; /* Buffer address (low) */
339 unsigned short tbd_bufh; /* " " (high) */
340 };
341
342 /*
343 * Receive Buffer Descriptor (RBD).
344 */
345 typedef struct rbd_t rbd_t;
346 struct rbd_t
347 {
348 unsigned short rbd_status; /* Written by the 82586 */
349 #define RBD_STATUS_EOF (0x1 << 15) /* This RBD is the */
350 /* last for this frame */
351 #define RBD_STATUS_F (0x1 << 14) /* ACNT field is valid */
352 #define RBD_STATUS_ACNT (0x3FFF << 0) /* Actual no. of data */
353 /* bytes in this buffer */
354 unsigned short rbd_next_rbd_offset; /* Next rbd in list */
355 unsigned short rbd_bufl; /* Data pointer (low) */
356 unsigned short rbd_bufh; /* " " (high) */
357 unsigned short rbd_el_size; /* EL+Data buf. size */
358 #define RBD_EL (0x1 << 15) /* This BD is the */
359 /* last in the list */
360 #define RBD_SIZE (0x3FFF << 0) /* No. of bytes the */
361 /* buffer can hold */
362 };
363
364 #define rbdoff(p,f) toff(rbd_t, p, f)
365
366 /*
367 * Frame Descriptor (FD).
368 */
369 typedef struct fd_t fd_t;
370 struct fd_t
371 {
372 unsigned short fd_status; /* Written by the 82586 */
373 #define FD_STATUS_C (0x1 << 15) /* Completed storing frame */
374 #define FD_STATUS_B (0x1 << 14) /* FD was consumed by RU */
375 #define FD_STATUS_OK (0x1 << 13) /* Frame rxd successfully */
376 #define FD_STATUS_S11 (0x1 << 11) /* CRC error */
377 #define FD_STATUS_S10 (0x1 << 10) /* Alignment error */
378 #define FD_STATUS_S9 (0x1 << 9) /* Ran out of resources */
379 #define FD_STATUS_S8 (0x1 << 8) /* Rx DMA overrun */
380 #define FD_STATUS_S7 (0x1 << 7) /* Frame too short */
381 #define FD_STATUS_S6 (0x1 << 6) /* No EOF flag */
382 unsigned short fd_command; /* Command */
383 #define FD_COMMAND_EL (0x1 << 15) /* Last FD in list */
384 #define FD_COMMAND_S (0x1 << 14) /* Suspend RU after rx */
385 unsigned short fd_link_offset; /* Next FD */
386 unsigned short fd_rbd_offset; /* First RBD (data) */
387 /* Prepared by CPU, */
388 /* updated by 82586 */
389 #if 0
390 I think the rest is unused since we
391 have set AC_CFG_ALOC(..). However, just
392 in case, we leave the space.
393 #endif /* 0 */
394 unsigned char fd_dest[ADDR_LEN]; /* Destination address */
395 /* Written by 82586 */
396 unsigned char fd_src[ADDR_LEN]; /* Source address */
397 /* Written by 82586 */
398 unsigned short fd_length; /* Frame length or type */
399 /* Written by 82586 */
400 };
401
402 #define fdoff(p,f) toff(fd_t, p, f)
403
404 /*
405 * This software may only be used and distributed
406 * according to the terms of the GNU Public License.
407 *
408 * For more details, see wavelan.c.
409 */
410 #endif /* defined(CONFIG_WAVELAN) */