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