/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION  1986,1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header: unreg.h,v 1.1 89/03/29 17:46:11 probe Exp $ */
/* $ACIS:if_unreg.h 9.0$ */
/* $Source: /mit/cgw/src/tftp.rt/RCS/unreg.h,v $ */

#if !defined(lint) && !defined(LOCORE)  && defined(RCS_HDRS)
static char *rcsidif_unreg = "$Header: unreg.h,v 1.1 89/03/29 17:46:11 probe Exp $";
#endif

/*
 * Ungermann-Bass PC-NIC Ethernet adapter memory map  (4.3 driver)
 */

#define UN_NUMRBUFS	96
#define UN_LASTRBUF	(UN_NUMRBUFS - 1)
#define UN_RBUFSIZE	128
#define UN_XBSIZE	2048
#define ETH_ADDR_SIZE	6

struct undevice {
	char un_eprom[8192];	/* Ethernet hardware address hidden here */
	char un_hole1[128];
	char un_xsar[2];	/* Transmit starting address register */
	char un_csr;		/* Control/status reg */
	char un_fppepp;		/* Receive buffer pointer regs */
	char un_hole2[124];
	char un_pram[UN_NUMRBUFS]; /* Page ram (status of receive buffers) */
	char un_hole3[32];
	struct {		/* Fujitsu EDLC regs */
		char xstat;		/* Transmitter status */
		char xmask;		/* Transmit interrupt mask */
		char rstat;		/* Receive status */
		char rmask;		/* Receive interrupt mask */
		char tmode;		/* Transmit mode */
		char rmode;		/* Receive mode */
		char reset;		/* Reset latch */
		char tdr1;		/* Time domain reflectometer reg LSB */
		char nodeID[ETH_ADDR_SIZE];	/* Ethernet address (W/O) */
		char res;		/* Reserved */
		char tdr2;		/* T.D.R. register MSB */
	} un_edlc;
	char un_hole4[7792];
	char un_rcvbuf[UN_NUMRBUFS][UN_RBUFSIZE]; /* Receive buffers */
	char un_xmtbuf[2][UN_XBSIZE]; /* Transmit buffers */
};

/*
 *  EPROM locations of interest
 */

/*  wired-in default ethernet address */

#define UN_EADDROFF	0x10

/*
 *  Transmit starting address register (xsar)
 */
#define UN_XMIT(mb,addr) {\
	register x;\
	MM_OUT(&(mb)->un_xsar[1], (addr) & 0xFF);\
	MM_OUT(&(mb)->un_xsar[0], (addr)>>8 &0xF);\
	x = MM_IN(&(mb)->un_xsar[0]);\
}

/*  The following macro clears the "Packet Available" flag */
#define UN_CLRPAV(mb) {register x; x = MM_IN(&(mb)->un_xsar[1]);}
	
/*
 *  Control and status reg (csr)
 */
	/* On writes - it's the control register */
#define UN_TXRIENB	0x80	/* Allow Tx Rdy interrupts */
#define UN_PAVIENB	0x40	/* Allow PAV bit to generate an interrupt */
#define UN_GSFTINT	0x20	/* Generate software interrupt */
#define UN_TIMIENB	0x10	/* Alllow Timer interrupts */
/* bits 0 - 3 ignored */

#define UN_IENABLE	(UN_TXRIENB+UN_PAVIENB)

	/*
	 *  On reads - it's the status register
	 *
	 *  N.B. -- INTERRUPT BITS ARE COMPLEMENTED!
	 *  (i.e. (undevice.csr & UN_TXRINT) == 0 for a Tx Rdy interrupt
	 */

#define UN_TXRINT	0x80	/* Tx Rdy interrupt */
#define UN_PAVINT	0x40	/* PAV (page available) interrupt */
#define UN_SFTINT	0x20	/* software interrupt */
#define UN_TIMINT	0x10	/* timer interrupt */
#define UN_RCVINT	0x08	/* EDLC receiver interrupt */
#define UN_XMTINT	0x04	/* EDLC transmitter interrupt */
#define UN_TPOK		0x02	/* Transmitted packet OK */
#define UN_TXDONE	0x01	/* Transmitter done transmitting */
#define UN_XMITDONE (UN_TPOK+UN_TXDONE)

#define UN_CSRBITS "\20\10TXRDY\7PAV\4RCV\3XMT\2TPOK\1TXDONE\n"

