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 General Public License. 411 * 412 * For more details, see wavelan.c. 413 */ 414