Home | History | Annotate | Line # | Download | only in dev
if_ie.c revision 1.23
      1 /*	$NetBSD: if_ie.c,v 1.23 1997/11/05 00:02:51 gwr Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1993, 1994, 1995 Charles Hannum.
      5  * Copyright (c) 1992, 1993, University of Vermont and State
      6  *  Agricultural College.
      7  * Copyright (c) 1992, 1993, Garrett A. Wollman.
      8  *
      9  * Portions:
     10  * Copyright (c) 1994, 1995, Rafal K. Boni
     11  * Copyright (c) 1990, 1991, William F. Jolitz
     12  * Copyright (c) 1990, The Regents of the University of California
     13  *
     14  * All rights reserved.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by Charles Hannum, by the
     27  *	University of Vermont and State Agricultural College and Garrett A.
     28  *	Wollman, by William F. Jolitz, and by the University of California,
     29  *	Berkeley, Lawrence Berkeley Laboratory, and its contributors.
     30  * 4. Neither the names of the Universities nor the names of the authors
     31  *    may be used to endorse or promote products derived from this software
     32  *    without specific prior written permission.
     33  *
     34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
     38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     44  * SUCH DAMAGE.
     45  */
     46 
     47 /*
     48  * Intel 82586 Ethernet chip
     49  * Register, bit, and structure definitions.
     50  *
     51  * Original StarLAN driver written by Garrett Wollman with reference to the
     52  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
     53  *
     54  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
     55  *
     56  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
     57  *
     58  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
     59  *
     60  * Converted to SUN ie driver by Charles D. Cranor,
     61  *		October 1994, January 1995.
     62  * This sun version based on i386 version 1.30.
     63  * [ see sys/dev/isa/if_ie.c ]
     64  */
     65 
     66 /*
     67  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
     68  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
     69  * SUN, making life difficult.  Programming this chip is mostly the same,
     70  * but certain details differ from system to system.  This driver is
     71  * written so that different "ie" interfaces can be controled by the same
     72  * driver.
     73  */
     74 
     75 /*
     76    Mode of operation:
     77 
     78    We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
     79    received frame descriptors around for the receiver to use, and
     80    NRXBUF associated receive buffer descriptors, both in a circular
     81    list.  Whenever a frame is received, we rotate both lists as
     82    necessary.  (The 586 treats both lists as a simple queue.)  We also
     83    keep a transmit command around so that packets can be sent off
     84    quickly.
     85 
     86    We configure the adapter in AL-LOC = 1 mode, which means that the
     87    Ethernet/802.3 MAC header is placed at the beginning of the receive
     88    buffer rather than being split off into various fields in the RFD.
     89    This also means that we must include this header in the transmit
     90    buffer as well.
     91 
     92    By convention, all transmit commands, and only transmit commands,
     93    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
     94    when an interrupt arrives at ieintr(), it is immediately possible
     95    to tell what precisely caused it.  ANY OTHER command-sending
     96    routines should run at splnet(), and should post an acknowledgement
     97    to every interrupt they generate.
     98 */
     99 
    100 #include "bpfilter.h"
    101 
    102 #include <sys/param.h>
    103 #include <sys/systm.h>
    104 #include <sys/mbuf.h>
    105 #include <sys/buf.h>
    106 #include <sys/protosw.h>
    107 #include <sys/socket.h>
    108 #include <sys/ioctl.h>
    109 #include <sys/errno.h>
    110 #include <sys/syslog.h>
    111 #include <sys/device.h>
    112 
    113 #include <net/if.h>
    114 #include <net/if_types.h>
    115 #include <net/if_dl.h>
    116 #include <net/if_ether.h>
    117 
    118 #if NBPFILTER > 0
    119 #include <net/bpf.h>
    120 #include <net/bpfdesc.h>
    121 #endif
    122 
    123 #ifdef INET
    124 #include <netinet/in.h>
    125 #include <netinet/in_systm.h>
    126 #include <netinet/in_var.h>
    127 #include <netinet/ip.h>
    128 #include <netinet/if_inarp.h>
    129 #endif
    130 
    131 #ifdef NS
    132 #include <netns/ns.h>
    133 #include <netns/ns_if.h>
    134 #endif
    135 
    136 #include <vm/vm.h>
    137 
    138 #include <machine/autoconf.h>
    139 #include <machine/cpu.h>
    140 #include <machine/pmap.h>
    141 
    142 /*
    143  * ugly byte-order hack for SUNs
    144  */
    145 
    146 #define XSWAP(y)	( (((y)&0xff00) >> 8) | (((y)&0xff) << 8) )
    147 #define SWAP(x)		((u_short)(XSWAP((u_short)(x))))
    148 
    149 #include "i82586.h"
    150 #include "if_iereg.h"
    151 #include "if_ievar.h"
    152 
    153 /* #define	IEDEBUG	XXX */
    154 
    155 /*
    156  * IED: ie debug flags
    157  */
    158 
    159 #define	IED_RINT	0x01
    160 #define	IED_TINT	0x02
    161 #define	IED_RNR		0x04
    162 #define	IED_CNA		0x08
    163 #define	IED_READFRAME	0x10
    164 #define	IED_ENQ		0x20
    165 #define	IED_XMIT	0x40
    166 #define	IED_ALL		0x7f
    167 
    168 #define	ETHER_MIN_LEN	64
    169 #define	ETHER_MAX_LEN	1518
    170 #define	ETHER_ADDR_LEN	6
    171 
    172 #ifdef	IEDEBUG
    173 #define	inline	/* not */
    174 void print_rbd __P((volatile struct ie_recv_buf_desc *));
    175 int     in_ierint = 0;
    176 int     in_ietint = 0;
    177 int     ie_debug_flags = 0;
    178 #endif
    179 
    180 /* XXX - Skip TDR for now - it always complains... */
    181 int 	ie_run_tdr = 0;
    182 
    183 static void iewatchdog __P((struct ifnet *));
    184 static int ieinit __P((struct ie_softc *));
    185 static int ieioctl __P((struct ifnet *, u_long, caddr_t));
    186 static void iestart __P((struct ifnet *));
    187 static void iereset __P((struct ie_softc *));
    188 static int ie_setupram __P((struct ie_softc *sc));
    189 
    190 static int cmd_and_wait __P((struct ie_softc *, int, void *, int));
    191 
    192 static void ie_drop_packet_buffer __P((struct ie_softc *));
    193 static void ie_readframe __P((struct ie_softc *, int));
    194 static inline void ie_setup_config __P((struct ie_config_cmd *, int, int));
    195 
    196 static void ierint __P((struct ie_softc *));
    197 static void iestop __P((struct ie_softc *));
    198 static void ietint __P((struct ie_softc *));
    199 static void iexmit __P((struct ie_softc *));
    200 
    201 static int mc_setup __P((struct ie_softc *, void *));
    202 static void mc_reset __P((struct ie_softc *));
    203 static void run_tdr __P((struct ie_softc *, struct ie_tdr_cmd *));
    204 static void iememinit __P((struct ie_softc *));
    205 
    206 static inline char * Align __P((char *));
    207 static inline u_int Swap32 __P((u_int x));
    208 static inline u_int vtop24 __P((struct ie_softc *, void *));
    209 static inline u_short vtop16sw __P((struct ie_softc *, void *));
    210 
    211 static inline void ie_ack __P((struct ie_softc *, u_int));
    212 static inline u_short ether_cmp __P((u_char *, u_char *));
    213 static inline int check_eh __P((struct ie_softc *,
    214 		struct ether_header *eh, int *));
    215 static inline int ie_buflen __P((struct ie_softc *, int));
    216 static inline int ie_packet_len __P((struct ie_softc *));
    217 static inline struct mbuf * ieget __P((struct ie_softc *sc,
    218 		struct ether_header *ehp, int *to_bpf));
    219 
    220 
    221 struct cfdriver ie_cd = {
    222 	NULL, "ie", DV_IFNET
    223 };
    224 
    225 /*
    226  * Here are a few useful functions.  We could have done these as macros,
    227  * but since we have the inline facility, it makes sense to use that
    228  * instead.
    229  */
    230 
    231 /* KVA to 24 bit device address */
    232 static inline u_int
    233 vtop24(sc, ptr)
    234 	struct ie_softc *sc;
    235 	void *ptr;
    236 {
    237 	u_int pa;
    238 
    239 	pa = ((caddr_t)ptr) - sc->sc_iobase;
    240 #ifdef	IEDEBUG
    241 	if (pa & ~0xffFFff)
    242 		panic("ie:vtop24");
    243 #endif
    244 	return (pa);
    245 }
    246 
    247 /* KVA to 16 bit offset, swapped */
    248 static inline u_short
    249 vtop16sw(sc, ptr)
    250 	struct ie_softc *sc;
    251 	void *ptr;
    252 {
    253 	u_int pa;
    254 
    255 	pa = ((caddr_t)ptr) - sc->sc_maddr;
    256 #ifdef	IEDEBUG
    257 	if (pa & ~0xFFff)
    258 		panic("ie:vtop16");
    259 #endif
    260 
    261 	return (SWAP(pa));
    262 }
    263 
    264 static inline u_int
    265 Swap32(x)
    266 	u_int x;
    267 {
    268 	u_int y;
    269 
    270 	y = x & 0xFF;
    271 	y <<= 8; x >>= 8;
    272 	y |= x & 0xFF;
    273 	y <<= 8; x >>= 8;
    274 	y |= x & 0xFF;
    275 	y <<= 8; x >>= 8;
    276 	y |= x & 0xFF;
    277 
    278 	return (y);
    279 }
    280 
    281 static inline char *
    282 Align(ptr)
    283 	caddr_t ptr;
    284 {
    285 	u_long  l = (u_long)ptr;
    286 
    287 	l = (l + 3) & ~3L;
    288 	return ((char *)l);
    289 }
    290 
    291 
    292 static inline void
    293 ie_ack(sc, mask)
    294 	struct ie_softc *sc;
    295 	u_int mask;
    296 {
    297 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    298 
    299 	cmd_and_wait(sc, scb->ie_status & mask, 0, 0);
    300 }
    301 
    302 
    303 /*
    304  * Taken almost exactly from Bill's if_is.c,
    305  * then modified beyond recognition...
    306  */
    307 void
    308 ie_attach(sc)
    309 	struct ie_softc *sc;
    310 {
    311 	struct ifnet *ifp = &sc->sc_if;
    312 
    313 	/* MD code has done its part before calling this. */
    314 	printf(": macaddr %s\n", ether_sprintf(sc->sc_addr));
    315 
    316 	/*
    317 	 * Compute number of transmit and receive buffers.
    318 	 * Tx buffers take 1536 bytes, and fixed in number.
    319 	 * Rx buffers are 512 bytes each, variable number.
    320 	 * Need at least 1 frame for each 3 rx buffers.
    321 	 * The ratio 3bufs:2frames is a compromise.
    322 	 */
    323 	sc->ntxbuf = NTXBUF;	/* XXX - Fix me... */
    324 	switch (sc->sc_msize) {
    325 	case 16384:
    326 		sc->nframes = 8 * 4;
    327 		sc->nrxbuf  = 8 * 6;
    328 		break;
    329 	case 32768:
    330 		sc->nframes = 16 * 4;
    331 		sc->nrxbuf  = 16 * 6;
    332 		break;
    333 	case 65536:
    334 		sc->nframes = 32 * 4;
    335 		sc->nrxbuf  = 32 * 6;
    336 		break;
    337 	default:
    338 		sc->nframes = 0;
    339 	}
    340 	if (sc->nframes > MXFRAMES)
    341 		sc->nframes = MXFRAMES;
    342 	if (sc->nrxbuf > MXRXBUF)
    343 		sc->nrxbuf = MXRXBUF;
    344 
    345 #ifdef	IEDEBUG
    346 	printf("%s: %dK memory, %d tx frames, %d rx frames, %d rx bufs\n",
    347 	    sc->sc_dev.dv_xname, (sc->sc_msize >> 10),
    348 	    sc->ntxbuf, sc->nframes, sc->nrxbuf);
    349 #endif
    350 
    351 	if ((sc->nframes <= 0) || (sc->nrxbuf <= 0))
    352 		panic("ie_attach: weird memory size");
    353 
    354 	/*
    355 	 * Setup RAM for transmit/receive
    356 	 */
    357 	if (ie_setupram(sc) == 0) {
    358 		printf(": RAM CONFIG FAILED!\n");
    359 		/* XXX should reclaim resources? */
    360 		return;
    361 	}
    362 
    363 	/*
    364 	 * Initialize and attach S/W interface
    365 	 */
    366 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
    367 	ifp->if_softc = sc;
    368 	ifp->if_start = iestart;
    369 	ifp->if_ioctl = ieioctl;
    370 	ifp->if_watchdog = iewatchdog;
    371 	ifp->if_flags =
    372 	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
    373 
    374 	/* Attach the interface. */
    375 	if_attach(ifp);
    376 	ether_ifattach(ifp, sc->sc_addr);
    377 #if NBPFILTER > 0
    378 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
    379 #endif
    380 }
    381 
    382 /*
    383  * Setup IE's ram space.
    384  */
    385 static int
    386 ie_setupram(sc)
    387 	struct ie_softc *sc;
    388 {
    389 	volatile struct ie_sys_conf_ptr *scp;
    390 	volatile struct ie_int_sys_conf_ptr *iscp;
    391 	volatile struct ie_sys_ctl_block *scb;
    392 	int off;
    393 
    394 	/*
    395 	 * Allocate from end of buffer space for
    396 	 * ISCP, SCB, and other small stuff.
    397 	 */
    398 	off = sc->buf_area_sz;
    399 	off &= ~3;
    400 
    401 	/* SCP (address already chosen). */
    402 	scp = sc->scp;
    403 	(sc->sc_bzero)((char *) scp, sizeof(*scp));
    404 
    405 	/* ISCP */
    406 	off -= sizeof(*iscp);
    407 	iscp = (volatile void *) (sc->buf_area + off);
    408 	(sc->sc_bzero)((char *) iscp, sizeof(*iscp));
    409 	sc->iscp = iscp;
    410 
    411 	/* SCB */
    412 	off -= sizeof(*scb);
    413 	scb  = (volatile void *) (sc->buf_area + off);
    414 	(sc->sc_bzero)((char *) scb, sizeof(*scb));
    415 	sc->scb = scb;
    416 
    417 	/* Remainder is for buffers, etc. */
    418 	sc->buf_area_sz = off;
    419 
    420 	/*
    421 	 * Now fill in the structures we just allocated.
    422 	 */
    423 
    424 	/* SCP: main thing is 24-bit ptr to ISCP */
    425 	scp->ie_bus_use = 0;	/* 16-bit */
    426 	scp->ie_iscp_ptr = Swap32(vtop24(sc, (void*)iscp));
    427 
    428 	/* ISCP */
    429 	iscp->ie_busy = 1;	/* ie_busy == char */
    430 	iscp->ie_scb_offset = vtop16sw(sc, (void*)scb);
    431 	iscp->ie_base = Swap32(vtop24(sc, sc->sc_maddr));
    432 
    433 	/* SCB */
    434 	scb->ie_command_list = SWAP(0xffff);
    435 	scb->ie_recv_list    = SWAP(0xffff);
    436 
    437 	/* Other stuff is done in ieinit() */
    438 	(sc->reset_586) (sc);
    439 	(sc->chan_attn) (sc);
    440 
    441 	delay(100);		/* wait a while... */
    442 
    443 	if (iscp->ie_busy) {
    444 		return 0;
    445 	}
    446 	/*
    447 	 * Acknowledge any interrupts we may have caused...
    448 	 */
    449 	ie_ack(sc, IE_ST_WHENCE);
    450 
    451 	return 1;
    452 }
    453 
    454 /*
    455  * Device timeout/watchdog routine.  Entered if the device neglects to
    456  * generate an interrupt after a transmit has been started on it.
    457  */
    458 static void
    459 iewatchdog(ifp)
    460 	struct ifnet *ifp;
    461 {
    462 	struct ie_softc *sc = ifp->if_softc;
    463 
    464 	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
    465 	++ifp->if_oerrors;
    466 	iereset(sc);
    467 }
    468 
    469 /*
    470  * What to do upon receipt of an interrupt.
    471  */
    472 int
    473 ie_intr(arg)
    474 	void *arg;
    475 {
    476 	struct ie_softc *sc = arg;
    477 	register u_short status;
    478 	int loopcnt;
    479 
    480 	/*
    481 	 * check for parity error
    482 	 */
    483 	if (sc->hard_type == IE_VME) {
    484 		volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg;
    485 		if (iev->status & IEVME_PERR) {
    486 			printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
    487 			    sc->sc_dev.dv_xname, iev->pectrl,
    488 			    iev->pectrl & IEVME_HADDR, iev->peaddr);
    489 			iev->pectrl = iev->pectrl | IEVME_PARACK;
    490 		}
    491 	}
    492 
    493 	status = sc->scb->ie_status;
    494 	if ((status & IE_ST_WHENCE) == 0)
    495 		return 0;
    496 
    497 	loopcnt = sc->nframes;
    498 loop:
    499 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    500 	ie_ack(sc, IE_ST_WHENCE & status);
    501 
    502 	if (status & (IE_ST_RECV | IE_ST_RNR)) {
    503 #ifdef IEDEBUG
    504 		in_ierint++;
    505 		if (sc->sc_debug & IED_RINT)
    506 			printf("%s: rint\n", sc->sc_dev.dv_xname);
    507 #endif
    508 		ierint(sc);
    509 #ifdef IEDEBUG
    510 		in_ierint--;
    511 #endif
    512 	}
    513 
    514 	if (status & IE_ST_DONE) {
    515 #ifdef IEDEBUG
    516 		in_ietint++;
    517 		if (sc->sc_debug & IED_TINT)
    518 			printf("%s: tint\n", sc->sc_dev.dv_xname);
    519 #endif
    520 		ietint(sc);
    521 #ifdef IEDEBUG
    522 		in_ietint--;
    523 #endif
    524 	}
    525 
    526 	/*
    527 	 * Receiver not ready (RNR) just means it has
    528 	 * run out of resources (buffers or frames).
    529 	 * One can easily cause this with (i.e.) spray.
    530 	 * This is not a serious error, so be silent.
    531 	 */
    532 	if (status & IE_ST_RNR) {
    533 #ifdef IEDEBUG
    534 		printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
    535 #endif
    536 		sc->sc_if.if_ierrors++;
    537 		iereset(sc);
    538 	}
    539 
    540 #ifdef IEDEBUG
    541 	if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
    542 		printf("%s: cna\n", sc->sc_dev.dv_xname);
    543 #endif
    544 
    545 	status = sc->scb->ie_status;
    546 	if (status & IE_ST_WHENCE) {
    547 		/* It still wants service... */
    548 		if (--loopcnt > 0)
    549 			goto loop;
    550 		/* ... but we've been here long enough. */
    551 		log(LOG_ERR, "%s: interrupt stuck?\n",
    552 			sc->sc_dev.dv_xname);
    553 		iereset(sc);
    554 	}
    555 	return 1;
    556 }
    557 
    558 /*
    559  * Process a received-frame interrupt.
    560  */
    561 void
    562 ierint(sc)
    563 	struct ie_softc *sc;
    564 {
    565 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    566 	int i, status;
    567 	static int timesthru = 1024;
    568 
    569 	i = sc->rfhead;
    570 	for (;;) {
    571 		status = sc->rframes[i]->ie_fd_status;
    572 
    573 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
    574 			if (!--timesthru) {
    575 				sc->sc_if.if_ierrors +=
    576 				    SWAP(scb->ie_err_crc) +
    577 				    SWAP(scb->ie_err_align) +
    578 				    SWAP(scb->ie_err_resource) +
    579 				    SWAP(scb->ie_err_overrun);
    580 				scb->ie_err_crc = 0;
    581 				scb->ie_err_align = 0;
    582 				scb->ie_err_resource = 0;
    583 				scb->ie_err_overrun = 0;
    584 				timesthru = 1024;
    585 			}
    586 			ie_readframe(sc, i);
    587 		} else {
    588 			if ((status & IE_FD_RNR) != 0 &&
    589 			    (scb->ie_status & IE_RU_READY) == 0) {
    590 				sc->rframes[0]->ie_fd_buf_desc =
    591 					vtop16sw(sc, (void*) sc->rbuffs[0]);
    592 				scb->ie_recv_list =
    593 					vtop16sw(sc, (void*) sc->rframes[0]);
    594 				cmd_and_wait(sc, IE_RU_START, 0, 0);
    595 			}
    596 			break;
    597 		}
    598 		i = (i + 1) % sc->nframes;
    599 	}
    600 }
    601 
    602 /*
    603  * Process a command-complete interrupt.  These are only generated by the
    604  * transmission of frames.  This routine is deceptively simple, since most
    605  * of the real work is done by iestart().
    606  */
    607 void
    608 ietint(sc)
    609 	struct ie_softc *sc;
    610 {
    611 	struct ifnet *ifp;
    612 	int status;
    613 
    614 	ifp = &sc->sc_if;
    615 
    616 	ifp->if_timer = 0;
    617 	ifp->if_flags &= ~IFF_OACTIVE;
    618 
    619 	status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
    620 
    621 	if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
    622 		printf("ietint: command still busy!\n");
    623 
    624 	if (status & IE_STAT_OK) {
    625 		ifp->if_opackets++;
    626 		ifp->if_collisions +=
    627 		  SWAP(status & IE_XS_MAXCOLL);
    628 	} else {
    629 		ifp->if_oerrors++;
    630 		/*
    631 		 * XXX
    632 		 * Check SQE and DEFERRED?
    633 		 * What if more than one bit is set?
    634 		 */
    635 		if (status & IE_STAT_ABORT)
    636 			printf("%s: send aborted\n", sc->sc_dev.dv_xname);
    637 		if (status & IE_XS_LATECOLL)
    638 			printf("%s: late collision\n", sc->sc_dev.dv_xname);
    639 		if (status & IE_XS_NOCARRIER)
    640 			printf("%s: no carrier\n", sc->sc_dev.dv_xname);
    641 		if (status & IE_XS_LOSTCTS)
    642 			printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
    643 		if (status & IE_XS_UNDERRUN)
    644 			printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
    645 		if (status & IE_XS_EXCMAX) {
    646 			/* Do not print this one (too noisy). */
    647 			ifp->if_collisions += 16;
    648 		}
    649 	}
    650 
    651 	/*
    652 	 * If multicast addresses were added or deleted while we
    653 	 * were transmitting, mc_reset() set the want_mcsetup flag
    654 	 * indicating that we should do it.
    655 	 */
    656 	if (sc->want_mcsetup) {
    657 		mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
    658 		sc->want_mcsetup = 0;
    659 	}
    660 
    661 	/* Done with the buffer. */
    662 	sc->xmit_busy--;
    663 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    664 
    665 	/* Start the next packet, if any, transmitting. */
    666 	if (sc->xmit_busy > 0)
    667 		iexmit(sc);
    668 
    669 	iestart(ifp);
    670 }
    671 
    672 /*
    673  * Compare two Ether/802 addresses for equality, inlined and
    674  * unrolled for speed.  I'd love to have an inline assembler
    675  * version of this...   XXX: Who wanted that? mycroft?
    676  * I wrote one, but the following is just as efficient.
    677  * This expands to 10 short m68k instructions! -gwr
    678  * Note: use this like bcmp()
    679  */
    680 static inline u_short
    681 ether_cmp(one, two)
    682 	u_char *one, *two;
    683 {
    684 	register u_short *a = (u_short *) one;
    685 	register u_short *b = (u_short *) two;
    686 	register u_short diff;
    687 
    688 	diff  = *a++ - *b++;
    689 	diff |= *a++ - *b++;
    690 	diff |= *a++ - *b++;
    691 
    692 	return (diff);
    693 }
    694 #define	ether_equal !ether_cmp
    695 
    696 /*
    697  * Check for a valid address.  to_bpf is filled in with one of the following:
    698  *   0 -> BPF doesn't get this packet
    699  *   1 -> BPF does get this packet
    700  *   2 -> BPF does get this packet, but we don't
    701  * Return value is true if the packet is for us, and false otherwise.
    702  *
    703  * This routine is a mess, but it's also critical that it be as fast
    704  * as possible.  It could be made cleaner if we can assume that the
    705  * only client which will fiddle with IFF_PROMISC is BPF.  This is
    706  * probably a good assumption, but we do not make it here.  (Yet.)
    707  */
    708 static inline int
    709 check_eh(sc, eh, to_bpf)
    710 	struct ie_softc *sc;
    711 	struct ether_header *eh;
    712 	int *to_bpf;
    713 {
    714 	struct ifnet *ifp;
    715 	int i;
    716 
    717 	ifp = &sc->sc_if;
    718 
    719 	switch (sc->promisc) {
    720 	case IFF_ALLMULTI:
    721 		/*
    722 		 * Receiving all multicasts, but no unicasts except those
    723 		 * destined for us.
    724 		 */
    725 #if NBPFILTER > 0
    726 		/* BPF gets this packet if anybody cares */
    727 		*to_bpf = (ifp->if_bpf != 0);
    728 #endif
    729 		if (eh->ether_dhost[0] & 1)
    730 			return 1;
    731 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    732 			return 1;
    733 		return 0;
    734 
    735 	case IFF_PROMISC:
    736 		/*
    737 		 * Receiving all packets.  These need to be passed on to BPF.
    738 		 */
    739 #if NBPFILTER > 0
    740 		*to_bpf = (ifp->if_bpf != 0);
    741 #endif
    742 		/* If for us, accept and hand up to BPF */
    743 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    744 			return 1;
    745 
    746 #if NBPFILTER > 0
    747 		if (*to_bpf)
    748 			*to_bpf = 2;	/* we don't need to see it */
    749 #endif
    750 
    751 		/*
    752 		 * Not a multicast, so BPF wants to see it but we don't.
    753 		 */
    754 		if (!(eh->ether_dhost[0] & 1))
    755 			return 1;
    756 
    757 		/*
    758 		 * If it's one of our multicast groups, accept it and pass it
    759 		 * up.
    760 		 */
    761 		for (i = 0; i < sc->mcast_count; i++) {
    762 			if (ether_equal(eh->ether_dhost,
    763 			    (u_char *)&sc->mcast_addrs[i])) {
    764 #if NBPFILTER > 0
    765 				if (*to_bpf)
    766 					*to_bpf = 1;
    767 #endif
    768 				return 1;
    769 			}
    770 		}
    771 		return 1;
    772 
    773 	case IFF_ALLMULTI | IFF_PROMISC:
    774 		/*
    775 		 * Acting as a multicast router, and BPF running at the same
    776 		 * time.  Whew!  (Hope this is a fast machine...)
    777 		 */
    778 #if NBPFILTER > 0
    779 		*to_bpf = (ifp->if_bpf != 0);
    780 #endif
    781 		/* We want to see multicasts. */
    782 		if (eh->ether_dhost[0] & 1)
    783 			return 1;
    784 
    785 		/* We want to see our own packets */
    786 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    787 			return 1;
    788 
    789 		/* Anything else goes to BPF but nothing else. */
    790 #if NBPFILTER > 0
    791 		if (*to_bpf)
    792 			*to_bpf = 2;
    793 #endif
    794 		return 1;
    795 
    796 	case 0:
    797 		/*
    798 		 * Only accept unicast packets destined for us, or multicasts
    799 		 * for groups that we belong to.  For now, we assume that the
    800 		 * '586 will only return packets that we asked it for.  This
    801 		 * isn't strictly true (it uses hashing for the multicast filter),
    802 		 * but it will do in this case, and we want to get out of here
    803 		 * as quickly as possible.
    804 		 */
    805 #if NBPFILTER > 0
    806 		*to_bpf = (ifp->if_bpf != 0);
    807 #endif
    808 		return 1;
    809 	}
    810 #ifdef	DIAGNOSTIC
    811 	panic("ie: check_eh, impossible");
    812 #endif
    813 	return 0;
    814 }
    815 
    816 /*
    817  * We want to isolate the bits that have meaning...  This assumes that
    818  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
    819  * the size of the buffer, then we are screwed anyway.
    820  */
    821 static inline int
    822 ie_buflen(sc, head)
    823 	struct ie_softc *sc;
    824 	int head;
    825 {
    826 	register int len;
    827 
    828 	len = SWAP(sc->rbuffs[head]->ie_rbd_actual);
    829 	len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1));
    830 	return (len);
    831 }
    832 
    833 static inline int
    834 ie_packet_len(sc)
    835 	struct ie_softc *sc;
    836 {
    837 	int i;
    838 	int head = sc->rbhead;
    839 	int acc = 0;
    840 
    841 	do {
    842 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
    843 #ifdef IEDEBUG
    844 			print_rbd(sc->rbuffs[sc->rbhead]);
    845 #endif
    846 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
    847 			    sc->sc_dev.dv_xname, sc->rbhead);
    848 			iereset(sc);
    849 			return -1;
    850 		}
    851 
    852 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
    853 
    854 		acc += ie_buflen(sc, head);
    855 		head = (head + 1) % sc->nrxbuf;
    856 	} while (!i);
    857 
    858 	return acc;
    859 }
    860 
    861 /*
    862  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
    863  * command to the chip to be executed.  On the way, if we have a BPF listener
    864  * also give him a copy.
    865  */
    866 static void
    867 iexmit(sc)
    868 	struct ie_softc *sc;
    869 {
    870 	struct ifnet *ifp;
    871 
    872 	ifp = &sc->sc_if;
    873 
    874 #ifdef IEDEBUG
    875 	if (sc->sc_debug & IED_XMIT)
    876 		printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname,
    877 		    sc->xctail);
    878 #endif
    879 
    880 #if NBPFILTER > 0
    881 	/*
    882 	 * If BPF is listening on this interface, let it see the packet before
    883 	 * we push it on the wire.
    884 	 */
    885 	if (ifp->if_bpf)
    886 		bpf_tap(ifp->if_bpf,
    887 		    sc->xmit_cbuffs[sc->xctail],
    888 		    SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
    889 #endif
    890 
    891 	sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
    892 	sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
    893 	sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
    894 	    Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail]));
    895 
    896 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
    897 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
    898 	    IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
    899 
    900 	sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
    901 	sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
    902 	    vtop16sw(sc, (void*) sc->xmit_buffs[sc->xctail]);
    903 
    904 	sc->scb->ie_command_list =
    905 	    vtop16sw(sc, (void*) sc->xmit_cmds[sc->xctail]);
    906 	cmd_and_wait(sc, IE_CU_START, 0, 0);
    907 
    908 	ifp->if_timer = 5;
    909 }
    910 
    911 /*
    912  * Read data off the interface, and turn it into an mbuf chain.
    913  *
    914  * This code is DRAMATICALLY different from the previous version; this
    915  * version tries to allocate the entire mbuf chain up front, given the
    916  * length of the data available.  This enables us to allocate mbuf
    917  * clusters in many situations where before we would have had a long
    918  * chain of partially-full mbufs.  This should help to speed up the
    919  * operation considerably.  (Provided that it works, of course.)
    920  */
    921 static inline struct mbuf *
    922 ieget(sc, ehp, to_bpf)
    923 	struct ie_softc *sc;
    924 	struct ether_header *ehp;
    925 	int *to_bpf;
    926 {
    927 	struct mbuf *top, **mp, *m;
    928 	int len, totlen, resid;
    929 	int thisrboff, thismboff;
    930 	int head;
    931 
    932 	totlen = ie_packet_len(sc);
    933 	if (totlen <= 0)
    934 		return 0;
    935 
    936 	head = sc->rbhead;
    937 
    938 	/*
    939 	 * Snarf the Ethernet header.
    940 	 */
    941 	(sc->sc_bcopy)((caddr_t)sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp);
    942 
    943 	/*
    944 	 * As quickly as possible, check if this packet is for us.
    945 	 * If not, don't waste a single cycle copying the rest of the
    946 	 * packet in.
    947 	 * This is only a consideration when FILTER is defined; i.e., when
    948 	 * we are either running BPF or doing multicasting.
    949 	 */
    950 	if (!check_eh(sc, ehp, to_bpf)) {
    951 		/* just this case, it's not an error */
    952 		sc->sc_if.if_ierrors--;
    953 		return 0;
    954 	}
    955 
    956 	resid = totlen -= (thisrboff = sizeof *ehp);
    957 
    958 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    959 	if (m == 0)
    960 		return 0;
    961 
    962 	m->m_pkthdr.rcvif = &sc->sc_if;
    963 	m->m_pkthdr.len = totlen;
    964 	len = MHLEN;
    965 	top = 0;
    966 	mp = &top;
    967 
    968 	/*
    969 	 * This loop goes through and allocates mbufs for all the data we will
    970 	 * be copying in.  It does not actually do the copying yet.
    971 	 */
    972 	while (totlen > 0) {
    973 		if (top) {
    974 			MGET(m, M_DONTWAIT, MT_DATA);
    975 			if (m == 0) {
    976 				m_freem(top);
    977 				return 0;
    978 			}
    979 			len = MLEN;
    980 		}
    981 		if (totlen >= MINCLSIZE) {
    982 			MCLGET(m, M_DONTWAIT);
    983 			if (m->m_flags & M_EXT)
    984 				len = MCLBYTES;
    985 		}
    986 		m->m_len = len = min(totlen, len);
    987 		totlen -= len;
    988 		*mp = m;
    989 		mp = &m->m_next;
    990 	}
    991 
    992 	m = top;
    993 	thismboff = 0;
    994 
    995 	/*
    996 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
    997 	 * time) and stuff the data into it.  There are no possible failures
    998 	 * at or after this point.
    999 	 */
   1000 	while (resid > 0) {
   1001 		int thisrblen = ie_buflen(sc, head) - thisrboff;
   1002 		int thismblen = m->m_len - thismboff;
   1003 
   1004 		len = min(thisrblen, thismblen);
   1005 		(sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + thisrboff),
   1006 		    mtod(m, caddr_t) + thismboff, (u_int)len);
   1007 		resid -= len;
   1008 
   1009 		if (len == thismblen) {
   1010 			m = m->m_next;
   1011 			thismboff = 0;
   1012 		} else
   1013 			thismboff += len;
   1014 
   1015 		if (len == thisrblen) {
   1016 			head = (head + 1) % sc->nrxbuf;
   1017 			thisrboff = 0;
   1018 		} else
   1019 			thisrboff += len;
   1020 	}
   1021 
   1022 	/*
   1023 	 * Unless something changed strangely while we were doing the copy,
   1024 	 * we have now copied everything in from the shared memory.
   1025 	 * This means that we are done.
   1026 	 */
   1027 	return top;
   1028 }
   1029 
   1030 /*
   1031  * Read frame NUM from unit UNIT (pre-cached as IE).
   1032  *
   1033  * This routine reads the RFD at NUM, and copies in the buffers from
   1034  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
   1035  * doesn't start complaining.  Trailers are DROPPED---there's no point
   1036  * in wasting time on confusing code to deal with them.  Hopefully,
   1037  * this machine will never ARP for trailers anyway.
   1038  */
   1039 static void
   1040 ie_readframe(sc, num)
   1041 	struct ie_softc *sc;
   1042 	int num;			/* frame number to read */
   1043 {
   1044 	int status;
   1045 	struct mbuf *m = 0;
   1046 	struct ether_header eh;
   1047 #if NBPFILTER > 0
   1048 	int bpf_gets_it = 0;
   1049 #endif
   1050 
   1051 	status = sc->rframes[num]->ie_fd_status;
   1052 
   1053 	/* Advance the RFD list, since we're done with this descriptor. */
   1054 	sc->rframes[num]->ie_fd_status = SWAP(0);
   1055 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
   1056 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
   1057 	sc->rftail = (sc->rftail + 1) % sc->nframes;
   1058 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
   1059 
   1060 	if (status & IE_FD_OK) {
   1061 #if NBPFILTER > 0
   1062 		m = ieget(sc, &eh, &bpf_gets_it);
   1063 #else
   1064 		m = ieget(sc, &eh, 0);
   1065 #endif
   1066 		ie_drop_packet_buffer(sc);
   1067 	}
   1068 	if (m == 0) {
   1069 		sc->sc_if.if_ierrors++;
   1070 		return;
   1071 	}
   1072 
   1073 #ifdef IEDEBUG
   1074 	if (sc->sc_debug & IED_READFRAME)
   1075 		printf("%s: frame from ether %s type 0x%x\n",
   1076 			sc->sc_dev.dv_xname,
   1077 		    ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
   1078 #endif
   1079 
   1080 #if NBPFILTER > 0
   1081 	/*
   1082 	 * Check for a BPF filter; if so, hand it up.
   1083 	 * Note that we have to stick an extra mbuf up front, because
   1084 	 * bpf_mtap expects to have the ether header at the front.
   1085 	 * It doesn't matter that this results in an ill-formatted mbuf chain,
   1086 	 * since BPF just looks at the data.  (It doesn't try to free the mbuf,
   1087 	 * tho' it will make a copy for tcpdump.)
   1088 	 */
   1089 	if (bpf_gets_it) {
   1090 		struct mbuf m0;
   1091 		m0.m_len = sizeof eh;
   1092 		m0.m_data = (caddr_t)&eh;
   1093 		m0.m_next = m;
   1094 
   1095 		/* Pass it up. */
   1096 		bpf_mtap(sc->sc_if.if_bpf, &m0);
   1097 
   1098 		/*
   1099 		 * A signal passed up from the filtering code indicating that
   1100 		 * the packet is intended for BPF but not for the protocol
   1101 		 * machinery.  We can save a few cycles by not handing it off
   1102 		 * to them.
   1103 		 */
   1104 		if (bpf_gets_it == 2) {
   1105 			m_freem(m);
   1106 			return;
   1107 		}
   1108 	}
   1109 #endif	/* NBPFILTER > 0 */
   1110 
   1111 	/*
   1112 	 * In here there used to be code to check destination addresses upon
   1113 	 * receipt of a packet.  We have deleted that code, and replaced it
   1114 	 * with code to check the address much earlier in the cycle, before
   1115 	 * copying the data in; this saves us valuable cycles when operating
   1116 	 * as a multicast router or when using BPF.
   1117 	 */
   1118 
   1119 	/*
   1120 	 * Finally pass this packet up to higher layers.
   1121 	 */
   1122 	ether_input(&sc->sc_if, &eh, m);
   1123 	sc->sc_if.if_ipackets++;
   1124 }
   1125 
   1126 static void
   1127 ie_drop_packet_buffer(sc)
   1128 	struct ie_softc *sc;
   1129 {
   1130 	int i;
   1131 
   1132 	do {
   1133 		/*
   1134 		 * This means we are somehow out of sync.  So, we reset the
   1135 		 * adapter.
   1136 		 */
   1137 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
   1138 #ifdef IEDEBUG
   1139 			print_rbd(sc->rbuffs[sc->rbhead]);
   1140 #endif
   1141 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
   1142 			    sc->sc_dev.dv_xname, sc->rbhead);
   1143 			iereset(sc);
   1144 			return;
   1145 		}
   1146 
   1147 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
   1148 
   1149 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
   1150 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
   1151 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
   1152 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
   1153 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
   1154 	} while (!i);
   1155 }
   1156 
   1157 /*
   1158  * Start transmission on an interface.
   1159  */
   1160 static void
   1161 iestart(ifp)
   1162 	struct ifnet *ifp;
   1163 {
   1164 	struct ie_softc *sc = ifp->if_softc;
   1165 	struct mbuf *m0, *m;
   1166 	u_char *buffer;
   1167 	u_short len;
   1168 
   1169 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   1170 		return;
   1171 
   1172 	for (;;) {
   1173 		if (sc->xmit_busy == sc->ntxbuf) {
   1174 			ifp->if_flags |= IFF_OACTIVE;
   1175 			break;
   1176 		}
   1177 
   1178 		IF_DEQUEUE(&ifp->if_snd, m0);
   1179 		if (m0 == 0)
   1180 			break;
   1181 
   1182 		/* We need to use m->m_pkthdr.len, so require the header */
   1183 		if ((m0->m_flags & M_PKTHDR) == 0)
   1184 			panic("iestart: no header mbuf");
   1185 
   1186 #if NBPFILTER > 0
   1187 		/* Tap off here if there is a BPF listener. */
   1188 		if (ifp->if_bpf)
   1189 			bpf_mtap(ifp->if_bpf, m0);
   1190 #endif
   1191 
   1192 #ifdef IEDEBUG
   1193 		if (sc->sc_debug & IED_ENQ)
   1194 			printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
   1195 			    sc->xchead);
   1196 #endif
   1197 
   1198 		buffer = sc->xmit_cbuffs[sc->xchead];
   1199 		for (m = m0; m != 0; m = m->m_next) {
   1200 			(sc->sc_bcopy)(mtod(m, caddr_t), buffer, m->m_len);
   1201 			buffer += m->m_len;
   1202 		}
   1203 		len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
   1204 
   1205 		m_freem(m0);
   1206 		sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
   1207 
   1208 		/* Start the first packet transmitting. */
   1209 		if (sc->xmit_busy == 0)
   1210 			iexmit(sc);
   1211 
   1212 		sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
   1213 		sc->xmit_busy++;
   1214 	}
   1215 }
   1216 
   1217 static void
   1218 iereset(sc)
   1219 	struct ie_softc *sc;
   1220 {
   1221 	int s = splnet();
   1222 
   1223 	/* No message here.  The caller does that. */
   1224 	iestop(sc);
   1225 
   1226 	/*
   1227 	 * Stop i82586 dead in its tracks.
   1228 	 */
   1229 	if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
   1230 		printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
   1231 
   1232 	if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
   1233 		printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
   1234 
   1235 	ieinit(sc);
   1236 
   1237 	splx(s);
   1238 }
   1239 
   1240 /*
   1241  * Send a command to the controller and wait for it to either
   1242  * complete or be accepted, depending on the command.  If the
   1243  * command pointer is null, then pretend that the command is
   1244  * not an action command.  If the command pointer is not null,
   1245  * and the command is an action command, wait for
   1246  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
   1247  * to become true.
   1248  */
   1249 static int
   1250 cmd_and_wait(sc, cmd, pcmd, mask)
   1251 	struct ie_softc *sc;
   1252 	int cmd;
   1253 	void *pcmd;	/* XXX - Was volatile */
   1254 	int mask;
   1255 {
   1256 	volatile struct ie_cmd_common *cc = pcmd;
   1257 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1258 	int tmo;
   1259 
   1260 	scb->ie_command = (u_short)cmd;
   1261 	(sc->chan_attn)(sc);
   1262 
   1263 	/* Wait for the command to be accepted by the CU. */
   1264 	tmo = 10;
   1265 	while (scb->ie_command && --tmo)
   1266 		delay(10);
   1267 	if (scb->ie_command) {
   1268 #ifdef	IEDEBUG
   1269 		printf("%s: cmd_and_wait, CU stuck (1)\n",
   1270 		    sc->sc_dev.dv_xname);
   1271 #endif
   1272 		return -1;	/* timed out */
   1273 	}
   1274 
   1275 	/*
   1276 	 * If asked, also wait for it to finish.
   1277 	 */
   1278 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
   1279 
   1280 		/*
   1281 		 * According to the packet driver, the minimum timeout should
   1282 		 * be .369 seconds, which we round up to .4.
   1283 		 */
   1284 		tmo = 36900;
   1285 
   1286 		/*
   1287 		 * Now spin-lock waiting for status.  This is not a very nice
   1288 		 * thing to do, but I haven't figured out how, or indeed if, we
   1289 		 * can put the process waiting for action to sleep.  (We may
   1290 		 * be getting called through some other timeout running in the
   1291 		 * kernel.)
   1292 		 */
   1293 		while (((cc->ie_cmd_status & mask) == 0) && --tmo)
   1294 			delay(10);
   1295 
   1296 		if ((cc->ie_cmd_status & mask) == 0) {
   1297 #ifdef	IEDEBUG
   1298 			printf("%s: cmd_and_wait, CU stuck (2)\n",
   1299 				   sc->sc_dev.dv_xname);
   1300 #endif
   1301 			return -1;	/* timed out */
   1302 		}
   1303 	}
   1304 	return 0;
   1305 }
   1306 
   1307 /*
   1308  * Run the time-domain reflectometer.
   1309  */
   1310 static void
   1311 run_tdr(sc, cmd)
   1312 	struct ie_softc *sc;
   1313 	struct ie_tdr_cmd *cmd;
   1314 {
   1315 	int result;
   1316 
   1317 	cmd->com.ie_cmd_status = SWAP(0);
   1318 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
   1319 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1320 
   1321 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1322 	cmd->ie_tdr_time = SWAP(0);
   1323 
   1324 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1325 	    !(cmd->com.ie_cmd_status & IE_STAT_OK))
   1326 		result = 0x10000;	/* impossible value */
   1327 	else
   1328 		result = cmd->ie_tdr_time;
   1329 
   1330 	ie_ack(sc, IE_ST_WHENCE);
   1331 
   1332 	if (result & IE_TDR_SUCCESS)
   1333 		return;
   1334 
   1335 	if (result & 0x10000) {
   1336 		printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
   1337 	} else if (result & IE_TDR_XCVR) {
   1338 		printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
   1339 	} else if (result & IE_TDR_OPEN) {
   1340 		printf("%s: TDR detected an open %d clocks away\n",
   1341 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1342 	} else if (result & IE_TDR_SHORT) {
   1343 		printf("%s: TDR detected a short %d clocks away\n",
   1344 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1345 	} else {
   1346 		printf("%s: TDR returned unknown status 0x%x\n",
   1347 		    sc->sc_dev.dv_xname, result);
   1348 	}
   1349 }
   1350 
   1351 /*
   1352  * iememinit: set up the buffers
   1353  *
   1354  * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1355  * this is to be used for the buffers.  the chip indexs its control data
   1356  * structures with 16 bit offsets, and it indexes actual buffers with
   1357  * 24 bit addresses.   so we should allocate control buffers first so that
   1358  * we don't overflow the 16 bit offset field.   The number of transmit
   1359  * buffers is fixed at compile time.
   1360  *
   1361  * note: this function was written to be easy to understand, rather than
   1362  *       highly efficient (it isn't in the critical path).
   1363  *
   1364  * The memory layout is: tbufs, rbufs, (gap), control blocks
   1365  * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
   1366  * XXX - This needs review...
   1367  */
   1368 static void
   1369 iememinit(sc)
   1370 	struct ie_softc *sc;
   1371 {
   1372 	char *ptr;
   1373 	int i;
   1374 	u_short nxt;
   1375 
   1376 	/* First, zero all the memory. */
   1377 	ptr = sc->buf_area;
   1378 	(sc->sc_bzero)(ptr, sc->buf_area_sz);
   1379 
   1380 	/* Allocate tx/rx buffers. */
   1381 	for (i = 0; i < NTXBUF; i++) {
   1382 		sc->xmit_cbuffs[i] = ptr;
   1383 		ptr += IE_TBUF_SIZE;
   1384 	}
   1385 	for (i = 0; i < sc->nrxbuf; i++) {
   1386 		sc->cbuffs[i] = ptr;
   1387 		ptr += IE_RBUF_SIZE;
   1388 	}
   1389 
   1390 	/* Small pad (Don't trust the chip...) */
   1391 	ptr += 16;
   1392 
   1393 	/* Allocate and fill in xmit buffer descriptors. */
   1394 	for (i = 0; i < NTXBUF; i++) {
   1395 		sc->xmit_buffs[i] = (volatile void *) ptr;
   1396 		ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
   1397 		sc->xmit_buffs[i]->ie_xmit_buf =
   1398 		    Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
   1399 		sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
   1400 	}
   1401 
   1402 	/* Allocate and fill in recv buffer descriptors. */
   1403 	for (i = 0; i < sc->nrxbuf; i++) {
   1404 		sc->rbuffs[i] = (volatile void *) ptr;
   1405 		ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
   1406 		sc->rbuffs[i]->ie_rbd_buffer =
   1407 			Swap32(vtop24(sc, sc->cbuffs[i]));
   1408 		sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
   1409 	}
   1410 
   1411 	/* link together recv bufs and set EOL on last */
   1412 	i = sc->nrxbuf - 1;
   1413 	sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
   1414 	nxt = vtop16sw(sc, (void*) sc->rbuffs[0]);
   1415 	do {
   1416 		sc->rbuffs[i]->ie_rbd_next = nxt;
   1417 		nxt = vtop16sw(sc, (void*) sc->rbuffs[i]);
   1418 	} while (--i >= 0);
   1419 
   1420 	/* Allocate transmit commands. */
   1421 	for (i = 0; i < NTXBUF; i++) {
   1422 		sc->xmit_cmds[i] = (volatile void *) ptr;
   1423 		ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
   1424 		sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
   1425 	}
   1426 
   1427 	/* Allocate receive frames. */
   1428 	for (i = 0; i < sc->nframes; i++) {
   1429 		sc->rframes[i] = (volatile void *) ptr;
   1430 		ptr = Align(ptr + sizeof(*sc->rframes[i]));
   1431 	}
   1432 
   1433 	/* Link together recv frames and set EOL on last */
   1434 	i = sc->nframes - 1;
   1435 	sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
   1436 	nxt = vtop16sw(sc, (void*) sc->rframes[0]);
   1437 	do {
   1438 		sc->rframes[i]->ie_fd_next = nxt;
   1439 		nxt = vtop16sw(sc, (void*) sc->rframes[i]);
   1440 	} while (--i >= 0);
   1441 
   1442 
   1443 	/* Pointers to last packet sent and next available transmit buffer. */
   1444 	sc->xchead = sc->xctail = 0;
   1445 
   1446 	/* Clear transmit-busy flag. */
   1447 	sc->xmit_busy = 0;
   1448 
   1449 	/*
   1450 	 * Set the head and tail pointers on receive to keep track of
   1451 	 * the order in which RFDs and RBDs are used.   link the
   1452 	 * recv frames and buffer into the scb.
   1453 	 */
   1454 	sc->rfhead = 0;
   1455 	sc->rftail = sc->nframes - 1;
   1456 	sc->rbhead = 0;
   1457 	sc->rbtail = sc->nrxbuf - 1;
   1458 
   1459 	sc->scb->ie_recv_list =
   1460 	    vtop16sw(sc, (void*) sc->rframes[0]);
   1461 	sc->rframes[0]->ie_fd_buf_desc =
   1462 	    vtop16sw(sc, (void*) sc->rbuffs[0]);
   1463 
   1464 	i = (ptr - sc->buf_area);
   1465 #ifdef IEDEBUG
   1466 	printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
   1467 #endif
   1468 	if (i > sc->buf_area_sz)
   1469 		panic("ie: iememinit, out of space");
   1470 }
   1471 
   1472 /*
   1473  * Run the multicast setup command.
   1474  * Called at splnet().
   1475  */
   1476 static int
   1477 mc_setup(sc, ptr)
   1478 	struct ie_softc *sc;
   1479 	void *ptr;
   1480 {
   1481 	struct ie_mcast_cmd *cmd = ptr;	/* XXX - Was volatile */
   1482 
   1483 	cmd->com.ie_cmd_status = SWAP(0);
   1484 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
   1485 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1486 
   1487 	(sc->sc_bcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
   1488 	    sc->mcast_count * sizeof *sc->mcast_addrs);
   1489 
   1490 	cmd->ie_mcast_bytes =
   1491 		SWAP(sc->mcast_count * ETHER_ADDR_LEN);	/* grrr... */
   1492 
   1493 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1494 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1495 	    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1496 		printf("%s: multicast address setup command failed\n",
   1497 		    sc->sc_dev.dv_xname);
   1498 		return 0;
   1499 	}
   1500 	return 1;
   1501 }
   1502 
   1503 static inline void
   1504 ie_setup_config(cmd, promiscuous, manchester)
   1505 	struct ie_config_cmd *cmd;	/* XXX - was volatile */
   1506 	int promiscuous, manchester;
   1507 {
   1508 
   1509 	/*
   1510 	 * these are all char's so no need to byte-swap
   1511 	 */
   1512 	cmd->ie_config_count = 0x0c;
   1513 	cmd->ie_fifo = 8;
   1514 	cmd->ie_save_bad = 0x40;
   1515 	cmd->ie_addr_len = 0x2e;
   1516 	cmd->ie_priority = 0;
   1517 	cmd->ie_ifs = 0x60;
   1518 	cmd->ie_slot_low = 0;
   1519 	cmd->ie_slot_high = 0xf2;
   1520 	cmd->ie_promisc = promiscuous | manchester << 2;
   1521 	cmd->ie_crs_cdt = 0;
   1522 	cmd->ie_min_len = 64;
   1523 	cmd->ie_junk = 0xff;
   1524 }
   1525 
   1526 /*
   1527  * This routine inits the ie.
   1528  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
   1529  * starting the receiver unit, and clearing interrupts.
   1530  *
   1531  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
   1532  */
   1533 static int
   1534 ieinit(sc)
   1535 	struct ie_softc *sc;
   1536 {
   1537 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1538 	void *ptr;
   1539 	struct ifnet *ifp;
   1540 
   1541 	ifp = &sc->sc_if;
   1542 	ptr = sc->buf_area;	/* XXX - Use scb instead? */
   1543 
   1544 	/*
   1545 	 * Send the configure command first.
   1546 	 */
   1547 	{
   1548 		struct ie_config_cmd *cmd = ptr;	/* XXX - Was volatile */
   1549 
   1550 		scb->ie_command_list = vtop16sw(sc, cmd);
   1551 		cmd->com.ie_cmd_status = SWAP(0);
   1552 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
   1553 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1554 
   1555 		ie_setup_config(cmd, (sc->promisc != 0), 0);
   1556 
   1557 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1558 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1559 			printf("%s: configure command failed\n",
   1560 			    sc->sc_dev.dv_xname);
   1561 			return 0;
   1562 		}
   1563 	}
   1564 
   1565 	/*
   1566 	 * Now send the Individual Address Setup command.
   1567 	 */
   1568 	{
   1569 		struct ie_iasetup_cmd *cmd = ptr;	/* XXX - Was volatile */
   1570 
   1571 		scb->ie_command_list = vtop16sw(sc, cmd);
   1572 		cmd->com.ie_cmd_status = SWAP(0);
   1573 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
   1574 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1575 
   1576 		(sc->sc_bcopy)(LLADDR(ifp->if_sadl),
   1577 		    (caddr_t)&cmd->ie_address, sizeof(cmd->ie_address));
   1578 
   1579 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1580 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1581 			printf("%s: individual address setup command failed\n",
   1582 			    sc->sc_dev.dv_xname);
   1583 			return 0;
   1584 		}
   1585 	}
   1586 
   1587 	/*
   1588 	 * Now run the time-domain reflectometer.
   1589 	 */
   1590 	if (ie_run_tdr)
   1591 		run_tdr(sc, ptr);
   1592 
   1593 	/*
   1594 	 * Acknowledge any interrupts we have generated thus far.
   1595 	 */
   1596 	ie_ack(sc, IE_ST_WHENCE);
   1597 
   1598 	/*
   1599 	 * Set up the transmit and recv buffers.
   1600 	 */
   1601 	iememinit(sc);
   1602 
   1603 	/* tell higher levels that we are here */
   1604 	ifp->if_flags |= IFF_RUNNING;
   1605 	ifp->if_flags &= ~IFF_OACTIVE;
   1606 
   1607 	sc->scb->ie_recv_list =
   1608 	    vtop16sw(sc, (void*) sc->rframes[0]);
   1609 	cmd_and_wait(sc, IE_RU_START, 0, 0);
   1610 
   1611 	ie_ack(sc, IE_ST_WHENCE);
   1612 
   1613 	if (sc->run_586)
   1614 		(sc->run_586)(sc);
   1615 
   1616 	return 0;
   1617 }
   1618 
   1619 static void
   1620 iestop(sc)
   1621 	struct ie_softc *sc;
   1622 {
   1623 
   1624 	cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
   1625 }
   1626 
   1627 static int
   1628 ieioctl(ifp, cmd, data)
   1629 	register struct ifnet *ifp;
   1630 	u_long cmd;
   1631 	caddr_t data;
   1632 {
   1633 	struct ie_softc *sc = ifp->if_softc;
   1634 	struct ifaddr *ifa = (struct ifaddr *)data;
   1635 	struct ifreq *ifr = (struct ifreq *)data;
   1636 	int s, error = 0;
   1637 
   1638 	s = splnet();
   1639 
   1640 	switch (cmd) {
   1641 
   1642 	case SIOCSIFADDR:
   1643 		ifp->if_flags |= IFF_UP;
   1644 
   1645 		switch (ifa->ifa_addr->sa_family) {
   1646 #ifdef INET
   1647 		case AF_INET:
   1648 			ieinit(sc);
   1649 			arp_ifinit(ifp, ifa);
   1650 			break;
   1651 #endif
   1652 #ifdef NS
   1653 		/* XXX - This code is probably wrong. */
   1654 		case AF_NS:
   1655 		    {
   1656 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
   1657 
   1658 			if (ns_nullhost(*ina))
   1659 				ina->x_host =
   1660 				    *(union ns_host *)LLADDR(ifp->if_sadl);
   1661 			else
   1662 				bcopy(ina->x_host.c_host,
   1663 				    LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   1664 			/* Set new address. */
   1665 			ieinit(sc);
   1666 			break;
   1667 		    }
   1668 #endif /* NS */
   1669 		default:
   1670 			ieinit(sc);
   1671 			break;
   1672 		}
   1673 		break;
   1674 
   1675 	case SIOCSIFFLAGS:
   1676 		sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
   1677 
   1678 		if ((ifp->if_flags & IFF_UP) == 0 &&
   1679 		    (ifp->if_flags & IFF_RUNNING) != 0) {
   1680 			/*
   1681 			 * If interface is marked down and it is running, then
   1682 			 * stop it.
   1683 			 */
   1684 			iestop(sc);
   1685 			ifp->if_flags &= ~IFF_RUNNING;
   1686 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
   1687 			(ifp->if_flags & IFF_RUNNING) == 0) {
   1688 			/*
   1689 			 * If interface is marked up and it is stopped, then
   1690 			 * start it.
   1691 			 */
   1692 			ieinit(sc);
   1693 		} else {
   1694 			/*
   1695 			 * Reset the interface to pick up changes in any other
   1696 			 * flags that affect hardware registers.
   1697 			 */
   1698 			iestop(sc);
   1699 			ieinit(sc);
   1700 		}
   1701 #ifdef IEDEBUG
   1702 		if (ifp->if_flags & IFF_DEBUG)
   1703 			sc->sc_debug = IED_ALL;
   1704 		else
   1705 			sc->sc_debug = ie_debug_flags;
   1706 #endif
   1707 		break;
   1708 
   1709 	case SIOCADDMULTI:
   1710 	case SIOCDELMULTI:
   1711 		error = (cmd == SIOCADDMULTI) ?
   1712 		    ether_addmulti(ifr, &sc->sc_ethercom) :
   1713 		    ether_delmulti(ifr, &sc->sc_ethercom);
   1714 
   1715 		if (error == ENETRESET) {
   1716 			/*
   1717 			 * Multicast list has changed; set the hardware filter
   1718 			 * accordingly.
   1719 			 */
   1720 			mc_reset(sc);
   1721 			error = 0;
   1722 		}
   1723 		break;
   1724 
   1725 	default:
   1726 		error = EINVAL;
   1727 	}
   1728 	splx(s);
   1729 	return error;
   1730 }
   1731 
   1732 static void
   1733 mc_reset(sc)
   1734 	struct ie_softc *sc;
   1735 {
   1736 	struct ether_multi *enm;
   1737 	struct ether_multistep step;
   1738 	struct ifnet *ifp;
   1739 
   1740 	ifp = &sc->sc_if;
   1741 
   1742 	/*
   1743 	 * Step through the list of addresses.
   1744 	 */
   1745 	sc->mcast_count = 0;
   1746 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1747 	while (enm) {
   1748 		if (sc->mcast_count >= MAXMCAST ||
   1749 		    bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
   1750 			ifp->if_flags |= IFF_ALLMULTI;
   1751 			ieioctl(ifp, SIOCSIFFLAGS, (void *)0);
   1752 			goto setflag;
   1753 		}
   1754 		bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
   1755 		sc->mcast_count++;
   1756 		ETHER_NEXT_MULTI(step, enm);
   1757 	}
   1758 setflag:
   1759 	sc->want_mcsetup = 1;
   1760 }
   1761 
   1762 #ifdef IEDEBUG
   1763 void
   1764 print_rbd(rbd)
   1765 	volatile struct ie_recv_buf_desc *rbd;
   1766 {
   1767 
   1768 	printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
   1769 	    "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
   1770 	    rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
   1771 	    rbd->mbz);
   1772 }
   1773 #endif
   1774