i82586.h 13.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
/*
 * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
 *
 * See:
 *	Intel Microcommunications 1991
 *	p1-1 to p1-37
 *	Intel order No. 231658
 *	ISBN 1-55512-119-5
 *
 *     Unfortunately, the above chapter mentions neither
 * the System Configuration Pointer (SCP) nor the
 * Intermediate System Configuration Pointer (ISCP),
 * so we probably need to look elsewhere for the
 * whole story -- some recommend the "Intel LAN
 * Components manual" but I have neither a copy
 * nor a full reference.  But "elsewhere" may be
 * in the same publication...
 *     The description of a later device, the
 * "82596CA High-Performance 32-Bit Local Area Network
 * Coprocessor", (ibid. p1-38 to p1-109) does mention
 * the SCP and ISCP and also has an i82586 compatibility
 * mode.  Even more useful is "AP-235 An 82586 Data Link
 * Driver" (ibid. p1-337 to p1-417).
 */

#define	I82586_MEMZ	(64 * 1024)

#define	I82586_SCP_ADDR	(I82586_MEMZ - sizeof(scp_t))

#define	ADDR_LEN	6
#define	I82586NULL	0xFFFF

#define	toff(t,p,f) 	(unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)

/*
 * System Configuration Pointer (SCP).
 */
typedef struct scp_t	scp_t;
struct scp_t
{
	unsigned short	scp_sysbus;	/* 82586 bus width:	*/
#define		SCP_SY_16BBUS	(0x0 << 0)	/* 16 bits */
#define		SCP_SY_8BBUS	(0x1 << 0)	/*  8 bits. */
	unsigned short	scp_junk[2];	/* Unused */
	unsigned short	scp_iscpl;	/* lower 16 bits of ISCP_ADDR */
	unsigned short	scp_iscph;	/* upper 16 bits of ISCP_ADDR */
};

/*
 * Intermediate System Configuration Pointer (ISCP).
 */
typedef struct iscp_t	iscp_t;
struct iscp_t
{
	unsigned short	iscp_busy;	/* set by CPU before first CA,	*/
					/* cleared by 82586 after read.	*/
	unsigned short	iscp_offset;	/* offset of SCB		*/
	unsigned short	iscp_basel;	/* base of SCB			*/
	unsigned short	iscp_baseh;	/*  "				*/
};

/*
 * System Control Block (SCB).
 *	The 82586 writes its status to scb_status and then
 *	raises an interrupt to alert the CPU.
 *	The CPU writes a command to scb_command and
 *	then issues a Channel Attention (CA) to alert the 82586.
 */
