i82586.h revision 50477
177957Sbenno/*- 290643Sbenno * Copyright (c) 1992, University of Vermont and State Agricultural College. 390643Sbenno * Copyright (c) 1992, Garrett A. Wollman. 490643Sbenno * All rights reserved. 590643Sbenno * 690643Sbenno * Redistribution and use in source and binary forms, with or without 790643Sbenno * modification, are permitted provided that the following conditions 890643Sbenno * are met: 990643Sbenno * 1. Redistributions of source code must retain the above copyright 1090643Sbenno * notice, this list of conditions and the following disclaimer. 1190643Sbenno * 2. Redistributions in binary form must reproduce the above copyright 1290643Sbenno * notice, this list of conditions and the following disclaimer in the 1390643Sbenno * documentation and/or other materials provided with the distribution. 1490643Sbenno * 3. All advertising materials mentioning features or use of this software 1590643Sbenno * must display the following acknowledgement: 1690643Sbenno * This product includes software developed by the University of 1790643Sbenno * Vermont and State Agricultural College and Garrett A. Wollman. 1890643Sbenno * 4. Neither the name of the University nor the name of the author 1990643Sbenno * may be used to endorse or promote products derived from this software 2090643Sbenno * without specific prior written permission. 2190643Sbenno * 2290643Sbenno * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2390643Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2490643Sbenno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2590643Sbenno * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHOR BE LIABLE 2690643Sbenno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2790643Sbenno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2890643Sbenno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2990643Sbenno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3090643Sbenno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3190643Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3290643Sbenno * SUCH DAMAGE. 3390643Sbenno * 3490643Sbenno * $FreeBSD: head/sys/dev/ic/i82586.h 50477 1999-08-28 01:08:13Z peter $ 3590643Sbenno */ 3690643Sbenno 3777957Sbenno/* 3877957Sbenno * Intel 82586 Ethernet chip 3977957Sbenno * Register, bit, and structure definitions. 4077957Sbenno * 4177957Sbenno * Written by GAW with reference to the Clarkson Packet Driver code for this 4277957Sbenno * chip written by Russ Nelson and others. 4377957Sbenno */ 4477957Sbenno 4577957Sbennostruct ie_en_addr { 4677957Sbenno u_char data[6]; 4777957Sbenno}; 4877957Sbenno 4977957Sbenno/* 5077957Sbenno * This is the master configuration block. It tells the hardware where all 5177957Sbenno * the rest of the stuff is. 5277957Sbenno */ 5377957Sbennostruct ie_sys_conf_ptr { 5477957Sbenno u_short mbz; /* must be zero */ 5577957Sbenno u_char ie_bus_use; /* true if 8-bit only */ 5677957Sbenno u_char mbz2[5]; /* must be zero */ 5777957Sbenno caddr_t ie_iscp_ptr; /* 24-bit physaddr of ISCP */ 5877957Sbenno}; 5977957Sbenno 6077957Sbenno/* 6177957Sbenno * Note that this is wired in hardware; the SCP is always located here, no 6277957Sbenno * matter what. 6377957Sbenno */ 6477957Sbenno#define IE_SCP_ADDR 0xfffff4 6577957Sbenno 6678880Sbenno/* 6777957Sbenno * The tells the hardware where all the rest of the stuff is, too. 6877957Sbenno * FIXME: some of these should be re-commented after we figure out their 6977957Sbenno * REAL function. 7077957Sbenno */ 7177957Sbennostruct ie_int_sys_conf_ptr { 7277957Sbenno u_char ie_busy; /* zeroed after init */ 7377957Sbenno u_char mbz; 7477957Sbenno u_short ie_scb_offset; /* 16-bit physaddr of next struct */ 7577957Sbenno caddr_t ie_base; /* 24-bit physaddr for all 16-bit vars */ 7677957Sbenno}; 7777957Sbenno 7877957Sbenno/* 7977957Sbenno * This FINALLY tells the hardware what to do and where to put it. 8077957Sbenno */ 8177957Sbennostruct ie_sys_ctl_block { 8277957Sbenno u_short ie_status; /* status word */ 8377957Sbenno u_short ie_command; /* command word */ 8477957Sbenno u_short ie_command_list; /* 16-pointer to command block list */ 8577957Sbenno u_short ie_recv_list; /* 16-pointer to receive frame list */ 8677957Sbenno u_short ie_err_crc; /* CRC errors */ 8777957Sbenno u_short ie_err_align; /* Alignment errors */ 8877957Sbenno u_short ie_err_resource; /* Resource errors */ 8977957Sbenno u_short ie_err_overrun; /* Overrun errors */ 9077957Sbenno}; 9177957Sbenno 9277957Sbenno/* Command values */ 9377957Sbenno#define IE_RU_COMMAND 0x0070 /* mask for RU command */ 9477957Sbenno#define IE_RU_NOP 0 /* for completeness */ 9577957Sbenno#define IE_RU_START 0x0010 /* start receive unit command */ 9677957Sbenno#define IE_RU_ENABLE 0x0020 /* enable receiver command */ 9777957Sbenno#define IE_RU_DISABLE 0x0030 /* disable receiver command */ 9890643Sbenno#define IE_RU_ABORT 0x0040 /* abort current receive operation */ 9990643Sbenno 10090643Sbenno#define IE_CU_COMMAND 0x0700 /* mask for CU command */ 10190643Sbenno#define IE_CU_NOP 0 /* included for completeness */ 10290643Sbenno#define IE_CU_START 0x0100 /* do-command command */ 10390643Sbenno#define IE_CU_RESUME 0x0200 /* resume a suspended cmd list */ 10490643Sbenno#define IE_CU_STOP 0x0300 /* SUSPEND was already taken */ 10590643Sbenno#define IE_CU_ABORT 0x0400 /* abort current command */ 10690643Sbenno 10790643Sbenno#define IE_ACK_COMMAND 0xf000 /* mask for ACK command */ 10890643Sbenno#define IE_ACK_CX 0x8000 /* ack IE_ST_DONE */ 10990643Sbenno#define IE_ACK_FR 0x4000 /* ack IE_ST_RECV */ 11090643Sbenno#define IE_ACK_CNA 0x2000 /* ack IE_ST_ALLDONE */ 11190643Sbenno#define IE_ACK_RNR 0x1000 /* ack IE_ST_RNR */ 11290643Sbenno 11390643Sbenno#define IE_ACTION_COMMAND(x) (((x) & IE_CU_COMMAND) == IE_CU_START) 11490643Sbenno /* is this command an action command? */ 11590643Sbenno 11690643Sbenno/* Status values */ 11790643Sbenno#define IE_ST_WHENCE 0xf000 /* mask for cause of interrupt */ 11890643Sbenno#define IE_ST_DONE 0x8000 /* command with I bit completed */ 11977957Sbenno#define IE_ST_RECV 0x4000 /* frame received */ 12080431Speter#define IE_ST_ALLDONE 0x2000 /* all commands completed */ 12190643Sbenno#define IE_ST_RNR 0x1000 /* receive not ready */ 12290643Sbenno 12390643Sbenno#define IE_CU_STATUS 0x700 /* mask for command unit status */ 12490643Sbenno#define IE_CU_ACTIVE 0x200 /* command unit is active */ 12577957Sbenno#define IE_CU_SUSPEND 0x100 /* command unit is suspended */ 12690643Sbenno 12790643Sbenno#define IE_RU_STATUS 0x70 /* mask for receiver unit status */ 12877957Sbenno#define IE_RU_SUSPEND 0x10 /* receiver is suspended */ 12977957Sbenno#define IE_RU_NOSPACE 0x20 /* receiver has no resources */ 13090643Sbenno#define IE_RU_READY 0x40 /* reveiver is ready */ 13190643Sbenno 13290643Sbenno/* 13377957Sbenno * This is filled in partially by the chip, partially by us. 13477957Sbenno */ 13577957Sbennostruct ie_recv_frame_desc { 13677957Sbenno u_short ie_fd_status; /* status for this frame */ 13777957Sbenno u_short ie_fd_last; /* end of frame list flag */ 13877957Sbenno u_short ie_fd_next; /* 16-pointer to next RFD */ 13977957Sbenno u_short ie_fd_buf_desc; /* 16-pointer to list of buffer desc's */ 14077957Sbenno struct ie_en_addr dest; /* destination ether */ 14177957Sbenno struct ie_en_addr src; /* source ether */ 14277957Sbenno u_short ie_length; /* 802 length/Ether type */ 14383730Smp u_short mbz; /* must be zero */ 14490643Sbenno}; 14590643Sbenno 14690643Sbenno#define IE_FD_LAST 0x8000 /* last rfd in list */ 14777957Sbenno#define IE_FD_SUSP 0x4000 /* suspend RU after receipt */ 14890643Sbenno 14977957Sbenno#define IE_FD_COMPLETE 0x8000 /* frame is complete */ 15090643Sbenno#define IE_FD_BUSY 0x4000 /* frame is busy */ 15177957Sbenno#define IE_FD_OK 0x2000 /* frame is bad */ 15290643Sbenno#define IE_FD_RNR 0x0200 /* receiver out of resources here */ 15377957Sbenno 15490643Sbenno/* 15590643Sbenno * linked list of buffers... 15690643Sbenno */ 15790643Sbennostruct ie_recv_buf_desc { 15890643Sbenno u_short ie_rbd_actual; /* status for this buffer */ 15990643Sbenno u_short ie_rbd_next; /* 16-pointer to next RBD */ 16090643Sbenno caddr_t ie_rbd_buffer; /* 24-pointer to buffer for this RBD */ 16190643Sbenno u_short ie_rbd_length; /* length of the buffer */ 16290643Sbenno u_short mbz; /* must be zero */ 16390643Sbenno}; 16490643Sbenno 16590643Sbenno#define IE_RBD_LAST 0x8000 /* last buffer */ 16690643Sbenno#define IE_RBD_USED 0x4000 /* this buffer has data */ 16790643Sbenno/* 16890643Sbenno * All commands share this in common. 16990643Sbenno */ 17090643Sbennostruct ie_cmd_common { 17190643Sbenno u_short ie_cmd_status; /* status of this command */ 17290643Sbenno u_short ie_cmd_cmd; /* command word */ 17390643Sbenno u_short ie_cmd_link; /* link to next command */ 17490643Sbenno}; 17590643Sbenno 17690643Sbenno#define IE_STAT_COMPL 0x8000 /* command is completed */ 17790643Sbenno#define IE_STAT_BUSY 0x4000 /* command is running now */ 17890643Sbenno#define IE_STAT_OK 0x2000 /* command completed successfully */ 17990643Sbenno 18090643Sbenno#define IE_CMD_NOP 0x0000 /* NOP */ 18190643Sbenno#define IE_CMD_IASETUP 0x0001 /* initial address setup */ 18290643Sbenno#define IE_CMD_CONFIG 0x0002 /* configure command */ 18390643Sbenno#define IE_CMD_MCAST 0x0003 /* multicast setup command */ 18490643Sbenno#define IE_CMD_XMIT 0x0004 /* transmit command */ 18577957Sbenno#define IE_CMD_TDR 0x0005 /* time-domain reflectometer command */ 18677957Sbenno#define IE_CMD_DUMP 0x0006 /* dump command */ 18790643Sbenno#define IE_CMD_DIAGNOSE 0x0007 /* diagnostics command */ 18890643Sbenno 18990643Sbenno#define IE_CMD_LAST 0x8000 /* this is the last command in the list */ 19090643Sbenno#define IE_CMD_SUSPEND 0x4000 /* suspend CU after this command */ 19190643Sbenno#define IE_CMD_INTR 0x2000 /* post an interrupt after completion */ 19290643Sbenno 19377957Sbenno/* 19490643Sbenno * This is the command to transmit a frame. 19577957Sbenno */ 19690643Sbennostruct ie_xmit_cmd { 19790643Sbenno struct ie_cmd_common com; /* common part */ 19890643Sbenno#define ie_xmit_status com.ie_cmd_status 19990643Sbenno 20090643Sbenno u_short ie_xmit_desc; /* 16-pointer to buffer descriptor */ 20177957Sbenno struct ie_en_addr ie_xmit_addr; /* destination address */ 20290643Sbenno 20390643Sbenno u_short ie_xmit_length; /* 802.3 length/Ether type field */ 20490643Sbenno}; 20590643Sbenno 20690643Sbenno#define IE_XS_MAXCOLL 0x000f /* number of collisions during transmit */ 20777957Sbenno#define IE_XS_EXCMAX 0x0020 /* exceeded maximum number of collisions */ 20890643Sbenno#define IE_XS_SQE 0x0040 /* SQE positive */ 20990643Sbenno#define IE_XS_DEFERRED 0x0080 /* transmission deferred */ 21090643Sbenno#define IE_XS_UNDERRUN 0x0100 /* DMA underrun */ 21190643Sbenno#define IE_XS_LOSTCTS 0x0200 /* Lost CTS */ 21290643Sbenno#define IE_XS_NOCARRIER 0x0400 /* No Carrier */ 21390643Sbenno#define IE_XS_LATECOLL 0x0800 /* Late collision */ 21490643Sbenno 21590643Sbenno/* 21677957Sbenno * This is a buffer descriptor for a frame to be transmitted. 21790643Sbenno */ 21890643Sbenno 21990643Sbennostruct ie_xmit_buf { 22090643Sbenno u_short ie_xmit_flags; /* see below */ 22190643Sbenno u_short ie_xmit_next; /* 16-pointer to next desc. */ 22290643Sbenno caddr_t ie_xmit_buf; /* 24-pointer to the actual buffer */ 22377957Sbenno}; 22490643Sbenno 22590643Sbenno#define IE_XMIT_LAST 0x8000 /* this TBD is the last one */ 22690643Sbenno/* The rest of the `flags' word is actually the length. */ 22790643Sbenno 22890643Sbenno/* 22977957Sbenno * Multicast setup command. 23090643Sbenno */ 23190643Sbenno 23290643Sbenno#define MAXMCAST 50 /* must fit in transmit buffer */ 23390643Sbenno 23490643Sbennostruct ie_mcast_cmd { 23590643Sbenno struct ie_cmd_common com; /* common part */ 23677957Sbenno#define ie_mcast_status com.ie_cmd_status 23790643Sbenno 23890643Sbenno u_short ie_mcast_bytes; /* size (in bytes) of multicast addresses */ 23990643Sbenno struct ie_en_addr ie_mcast_addrs[MAXMCAST + 1]; /* space for them */ 24090643Sbenno}; 24190643Sbenno 24290643Sbenno/* 24390643Sbenno * Time Domain Reflectometer command. 24490643Sbenno */ 24577957Sbenno 24690643Sbennostruct ie_tdr_cmd { 24790643Sbenno struct ie_cmd_common com; /* common part */ 24890643Sbenno#define ie_tdr_status com.ie_cmd_status 24990643Sbenno 25090643Sbenno u_short ie_tdr_time; /* error bits and time */ 25190643Sbenno}; 25277957Sbenno 25390643Sbenno#define IE_TDR_SUCCESS 0x8000 /* TDR succeeded without error */ 25490643Sbenno#define IE_TDR_XCVR 0x4000 /* detected a transceiver problem */ 25577957Sbenno#define IE_TDR_OPEN 0x2000 /* detected an open */ 25690643Sbenno#define IE_TDR_SHORT 0x1000 /* TDR detected a short */ 25790643Sbenno#define IE_TDR_TIME 0x07ff /* mask for reflection time */ 25877957Sbenno 25990643Sbenno/* 26077957Sbenno * Initial Address Setup command 26190643Sbenno */ 26290643Sbennostruct ie_iasetup_cmd { 26390643Sbenno struct ie_cmd_common com; 26490643Sbenno#define ie_iasetup_status com.ie_cmd_status 26590643Sbenno 26690643Sbenno struct ie_en_addr ie_address; 26790643Sbenno}; 26890643Sbenno 26990643Sbenno/* 27090643Sbenno * Configuration command 27190643Sbenno */ 27290643Sbennostruct ie_config_cmd { 27390643Sbenno struct ie_cmd_common com; /* common part */ 27490643Sbenno#define ie_config_status com.ie_cmd_status 27590643Sbenno 27690643Sbenno u_char ie_config_count; /* byte count (0x0c) */ 27790643Sbenno u_char ie_fifo; /* fifo (8) */ 27890643Sbenno u_char ie_save_bad; /* save bad frames (0x40) */ 27990643Sbenno u_char ie_addr_len; /* address length (0x2e) (AL-LOC == 1) */ 28090643Sbenno u_char ie_priority; /* priority and backoff (0x0) */ 28190643Sbenno u_char ie_ifs; /* inter-frame spacing (0x60) */ 28290643Sbenno u_char ie_slot_low; /* slot time, LSB (0x0) */ 28390643Sbenno u_char ie_slot_high; /* slot time, MSN, and retries (0xf2) */ 28490643Sbenno u_char ie_promisc; /* 1 if promiscuous, else 0 */ 28577957Sbenno u_char ie_crs_cdt; /* CSMA/CD parameters (0x0) */ 28690643Sbenno u_char ie_min_len; /* min frame length (0x40) */ 28777957Sbenno u_char ie_junk; /* stuff for 82596 (0xff) */ 28890643Sbenno}; 28990643Sbenno 29077957Sbenno/* 29190643Sbenno * Here are a few useful functions. We could have done these as macros, 29290643Sbenno * but since we have the inline facility, it makes sense to use that 29390643Sbenno * instead. 29490643Sbenno */ 29577957Sbennostatic __inline void 29690643Sbennoie_setup_config(volatile struct ie_config_cmd *cmd, 29790643Sbenno int promiscuous, int manchester) { 29890643Sbenno cmd->ie_config_count = 0x0c; 29990643Sbenno cmd->ie_fifo = 8; 30077957Sbenno cmd->ie_save_bad = 0x40; 30177957Sbenno cmd->ie_addr_len = 0x2e; 30290643Sbenno cmd->ie_priority = 0; 30377957Sbenno cmd->ie_ifs = 0x60; 30490643Sbenno cmd->ie_slot_low = 0; 30590643Sbenno cmd->ie_slot_high = 0xf2; 30690643Sbenno cmd->ie_promisc = !!promiscuous | manchester << 2; 30790643Sbenno cmd->ie_crs_cdt = 0; 30890643Sbenno cmd->ie_min_len = 64; 30990643Sbenno cmd->ie_junk = 0xff; 31090643Sbenno} 31190643Sbenno 31290643Sbennostatic __inline void * 31390643SbennoAlign(void *ptr) { 31490643Sbenno uintptr_t l = (uintptr_t)ptr; 31590643Sbenno l = (l + 3) & ~3L; 31690643Sbenno return (void *)l; 31790643Sbenno} 31890643Sbenno 31990643Sbennostatic __inline volatile void * 32090643SbennoAlignvol(volatile void *ptr) { 32190643Sbenno uintptr_t l = (uintptr_t)ptr; 32290643Sbenno l = (l + 3) & ~3L; 32390643Sbenno return (volatile void *)l; 32477957Sbenno} 32590643Sbenno 32690643Sbennostatic __inline void 32777957Sbennoie_ack(volatile struct ie_sys_ctl_block *scb, 32890643Sbenno u_int mask, int unit, 32990643Sbenno void (*ca)(int)) { 33090643Sbenno scb->ie_command = scb->ie_status & mask; 33190643Sbenno (*ca)(unit); 33290643Sbenno} 33390643Sbenno