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