typedef struct scb_t	scb_t;
struct scb_t
{
	unsigned short	scb_status;	/* Status of 82586		*/
#define		SCB_ST_INT	(0xF << 12)	/* Some of:		*/
#define		SCB_ST_CX	(0x1 << 15)	/* Cmd completed	*/
#define		SCB_ST_FR	(0x1 << 14)	/* Frame received	*/
#define		SCB_ST_CNA	(0x1 << 13)	/* Cmd unit not active	*/
#define		SCB_ST_RNR	(0x1 << 12)	/* Rcv unit not ready	*/
#define		SCB_ST_JUNK0	(0x1 << 11)	/* 0			*/
#define		SCB_ST_CUS	(0x7 <<  8)	/* Cmd unit status	*/
#define			SCB_ST_CUS_IDLE	(0 << 8)	/* Idle		*/
#define			SCB_ST_CUS_SUSP	(1 << 8)	/* Suspended	*/
#define			SCB_ST_CUS_ACTV	(2 << 8)	/* Active	*/
#define		SCB_ST_JUNK1	(0x1 <<  7)	/* 0			*/
#define		SCB_ST_RUS	(0x7 <<  4)	/* Rcv unit status	*/
#define			SCB_ST_RUS_IDLE	(0 << 4)	/* Idle		*/
#define			SCB_ST_RUS_SUSP	(1 << 4)	/* Suspended	*/
#define			SCB_ST_RUS_NRES	(2 << 4)	/* No resources	*/
#define			SCB_ST_RUS_RDY	(4 << 4)	/* Ready	*/
	unsigned short	scb_command;	/* Next command			*/
#define		SCB_CMD_ACK_CX	(0x1 << 15)	/* Ack cmd completion	*/
#define		SCB_CMD_ACK_FR	(0x1 << 14)	/* Ack frame received	*/
#define		SCB_CMD_ACK_CNA	(0x1 << 13)	/* Ack CU not active	*/
#define		SCB_CMD_ACK_RNR	(0x1 << 12)	/* Ack RU not ready	*/
#define		SCB_CMD_JUNKX	(0x1 << 11)	/* Unused		*/
#define		SCB_CMD_CUC	(0x7 <<  8)	/* Command Unit command	*/
#define			SCB_CMD_CUC_NOP	(0 << 8)	/* Nop		*/
#define			SCB_CMD_CUC_GO	(1 << 8)	/* Start cbl_offset */
#define			SCB_CMD_CUC_RES	(2 << 8)	/* Resume execution */
#define			SCB_CMD_CUC_SUS	(3 << 8)	/* Suspend   "	*/
#define			SCB_CMD_CUC_ABT	(4 << 8)	/* Abort     "	*/
#define		SCB_CMD_RESET	(0x1 <<  7)	/* Reset chip (hardware) */
#define		SCB_CMD_RUC	(0x7 <<  4)	/* Receive Unit command	*/
#define			SCB_CMD_RUC_NOP	(0 << 4)	/* Nop		*/
#define			SCB_CMD_RUC_GO	(1 << 4)	/* Start rfa_offset */
#define			SCB_CMD_RUC_RES	(2 << 4)	/* Resume reception */
#define			SCB_CMD_RUC_SUS	(3 << 4)	/* Suspend   "	*/
#define			SCB_CMD_RUC_ABT	(4 << 4)	/* Abort     "	*/
	unsigned short	scb_cbl_offset;	/* Offset of first command unit	*/
					/* Action Command		*/
	unsigned short	scb_rfa_offset;	/* Offset of first Receive	*/
					/* Frame Descriptor in the	*/
					/* Receive Frame Area		*/
	unsigned short	scb_crcerrs;	/* Properly aligned frames	*/
					/* received with a CRC error	*/
	unsigned short	scb_alnerrs;	/* Misaligned frames received	*/
					/* with a CRC error		*/
	unsigned short	scb_rscerrs;	/* Frames lost due to no space	*/
	unsigned short	scb_ovrnerrs;	/* Frames lost due to slow bus	*/
};

#define	scboff(p,f) 	toff(scb_t, p, f)

/*
 * The eight Action Commands.
 */
typedef enum acmd_e	acmd_e;
enum acmd_e
{
	acmd_nop	= 0,	/* Do nothing				*/
	acmd_ia_setup	= 1,	/* Load an (ethernet) address into the	*/
				/* 82586				*/
	acmd_configure	= 2,	/* Update the 82586 operating parameters */
	acmd_mc_setup	= 3,	/* Load a list of (ethernet) multicast	*/
				/* addresses into the 82586		*/
	acmd_transmit	= 4,	/* Transmit a frame			*/
	acmd_tdr	= 5,	/* Perform a Time Domain Reflectometer	*/
				/* test on the serial link		*/
	acmd_dump	= 6,	/* Copy 82586 registers to memory	*/
	acmd_diagnose	= 7,	/* Run an internal self test		*/
};

/*
 * Generic Action Command header.
 */
