xref: /csrg-svn/sys/vax/if/if_qe.c (revision 44562)
135326Sbostic /*
235326Sbostic  * Copyright (c) 1988 Regents of the University of California.
335326Sbostic  * All rights reserved.
435326Sbostic  *
535326Sbostic  * This code is derived from software contributed to Berkeley by
635326Sbostic  * Digital Equipment Corp.
735326Sbostic  *
8*44562Sbostic  * %sccs.include.redist.c%
935326Sbostic  *
10*44562Sbostic  *	@(#)if_qe.c	7.16 (Berkeley) 06/28/90
1135326Sbostic  */
1227477Skjd 
1327915Skarels /* from  @(#)if_qe.c	1.15	(ULTRIX)	4/16/86 */
1436820Skarels 
1527477Skjd /****************************************************************
1627477Skjd  *								*
1727477Skjd  *        Licensed from Digital Equipment Corporation 		*
1827477Skjd  *                       Copyright (c) 				*
1927477Skjd  *               Digital Equipment Corporation			*
2027477Skjd  *                   Maynard, Massachusetts 			*
2127477Skjd  *                         1985, 1986 				*
2227477Skjd  *                    All rights reserved. 			*
2327477Skjd  *								*
2427477Skjd  *        The Information in this software is subject to change *
2527477Skjd  *   without notice and should not be construed as a commitment *
2627477Skjd  *   by  Digital  Equipment  Corporation.   Digital   makes  no *
2727477Skjd  *   representations about the suitability of this software for *
2827477Skjd  *   any purpose.  It is supplied "As Is" without expressed  or *
2927477Skjd  *   implied  warranty. 					*
3027477Skjd  *								*
3127477Skjd  *        If the Regents of the University of California or its *
3227477Skjd  *   licensees modify the software in a manner creating  	*
3327915Skarels  *   derivative copyright rights, appropriate copyright  	*
3427915Skarels  *   legends may be placed on the derivative work in addition   *
3527477Skjd  *   to that set forth above. 					*
3627477Skjd  *								*
3727477Skjd  ****************************************************************/
3827477Skjd /* ---------------------------------------------------------------------
3936820Skarels  * Modification History
4027477Skjd  *
4127477Skjd  * 15-Apr-86  -- afd
4227477Skjd  *	Rename "unused_multi" to "qunused_multi" for extending Generic
4327477Skjd  *	kernel to MicroVAXen.
4427477Skjd  *
4527477Skjd  * 18-mar-86  -- jaw     br/cvec changed to NOT use registers.
4627477Skjd  *
4727477Skjd  * 12 March 86 -- Jeff Chase
4827477Skjd  *	Modified to handle the new MCLGET macro
4927477Skjd  *	Changed if_qe_data.c to use more receive buffers
5027477Skjd  *	Added a flag to poke with adb to log qe_restarts on console
5127477Skjd  *
5227477Skjd  * 19 Oct 85 -- rjl
5327477Skjd  *	Changed the watch dog timer from 30 seconds to 3.  VMS is using
5427477Skjd  * 	less than 1 second in their's. Also turned the printf into an
5527477Skjd  *	mprintf.
5627477Skjd  *
5727477Skjd  *  09/16/85 -- Larry Cohen
5836820Skarels  * 		Add 43bsd alpha tape changes for subnet routing
5927477Skjd  *
6027477Skjd  *  1 Aug 85 -- rjl
6127477Skjd  *	Panic on a non-existent memory interrupt and the case where a packet
6236820Skarels  *	was chained.  The first should never happen because non-existant
6327477Skjd  *	memory interrupts cause a bus reset. The second should never happen
6427477Skjd  *	because we hang 2k input buffers on the device.
6527477Skjd  *
6627477Skjd  *  1 Aug 85 -- rich
6727477Skjd  *      Fixed the broadcast loopback code to handle Clusters without
6827477Skjd  *      wedging the system.
6927477Skjd  *
7027477Skjd  *  27 Feb. 85 -- ejf
7127477Skjd  *	Return default hardware address on ioctl request.
7227477Skjd  *
7327477Skjd  *  12 Feb. 85 -- ejf
7427477Skjd  *	Added internal extended loopback capability.
7527477Skjd  *
7627477Skjd  *  27 Dec. 84 -- rjl
7727477Skjd  *	Fixed bug that caused every other transmit descriptor to be used
7827477Skjd  *	instead of every descriptor.
7927477Skjd  *
8027477Skjd  *  21 Dec. 84 -- rjl
8127477Skjd  *	Added watchdog timer to mask hardware bug that causes device lockup.
8227477Skjd  *
8327477Skjd  *  18 Dec. 84 -- rjl
8427477Skjd  *	Reworked driver to use q-bus mapping routines.  MicroVAX-I now does
8527477Skjd  *	copying instead of m-buf shuffleing.
8627477Skjd  *	A number of deficencies in the hardware/firmware were compensated
8727477Skjd  *	for. See comments in qestart and qerint.
8827477Skjd  *
8927477Skjd  *  14 Nov. 84 -- jf
9027477Skjd  *	Added usage counts for multicast addresses.
9127477Skjd  *	Updated general protocol support to allow access to the Ethernet
9227477Skjd  *	header.
9327477Skjd  *
9427477Skjd  *  04 Oct. 84 -- jf
9527477Skjd  *	Added support for new ioctls to add and delete multicast addresses
9627477Skjd  *	and set the physical address.
9727477Skjd  *	Add support for general protocols.
9827477Skjd  *
9927477Skjd  *  14 Aug. 84 -- rjl
10027477Skjd  *	Integrated Shannon changes. (allow arp above 1024 and ? )
10127477Skjd  *
10227477Skjd  *  13 Feb. 84 -- rjl
10327477Skjd  *
10427477Skjd  *	Initial version of driver. derived from IL driver.
10536820Skarels  *
10627477Skjd  * ---------------------------------------------------------------------
10727477Skjd  */
10836820Skarels 
10927477Skjd #include "qe.h"
11027915Skarels #if	NQE > 0
11127477Skjd /*
11227477Skjd  * Digital Q-BUS to NI Adapter
11327477Skjd  */
11427915Skarels #include "param.h"
11527915Skarels #include "systm.h"
11627915Skarels #include "mbuf.h"
11727915Skarels #include "buf.h"
11827915Skarels #include "protosw.h"
11927915Skarels #include "socket.h"
12027915Skarels #include "vmmac.h"
12127915Skarels #include "ioctl.h"
12227915Skarels #include "errno.h"
12327915Skarels #include "syslog.h"
12427915Skarels #include "time.h"
12527915Skarels #include "kernel.h"
12627915Skarels 
12727915Skarels #include "../net/if.h"
12827915Skarels #include "../net/netisr.h"
12927915Skarels #include "../net/route.h"
13027915Skarels 
13127915Skarels #ifdef INET
13227915Skarels #include "../netinet/in.h"
13327915Skarels #include "../netinet/in_systm.h"
13427915Skarels #include "../netinet/in_var.h"
13527915Skarels #include "../netinet/ip.h"
13627915Skarels #include "../netinet/if_ether.h"
13727915Skarels #endif
13827915Skarels 
13927915Skarels #ifdef NS
14027915Skarels #include "../netns/ns.h"
14127915Skarels #include "../netns/ns_if.h"
14227915Skarels #endif
14327915Skarels 
14438985Skarels #ifdef ISO
14538985Skarels #include "../netiso/iso.h"
14638985Skarels #include "../netiso/iso_var.h"
14743337Ssklower extern char all_es_snpa[], all_is_snpa[];
14838985Skarels #endif
14938985Skarels 
15034530Skarels #include "../vax/pte.h"
15127915Skarels #include "../vax/cpu.h"
15227915Skarels #include "../vax/mtpr.h"
15327915Skarels #include "if_qereg.h"
15427915Skarels #include "if_uba.h"
15527915Skarels #include "../vaxuba/ubareg.h"
15627915Skarels #include "../vaxuba/ubavar.h"
15736820Skarels 
15836820Skarels #if NQE == 1 && !defined(QNIVERT)
15930604Skarels #define NRCV	15	 		/* Receive descriptors		*/
16030604Skarels #else
16136820Skarels #define NRCV	10	 		/* Receive descriptors		*/
16230604Skarels #endif
16327915Skarels #define NXMT	5	 		/* Transmit descriptors		*/
16427915Skarels #define NTOT	(NXMT + NRCV)
16534530Skarels 
16634530Skarels #define	QETIMEOUT	2		/* transmit timeout, must be > 1 */
16739448Smckusick #define QESLOWTIMEOUT	40		/* timeout when no xmits in progress */
16836820Skarels 
16927915Skarels /*
17027915Skarels  * This constant should really be 60 because the qna adds 4 bytes of crc.
17127915Skarels  * However when set to 60 our packets are ignored by deuna's , 3coms are
17227915Skarels  * okay ??????????????????????????????????????????
17327915Skarels  */
17427915Skarels #define MINDATA 64
17536820Skarels 
17627915Skarels /*
17727915Skarels  * Ethernet software status per interface.
17827915Skarels  *
17927915Skarels  * Each interface is referenced by a network interface structure,
18034530Skarels  * qe_if, which the routing code uses to locate the interface.
18127915Skarels  * This structure contains the output queue for the interface, its address, ...
18227915Skarels  */
18327915Skarels struct	qe_softc {
18434530Skarels 	struct	arpcom qe_ac;		/* Ethernet common part 	*/
18534530Skarels #define	qe_if	qe_ac.ac_if		/* network-visible interface 	*/
18634530Skarels #define	qe_addr	qe_ac.ac_enaddr		/* hardware Ethernet address 	*/
18727915Skarels 	struct	ifubinfo qe_uba;	/* Q-bus resources 		*/
18827915Skarels 	struct	ifrw qe_ifr[NRCV];	/*	for receive buffers;	*/
18927915Skarels 	struct	ifxmt qe_ifw[NXMT];	/*	for xmit buffers;	*/
19027915Skarels 	int	qe_flags;		/* software state		*/
19127915Skarels #define	QEF_RUNNING	0x01
19227915Skarels #define	QEF_SETADDR	0x02
19339420Smckusick #define QEF_FASTTIMEO	0x04
19427915Skarels 	int	setupaddr;		/* mapping info for setup pkts  */
19536031Skarels 	int	ipl;			/* interrupt priority		*/
19627915Skarels 	struct	qe_ring *rringaddr;	/* mapping info for rings	*/
19727915Skarels 	struct	qe_ring *tringaddr;	/*       ""			*/
19827915Skarels 	struct	qe_ring rring[NRCV+1];	/* Receive ring descriptors 	*/
19927915Skarels 	struct	qe_ring tring[NXMT+1];	/* Transmit ring descriptors 	*/
20027915Skarels 	u_char	setup_pkt[16][8];	/* Setup packet			*/
20127915Skarels 	int	rindex;			/* Receive index		*/
20227915Skarels 	int	tindex;			/* Transmit index		*/
20327915Skarels 	int	otindex;		/* Old transmit index		*/
20427915Skarels 	int	qe_intvec;		/* Interrupt vector 		*/
20527915Skarels 	struct	qedevice *addr;		/* device addr			*/
20627915Skarels 	int 	setupqueued;		/* setup packet queued		*/
20727915Skarels 	int	nxmit;			/* Transmits in progress	*/
20827915Skarels 	int	qe_restarts;		/* timeouts			*/
20927915Skarels } qe_softc[NQE];
21027915Skarels 
21127915Skarels struct	uba_device *qeinfo[NQE];
21236820Skarels 
21327477Skjd extern struct timeval time;
21436820Skarels 
21534530Skarels int	qeprobe(), qeattach(), qeintr(), qetimeout();
21638985Skarels int	qeinit(), qeioctl(), qereset(), qestart();
21736820Skarels 
21827477Skjd u_short qestd[] = { 0 };
21927477Skjd struct	uba_driver qedriver =
22027477Skjd 	{ qeprobe, 0, qeattach, 0, qestd, "qe", qeinfo };
22136820Skarels 
22227477Skjd #define	QEUNIT(x)	minor(x)
22327477Skjd /*
22427915Skarels  * The deqna shouldn't receive more than ETHERMTU + sizeof(struct ether_header)
22527477Skjd  * but will actually take in up to 2048 bytes. To guard against the receiver
22636820Skarels  * chaining buffers (which we aren't prepared to handle) we allocate 2kb
22727477Skjd  * size buffers.
22827477Skjd  */
22927477Skjd #define MAXPACKETSIZE 2048		/* Should really be ETHERMTU	*/
23027477Skjd /*
23127477Skjd  * Probe the QNA to see if it's there
23227477Skjd  */
23336031Skarels qeprobe(reg, ui)
23427477Skjd 	caddr_t reg;
23536031Skarels 	struct uba_device *ui;
23627477Skjd {
23727915Skarels 	register int br, cvec;		/* r11, r10 value-result */
23827477Skjd 	register struct qedevice *addr = (struct qedevice *)reg;
23936820Skarels 	register struct qe_ring *rp;
24027477Skjd 	register struct qe_ring *prp; 	/* physical rp 		*/
24136031Skarels 	register int i;
24236031Skarels 	register struct qe_softc *sc = &qe_softc[ui->ui_unit];
24336820Skarels 
24428927Skarels #ifdef lint
24528927Skarels 	br = 0; cvec = br; br = cvec;
24628953Skarels 	qeintr(0);
24728927Skarels #endif
24836820Skarels 
24927477Skjd 	/*
25036820Skarels 	 * The QNA interrupts on i/o operations. To do an I/O operation
25127477Skjd 	 * we have to setup the interface by transmitting a setup  packet.
25227477Skjd 	 */
25327477Skjd 	addr->qe_csr = QE_RESET;
25435762Skarels 	addr->qe_csr &= ~QE_RESET;
25527477Skjd 	addr->qe_vector = (uba_hd[numuba].uh_lastiv -= 4);
25636820Skarels 
25727477Skjd 	/*
25827477Skjd 	 * Map the communications area and the setup packet.
25927477Skjd 	 */
26027477Skjd 	sc->setupaddr =
26128953Skarels 		uballoc(0, (caddr_t)sc->setup_pkt, sizeof(sc->setup_pkt), 0);
26228953Skarels 	sc->rringaddr = (struct qe_ring *) uballoc(0, (caddr_t)sc->rring,
26328953Skarels 		sizeof(struct qe_ring) * (NTOT+2), 0);
26436031Skarels 	prp = (struct qe_ring *)UBAI_ADDR((int)sc->rringaddr);
26536820Skarels 
26627477Skjd 	/*
26727477Skjd 	 * The QNA will loop the setup packet back to the receive ring
26836820Skarels 	 * for verification, therefore we initialize the first
26927477Skjd 	 * receive & transmit ring descriptors and link the setup packet
27027477Skjd 	 * to them.
27127477Skjd 	 */
27236031Skarels 	qeinitdesc(sc->tring, (caddr_t)UBAI_ADDR(sc->setupaddr),
27328953Skarels 	    sizeof(sc->setup_pkt));
27436031Skarels 	qeinitdesc(sc->rring, (caddr_t)UBAI_ADDR(sc->setupaddr),
27528953Skarels 	    sizeof(sc->setup_pkt));
27636820Skarels 
27727477Skjd 	rp = (struct qe_ring *)sc->tring;
27827477Skjd 	rp->qe_setup = 1;
27927477Skjd 	rp->qe_eomsg = 1;
28027477Skjd 	rp->qe_flag = rp->qe_status1 = QE_NOTYET;
28127477Skjd 	rp->qe_valid = 1;
28236820Skarels 
28327477Skjd 	rp = (struct qe_ring *)sc->rring;
28427477Skjd 	rp->qe_flag = rp->qe_status1 = QE_NOTYET;
28527477Skjd 	rp->qe_valid = 1;
28636820Skarels 
28727477Skjd 	/*
28827477Skjd 	 * Get the addr off of the interface and place it into the setup
28927477Skjd 	 * packet. This code looks strange due to the fact that the address
29036820Skarels 	 * is placed in the setup packet in col. major order.
29127477Skjd 	 */
29227477Skjd 	for( i = 0 ; i < 6 ; i++ )
29327477Skjd 		sc->setup_pkt[i][1] = addr->qe_sta_addr[i];
29436820Skarels 
29527477Skjd 	qesetup( sc );
29627477Skjd 	/*
29727477Skjd 	 * Start the interface and wait for the packet.
29827477Skjd 	 */
29936031Skarels 	(void) spl6();
30027477Skjd 	addr->qe_csr = QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT;
30127477Skjd 	addr->qe_rcvlist_lo = (short)prp;
30227477Skjd 	addr->qe_rcvlist_hi = (short)((int)prp >> 16);
30327915Skarels 	prp += NRCV+1;
30427477Skjd 	addr->qe_xmtlist_lo = (short)prp;
30527477Skjd 	addr->qe_xmtlist_hi = (short)((int)prp >> 16);
30627477Skjd 	DELAY(10000);
30727477Skjd 	/*
30827915Skarels 	 * All done with the bus resources.
30927477Skjd 	 */
31027915Skarels 	ubarelse(0, &sc->setupaddr);
31128953Skarels 	ubarelse(0, (int *)&sc->rringaddr);
31236031Skarels 	sc->ipl = br = qbgetpri();
31327477Skjd 	return( sizeof(struct qedevice) );
31427477Skjd }
31536820Skarels 
31627477Skjd /*
31727477Skjd  * Interface exists: make available by filling in network interface
31827477Skjd  * record.  System will initialize the interface when it is ready
31927477Skjd  * to accept packets.
32027477Skjd  */
32127477Skjd qeattach(ui)
32227477Skjd 	struct uba_device *ui;
32327477Skjd {
32427477Skjd 	register struct qe_softc *sc = &qe_softc[ui->ui_unit];
32534530Skarels 	register struct ifnet *ifp = &sc->qe_if;
32627477Skjd 	register struct qedevice *addr = (struct qedevice *)ui->ui_addr;
32727477Skjd 	register int i;
32836820Skarels 
32927477Skjd 	ifp->if_unit = ui->ui_unit;
33027477Skjd 	ifp->if_name = "qe";
33127477Skjd 	ifp->if_mtu = ETHERMTU;
33227915Skarels 	ifp->if_flags = IFF_BROADCAST;
33336820Skarels 
33427477Skjd 	/*
33527477Skjd 	 * Read the address from the prom and save it.
33627477Skjd 	 */
33727477Skjd 	for( i=0 ; i<6 ; i++ )
33836820Skarels 		sc->setup_pkt[i][1] = sc->qe_addr[i] = addr->qe_sta_addr[i] & 0xff;
33935762Skarels 	addr->qe_vector |= 1;
34035762Skarels 	printf("qe%d: %s, hardware address %s\n", ui->ui_unit,
34135762Skarels 		addr->qe_vector&01 ? "delqa":"deqna",
34234551Smarc 		ether_sprintf(sc->qe_addr));
34335762Skarels 	addr->qe_vector &= ~1;
34436820Skarels 
34527477Skjd 	/*
34627477Skjd 	 * Save the vector for initialization at reset time.
34727477Skjd 	 */
34827477Skjd 	sc->qe_intvec = addr->qe_vector;
34936820Skarels 
35027477Skjd 	ifp->if_init = qeinit;
35138985Skarels 	ifp->if_output = ether_output;
35238985Skarels 	ifp->if_start = qestart;
35327477Skjd 	ifp->if_ioctl = qeioctl;
35427477Skjd 	ifp->if_reset = qereset;
35534530Skarels 	ifp->if_watchdog = qetimeout;
35627915Skarels 	sc->qe_uba.iff_flags = UBA_CANTWAIT;
35727477Skjd 	if_attach(ifp);
35827477Skjd }
35936820Skarels 
36027477Skjd /*
36127477Skjd  * Reset of interface after UNIBUS reset.
36227477Skjd  * If interface is on specified uba, reset its state.
36327477Skjd  */
36427477Skjd qereset(unit, uban)
36527477Skjd 	int unit, uban;
36627477Skjd {
36727477Skjd 	register struct uba_device *ui;
36836820Skarels 
36927915Skarels 	if (unit >= NQE || (ui = qeinfo[unit]) == 0 || ui->ui_alive == 0 ||
37027477Skjd 		ui->ui_ubanum != uban)
37127477Skjd 		return;
37227477Skjd 	printf(" qe%d", unit);
37334530Skarels 	qe_softc[unit].qe_if.if_flags &= ~IFF_RUNNING;
37427477Skjd 	qeinit(unit);
37527477Skjd }
37636820Skarels 
37727477Skjd /*
37836820Skarels  * Initialization of interface.
37927477Skjd  */
38027477Skjd qeinit(unit)
38127477Skjd 	int unit;
38227477Skjd {
38327477Skjd 	register struct qe_softc *sc = &qe_softc[unit];
38427477Skjd 	register struct uba_device *ui = qeinfo[unit];
38527477Skjd 	register struct qedevice *addr = (struct qedevice *)ui->ui_addr;
38634530Skarels 	register struct ifnet *ifp = &sc->qe_if;
38727477Skjd 	register i;
38827477Skjd 	int s;
38936820Skarels 
39027477Skjd 	/* address not known */
39127477Skjd 	if (ifp->if_addrlist == (struct ifaddr *)0)
39227477Skjd 			return;
39327915Skarels 	if (sc->qe_flags & QEF_RUNNING)
39427477Skjd 		return;
39536820Skarels 
39627915Skarels 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
39727915Skarels 		/*
39836820Skarels 		 * map the communications area onto the device
39927915Skarels 		 */
40036031Skarels 		i = uballoc(0, (caddr_t)sc->rring,
40136031Skarels 		    sizeof(struct qe_ring) * (NTOT+2), 0);
40236031Skarels 		if (i == 0)
40336031Skarels 			goto fail;
40436031Skarels 		sc->rringaddr = (struct qe_ring *)UBAI_ADDR(i);
40527915Skarels 		sc->tringaddr = sc->rringaddr + NRCV + 1;
40636031Skarels 		i = uballoc(0, (caddr_t)sc->setup_pkt,
40736031Skarels 		    sizeof(sc->setup_pkt), 0);
40836031Skarels 		if (i == 0)
40936031Skarels 			goto fail;
41036031Skarels 		sc->setupaddr =	UBAI_ADDR(i);
41127915Skarels 		/*
41227915Skarels 		 * init buffers and maps
41327915Skarels 		 */
41427915Skarels 		if (if_ubaminit(&sc->qe_uba, ui->ui_ubanum,
41527915Skarels 		    sizeof (struct ether_header), (int)btoc(MAXPACKETSIZE),
41627915Skarels 		    sc->qe_ifr, NRCV, sc->qe_ifw, NXMT) == 0) {
41736031Skarels 	fail:
41836820Skarels 			printf("qe%d: can't allocate uba resources\n", unit);
41934530Skarels 			sc->qe_if.if_flags &= ~IFF_UP;
42027915Skarels 			return;
42127915Skarels 		}
42227477Skjd 	}
42327477Skjd 	/*
42427477Skjd 	 * Init the buffer descriptors and indexes for each of the lists and
42527477Skjd 	 * loop them back to form a ring.
42627477Skjd 	 */
42727915Skarels 	for (i = 0; i < NRCV; i++) {
42827477Skjd 		qeinitdesc( &sc->rring[i],
42936031Skarels 		    (caddr_t)UBAI_ADDR(sc->qe_ifr[i].ifrw_info), MAXPACKETSIZE);
43027477Skjd 		sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET;
43127477Skjd 		sc->rring[i].qe_valid = 1;
43227477Skjd 	}
43328953Skarels 	qeinitdesc(&sc->rring[i], (caddr_t)NULL, 0);
43436820Skarels 
43527477Skjd 	sc->rring[i].qe_addr_lo = (short)sc->rringaddr;
43627477Skjd 	sc->rring[i].qe_addr_hi = (short)((int)sc->rringaddr >> 16);
43727477Skjd 	sc->rring[i].qe_chain = 1;
43827477Skjd 	sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET;
43927477Skjd 	sc->rring[i].qe_valid = 1;
44036820Skarels 
44127915Skarels 	for( i = 0 ; i <= NXMT ; i++ )
44228953Skarels 		qeinitdesc(&sc->tring[i], (caddr_t)NULL, 0);
44327477Skjd 	i--;
44436820Skarels 
44527477Skjd 	sc->tring[i].qe_addr_lo = (short)sc->tringaddr;
44627477Skjd 	sc->tring[i].qe_addr_hi = (short)((int)sc->tringaddr >> 16);
44727477Skjd 	sc->tring[i].qe_chain = 1;
44827477Skjd 	sc->tring[i].qe_flag = sc->tring[i].qe_status1 = QE_NOTYET;
44927477Skjd 	sc->tring[i].qe_valid = 1;
45036820Skarels 
45127477Skjd 	sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0;
45236820Skarels 
45327477Skjd 	/*
45436820Skarels 	 * Take the interface out of reset, program the vector,
45527477Skjd 	 * enable interrupts, and tell the world we are up.
45627477Skjd 	 */
45727477Skjd 	s = splimp();
45827477Skjd 	addr->qe_vector = sc->qe_intvec;
45927477Skjd 	sc->addr = addr;
46027915Skarels 	addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT |
46127915Skarels 	    QE_RCV_INT | QE_ILOOP;
46227477Skjd 	addr->qe_rcvlist_lo = (short)sc->rringaddr;
46327477Skjd 	addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16);
46427477Skjd 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
46527915Skarels 	sc->qe_flags |= QEF_RUNNING;
46627477Skjd 	qesetup( sc );
46738985Skarels 	(void) qestart( ifp );
46839420Smckusick 	sc->qe_if.if_timer = QESLOWTIMEOUT;	/* Start watchdog */
46927477Skjd 	splx( s );
47027477Skjd }
47136820Skarels 
47227477Skjd /*
47327477Skjd  * Start output on interface.
47427477Skjd  *
47527477Skjd  */
47638985Skarels qestart(ifp)
47738985Skarels 	struct ifnet *ifp;
47827477Skjd {
47938985Skarels 	int unit =  ifp->if_unit;
48027477Skjd 	struct uba_device *ui = qeinfo[unit];
48127477Skjd 	register struct qe_softc *sc = &qe_softc[unit];
48227477Skjd 	register struct qedevice *addr;
48327477Skjd 	register struct qe_ring *rp;
48427477Skjd 	register index;
48528927Skarels 	struct mbuf *m;
48628927Skarels 	int buf_addr, len, s;
48736820Skarels 
48836820Skarels 
48927477Skjd 	s = splimp();
49027477Skjd 	addr = (struct qedevice *)ui->ui_addr;
49127477Skjd 	/*
49227477Skjd 	 * The deqna doesn't look at anything but the valid bit
49327477Skjd 	 * to determine if it should transmit this packet. If you have
49427477Skjd 	 * a ring and fill it the device will loop indefinately on the
49527477Skjd 	 * packet and continue to flood the net with packets until you
49627477Skjd 	 * break the ring. For this reason we never queue more than n-1
49736820Skarels 	 * packets in the transmit ring.
49827477Skjd 	 *
49927477Skjd 	 * The microcoders should have obeyed their own defination of the
50027477Skjd 	 * flag and status words, but instead we have to compensate.
50127477Skjd 	 */
50236820Skarels 	for( index = sc->tindex;
50327915Skarels 		sc->tring[index].qe_valid == 0 && sc->nxmit < (NXMT-1) ;
50427915Skarels 		sc->tindex = index = ++index % NXMT){
50527477Skjd 		rp = &sc->tring[index];
50627477Skjd 		if( sc->setupqueued ) {
50727477Skjd 			buf_addr = sc->setupaddr;
50827477Skjd 			len = 128;
50927477Skjd 			rp->qe_setup = 1;
51027477Skjd 			sc->setupqueued = 0;
51127477Skjd 		} else {
51234530Skarels 			IF_DEQUEUE(&sc->qe_if.if_snd, m);
51327477Skjd 			if( m == 0 ){
51427477Skjd 				splx(s);
51538985Skarels 				return (0);
51627477Skjd 			}
51727915Skarels 			buf_addr = sc->qe_ifw[index].ifw_info;
51827915Skarels 			len = if_ubaput(&sc->qe_uba, &sc->qe_ifw[index], m);
51927477Skjd 		}
52027477Skjd 		/*
52136820Skarels 		 *  Does buffer end on odd byte ?
52227477Skjd 		 */
52327477Skjd 		if( len & 1 ) {
52427477Skjd 			len++;
52527477Skjd 			rp->qe_odd_end = 1;
52627477Skjd 		}
52727477Skjd 		if( len < MINDATA )
52827477Skjd 			len = MINDATA;
52927477Skjd 		rp->qe_buf_len = -(len/2);
53036031Skarels 		buf_addr = UBAI_ADDR(buf_addr);
53127477Skjd 		rp->qe_flag = rp->qe_status1 = QE_NOTYET;
53227477Skjd 		rp->qe_addr_lo = (short)buf_addr;
53327477Skjd 		rp->qe_addr_hi = (short)(buf_addr >> 16);
53427477Skjd 		rp->qe_eomsg = 1;
53527477Skjd 		rp->qe_flag = rp->qe_status1 = QE_NOTYET;
53627477Skjd 		rp->qe_valid = 1;
53739420Smckusick 		if (sc->nxmit++ == 0) {
53839420Smckusick 			sc->qe_flags |= QEF_FASTTIMEO;
53936820Skarels 			sc->qe_if.if_timer = QETIMEOUT;
54039420Smckusick 		}
54136820Skarels 
54227477Skjd 		/*
54327477Skjd 		 * See if the xmit list is invalid.
54427477Skjd 		 */
54527477Skjd 		if( addr->qe_csr & QE_XL_INVALID ) {
54627477Skjd 			buf_addr = (int)(sc->tringaddr+index);
54727477Skjd 			addr->qe_xmtlist_lo = (short)buf_addr;
54827477Skjd 			addr->qe_xmtlist_hi = (short)(buf_addr >> 16);
54927477Skjd 		}
55027477Skjd 	}
55127477Skjd 	splx( s );
55238985Skarels 	return (0);
55327477Skjd }
55436820Skarels 
55527477Skjd /*
55627477Skjd  * Ethernet interface interrupt processor
55727477Skjd  */
55827477Skjd qeintr(unit)
55927477Skjd 	int unit;
56027477Skjd {
56127477Skjd 	register struct qe_softc *sc = &qe_softc[unit];
56227477Skjd 	struct qedevice *addr = (struct qedevice *)qeinfo[unit]->ui_addr;
56336031Skarels 	int buf_addr, csr;
56436820Skarels 
56538985Skarels #ifdef notdef
56636031Skarels 	splx(sc->ipl);
56738985Skarels #else
56836820Skarels 	(void) splimp();
56938985Skarels #endif
57039420Smckusick 	if (!(sc->qe_flags & QEF_FASTTIMEO))
57139420Smckusick 		sc->qe_if.if_timer = QESLOWTIMEOUT; /* Restart timer clock */
57227477Skjd 	csr = addr->qe_csr;
57327915Skarels 	addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT | QE_ILOOP;
57436820Skarels 	if( csr & QE_RCV_INT )
57527477Skjd 		qerint( unit );
57627477Skjd 	if( csr & QE_XMIT_INT )
57727477Skjd 		qetint( unit );
57827477Skjd 	if( csr & QE_NEX_MEM_INT )
57936820Skarels 		printf("qe%d: Nonexistent memory interrupt\n", unit);
58036820Skarels 
58127477Skjd 	if( addr->qe_csr & QE_RL_INVALID && sc->rring[sc->rindex].qe_status1 == QE_NOTYET ) {
58227477Skjd 		buf_addr = (int)&sc->rringaddr[sc->rindex];
58327477Skjd 		addr->qe_rcvlist_lo = (short)buf_addr;
58427477Skjd 		addr->qe_rcvlist_hi = (short)(buf_addr >> 16);
58527477Skjd 	}
58627477Skjd }
58736820Skarels 
58827477Skjd /*
58927477Skjd  * Ethernet interface transmit interrupt.
59027477Skjd  */
59136820Skarels 
59227477Skjd qetint(unit)
59327477Skjd 	int unit;
59427477Skjd {
59527477Skjd 	register struct qe_softc *sc = &qe_softc[unit];
59627477Skjd 	register struct qe_ring *rp;
59727477Skjd 	register struct ifxmt *ifxp;
59828927Skarels 	int status1, setupflag;
59927477Skjd 	short len;
60036820Skarels 
60136820Skarels 
60227477Skjd 	while( sc->otindex != sc->tindex && sc->tring[sc->otindex].qe_status1 != QE_NOTYET && sc->nxmit > 0 ) {
60327477Skjd 		/*
60427477Skjd 		 * Save the status words from the descriptor so that it can
60527477Skjd 		 * be released.
60627477Skjd 		 */
60727477Skjd 		rp = &sc->tring[sc->otindex];
60827477Skjd 		status1 = rp->qe_status1;
60927477Skjd 		setupflag = rp->qe_setup;
61027477Skjd 		len = (-rp->qe_buf_len) * 2;
61127477Skjd 		if( rp->qe_odd_end )
61227477Skjd 			len++;
61327477Skjd 		/*
61427477Skjd 		 * Init the buffer descriptor
61527477Skjd 		 */
61628953Skarels 		bzero((caddr_t)rp, sizeof(struct qe_ring));
61739420Smckusick 		if( --sc->nxmit == 0 ) {
61839420Smckusick 			sc->qe_flags &= ~QEF_FASTTIMEO;
61939420Smckusick 			sc->qe_if.if_timer = QESLOWTIMEOUT;
62039420Smckusick 		}
62127477Skjd 		if( !setupflag ) {
62227477Skjd 			/*
62327477Skjd 			 * Do some statistics.
62427477Skjd 			 */
62534530Skarels 			sc->qe_if.if_opackets++;
62634530Skarels 			sc->qe_if.if_collisions += ( status1 & QE_CCNT ) >> 4;
62727915Skarels 			if (status1 & QE_ERROR)
62834530Skarels 				sc->qe_if.if_oerrors++;
62927477Skjd 			/*
63027477Skjd 			 * If this was a broadcast packet loop it
63127915Skarels 			 * back because the hardware can't hear its own
63227915Skarels 			 * transmits.
63327477Skjd 			 */
63427915Skarels 			ifxp = &sc->qe_ifw[sc->otindex];
63532086Skarels 			if (bcmp((caddr_t)((struct ether_header *)ifxp->ifw_addr)->ether_dhost,
63632086Skarels 			   (caddr_t)etherbroadcastaddr,
63732086Skarels 			   sizeof(etherbroadcastaddr)) == 0)
63832086Skarels 				qeread(sc, &ifxp->ifrw,
63932086Skarels 				    len - sizeof(struct ether_header));
64027915Skarels 			if (ifxp->ifw_xtofree) {
64127915Skarels 				m_freem(ifxp->ifw_xtofree);
64227915Skarels 				ifxp->ifw_xtofree = 0;
64327477Skjd 			}
64427477Skjd 		}
64527915Skarels 		sc->otindex = ++sc->otindex % NXMT;
64627477Skjd 	}
64738985Skarels 	(void) qestart( &sc->qe_if );
64827477Skjd }
64936820Skarels 
65027477Skjd /*
65127477Skjd  * Ethernet interface receiver interrupt.
65236820Skarels  * If can't determine length from type, then have to drop packet.
65336820Skarels  * Othewise decapsulate packet based on type and pass to type specific
65427477Skjd  * higher-level input routine.
65527477Skjd  */
65627477Skjd qerint(unit)
65727477Skjd 	int unit;
65827477Skjd {
65927477Skjd 	register struct qe_softc *sc = &qe_softc[unit];
66027477Skjd 	register struct qe_ring *rp;
66127477Skjd 	int len, status1, status2;
66227477Skjd 	int bufaddr;
66336820Skarels 
66427477Skjd 	/*
66527477Skjd 	 * Traverse the receive ring looking for packets to pass back.
66627477Skjd 	 * The search is complete when we find a descriptor not in use.
66727477Skjd 	 *
66827477Skjd 	 * As in the transmit case the deqna doesn't honor it's own protocols
66927477Skjd 	 * so there exists the possibility that the device can beat us around
67027477Skjd 	 * the ring. The proper way to guard against this is to insure that
67127477Skjd 	 * there is always at least one invalid descriptor. We chose instead
67227477Skjd 	 * to make the ring large enough to minimize the problem. With a ring
67327477Skjd 	 * size of 4 we haven't been able to see the problem. To be safe we
67427477Skjd 	 * doubled that to 8.
67527477Skjd 	 *
67627477Skjd 	 */
67727915Skarels 	for( ; sc->rring[sc->rindex].qe_status1 != QE_NOTYET ; sc->rindex = ++sc->rindex % NRCV ){
67827477Skjd 		rp = &sc->rring[sc->rindex];
67927477Skjd 		status1 = rp->qe_status1;
68027477Skjd 		status2 = rp->qe_status2;
68128953Skarels 		bzero((caddr_t)rp, sizeof(struct qe_ring));
68227477Skjd 		if( (status1 & QE_MASK) == QE_MASK )
68327477Skjd 			panic("qe: chained packet");
68427915Skarels 		len = ((status1 & QE_RBL_HI) | (status2 & QE_RBL_LO)) + 60;
68534530Skarels 		sc->qe_if.if_ipackets++;
68636820Skarels 
68732086Skarels 		if (status1 & QE_ERROR) {
68832086Skarels 			if ((status1 & QE_RUNT) == 0)
68934530Skarels 				sc->qe_if.if_ierrors++;
69032086Skarels 		} else {
69127915Skarels 			/*
69227915Skarels 			 * We don't process setup packets.
69327915Skarels 			 */
69427915Skarels 			if( !(status1 & QE_ESETUP) )
69527915Skarels 				qeread(sc, &sc->qe_ifr[sc->rindex],
69627915Skarels 					len - sizeof(struct ether_header));
69727477Skjd 		}
69827477Skjd 		/*
69927477Skjd 		 * Return the buffer to the ring
70027477Skjd 		 */
70136031Skarels 		bufaddr = (int)UBAI_ADDR(sc->qe_ifr[sc->rindex].ifrw_info);
70227477Skjd 		rp->qe_buf_len = -((MAXPACKETSIZE)/2);
70327477Skjd 		rp->qe_addr_lo = (short)bufaddr;
70427477Skjd 		rp->qe_addr_hi = (short)((int)bufaddr >> 16);
70527477Skjd 		rp->qe_flag = rp->qe_status1 = QE_NOTYET;
70627477Skjd 		rp->qe_valid = 1;
70727477Skjd 	}
70827477Skjd }
70936820Skarels 
71027477Skjd /*
71127477Skjd  * Process an ioctl request.
71227477Skjd  */
71327477Skjd qeioctl(ifp, cmd, data)
71427477Skjd 	register struct ifnet *ifp;
71527477Skjd 	int cmd;
71627477Skjd 	caddr_t data;
71727477Skjd {
71827477Skjd 	struct qe_softc *sc = &qe_softc[ifp->if_unit];
71927477Skjd 	struct ifaddr *ifa = (struct ifaddr *)data;
72028927Skarels 	int s = splimp(), error = 0;
72136820Skarels 
72227477Skjd 	switch (cmd) {
72336820Skarels 
72427477Skjd 	case SIOCSIFADDR:
72527477Skjd 		ifp->if_flags |= IFF_UP;
72627477Skjd 		qeinit(ifp->if_unit);
72738985Skarels 		switch(ifa->ifa_addr->sa_family) {
72827477Skjd #ifdef INET
72927477Skjd 		case AF_INET:
73027477Skjd 			((struct arpcom *)ifp)->ac_ipaddr =
73127477Skjd 				IA_SIN(ifa)->sin_addr;
73227477Skjd 			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
73327477Skjd 			break;
73427477Skjd #endif
73527915Skarels #ifdef NS
73627915Skarels 		case AF_NS:
73727915Skarels 		    {
73827915Skarels 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
73936820Skarels 
74027915Skarels 			if (ns_nullhost(*ina))
74134530Skarels 				ina->x_host = *(union ns_host *)(sc->qe_addr);
74227915Skarels 			else
74327915Skarels 				qe_setaddr(ina->x_host.c_host, ifp->if_unit);
74427477Skjd 			break;
74527915Skarels 		    }
74627915Skarels #endif
74727477Skjd 		}
74827477Skjd 		break;
74927915Skarels 
75027915Skarels 	case SIOCSIFFLAGS:
75127915Skarels 		if ((ifp->if_flags & IFF_UP) == 0 &&
75227915Skarels 		    sc->qe_flags & QEF_RUNNING) {
75327915Skarels 			((struct qedevice *)
75427915Skarels 			   (qeinfo[ifp->if_unit]->ui_addr))->qe_csr = QE_RESET;
75527915Skarels 			sc->qe_flags &= ~QEF_RUNNING;
75630604Skarels 		} else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
75730604Skarels 		    IFF_RUNNING && (sc->qe_flags & QEF_RUNNING) == 0)
75828953Skarels 			qerestart(sc);
75927915Skarels 		break;
76027915Skarels 
76127477Skjd 	default:
76227477Skjd 		error = EINVAL;
76336820Skarels 
76427477Skjd 	}
76528927Skarels 	splx(s);
76627477Skjd 	return (error);
76727477Skjd }
76836820Skarels 
76927915Skarels /*
77027915Skarels  * set ethernet address for unit
77127915Skarels  */
77227915Skarels qe_setaddr(physaddr, unit)
77327915Skarels 	u_char *physaddr;
77427915Skarels 	int unit;
77527915Skarels {
77627915Skarels 	register struct qe_softc *sc = &qe_softc[unit];
77727915Skarels 	register int i;
77827915Skarels 
77927915Skarels 	for (i = 0; i < 6; i++)
78034530Skarels 		sc->setup_pkt[i][1] = sc->qe_addr[i] = physaddr[i];
78127915Skarels 	sc->qe_flags |= QEF_SETADDR;
78234530Skarels 	if (sc->qe_if.if_flags & IFF_RUNNING)
78327915Skarels 		qesetup(sc);
78427915Skarels 	qeinit(unit);
78527915Skarels }
78636820Skarels 
78736820Skarels 
78827477Skjd /*
78927477Skjd  * Initialize a ring descriptor with mbuf allocation side effects
79027477Skjd  */
79128953Skarels qeinitdesc(rp, addr, len)
79227477Skjd 	register struct qe_ring *rp;
79328953Skarels 	caddr_t addr; 			/* mapped address */
79427477Skjd 	int len;
79527477Skjd {
79627477Skjd 	/*
79727477Skjd 	 * clear the entire descriptor
79827477Skjd 	 */
79928953Skarels 	bzero((caddr_t)rp, sizeof(struct qe_ring));
80036820Skarels 
80127477Skjd 	if( len ) {
80227477Skjd 		rp->qe_buf_len = -(len/2);
80328927Skarels 		rp->qe_addr_lo = (short)addr;
80428927Skarels 		rp->qe_addr_hi = (short)((int)addr >> 16);
80527477Skjd 	}
80627477Skjd }
80727477Skjd /*
80827477Skjd  * Build a setup packet - the physical address will already be present
80927477Skjd  * in first column.
81027477Skjd  */
81127477Skjd qesetup( sc )
81227477Skjd struct qe_softc *sc;
81327477Skjd {
81428927Skarels 	register i, j;
81536820Skarels 
81627477Skjd 	/*
81727477Skjd 	 * Copy the target address to the rest of the entries in this row.
81827477Skjd 	 */
81927477Skjd 	 for ( j = 0; j < 6 ; j++ )
82027477Skjd 		for ( i = 2 ; i < 8 ; i++ )
82127477Skjd 			sc->setup_pkt[j][i] = sc->setup_pkt[j][1];
82227477Skjd 	/*
82327477Skjd 	 * Duplicate the first half.
82427477Skjd 	 */
82528953Skarels 	bcopy((caddr_t)sc->setup_pkt[0], (caddr_t)sc->setup_pkt[8], 64);
82627477Skjd 	/*
82738985Skarels 	 * Fill in the broadcast (and ISO multicast) address(es).
82827477Skjd 	 */
82938985Skarels 	for ( i = 0; i < 6 ; i++ ) {
83027477Skjd 		sc->setup_pkt[i][2] = 0xff;
83138985Skarels #ifdef ISO
83243337Ssklower 		sc->setup_pkt[i][3] = all_es_snpa[i];
83343337Ssklower 		sc->setup_pkt[i][4] = all_is_snpa[i];
83438985Skarels #endif
83538985Skarels 	}
83627477Skjd 	sc->setupqueued++;
83727477Skjd }
83827915Skarels 
83927477Skjd /*
84027477Skjd  * Pass a packet to the higher levels.
84127477Skjd  * We deal with the trailer protocol here.
84227477Skjd  */
84327915Skarels qeread(sc, ifrw, len)
84427477Skjd 	register struct qe_softc *sc;
84527477Skjd 	struct ifrw *ifrw;
84627477Skjd 	int len;
84727477Skjd {
84828927Skarels 	struct ether_header *eh;
84928927Skarels     	struct mbuf *m;
85036031Skarels 	int off, resid, s;
85127477Skjd 	struct ifqueue *inq;
85236820Skarels 
85327477Skjd 	/*
85427477Skjd 	 * Deal with trailer protocol: if type is INET trailer
85527477Skjd 	 * get true type from first 16-bit word past data.
85627477Skjd 	 * Remember that type was trailer by setting off.
85727477Skjd 	 */
85836820Skarels 
85927477Skjd 	eh = (struct ether_header *)ifrw->ifrw_addr;
86027477Skjd 	eh->ether_type = ntohs((u_short)eh->ether_type);
86127477Skjd #define	qedataaddr(eh, off, type)	((type)(((caddr_t)((eh)+1)+(off))))
86227477Skjd 	if (eh->ether_type >= ETHERTYPE_TRAIL &&
86327477Skjd 	    eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
86427477Skjd 		off = (eh->ether_type - ETHERTYPE_TRAIL) * 512;
86527477Skjd 		if (off >= ETHERMTU)
86627477Skjd 			return;		/* sanity */
86727915Skarels 		eh->ether_type = ntohs(*qedataaddr(eh,off, u_short *));
86827915Skarels 		resid = ntohs(*(qedataaddr(eh, off+2, u_short *)));
86927915Skarels 		if (off + resid > len)
87027915Skarels 		     return;		/* sanity */
87127915Skarels 		len = off + resid;
87227915Skarels 	} else
87327477Skjd 		off = 0;
87427477Skjd 	if (len == 0)
87527477Skjd 		return;
87636820Skarels 
87727477Skjd 	/*
87827477Skjd 	 * Pull packet off interface.  Off is nonzero if packet
87927477Skjd 	 * has trailing header; qeget will then force this header
88027477Skjd 	 * information to be at the front, but we still have to drop
88127477Skjd 	 * the type and length which are at the front of any trailer data.
88227477Skjd 	 */
88334530Skarels 	m = if_ubaget(&sc->qe_uba, ifrw, len, off, &sc->qe_if);
88436820Skarels 
88538985Skarels 	if (m)
88638985Skarels 		ether_input(&sc->qe_if, eh, m);
88727477Skjd }
88827915Skarels 
88927477Skjd /*
89034530Skarels  * Watchdog timeout routine. There is a condition in the hardware that
89127477Skjd  * causes the board to lock up under heavy load. This routine detects
89227477Skjd  * the hang up and restarts the device.
89327477Skjd  */
89434530Skarels qetimeout(unit)
89534530Skarels 	int unit;
89627477Skjd {
89727477Skjd 	register struct qe_softc *sc;
89836820Skarels 
89934530Skarels 	sc = &qe_softc[unit];
90039420Smckusick #ifdef notdef
90134530Skarels 	log(LOG_ERR, "qe%d: transmit timeout, restarted %d\n",
90236820Skarels 	     unit, sc->qe_restarts++);
90339420Smckusick #endif
90434530Skarels 	qerestart(sc);
90527477Skjd }
90627477Skjd /*
90727477Skjd  * Restart for board lockup problem.
90827477Skjd  */
90927915Skarels qerestart(sc)
91027477Skjd 	register struct qe_softc *sc;
91127477Skjd {
91234530Skarels 	register struct ifnet *ifp = &sc->qe_if;
91327477Skjd 	register struct qedevice *addr = sc->addr;
91427477Skjd 	register struct qe_ring *rp;
91527477Skjd 	register i;
91636820Skarels 
91727477Skjd 	addr->qe_csr = QE_RESET;
91836820Skarels 	addr->qe_csr &= ~QE_RESET;
91927477Skjd 	qesetup( sc );
92027915Skarels 	for (i = 0, rp = sc->tring; i < NXMT; rp++, i++) {
92127477Skjd 		rp->qe_flag = rp->qe_status1 = QE_NOTYET;
92227477Skjd 		rp->qe_valid = 0;
92327477Skjd 	}
92427477Skjd 	sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0;
92527915Skarels 	addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT |
92627915Skarels 	    QE_RCV_INT | QE_ILOOP;
92727477Skjd 	addr->qe_rcvlist_lo = (short)sc->rringaddr;
92827477Skjd 	addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16);
92927915Skarels 	sc->qe_flags |= QEF_RUNNING;
93038985Skarels 	(void) qestart(ifp);
93127477Skjd }
93227477Skjd #endif
933