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