i82586.h revision 38232
10SN/A/*-
28276SN/A * Copyright (c) 1992, University of Vermont and State Agricultural College.
30SN/A * Copyright (c) 1992, Garrett A. Wollman.
40SN/A * All rights reserved.
50SN/A *
60SN/A * Redistribution and use in source and binary forms, with or without
70SN/A * modification, are permitted provided that the following conditions
80SN/A * are met:
90SN/A * 1. Redistributions of source code must retain the above copyright
100SN/A *    notice, this list of conditions and the following disclaimer.
110SN/A * 2. Redistributions in binary form must reproduce the above copyright
120SN/A *    notice, this list of conditions and the following disclaimer in the
130SN/A *    documentation and/or other materials provided with the distribution.
140SN/A * 3. All advertising materials mentioning features or use of this software
150SN/A *    must display the following acknowledgement:
160SN/A *	This product includes software developed by the University of
170SN/A *	Vermont and State Agricultural College and Garrett A. Wollman.
180SN/A * 4. Neither the name of the University nor the name of the author
191472SN/A *    may be used to endorse or promote products derived from this software
201472SN/A *    without specific prior written permission.
211472SN/A *
220SN/A * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
230SN/A * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
240SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251879SN/A * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHOR BE LIABLE
268413Spliden * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
278276SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281879SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
290SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
300SN/A * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
310SN/A * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
320SN/A * SUCH DAMAGE.
330SN/A *
340SN/A *	$Id: i82586.h,v 1.6 1998/04/15 17:45:58 bde Exp $
350SN/A */
360SN/A
370SN/A/*
380SN/A * Intel 82586 Ethernet chip
390SN/A * Register, bit, and structure definitions.
400SN/A *
410SN/A * Written by GAW with reference to the Clarkson Packet Driver code for this
420SN/A * chip written by Russ Nelson and others.
430SN/A */
440SN/A
450SN/Astruct ie_en_addr {
460SN/A	u_char data[6];
470SN/A};
480SN/A
490SN/A/*
500SN/A * This is the master configuration block.  It tells the hardware where all
510SN/A * the rest of the stuff is.
520SN/A */
530SN/Astruct ie_sys_conf_ptr {
540SN/A	u_short mbz;			/* must be zero */
550SN/A	u_char ie_bus_use;		/* true if 8-bit only */
560SN/A	u_char mbz2[5];			/* must be zero */
570SN/A	caddr_t ie_iscp_ptr;		/* 24-bit physaddr of ISCP */
580SN/A};
590SN/A
600SN/A/*
610SN/A * Note that this is wired in hardware; the SCP is always located here, no
620SN/A * matter what.
630SN/A */
640SN/A#define IE_SCP_ADDR 0xfffff4
650SN/A
660SN/A/*
670SN/A * The tells the hardware where all the rest of the stuff is, too.
680SN/A * FIXME: some of these should be re-commented after we figure out their
690SN/A * REAL function.
700SN/A */
710SN/Astruct ie_int_sys_conf_ptr {
720SN/A	u_char ie_busy;			/* zeroed after init */
730SN/A	u_char mbz;
740SN/A	u_short ie_scb_offset;		/* 16-bit physaddr of next struct */
750SN/A	caddr_t ie_base;		/* 24-bit physaddr for all 16-bit vars */
76237SN/A};
77237SN/A
780SN/A/*
790SN/A * This FINALLY tells the hardware what to do and where to put it.
800SN/A */
810SN/Astruct ie_sys_ctl_block {
820SN/A	u_short ie_status;		/* status word */
83535SN/A	u_short ie_command;		/* command word */
840SN/A	u_short ie_command_list;	/* 16-pointer to command block list */
850SN/A	u_short ie_recv_list;		/* 16-pointer to receive frame list */
860SN/A	u_short ie_err_crc;		/* CRC errors */
870SN/A	u_short ie_err_align;		/* Alignment errors */
880SN/A	u_short ie_err_resource;	/* Resource errors */
890SN/A	u_short ie_err_overrun;		/* Overrun errors */
900SN/A};
910SN/A
924820SN/A/* Command values */
934820SN/A#define IE_RU_COMMAND	0x0070	/* mask for RU command */
940SN/A#define IE_RU_NOP	0	/* for completeness */
950SN/A#define IE_RU_START	0x0010	/* start receive unit command */
960SN/A#define IE_RU_ENABLE	0x0020	/* enable receiver command */
970SN/A#define IE_RU_DISABLE	0x0030	/* disable receiver command */
980SN/A#define IE_RU_ABORT	0x0040	/* abort current receive operation */
990SN/A
1000SN/A#define IE_CU_COMMAND	0x0700	/* mask for CU command */
1010SN/A#define IE_CU_NOP	0	/* included for completeness */
1020SN/A#define IE_CU_START	0x0100	/* do-command command */
1030SN/A#define IE_CU_RESUME	0x0200	/* resume a suspended cmd list */
1040SN/A#define IE_CU_STOP	0x0300	/* SUSPEND was already taken */
1050SN/A#define IE_CU_ABORT	0x0400	/* abort current command */
1060SN/A
1070SN/A#define IE_ACK_COMMAND	0xf000	/* mask for ACK command */
1080SN/A#define IE_ACK_CX	0x8000	/* ack IE_ST_DONE */
1090SN/A#define IE_ACK_FR	0x4000	/* ack IE_ST_RECV */
1100SN/A#define IE_ACK_CNA	0x2000	/* ack IE_ST_ALLDONE */
1110SN/A#define IE_ACK_RNR	0x1000	/* ack IE_ST_RNR */
1120SN/A
1130SN/A#define IE_ACTION_COMMAND(x) (((x) & IE_CU_COMMAND) == IE_CU_START)
1140SN/A				/* is this command an action command? */
1150SN/A
1160SN/A/* Status values */
1170SN/A#define IE_ST_WHENCE	0xf000	/* mask for cause of interrupt */
1180SN/A#define IE_ST_DONE	0x8000	/* command with I bit completed */
1190SN/A#define IE_ST_RECV	0x4000	/* frame received */
1200SN/A#define IE_ST_ALLDONE	0x2000	/* all commands completed */
1210SN/A#define IE_ST_RNR	0x1000	/* receive not ready */
1220SN/A
1230SN/A#define IE_CU_STATUS	0x700	/* mask for command unit status */
1240SN/A#define IE_CU_ACTIVE	0x200	/* command unit is active */
1250SN/A#define IE_CU_SUSPEND	0x100	/* command unit is suspended */
1260SN/A
1270SN/A#define IE_RU_STATUS	0x70	/* mask for receiver unit status */
1280SN/A#define IE_RU_SUSPEND	0x10	/* receiver is suspended */
1290SN/A#define IE_RU_NOSPACE	0x20	/* receiver has no resources */
1300SN/A#define IE_RU_READY	0x40	/* reveiver is ready */
1310SN/A
1320SN/A/*
1330SN/A * This is filled in partially by the chip, partially by us.
1340SN/A */
1350SN/Astruct ie_recv_frame_desc {
1360SN/A	u_short ie_fd_status;		/* status for this frame */
1370SN/A	u_short ie_fd_last;		/* end of frame list flag */
1380SN/A	u_short ie_fd_next;		/* 16-pointer to next RFD */
1390SN/A	u_short ie_fd_buf_desc;		/* 16-pointer to list of buffer desc's */
1400SN/A	struct ie_en_addr dest;		/* destination ether */
1410SN/A	struct ie_en_addr src;		/* source ether */
1420SN/A	u_short ie_length;		/* 802 length/Ether type */
1430SN/A	u_short mbz;			/* must be zero */
1440SN/A};
1450SN/A
1464820SN/A#define IE_FD_LAST	0x8000	/* last rfd in list */
1470SN/A#define IE_FD_SUSP	0x4000	/* suspend RU after receipt */
1480SN/A
1490SN/A#define IE_FD_COMPLETE	0x8000	/* frame is complete */
1500SN/A#define IE_FD_BUSY	0x4000	/* frame is busy */
1510SN/A#define IE_FD_OK	0x2000	/* frame is bad */
1520SN/A#define IE_FD_RNR	0x0200	/* receiver out of resources here */
1530SN/A
1540SN/A/*
1550SN/A * linked list of buffers...
1560SN/A */
1570SN/Astruct ie_recv_buf_desc {
1580SN/A	u_short ie_rbd_actual;		/* status for this buffer */
1590SN/A	u_short ie_rbd_next;		/* 16-pointer to next RBD */
1600SN/A	caddr_t ie_rbd_buffer;		/* 24-pointer to buffer for this RBD */
1610SN/A	u_short ie_rbd_length;		/* length of the buffer */
1620SN/A	u_short mbz;			/* must be zero */
1630SN/A};
1640SN/A
1650SN/A#define IE_RBD_LAST	0x8000	/* last buffer */
1660SN/A#define IE_RBD_USED	0x4000	/* this buffer has data */
1670SN/A/*
1680SN/A * All commands share this in common.
1690SN/A */
1700SN/Astruct ie_cmd_common {
1710SN/A	u_short ie_cmd_status;		/* status of this command */
1720SN/A	u_short ie_cmd_cmd;		/* command word */
1730SN/A	u_short ie_cmd_link;		/* link to next command */
1740SN/A};
1750SN/A
1760SN/A#define IE_STAT_COMPL	0x8000	/* command is completed */
1770SN/A#define IE_STAT_BUSY	0x4000	/* command is running now */
1780SN/A#define IE_STAT_OK	0x2000	/* command completed successfully */
1790SN/A
1800SN/A#define IE_CMD_NOP	0x0000	/* NOP */
1810SN/A#define IE_CMD_IASETUP	0x0001	/* initial address setup */
1820SN/A#define IE_CMD_CONFIG	0x0002	/* configure command */
1830SN/A#define IE_CMD_MCAST	0x0003	/* multicast setup command */
1840SN/A#define IE_CMD_XMIT	0x0004	/* transmit command */
1850SN/A#define IE_CMD_TDR	0x0005	/* time-domain reflectometer command */
1860SN/A#define IE_CMD_DUMP	0x0006	/* dump command */
1870SN/A#define IE_CMD_DIAGNOSE	0x0007	/* diagnostics command */
1880SN/A
1890SN/A#define IE_CMD_LAST	0x8000	/* this is the last command in the list */
1900SN/A#define IE_CMD_SUSPEND	0x4000	/* suspend CU after this command */
1910SN/A#define IE_CMD_INTR	0x2000	/* post an interrupt after completion */
1920SN/A
1930SN/A/*
1940SN/A * This is the command to transmit a frame.
1950SN/A */
1960SN/Astruct ie_xmit_cmd {
1970SN/A	struct ie_cmd_common com;	/* common part */
1980SN/A#define ie_xmit_status com.ie_cmd_status
1990SN/A
2000SN/A	u_short ie_xmit_desc;		/* 16-pointer to buffer descriptor */
2010SN/A	struct ie_en_addr ie_xmit_addr; /* destination address */
2020SN/A
2030SN/A	u_short ie_xmit_length;		/* 802.3 length/Ether type field */
2040SN/A};
2050SN/A
2060SN/A#define IE_XS_MAXCOLL  	0x000f	/* number of collisions during transmit */
2070SN/A#define IE_XS_EXCMAX	0x0020	/* exceeded maximum number of collisions */
2080SN/A#define IE_XS_SQE	0x0040	/* SQE positive */
2090SN/A#define IE_XS_DEFERRED	0x0080	/* transmission deferred */
2100SN/A#define IE_XS_UNDERRUN	0x0100	/* DMA underrun */
2110SN/A#define IE_XS_LOSTCTS	0x0200	/* Lost CTS */
2120SN/A#define IE_XS_NOCARRIER	0x0400	/* No Carrier */
2130SN/A#define IE_XS_LATECOLL	0x0800	/* Late collision */
2140SN/A
2150SN/A/*
2160SN/A * This is a buffer descriptor for a frame to be transmitted.
2170SN/A */
2180SN/A
2190SN/Astruct ie_xmit_buf {
2208052SN/A	u_short ie_xmit_flags;		/* see below */
2210SN/A	u_short ie_xmit_next;		/* 16-pointer to next desc. */
2220SN/A	caddr_t ie_xmit_buf;		/* 24-pointer to the actual buffer */
2230SN/A};
2240SN/A
2250SN/A#define IE_XMIT_LAST 0x8000	/* this TBD is the last one */
2260SN/A/* The rest of the `flags' word is actually the length. */
2270SN/A
2280SN/A/*
2290SN/A * Multicast setup command.
2300SN/A */
2310SN/A
2320SN/A#define MAXMCAST 50		/* must fit in transmit buffer */
2330SN/A
2340SN/Astruct ie_mcast_cmd {
2350SN/A	struct ie_cmd_common com;	/* common part */
2360SN/A#define ie_mcast_status com.ie_cmd_status
2370SN/A
238535SN/A	u_short ie_mcast_bytes;	/* size (in bytes) of multicast addresses */
2390SN/A	struct ie_en_addr ie_mcast_addrs[MAXMCAST + 1];	/* space for them */
2400SN/A};
2410SN/A
2420SN/A/*
2430SN/A * Time Domain Reflectometer command.
2440SN/A */
2450SN/A
2460SN/Astruct ie_tdr_cmd {
2474820SN/A	struct ie_cmd_common com;	/* common part */
2484820SN/A#define ie_tdr_status com.ie_cmd_status
2490SN/A
2500SN/A	u_short ie_tdr_time;		/* error bits and time */
2510SN/A};
2520SN/A
2530SN/A#define IE_TDR_SUCCESS	0x8000	/* TDR succeeded without error */
2540SN/A#define IE_TDR_XCVR	0x4000	/* detected a transceiver problem */
2550SN/A#define IE_TDR_OPEN	0x2000	/* detected an open */
2560SN/A#define IE_TDR_SHORT	0x1000	/* TDR detected a short */
2570SN/A#define IE_TDR_TIME	0x07ff	/* mask for reflection time */
2580SN/A
2590SN/A/*
2600SN/A * Initial Address Setup command
2610SN/A */
2620SN/Astruct ie_iasetup_cmd {
2630SN/A	struct ie_cmd_common com;
2640SN/A#define ie_iasetup_status com.ie_cmd_status
2650SN/A
2660SN/A	struct ie_en_addr ie_address;
2670SN/A};
2680SN/A
2690SN/A/*
2700SN/A * Configuration command
2710SN/A */
2720SN/Astruct ie_config_cmd {
2730SN/A	struct ie_cmd_common com;	/* common part */
2740SN/A#define ie_config_status com.ie_cmd_status
2750SN/A
2760SN/A	u_char ie_config_count;		/* byte count (0x0c) */
2770SN/A	u_char ie_fifo;			/* fifo (8) */
2780SN/A	u_char ie_save_bad;		/* save bad frames (0x40) */
2790SN/A	u_char ie_addr_len;		/* address length (0x2e) (AL-LOC == 1) */
2800SN/A	u_char ie_priority;		/* priority and backoff (0x0) */
2810SN/A	u_char ie_ifs;			/* inter-frame spacing (0x60) */
2820SN/A	u_char ie_slot_low;		/* slot time, LSB (0x0) */
2830SN/A	u_char ie_slot_high;		/* slot time, MSN, and retries (0xf2) */
2840SN/A	u_char ie_promisc;		/* 1 if promiscuous, else 0 */
2850SN/A	u_char ie_crs_cdt;		/* CSMA/CD parameters (0x0) */
2860SN/A	u_char ie_min_len;		/* min frame length (0x40) */
2870SN/A	u_char ie_junk;			/* stuff for 82596 (0xff) */
2880SN/A};
2890SN/A
2900SN/A/*
2910SN/A * Here are a few useful functions.  We could have done these as macros,
2920SN/A * but since we have the inline facility, it makes sense to use that
2930SN/A * instead.
2940SN/A */
2950SN/Astatic __inline void
2960SN/Aie_setup_config(volatile struct ie_config_cmd *cmd,
2970SN/A		int promiscuous, int manchester) {
2980SN/A	cmd->ie_config_count = 0x0c;
2990SN/A	cmd->ie_fifo = 8;
3000SN/A	cmd->ie_save_bad = 0x40;
3014820SN/A	cmd->ie_addr_len = 0x2e;
3020SN/A	cmd->ie_priority = 0;
3030SN/A	cmd->ie_ifs = 0x60;
3040SN/A	cmd->ie_slot_low = 0;
3050SN/A	cmd->ie_slot_high = 0xf2;
3060SN/A	cmd->ie_promisc = !!promiscuous | manchester << 2;
3070SN/A	cmd->ie_crs_cdt = 0;
3080SN/A	cmd->ie_min_len = 64;
3090SN/A	cmd->ie_junk = 0xff;
3100SN/A}
3110SN/A
3120SN/Astatic __inline caddr_t
3130SN/AAlign(caddr_t ptr) {
3140SN/A	uintptr_t l = (uintptr_t)ptr;
3150SN/A	l = (l + 3) & ~3L;
3160SN/A	return (caddr_t)l;
3170SN/A}
3180SN/A
3190SN/Astatic __inline void
3200SN/Aie_ack(volatile struct ie_sys_ctl_block *scb,
3210SN/A				  u_int mask, int unit,
3220SN/A				  void (*ca)(int)) {
3230SN/A	scb->ie_command = scb->ie_status & mask;
3240SN/A	(*ca)(unit);
3250SN/A}
3260SN/A