/* rcsid[] = "$Header: ecreg.h,v 820.1 86/12/04 19:55:20 root Exp $" */
/* sccsid[]="%W% %Y% %Q% %G%" */

/************************************************************************
 *									*
 *				Copyright 1984				*
 *			VALID LOGIC SYSTEMS INCORPORATED		*
 *									*
 *	This listing contains confidential proprietary information	*
 *	which is not to be disclosed to unauthorized persons without	*
 *	written consent of an officer of Valid Logic Systems 		*
 *	Incoroporated.							*
 *									*
 *	The copyright notice appearing above is included to provide	*
 *	statutory protection in the event of unauthorized or 		*
 *	unintentional public disclosure.				*
 *									*
 ************************************************************************/

/* 3Com 3C400 Multibus Ethernet Controller definitions */


#define EC_MAXQLEN 5	/* Maximum output queue depth */


/* Debugging flag definitions */

#define DEBUG_All	 -1	/* All debugging flags */
#define DEBUG_XmtEvent	0x01	/* Trace transmit starts and completions */
#define DEBUG_XmtMsg	0x02	/* Trace (dump) transmit messages */
#define DEBUG_RcvEvent	0x04	/* Trace received message event */
#define DEBUG_RcvMsg	0x08	/* Trace (dump) received messages */
#define DEBUG_Jams	0x10	/* Trace JAM interrupts */

#define DEBUG_Events	0x15	/* Trace all events */


/* Multicast definitions
 *
 * The maximum number of multicast addresses in the software multicast filter
 * is determined by the limit of bytes movable through the IOCTL
 * interface (255).  Each multicast is set inidividually; they are
 * gotten (shown) as a set.  Thus the limit is INT(255/6) = 42.
 */

#define MAX_MULTICAST 42	/* Maximum number of multicast addreses */

/* Controller virtual addresses */

#define	MECSR(unit)	*(u_short*)(unit->virtualAddr + 0x0)
#define	MEBACK(unit)	*(u_short*)(unit->virtualAddr + 0x2)
#define	MEAROM(unit)	 (u_short*)(unit->virtualAddr + 0x400)
#define	MEARAM(unit)	 (u_short*)(unit->virtualAddr + 0x600)
#define	MEXHDR(unit)	 (u_short*)(unit->virtualAddr + 0x800)
#define	MEXBUF(unit)	 (u_short*)(unit->virtualAddr + 0x1000)
#define	MEAHDR(unit)	 (u_short*)(unit->virtualAddr + 0x1000)
#define	MEBHDR(unit)	 (u_short*)(unit->virtualAddr + 0x1800)


/* Control/status register fields */

#define	BBSW		0x8000	/* 1 => B buffer being used by Ether */
#define	ABSW		0x4000	/* 1 => A buffer being used by Ether */
#define	TBSW		0x2000	/* 1 => Transmit buffer being used by Ether */
#define	JAM		0x1000	/* Write 1 clears JAM (start backoff) */
#define	AMSW		0x0800	/* Write 1 enables controller until RESET */
#define	RBBA		0x0400	/* 1 => B packet is older than A packet */
#define	RESET		0x0100	/* Reset Controller */
#define	BINT		0x0080	/* Write 1 enables B packet recv'd interrupt */
#define	AINT		0x0040	/* Write 1 enables A packet recv'd interrupt */
#define	TINT		0x0020	/* Write 1 enables transmit done interrupt */
#define	JINT		0x0010	/* Write 1 enables jam interrupt */
#define	PA		0x000F	/* Packet types to receive */
#define INTENABLS	0x00F0	/* Enable all interrupts */


/* Values for PA field in control/status register */
/* Major values */

#define EC_PKTALL	0	/* All packets (promiscuous mode) */
#define EC_MINEMULTI	3	/* My packets plus multicast plus broadcast */
#define EC_MINEBROAD	6	/* My packets plus broadcast */

/* Add to previous values to limit received packets */

#define EC_NOERRORS	1	/* No pkts with RANGE, FCS or FRAME errors */
#define EC_NOFCSFRAME	2	/* No pkts with FCS or FRAME errors */


/* Receiver header fields */