typedef struct ach_t	ach_t;
struct ach_t
{
	unsigned short	ac_status;		/* Command status:	*/
#define		AC_SFLD_C	(0x1 << 15)	/* Command completed	*/
#define		AC_SFLD_B	(0x1 << 14)	/* Busy executing	*/
#define		AC_SFLD_OK	(0x1 << 13)	/* Completed error free	*/
#define		AC_SFLD_A	(0x1 << 12)	/* Command aborted	*/
#define		AC_SFLD_FAIL	(0x1 << 11)	/* Selftest failed	*/
#define		AC_SFLD_S10	(0x1 << 10)	/* No carrier sense	*/
						/* during transmission	*/
#define		AC_SFLD_S9	(0x1 <<  9)	/* Tx unsuccessful:	*/
						/* (stopped) lost CTS	*/
#define		AC_SFLD_S8	(0x1 <<  8)	/* Tx unsuccessful:	*/
						/* (stopped) slow DMA	*/
#define		AC_SFLD_S7	(0x1 <<  7)	/* Tx deferred:		*/
						/* other link traffic	*/
#define		AC_SFLD_S6	(0x1 <<  6)	/* Heart Beat: collision */
						/* detect after last tx	*/
#define		AC_SFLD_S5	(0x1 <<  5)	/* Tx stopped:		*/
						/* excessive collisions	*/
#define		AC_SFLD_MAXCOL	(0xF <<  0)	/* Collision count  	*/
	unsigned short	ac_command;		/* Command specifier:	*/
#define		AC_CFLD_EL	(0x1 << 15)	/* End of command list	*/
#define		AC_CFLD_S	(0x1 << 14)	/* Suspend on completion */
#define		AC_CFLD_I	(0x1 << 13)	/* Interrupt on completion */
#define		AC_CFLD_CMD	(0x7 <<  0)	/* acmd_e		*/
	unsigned short	ac_link;		/* Next Action Command	*/
};

#define	acoff(p,f) 	toff(ach_t, p, f)

/*
 * The Nop Action Command.
 */
typedef struct ac_nop_t	ac_nop_t;
struct ac_nop_t
{
	ach_t	nop_h;
};

/*
 * The IA-Setup Action Command.
 */
typedef struct ac_ias_t	ac_ias_t;
struct ac_ias_t
{
	ach_t		ias_h;
	unsigned char	ias_addr[ADDR_LEN]; /* The (ethernet) address	*/
};

/*
 * The Configure Action Command.
 */
typedef struct ac_cfg_t	ac_cfg_t;
struct ac_cfg_t
{
	ach_t		cfg_h;
	unsigned char	cfg_byte_cnt;	/* Size foll data: 4-12	*/
#define	AC_CFG_BYTE_CNT(v)	(((v) & 0xF) << 0)
	unsigned char	cfg_fifolim;	/* FIFO threshold	*/
#define	AC_CFG_FIFOLIM(v)	(((v) & 0xF) << 0)
	unsigned char	cfg_byte8;
#define	AC_CFG_SAV_BF(v) 	(((v) & 0x1) << 7)	/* Save rxd bad frames	*/
#define	AC_CFG_SRDY(v) 		(((v) & 0x1) << 6)	/* SRDY/ARDY pin means	*/
							/* external sync.	*/
	unsigned char	cfg_byte9;
#define	AC_CFG_ELPBCK(v)	(((v) & 0x1) << 7)	/* External loopback	*/
#define	AC_CFG_ILPBCK(v)	(((v) & 0x1) << 6)	/* Internal loopback	*/
#define	AC_CFG_PRELEN(v)	(((v) & 0x3) << 4)	/* Preamble length	*/
#define		AC_CFG_PLEN_2		0		/*  2 bytes	*/
#define		AC_CFG_PLEN_4		1		/*  4 bytes	*/
#define		AC_CFG_PLEN_8		2		/*  8 bytes	*/
#define		AC_CFG_PLEN_16		3		/* 16 bytes	*/
#define	AC_CFG_ALOC(v)		(((v) & 0x1) << 3)	/* Addr/len data is	*/
							/* explicit in buffers	*/
#define	AC_CFG_ADDRLEN(v)	(((v) & 0x7) << 0)	/* Bytes per address	*/
	unsigned char	cfg_byte10;
#define	AC_CFG_BOFMET(v)	(((v) & 0x1) << 7)	/* Use alternate expo.	*/
							/* backoff method	*/
#define	AC_CFG_ACR(v)		(((v) & 0x7) << 4)	/* Accelerated cont. res. */
#define	AC_CFG_LINPRIO(v)	(((v) & 0x7) << 0)	/* Linear priority	*/
	unsigned char	cfg_ifs;	/* Interframe spacing		*/
	unsigned char	cfg_slotl;	/* Slot time (low byte)		*/
	unsigned char	cfg_byte13;
#define	AC_CFG_RETRYNUM(v)	(((v) & 0xF) << 4)	/* Max. collision retry	*/
#define	AC_CFG_SLTTMHI(v)	(((v) & 0x7) << 0)	/* Slot time (high bits) */
	unsigned char	cfg_byte14;
#define	AC_CFG_FLGPAD(v)	(((v) & 0x1) << 7)	/* Pad with HDLC flags	*/
#define	AC_CFG_BTSTF(v)		(((v) & 0x1) << 6)	/* Do HDLC bitstuffing	*/
#define	AC_CFG_CRC16(v)		(((v) & 0x1) << 5)	/* 16 bit CCITT CRC	*/
#define	AC_CFG_NCRC(v)		(((v) & 0x1) << 4)	/* Insert no CRC	*/
#define	AC_CFG_TNCRS(v)		(((v) & 0x1) << 3)	/* Tx even if no carrier */
#define	AC_CFG_MANCH(v)		(((v) & 0x1) << 2)	/* Manchester coding	*/
#define	AC_CFG_BCDIS(v)		(((v) & 0x1) << 1)	/* Disable broadcast	*/
#define	AC_CFG_PRM(v)		(((v) & 0x1) << 0)	/* Promiscuous mode	*/
	unsigned char	cfg_byte15;
#define	AC_CFG_ICDS(v)		(((v) & 0x1) << 7)	/* Internal collision	*/
							/* detect source	*/
#define	AC_CFG_CDTF(v)		(((v) & 0x7) << 4)	/* Collision detect	*/
							/* filter in bit times	*/
#define	AC_CFG_ICSS(v)		(((v) & 0x1) << 3)	/* Internal carrier	*/
							/* sense source		*/
#define	AC_CFG_CSTF(v)		(((v) & 0x7) << 0)	/* Carrier sense	*/
							/* filter in bit times	*/
	unsigned short	cfg_min_frm_len;
#define	AC_CFG_MNFRM(v)		(((v) & 0xFF) << 0)	/* Min. bytes/frame (<= 255) */
};

