Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

i82586.h

Go to the documentation of this file.
00001 /*
00002  * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
00003  *
00004  * See:
00005  *      Intel Microcommunications 1991
00006  *      p1-1 to p1-37
00007  *      Intel order No. 231658
00008  *      ISBN 1-55512-119-5
00009  *
00010  *     Unfortunately, the above chapter mentions neither
00011  * the System Configuration Pointer (SCP) nor the
00012  * Intermediate System Configuration Pointer (ISCP),
00013  * so we probably need to look elsewhere for the
00014  * whole story -- some recommend the "Intel LAN
00015  * Components manual" but I have neither a copy
00016  * nor a full reference.  But "elsewhere" may be
00017  * in the same publication...
00018  *     The description of a later device, the
00019  * "82596CA High-Performance 32-Bit Local Area Network
00020  * Coprocessor", (ibid. p1-38 to p1-109) does mention
00021  * the SCP and ISCP and also has an i82586 compatibility
00022  * mode.  Even more useful is "AP-235 An 82586 Data Link
00023  * Driver" (ibid. p1-337 to p1-417).
00024  */
00025 
00026 #define I82586_MEMZ     (64 * 1024)
00027 
00028 #define I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t))
00029 
00030 #define ADDR_LEN        6
00031 #define I82586NULL      0xFFFF
00032 
00033 #define toff(t,p,f)     (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
00034 
00035 /*
00036  * System Configuration Pointer (SCP).
00037  */
00038 typedef struct scp_t    scp_t;
00039 struct scp_t
00040 {
00041         unsigned short  scp_sysbus;     /* 82586 bus width:     */
00042 #define         SCP_SY_16BBUS   (0x0 << 0)      /* 16 bits */
00043 #define         SCP_SY_8BBUS    (0x1 << 0)      /*  8 bits. */
00044         unsigned short  scp_junk[2];    /* Unused */
00045         unsigned short  scp_iscpl;      /* lower 16 bits of ISCP_ADDR */
00046         unsigned short  scp_iscph;      /* upper 16 bits of ISCP_ADDR */
00047 };
00048 
00049 /*
00050  * Intermediate System Configuration Pointer (ISCP).
00051  */
00052 typedef struct iscp_t   iscp_t;
00053 struct iscp_t
00054 {
00055         unsigned short  iscp_busy;      /* set by CPU before first CA,  */
00056                                         /* cleared by 82586 after read. */
00057         unsigned short  iscp_offset;    /* offset of SCB                */
00058         unsigned short  iscp_basel;     /* base of SCB                  */
00059         unsigned short  iscp_baseh;     /*  "                           */
00060 };
00061 
00062 /*
00063  * System Control Block (SCB).
00064  *      The 82586 writes its status to scb_status and then
00065  *      raises an interrupt to alert the CPU.
00066  *      The CPU writes a command to scb_command and
00067  *      then issues a Channel Attention (CA) to alert the 82586.
00068  */
00069 typedef struct scb_t    scb_t;
00070 struct scb_t
00071 {
00072         unsigned short  scb_status;     /* Status of 82586              */
00073 #define         SCB_ST_INT      (0xF << 12)     /* Some of:             */
00074 #define         SCB_ST_CX       (0x1 << 15)     /* Cmd completed        */
00075 #define         SCB_ST_FR       (0x1 << 14)     /* Frame received       */
00076 #define         SCB_ST_CNA      (0x1 << 13)     /* Cmd unit not active  */
00077 #define         SCB_ST_RNR      (0x1 << 12)     /* Rcv unit not ready   */
00078 #define         SCB_ST_JUNK0    (0x1 << 11)     /* 0                    */
00079 #define         SCB_ST_CUS      (0x7 <<  8)     /* Cmd unit status      */
00080 #define                 SCB_ST_CUS_IDLE (0 << 8)        /* Idle         */
00081 #define                 SCB_ST_CUS_SUSP (1 << 8)        /* Suspended    */
00082 #define                 SCB_ST_CUS_ACTV (2 << 8)        /* Active       */
00083 #define         SCB_ST_JUNK1    (0x1 <<  7)     /* 0                    */
00084 #define         SCB_ST_RUS      (0x7 <<  4)     /* Rcv unit status      */
00085 #define                 SCB_ST_RUS_IDLE (0 << 4)        /* Idle         */
00086 #define                 SCB_ST_RUS_SUSP (1 << 4)        /* Suspended    */
00087 #define                 SCB_ST_RUS_NRES (2 << 4)        /* No resources */
00088 #define                 SCB_ST_RUS_RDY  (4 << 4)        /* Ready        */
00089         unsigned short  scb_command;    /* Next command                 */
00090 #define         SCB_CMD_ACK_CX  (0x1 << 15)     /* Ack cmd completion   */
00091 #define         SCB_CMD_ACK_FR  (0x1 << 14)     /* Ack frame received   */
00092 #define         SCB_CMD_ACK_CNA (0x1 << 13)     /* Ack CU not active    */
00093 #define         SCB_CMD_ACK_RNR (0x1 << 12)     /* Ack RU not ready     */
00094 #define         SCB_CMD_JUNKX   (0x1 << 11)     /* Unused               */
00095 #define         SCB_CMD_CUC     (0x7 <<  8)     /* Command Unit command */
00096 #define                 SCB_CMD_CUC_NOP (0 << 8)        /* Nop          */
00097 #define                 SCB_CMD_CUC_GO  (1 << 8)        /* Start cbl_offset */
00098 #define                 SCB_CMD_CUC_RES (2 << 8)        /* Resume execution */
00099 #define                 SCB_CMD_CUC_SUS (3 << 8)        /* Suspend   "  */
00100 #define                 SCB_CMD_CUC_ABT (4 << 8)        /* Abort     "  */
00101 #define         SCB_CMD_RESET   (0x1 <<  7)     /* Reset chip (hardware) */
00102 #define         SCB_CMD_RUC     (0x7 <<  4)     /* Receive Unit command */
00103 #define                 SCB_CMD_RUC_NOP (0 << 4)        /* Nop          */
00104 #define                 SCB_CMD_RUC_GO  (1 << 4)        /* Start rfa_offset */
00105 #define                 SCB_CMD_RUC_RES (2 << 4)        /* Resume reception */
00106 #define                 SCB_CMD_RUC_SUS (3 << 4)        /* Suspend   "  */
00107 #define                 SCB_CMD_RUC_ABT (4 << 4)        /* Abort     "  */
00108         unsigned short  scb_cbl_offset; /* Offset of first command unit */
00109                                         /* Action Command               */
00110         unsigned short  scb_rfa_offset; /* Offset of first Receive      */
00111                                         /* Frame Descriptor in the      */
00112                                         /* Receive Frame Area           */
00113         unsigned short  scb_crcerrs;    /* Properly aligned frames      */
00114                                         /* received with a CRC error    */
00115         unsigned short  scb_alnerrs;    /* Misaligned frames received   */
00116                                         /* with a CRC error             */
00117         unsigned short  scb_rscerrs;    /* Frames lost due to no space  */
00118         unsigned short  scb_ovrnerrs;   /* Frames lost due to slow bus  */
00119 };
00120 
00121 #define scboff(p,f)     toff(scb_t, p, f)
00122 
00123 /*
00124  * The eight Action Commands.
00125  */
00126 typedef enum acmd_e     acmd_e;
00127 enum acmd_e
00128 {
00129         acmd_nop        = 0,    /* Do nothing                           */
00130         acmd_ia_setup   = 1,    /* Load an (ethernet) address into the  */
00131                                 /* 82586                                */
00132         acmd_configure  = 2,    /* Update the 82586 operating parameters */
00133         acmd_mc_setup   = 3,    /* Load a list of (ethernet) multicast  */
00134                                 /* addresses into the 82586             */
00135         acmd_transmit   = 4,    /* Transmit a frame                     */
00136         acmd_tdr        = 5,    /* Perform a Time Domain Reflectometer  */
00137                                 /* test on the serial link              */
00138         acmd_dump       = 6,    /* Copy 82586 registers to memory       */
00139         acmd_diagnose   = 7,    /* Run an internal self test            */
00140 };
00141 
00142 /*
00143  * Generic Action Command header.
00144  */
00145 typedef struct ach_t    ach_t;
00146 struct ach_t
00147 {
00148         unsigned short  ac_status;              /* Command status:      */
00149 #define         AC_SFLD_C       (0x1 << 15)     /* Command completed    */
00150 #define         AC_SFLD_B       (0x1 << 14)     /* Busy executing       */
00151 #define         AC_SFLD_OK      (0x1 << 13)     /* Completed error free */
00152 #define         AC_SFLD_A       (0x1 << 12)     /* Command aborted      */
00153 #define         AC_SFLD_FAIL    (0x1 << 11)     /* Selftest failed      */
00154 #define         AC_SFLD_S10     (0x1 << 10)     /* No carrier sense     */
00155                                                 /* during transmission  */
00156 #define         AC_SFLD_S9      (0x1 <<  9)     /* Tx unsuccessful:     */
00157                                                 /* (stopped) lost CTS   */
00158 #define         AC_SFLD_S8      (0x1 <<  8)     /* Tx unsuccessful:     */
00159                                                 /* (stopped) slow DMA   */
00160 #define         AC_SFLD_S7      (0x1 <<  7)     /* Tx deferred:         */
00161                                                 /* other link traffic   */
00162 #define         AC_SFLD_S6      (0x1 <<  6)     /* Heart Beat: collision */
00163                                                 /* detect after last tx */
00164 #define         AC_SFLD_S5      (0x1 <<  5)     /* Tx stopped:          */
00165                                                 /* excessive collisions */
00166 #define         AC_SFLD_MAXCOL  (0xF <<  0)     /* Collision count      */
00167         unsigned short  ac_command;             /* Command specifier:   */
00168 #define         AC_CFLD_EL      (0x1 << 15)     /* End of command list  */
00169 #define         AC_CFLD_S       (0x1 << 14)     /* Suspend on completion */
00170 #define         AC_CFLD_I       (0x1 << 13)     /* Interrupt on completion */
00171 #define         AC_CFLD_CMD     (0x7 <<  0)     /* acmd_e               */
00172         unsigned short  ac_link;                /* Next Action Command  */
00173 };
00174 
00175 #define acoff(p,f)      toff(ach_t, p, f)
00176 
00177 /*
00178  * The Nop Action Command.
00179  */
00180 typedef struct ac_nop_t ac_nop_t;
00181 struct ac_nop_t
00182 {
00183         ach_t   nop_h;
00184 };
00185 
00186 /*
00187  * The IA-Setup Action Command.
00188  */
00189 typedef struct ac_ias_t ac_ias_t;
00190 struct ac_ias_t
00191 {
00192         ach_t           ias_h;
00193         unsigned char   ias_addr[ADDR_LEN]; /* The (ethernet) address   */
00194 };
00195 
00196 /*
00197  * The Configure Action Command.
00198  */
00199 typedef struct ac_cfg_t ac_cfg_t;
00200 struct ac_cfg_t
00201 {
00202         ach_t           cfg_h;
00203         unsigned char   cfg_byte_cnt;   /* Size foll data: 4-12 */
00204 #define AC_CFG_BYTE_CNT(v)      (((v) & 0xF) << 0)
00205         unsigned char   cfg_fifolim;    /* FIFO threshold       */
00206 #define AC_CFG_FIFOLIM(v)       (((v) & 0xF) << 0)
00207         unsigned char   cfg_byte8;
00208 #define AC_CFG_SAV_BF(v)        (((v) & 0x1) << 7)      /* Save rxd bad frames  */
00209 #define AC_CFG_SRDY(v)          (((v) & 0x1) << 6)      /* SRDY/ARDY pin means  */
00210                                                         /* external sync.       */
00211         unsigned char   cfg_byte9;
00212 #define AC_CFG_ELPBCK(v)        (((v) & 0x1) << 7)      /* External loopback    */
00213 #define AC_CFG_ILPBCK(v)        (((v) & 0x1) << 6)      /* Internal loopback    */
00214 #define AC_CFG_PRELEN(v)        (((v) & 0x3) << 4)      /* Preamble length      */
00215 #define         AC_CFG_PLEN_2           0               /*  2 bytes     */
00216 #define         AC_CFG_PLEN_4           1               /*  4 bytes     */
00217 #define         AC_CFG_PLEN_8           2               /*  8 bytes     */
00218 #define         AC_CFG_PLEN_16          3               /* 16 bytes     */
00219 #define AC_CFG_ALOC(v)          (((v) & 0x1) << 3)      /* Addr/len data is     */
00220                                                         /* explicit in buffers  */
00221 #define AC_CFG_ADDRLEN(v)       (((v) & 0x7) << 0)      /* Bytes per address    */
00222         unsigned char   cfg_byte10;
00223 #define AC_CFG_BOFMET(v)        (((v) & 0x1) << 7)      /* Use alternate expo.  */
00224                                                         /* backoff method       */
00225 #define AC_CFG_ACR(v)           (((v) & 0x7) << 4)      /* Accelerated cont. res. */
00226 #define AC_CFG_LINPRIO(v)       (((v) & 0x7) << 0)      /* Linear priority      */
00227         unsigned char   cfg_ifs;        /* Interframe spacing           */
00228         unsigned char   cfg_slotl;      /* Slot time (low byte)         */
00229         unsigned char   cfg_byte13;
00230 #define AC_CFG_RETRYNUM(v)      (((v) & 0xF) << 4)      /* Max. collision retry */
00231 #define AC_CFG_SLTTMHI(v)       (((v) & 0x7) << 0)      /* Slot time (high bits) */
00232         unsigned char   cfg_byte14;
00233 #define AC_CFG_FLGPAD(v)        (((v) & 0x1) << 7)      /* Pad with HDLC flags  */
00234 #define AC_CFG_BTSTF(v)         (((v) & 0x1) << 6)      /* Do HDLC bitstuffing  */
00235 #define AC_CFG_CRC16(v)         (((v) & 0x1) << 5)      /* 16 bit CCITT CRC     */
00236 #define AC_CFG_NCRC(v)          (((v) & 0x1) << 4)      /* Insert no CRC        */
00237 #define AC_CFG_TNCRS(v)         (((v) & 0x1) << 3)      /* Tx even if no carrier */
00238 #define AC_CFG_MANCH(v)         (((v) & 0x1) << 2)      /* Manchester coding    */
00239 #define AC_CFG_BCDIS(v)         (((v) & 0x1) << 1)      /* Disable broadcast    */
00240 #define AC_CFG_PRM(v)           (((v) & 0x1) << 0)      /* Promiscuous mode     */
00241         unsigned char   cfg_byte15;
00242 #define AC_CFG_ICDS(v)          (((v) & 0x1) << 7)      /* Internal collision   */
00243                                                         /* detect source        */
00244 #define AC_CFG_CDTF(v)          (((v) & 0x7) << 4)      /* Collision detect     */
00245                                                         /* filter in bit times  */
00246 #define AC_CFG_ICSS(v)          (((v) & 0x1) << 3)      /* Internal carrier     */
00247                                                         /* sense source         */
00248 #define AC_CFG_CSTF(v)          (((v) & 0x7) << 0)      /* Carrier sense        */
00249                                                         /* filter in bit times  */
00250         unsigned short  cfg_min_frm_len;
00251 #define AC_CFG_MNFRM(v)         (((v) & 0xFF) << 0)     /* Min. bytes/frame (<= 255) */
00252 };
00253 
00254 /*
00255  * The MC-Setup Action Command.
00256  */
00257 typedef struct ac_mcs_t ac_mcs_t;
00258 struct ac_mcs_t
00259 {
00260         ach_t           mcs_h;
00261         unsigned short  mcs_cnt;        /* No. of bytes of MC addresses */
00262 #if 0
00263         unsigned char   mcs_data[ADDR_LEN]; /* The first MC address ..  */
00264         ...
00265 #endif
00266 };
00267 
00268 #define I82586_MAX_MULTICAST_ADDRESSES  128     /* Hardware hashed filter */
00269 
00270 /*
00271  * The Transmit Action Command.
00272  */
00273 typedef struct ac_tx_t  ac_tx_t;
00274 struct ac_tx_t
00275 {
00276         ach_t           tx_h;
00277         unsigned short  tx_tbd_offset;  /* Address of list of buffers.  */
00278 #if     0
00279 Linux packets are passed down with the destination MAC address
00280 and length/type field already prepended to the data,
00281 so we do not need to insert it.  Consistent with this
00282 we must also set the AC_CFG_ALOC(..) flag during the
00283 ac_cfg_t action command.
00284         unsigned char   tx_addr[ADDR_LEN]; /* The frame dest. address   */
00285         unsigned short  tx_length;      /* The frame length             */
00286 #endif  /* 0 */
00287 };
00288 
00289 /*
00290  * The Time Domain Reflectometer Action Command.
00291  */
00292 typedef struct ac_tdr_t ac_tdr_t;
00293 struct ac_tdr_t
00294 {
00295         ach_t           tdr_h;
00296         unsigned short  tdr_result;     /* Result.      */
00297 #define         AC_TDR_LNK_OK   (0x1 << 15)     /* No link problem      */
00298 #define         AC_TDR_XCVR_PRB (0x1 << 14)     /* Txcvr cable problem  */
00299 #define         AC_TDR_ET_OPN   (0x1 << 13)     /* Open on the link     */
00300 #define         AC_TDR_ET_SRT   (0x1 << 12)     /* Short on the link    */
00301 #define         AC_TDR_TIME     (0x7FF << 0)    /* Distance to problem  */
00302                                                 /* site in transmit     */
00303                                                 /* clock cycles         */
00304 };
00305 
00306 /*
00307  * The Dump Action Command.
00308  */
00309 typedef struct ac_dmp_t ac_dmp_t;
00310 struct ac_dmp_t
00311 {
00312         ach_t           dmp_h;
00313         unsigned short  dmp_offset;     /* Result.      */
00314 };
00315 
00316 /*
00317  * Size of the result of the dump command.
00318  */
00319 #define DUMPBYTES       170
00320 
00321 /*
00322  * The Diagnose Action Command.
00323  */
00324 typedef struct ac_dgn_t ac_dgn_t;
00325 struct ac_dgn_t
00326 {
00327         ach_t           dgn_h;
00328 };
00329 
00330 /*
00331  * Transmit Buffer Descriptor (TBD).
00332  */
00333 typedef struct tbd_t    tbd_t;
00334 struct tbd_t
00335 {
00336         unsigned short  tbd_status;             /* Written by the CPU   */
00337 #define         TBD_STATUS_EOF  (0x1 << 15)     /* This TBD is the      */
00338                                                 /* last for this frame  */
00339 #define         TBD_STATUS_ACNT (0x3FFF << 0)   /* Actual count of data */
00340                                                 /* bytes in this buffer */
00341         unsigned short  tbd_next_bd_offset;     /* Next in list         */
00342         unsigned short  tbd_bufl;               /* Buffer address (low) */
00343         unsigned short  tbd_bufh;               /*    "      "  (high)  */
00344 };
00345 
00346 /*
00347  * Receive Buffer Descriptor (RBD).
00348  */
00349 typedef struct rbd_t    rbd_t;
00350 struct rbd_t
00351 {
00352         unsigned short  rbd_status;             /* Written by the 82586 */
00353 #define         RBD_STATUS_EOF  (0x1 << 15)     /* This RBD is the      */
00354                                                 /* last for this frame  */
00355 #define         RBD_STATUS_F    (0x1 << 14)     /* ACNT field is valid  */
00356 #define         RBD_STATUS_ACNT (0x3FFF << 0)   /* Actual no. of data   */
00357                                                 /* bytes in this buffer */
00358         unsigned short  rbd_next_rbd_offset;    /* Next rbd in list     */
00359         unsigned short  rbd_bufl;               /* Data pointer (low)   */
00360         unsigned short  rbd_bufh;               /*  "      "    (high)  */
00361         unsigned short  rbd_el_size;            /* EL+Data buf. size    */
00362 #define         RBD_EL  (0x1 << 15)             /* This BD is the       */
00363                                                 /* last in the list     */
00364 #define         RBD_SIZE (0x3FFF << 0)          /* No. of bytes the     */
00365                                                 /* buffer can hold      */
00366 };
00367 
00368 #define rbdoff(p,f)     toff(rbd_t, p, f)
00369 
00370 /*
00371  * Frame Descriptor (FD).
00372  */
00373 typedef struct fd_t     fd_t;
00374 struct fd_t
00375 {
00376         unsigned short  fd_status;              /* Written by the 82586 */
00377 #define         FD_STATUS_C     (0x1 << 15)     /* Completed storing frame */
00378 #define         FD_STATUS_B     (0x1 << 14)     /* FD was consumed by RU */
00379 #define         FD_STATUS_OK    (0x1 << 13)     /* Frame rxd successfully */
00380 #define         FD_STATUS_S11   (0x1 << 11)     /* CRC error            */
00381 #define         FD_STATUS_S10   (0x1 << 10)     /* Alignment error      */
00382 #define         FD_STATUS_S9    (0x1 <<  9)     /* Ran out of resources */
00383 #define         FD_STATUS_S8    (0x1 <<  8)     /* Rx DMA overrun       */
00384 #define         FD_STATUS_S7    (0x1 <<  7)     /* Frame too short      */
00385 #define         FD_STATUS_S6    (0x1 <<  6)     /* No EOF flag          */
00386         unsigned short  fd_command;             /* Command              */
00387 #define         FD_COMMAND_EL   (0x1 << 15)     /* Last FD in list      */
00388 #define         FD_COMMAND_S    (0x1 << 14)     /* Suspend RU after rx  */
00389         unsigned short  fd_link_offset;         /* Next FD              */
00390         unsigned short  fd_rbd_offset;          /* First RBD (data)     */
00391                                                 /* Prepared by CPU,     */
00392                                                 /* updated by 82586     */
00393 #if     0
00394 I think the rest is unused since we
00395 have set AC_CFG_ALOC(..).  However, just
00396 in case, we leave the space.
00397 #endif  /* 0 */
00398         unsigned char   fd_dest[ADDR_LEN];      /* Destination address  */
00399                                                 /* Written by 82586     */
00400         unsigned char   fd_src[ADDR_LEN];       /* Source address       */
00401                                                 /* Written by 82586     */
00402         unsigned short  fd_length;              /* Frame length or type */
00403                                                 /* Written by 82586     */
00404 };
00405 
00406 #define fdoff(p,f)      toff(fd_t, p, f)
00407 
00408 /*
00409  * This software may only be used and distributed
00410  * according to the terms of the GNU Public License.
00411  *
00412  * For more details, see wavelan.c.
00413  */