#define	R_FCS		0x8000	/* 1 => Packet has a FCS error */
#define	R_BCAST		0x4000	/* 0 => Packet IS a broadcast packet */
#define	R_RANGE		0x2000	/* 1 => Packet has a RANGE error */
#define	R_MATCH		0x1000	/* 0 => Packet MATCHES physical address */
#define	R_FRAME		0x0800	/* 1 => Packet has a FRAME error */
#define	R_ERROR		0xA800	/* != 0 => Some error */
#define	R_OFFSET	0x07FF	/* Relative offset of first free byte */


/* Multibus controller space definitions */

#define ECBASE  0x380000		/* Physical address of first board */
#define ECSIZE  (8 * 1024)		/* Bytes of Multibus space per bd */
#define ECPAGES (ECSIZE >> pageshift)	/* Pages of Multibus space per bd */

/* IOCTL definitions */

#define	EC_IOCCLEARCOUNTERS	_IO(_IO_3COM, 1)
#define EC_IOCGETCOUNTERS	_IOR(_IO_3COM, 2, struct ec_counters)

#define EC_IOCENABLEMODE	_IOW(_IO_3COM, 3, int)
#define EC_IOCDISABLEMODE	_IOW(_IO_3COM, 4, int)
#define EC_IOCGETMODE		_IOR(_IO_3COM, 5, int)

#define EC_IOCCLEARDIST		_IO(_IO_3COM, 6)
#define EC_IOCGETRCVDIST	_IOR(_IO_3COM, 7, struct ec_pktdist)
#define EC_IOCGETXMTDIST	_IOR(_IO_3COM, 8, struct ec_pktdist)

#define EC_IOCADDMCAST		_IOW(_IO_3COM, 9, char [6])
#define EC_IOCDELMCAST		_IOW(_IO_3COM, 10, char [6])
#define EC_IOCGETMCAST		_IOR(_IO_3COM, 11, char [MAX_MULTICAST][6])

#define EC_IOCGETADDR		_IOR(_IO_3COM, 12, char [6])
#define EC_IOCSETADDR		_IOW(_IO_3COM, 13, char [6])

#define EC_IOCGETVERSION	_IOR(_IO_3COM, 14, int)

#define EC_IOCGETDEBUG		_IOR(_IO_3COM, 15, u_long)
#define EC_IOCSETDEBUG		_IOWR(_IO_3COM, 16, u_long)


/* Mode values for EC_IOC{ENABLE, DISABLE, SHOW}MODE */

#define EC_NORMAL	0x01	/* 1 => Allow normal transfer of packets */
#define EC_PROMISCUOUS	0x02	/* 1 => Monitor all network traffic */
#define EC_DISTRIBUTION	0x04	/* 1 => Collect size by Ethertype */
#define EC_TRAILER	0x08	/* 1 => Generate trailer protocol */

/* Packet size distributions (by protocol type)
 * Buckets for the following packet size groups are provided:
 *	1-64, 65-128, 129-256, 257-512, 513-1024, 1025-1500.
 *	NOTE: Total size must be < 255 bytes (IOCTL limitation)
 *		current size (4 * 6 * 5 = 120).
 */

#define NUM_ECBUCKETS		6
#define MAX_ECBUCKET		(NUM_ECBUCKETS - 1)

typedef int ec_pkttype[NUM_ECBUCKETS];

struct ec_pktdist {
    int ip[NUM_ECBUCKETS];	/* IP protocol */
    int arp[NUM_ECBUCKETS];	/* ARP protocol */
#ifdef notdef
    int bcast[NUM_ECBUCKETS];	/* VALID bcast protocol */
    int conn[NUM_ECBUCKETS];	/* VALID conn protocol */
    int rpc[NUM_ECBUCKETS];	/* VALID rpc protocol */
#endif
    int valid[NUM_ECBUCKETS];	/* VALID homogeneous protocols */
    int decnet[NUM_ECBUCKETS];	/* DECnet protocol family */
    int unknown[NUM_ECBUCKETS];	/* Default (unknown) */
};


/* Event counters 
 *	NOTE: Total size must be < 255 bytes (IOCTL limitation)
 *		current size (38 * 4 = 152).
 */

struct ec_counters {
	u_long	starttime;	/* Time statistics were started */
	u_long  startprom;	/* Time promiscuous mode was started */