/*
 * The MC-Setup Action Command.
 */
typedef struct ac_mcs_t	ac_mcs_t;
struct ac_mcs_t
{
	ach_t		mcs_h;
	unsigned short	mcs_cnt;	/* No. of bytes of MC addresses	*/
#if 0
	unsigned char	mcs_data[ADDR_LEN]; /* The first MC address ..	*/
	...
#endif
};

#define I82586_MAX_MULTICAST_ADDRESSES	128	/* Hardware hashed filter */

/*
 * The Transmit Action Command.
 */
typedef struct ac_tx_t	ac_tx_t;
struct ac_tx_t
{
	ach_t		tx_h;
	unsigned short	tx_tbd_offset;	/* Address of list of buffers.	*/
#if	0
Linux packets are passed down with the destination MAC address
and length/type field already prepended to the data,
so we do not need to insert it.  Consistent with this
we must also set the AC_CFG_ALOC(..) flag during the
ac_cfg_t action command.
	unsigned char	tx_addr[ADDR_LEN]; /* The frame dest. address	*/
	unsigned short	tx_length;	/* The frame length		*/
#endif	/* 0 */
};

/*
 * The Time Domain Reflectometer Action Command.
 */
typedef struct ac_tdr_t	ac_tdr_t;
struct ac_tdr_t
{
	ach_t		tdr_h;
	unsigned short	tdr_result;	/* Result.	*/
#define		AC_TDR_LNK_OK	(0x1 << 15)	/* No link problem	*/
#define		AC_TDR_XCVR_PRB	(0x1 << 14)	/* Txcvr cable problem	*/
#define		AC_TDR_ET_OPN	(0x1 << 13)	/* Open on the link	*/
#define		AC_TDR_ET_SRT	(0x1 << 12)	/* Short on the link	*/
#define		AC_TDR_TIME	(0x7FF << 0)	/* Distance to problem	*/
						/* site	in transmit	*/
						/* clock cycles		*/
};

/*
 * The Dump Action Command.
 */
typedef struct ac_dmp_t	ac_dmp_t;
struct ac_dmp_t
{
	ach_t		dmp_h;
	unsigned short	dmp_offset;	/* Result.	*/
};

/*
 * Size of the result of the dump command.
 */
#define	DUMPBYTES	170

/*
 * The Diagnose Action Command.
 */