/*
 *  Page RAM (status of receive pages)
 */

#define UN_LAST_PAGE	0x80
#define UN_PAGE_LENGTH_MASK	0x7f

/*
 *  Full Page Pointer / Empty Page Pointer (fppepp)
 *
 *  These are the two registers that the driver and the board use
 *  to maintain a circular buffer of received packets.  The driver
 *  writes the FPP to let the board know where the "full" pages start
 *  (so that the board doesn't re-fill them before the driver empties
 *  them).  The driver reads the EPP to determine where the empty
 *  pages start (so that it doesn't read them before the board fills
 *  them).  Since the FPP is write-only and the EPP is read-only, the
 *  2 registers share the same address.
 */

	/* On writes, this register is the FPP */
/*  It should be written with values between 0 and 95 */

	/*
	 *  The most significant bit is the "global interrupt" (re)enable.
	 *  The bit is wiggled off then on to re-enable interrupts.
	 */
#define UN_GLBIENB	(1 << 7)

#define UN_DISABLE(p)	MM_OUT(&addr->un_fppepp, p);  /* clears MSB */
#define UN_ENABLE(p)	MM_OUT(&addr->un_fppepp, p | UN_GLBIENB) /* sets it */

#define UN_GLOBIENB(p)	UN_DISABLE(p); UN_ENABLE(p)

	/* On reads, it's the EPP */
/*  Should contain values between 0 and 95 */
#define UN_PAGE_MASK	0x7f

	/*  The most significant bit is the Packet Available flag */
#define UN_PAV(mb) (MM_IN(&(mb)->un_fppepp) & 0x80)

/*

 *  Fujitsu Ethernet Data Link Controller (EDLC) registers
 *
 */

/*  The following constants apply to the xstat and xmask fields: */
	/*	char xstat;		/* Transmitter status */
	/*	char xmask;		/* Transmit interrupt mask */
#define XS_RDY	0x80		/* Transmitter ready for packet */
#define XS_NB	0x40		/* Net busy */
#define XS_XRCV	0x20		/* Transmission received */
#define XS_SHRT	0x10		/* Ethernet is shorted */
#define XS_UFLW 0x08		/* Underflow error occurred */
#define XS_COLL	0x04		/* Collision occurred */
#define XS_16CL	0x02		/* 16 consecutive collisions occurred */
#define XS_EPAR 0x01		/* Parity error occurred */
#define XS_CLEAR (XS_UFLW+XS_COLL+XS_16CL+XS_EPAR)
#define XS_BITS "\20\10XRDY\7NB\6XRCV\5SHRT\4UFLW\3COLL\2CL16\1EPAR\n"

/*  The next few constants apply to the rstat and rmask fields */
	/*	char rstat;		/* Receive status */
	/*	char rmask;		/* Receive interrupt mask */
#define RS_RPOK 0x80		/* Packet received OK */
#define RS_SHRT 0x08		/* Received short packet */
#define RS_ALGN 0x04		/* Alignment error detected */
#define RS_ECRC 0x02		/* CRC error detected */
#define RS_OFLW 0x01		/* Receive buffer overflow occurred */
#define RS_CLEAR (RS_RPOK+RS_SHRT+RS_ALGN+RS_ECRC+RS_OFLW)
#define RS_ERR  (RS_SHRT+RS_ALGN+RS_ECRC+RS_OFLW)
#define RS_BITS "\20\10RPOK\5RSET\4SHRT\3ALGN\2ECRC\1OFLW\n"

	/*	char tmode;		/* Transmit mode */
#define UN_NCOLL(mb) ((MM_IN(&(mb)->un_edlc.tmode) >> 4) & 15)
#define TM_IGNP 0x08		/* Ignore parity errors */
#define TM_LBC	0x02		/* Loopback control  - set => no loopback */
#define TM_NORMAL (TM_IGNP+TM_LBC)

	/*	char rmode;		/* Receive mode */
#define RM_NONE	0x00		/* Disable receiver */
#define RM_OURS 0x01		/* Accept ours and broadcast (and some multi)*/
#define RM_MULT 0x02		/* Accept ours and all multicast */
#define RM_ALL	0x03		/* Promiscuous mode -- accept all packets */
#define RM_NORMAL (RM_OURS)
	/*	char reset;		/* Reset latch */
#define RESET_ON 0x80
#define RESET_OFF 0