	int	rcvTotal;	/* Total packets from 3Com board */
	int	rcvBcast;	/* Broadcast packets detected */
	int	rcvMcast;	/* Multicast packets detected */
	int	rcvMine;	/* Packets addressed to this node detected */
	int	rcvTooBig;	/* Bad pkts discarded, too large (> 1500) */
	int	rcvTooSmall;	/* Bad pkts discarded, too small (< 64) */
	int	rcvNull;	/* Bad pkts discarded, no data */
	int	rcvError;	/* Bad pkts discarded, frame/fcs errors */
	int	rcvNoMcast;	/* Bad pkts discarded, failed mcast filter */
	int	rcvNoSpace;	/* Ok pkts discarded, no kernel space */
	int	rcvBadType;	/* Ok pkts discarded, unknown Ethertype */
	int	rcvBadValid;	/* Ok pkts discarded, unknown VALIDnet packet */
	int	rcvQueueFull;	/* Ok pkts discarded, queue full */
	int	rcvTrailer;	/* Ok pkts in trailer format */
	int	rcvBadTrailer;	/* Bad pkts discarded, invalid trailer format */
	int	rcvOk;		/* Ok pkts queued to next layer */

	int	xmtBcast;	/* Broadcast packets submitted for transmit */
	int	xmtMcast;	/* Multicast packets submitted  for transmit */
	int	xmtSingle;	/* Single address packets submitted for xmt */
	int	xmtTrailer;	/* Packets encoded in trailer format */
	int	xmtLoop;	/* Packets looped internally */
	int	xmtNoSpace;	/* Packets discarded, no kernel space */
	int	xmtQueueFull;	/* Packets discarded, transmit queue full */
	int	xmtQueued;	/* Packets queued for transmit */
	int	xmtCollisions;	/* Packet collisions */
	int	xmtStarts;	/* First time packet transmits */
	int	xmtRestarts;	/* Packet retransmits */
	int	xmtEmpty;	/* Transmit queue "now empty" transitions */
	int	xmtSent;	/* Packets transmitted successfully */
	int	xmtPoll;	/* Packets completed by polling */
	int	xmtBusy;	/* Packets discarded, Ethernet too busy */

	int	intrTotal;	/* Total interrupts from controller */
	int	intrAonly;	/* Interrupts from A buffer filled */
	int	intrBonly;	/* Interrupts from B buffer filled */
	int	intrAB;		/* Interrupts from A and B (A older) */
	int	intrBA;		/* Interrupts from B and A (B older) */
};

/*  A set of macros to pack and unpack shorts & longs into unsigned character
 *  arrays for machine independent transmission over the network.
 *
 *  machine:	shorts:		longs:
 *  --------	-------		------
 *  Vax:	<0> <1>		<0> <1> <2> <3>
 *  68000:	<1> <0>		<3> <2> <1> <0>
 *  Ethernet:	<1> <0>		<3> <2> <1> <0>
 *
 *  <0> = least significant byte
 *  <1> = most significant byte
 */

#define short2unpk(c,s) \
	*(u_char*)(c + 0) = (s >> 8) & 0xFF; \
	*(u_char*)(c + 1) = (s >> 0) & 0xFF;

#define long2unpk(c,l) \
	*(u_char*)(c + 0) = (l >> 24) & 0xFF; \
	*(u_char*)(c + 1) = (l >> 16) & 0xFF; \
	*(u_char*)(c + 2) = (l >>  8) & 0xFF; \
	*(u_char*)(c + 3) = (l >>  0) & 0xFF;

#define long2ea(c,l) \
	*(u_char*)(c + 0) = (l >> 16) & 0xFF; \
	*(u_char*)(c + 1) = (l >>  8) & 0xFF; \
	*(u_char*)(c + 2) = (l >>  0) & 0xFF;

#define unpk2short(c,s) \
	s = *(u_char*)(c+0)<<8 | *(u_char*)(c+1);

#define unpk2long(c,l) \
	l = *(u_char*)(c+0)<<24 | *(u_char*)(c+1)<<16 | \
	*(u_char*)(c+2)<<8 | *(u_char*)(c+3);

#define ea2long(c,l) \
	l = *(u_char*)(c+0)<<16 | *(u_char*)(c+1)<<8 | *(u_char*)(c+2);