typedef struct ac_dgn_t	ac_dgn_t;
struct ac_dgn_t
{
	ach_t		dgn_h;
};

/*
 * Transmit Buffer Descriptor (TBD).
 */
typedef struct tbd_t	tbd_t;
struct tbd_t
{
	unsigned short	tbd_status;		/* Written by the CPU	*/
#define		TBD_STATUS_EOF	(0x1 << 15)	/* This TBD is the	*/
						/* last for this frame	*/
#define		TBD_STATUS_ACNT	(0x3FFF << 0)	/* Actual count of data	*/
						/* bytes in this buffer	*/
	unsigned short	tbd_next_bd_offset;	/* Next in list		*/
	unsigned short	tbd_bufl;		/* Buffer address (low)	*/
	unsigned short	tbd_bufh;		/*    "	     "	(high)	*/
};

/*
 * Receive Buffer Descriptor (RBD).
 */
typedef struct rbd_t	rbd_t;
struct rbd_t
{
	unsigned short	rbd_status;		/* Written by the 82586	*/
#define		RBD_STATUS_EOF	(0x1 << 15)	/* This RBD is the	*/
						/* last for this frame	*/
#define		RBD_STATUS_F	(0x1 << 14)	/* ACNT field is valid	*/
#define		RBD_STATUS_ACNT	(0x3FFF << 0)	/* Actual no. of data	*/
						/* bytes in this buffer	*/
	unsigned short	rbd_next_rbd_offset;	/* Next rbd in list	*/
	unsigned short	rbd_bufl;		/* Data pointer (low)	*/
	unsigned short	rbd_bufh;		/*  "	   "    (high)	*/
	unsigned short	rbd_el_size;		/* EL+Data buf. size	*/
#define		RBD_EL	(0x1 << 15)		/* This BD is the	*/
						/* last in the list	*/
#define		RBD_SIZE (0x3FFF << 0)		/* No. of bytes the	*/
						/* buffer can hold	*/
};

#define	rbdoff(p,f) 	toff(rbd_t, p, f)

/*
 * Frame Descriptor (FD).
 */
typedef struct fd_t	fd_t;
struct fd_t
{
	unsigned short	fd_status;		/* Written by the 82586	*/
#define		FD_STATUS_C	(0x1 << 15)	/* Completed storing frame */
#define		FD_STATUS_B	(0x1 << 14)	/* FD was consumed by RU */
#define		FD_STATUS_OK	(0x1 << 13)	/* Frame rxd successfully */
#define		FD_STATUS_S11	(0x1 << 11)	/* CRC error		*/
#define		FD_STATUS_S10	(0x1 << 10)	/* Alignment error	*/
#define		FD_STATUS_S9	(0x1 <<  9)	/* Ran out of resources	*/
#define		FD_STATUS_S8	(0x1 <<  8)	/* Rx DMA overrun	*/
#define		FD_STATUS_S7	(0x1 <<  7)	/* Frame too short	*/
#define		FD_STATUS_S6	(0x1 <<  6)	/* No EOF flag		*/
	unsigned short	fd_command;		/* Command		*/
#define		FD_COMMAND_EL	(0x1 << 15)	/* Last FD in list	*/
#define		FD_COMMAND_S	(0x1 << 14)	/* Suspend RU after rx	*/
	unsigned short	fd_link_offset;		/* Next FD		*/
	unsigned short	fd_rbd_offset;		/* First RBD (data)	*/
						/* Prepared by CPU,	*/
						/* updated by 82586	*/
#if	0
I think the rest is unused since we
have set AC_CFG_ALOC(..).  However, just
in case, we leave the space.
#endif	/* 0 */
	unsigned char	fd_dest[ADDR_LEN];	/* Destination address	*/
						/* Written by 82586	*/
	unsigned char	fd_src[ADDR_LEN];	/* Source address	*/
						/* Written by 82586	*/
	unsigned short	fd_length;		/* Frame length or type	*/
						/* Written by 82586	*/
};

#define	fdoff(p,f) 	toff(fd_t, p, f)

/*
 * This software may only be used and distributed
 * according to the terms of the GNU General Public License.
 *
 * For more details, see wavelan.c.
 */