Home | History | Annotate | Line # | Download | only in dev
if_ie.c revision 1.21
      1 /*	$NetBSD: if_ie.c,v 1.21 1997/07/29 06:43:51 fair 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 & IE_ST_WHENCE;
    494 	if (status == 0)
    495 		return 0;
    496 
    497 	loopcnt = 5;
    498 loop:
    499 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    500 	ie_ack(sc, 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 & IE_ST_WHENCE;
    546 	if (status) {
    547 		if (--loopcnt > 0)
    548 			goto loop;
    549 		printf("%s: interrupt stuck?\n", sc->sc_dev.dv_xname);
    550 		iereset(sc);
    551 	}
    552 	return 1;
    553 }
    554 
    555 /*
    556  * Process a received-frame interrupt.
    557  */
    558 void
    559 ierint(sc)
    560 	struct ie_softc *sc;
    561 {
    562 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    563 	int i, status;
    564 	static int timesthru = 1024;
    565 
    566 	i = sc->rfhead;
    567 	for (;;) {
    568 		status = sc->rframes[i]->ie_fd_status;
    569 
    570 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
    571 			if (!--timesthru) {
    572 				sc->sc_if.if_ierrors +=
    573 				    SWAP(scb->ie_err_crc) +
    574 				    SWAP(scb->ie_err_align) +
    575 				    SWAP(scb->ie_err_resource) +
    576 				    SWAP(scb->ie_err_overrun);
    577 				scb->ie_err_crc = 0;
    578 				scb->ie_err_align = 0;
    579 				scb->ie_err_resource = 0;
    580 				scb->ie_err_overrun = 0;
    581 				timesthru = 1024;
    582 			}
    583 			ie_readframe(sc, i);
    584 		} else {
    585 			if ((status & IE_FD_RNR) != 0 &&
    586 			    (scb->ie_status & IE_RU_READY) == 0) {
    587 				sc->rframes[0]->ie_fd_buf_desc =
    588 					vtop16sw(sc, (void*) sc->rbuffs[0]);
    589 				scb->ie_recv_list =
    590 					vtop16sw(sc, (void*) sc->rframes[0]);
    591 				cmd_and_wait(sc, IE_RU_START, 0, 0);
    592 			}
    593 			break;
    594 		}
    595 		i = (i + 1) % sc->nframes;
    596 	}
    597 }
    598 
    599 /*
    600  * Process a command-complete interrupt.  These are only generated by the
    601  * transmission of frames.  This routine is deceptively simple, since most
    602  * of the real work is done by iestart().
    603  */
    604 void
    605 ietint(sc)
    606 	struct ie_softc *sc;
    607 {
    608 	struct ifnet *ifp;
    609 	int status;
    610 
    611 	ifp = &sc->sc_if;
    612 
    613 	ifp->if_timer = 0;
    614 	ifp->if_flags &= ~IFF_OACTIVE;
    615 
    616 	status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
    617 
    618 	if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
    619 		printf("ietint: command still busy!\n");
    620 
    621 	if (status & IE_STAT_OK) {
    622 		ifp->if_opackets++;
    623 		ifp->if_collisions +=
    624 		  SWAP(status & IE_XS_MAXCOLL);
    625 	} else {
    626 		ifp->if_oerrors++;
    627 		/*
    628 		 * XXX
    629 		 * Check SQE and DEFERRED?
    630 		 * What if more than one bit is set?
    631 		 */
    632 		if (status & IE_STAT_ABORT)
    633 			printf("%s: send aborted\n", sc->sc_dev.dv_xname);
    634 		if (status & IE_XS_LATECOLL)
    635 			printf("%s: late collision\n", sc->sc_dev.dv_xname);
    636 		if (status & IE_XS_NOCARRIER)
    637 			printf("%s: no carrier\n", sc->sc_dev.dv_xname);
    638 		if (status & IE_XS_LOSTCTS)
    639 			printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
    640 		if (status & IE_XS_UNDERRUN)
    641 			printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
    642 		if (status & IE_XS_EXCMAX) {
    643 			printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
    644 			ifp->if_collisions += 16;
    645 		}
    646 	}
    647 
    648 	/*
    649 	 * If multicast addresses were added or deleted while we
    650 	 * were transmitting, mc_reset() set the want_mcsetup flag
    651 	 * indicating that we should do it.
    652 	 */
    653 	if (sc->want_mcsetup) {
    654 		mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
    655 		sc->want_mcsetup = 0;
    656 	}
    657 
    658 	/* Done with the buffer. */
    659 	sc->xmit_busy--;
    660 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    661 
    662 	/* Start the next packet, if any, transmitting. */
    663 	if (sc->xmit_busy > 0)
    664 		iexmit(sc);
    665 
    666 	iestart(ifp);
    667 }
    668 
    669 /*
    670  * Compare two Ether/802 addresses for equality, inlined and
    671  * unrolled for speed.  I'd love to have an inline assembler
    672  * version of this...   XXX: Who wanted that? mycroft?
    673  * I wrote one, but the following is just as efficient.
    674  * This expands to 10 short m68k instructions! -gwr
    675  * Note: use this like bcmp()
    676  */
    677 static inline u_short
    678 ether_cmp(one, two)
    679 	u_char *one, *two;
    680 {
    681 	register u_short *a = (u_short *) one;
    682 	register u_short *b = (u_short *) two;
    683 	register u_short diff;
    684 
    685 	diff  = *a++ - *b++;
    686 	diff |= *a++ - *b++;
    687 	diff |= *a++ - *b++;
    688 
    689 	return (diff);
    690 }
    691 #define	ether_equal !ether_cmp
    692 
    693 /*
    694  * Check for a valid address.  to_bpf is filled in with one of the following:
    695  *   0 -> BPF doesn't get this packet
    696  *   1 -> BPF does get this packet
    697  *   2 -> BPF does get this packet, but we don't
    698  * Return value is true if the packet is for us, and false otherwise.
    699  *
    700  * This routine is a mess, but it's also critical that it be as fast
    701  * as possible.  It could be made cleaner if we can assume that the
    702  * only client which will fiddle with IFF_PROMISC is BPF.  This is
    703  * probably a good assumption, but we do not make it here.  (Yet.)
    704  */
    705 static inline int
    706 check_eh(sc, eh, to_bpf)
    707 	struct ie_softc *sc;
    708 	struct ether_header *eh;
    709 	int *to_bpf;
    710 {
    711 	struct ifnet *ifp;
    712 	int i;
    713 
    714 	ifp = &sc->sc_if;
    715 
    716 	switch (sc->promisc) {
    717 	case IFF_ALLMULTI:
    718 		/*
    719 		 * Receiving all multicasts, but no unicasts except those
    720 		 * destined for us.
    721 		 */
    722 #if NBPFILTER > 0
    723 		/* BPF gets this packet if anybody cares */
    724 		*to_bpf = (ifp->if_bpf != 0);
    725 #endif
    726 		if (eh->ether_dhost[0] & 1)
    727 			return 1;
    728 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    729 			return 1;
    730 		return 0;
    731 
    732 	case IFF_PROMISC:
    733 		/*
    734 		 * Receiving all packets.  These need to be passed on to BPF.
    735 		 */
    736 #if NBPFILTER > 0
    737 		*to_bpf = (ifp->if_bpf != 0);
    738 #endif
    739 		/* If for us, accept and hand up to BPF */
    740 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    741 			return 1;
    742 
    743 #if NBPFILTER > 0
    744 		if (*to_bpf)
    745 			*to_bpf = 2;	/* we don't need to see it */
    746 #endif
    747 
    748 		/*
    749 		 * Not a multicast, so BPF wants to see it but we don't.
    750 		 */
    751 		if (!(eh->ether_dhost[0] & 1))
    752 			return 1;
    753 
    754 		/*
    755 		 * If it's one of our multicast groups, accept it and pass it
    756 		 * up.
    757 		 */
    758 		for (i = 0; i < sc->mcast_count; i++) {
    759 			if (ether_equal(eh->ether_dhost,
    760 			    (u_char *)&sc->mcast_addrs[i])) {
    761 #if NBPFILTER > 0
    762 				if (*to_bpf)
    763 					*to_bpf = 1;
    764 #endif
    765 				return 1;
    766 			}
    767 		}
    768 		return 1;
    769 
    770 	case IFF_ALLMULTI | IFF_PROMISC:
    771 		/*
    772 		 * Acting as a multicast router, and BPF running at the same
    773 		 * time.  Whew!  (Hope this is a fast machine...)
    774 		 */
    775 #if NBPFILTER > 0
    776 		*to_bpf = (ifp->if_bpf != 0);
    777 #endif
    778 		/* We want to see multicasts. */
    779 		if (eh->ether_dhost[0] & 1)
    780 			return 1;
    781 
    782 		/* We want to see our own packets */
    783 		if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
    784 			return 1;
    785 
    786 		/* Anything else goes to BPF but nothing else. */
    787 #if NBPFILTER > 0
    788 		if (*to_bpf)
    789 			*to_bpf = 2;
    790 #endif
    791 		return 1;
    792 
    793 	case 0:
    794 		/*
    795 		 * Only accept unicast packets destined for us, or multicasts
    796 		 * for groups that we belong to.  For now, we assume that the
    797 		 * '586 will only return packets that we asked it for.  This
    798 		 * isn't strictly true (it uses hashing for the multicast filter),
    799 		 * but it will do in this case, and we want to get out of here
    800 		 * as quickly as possible.
    801 		 */
    802 #if NBPFILTER > 0
    803 		*to_bpf = (ifp->if_bpf != 0);
    804 #endif
    805 		return 1;
    806 	}
    807 #ifdef	DIAGNOSTIC
    808 	panic("ie: check_eh, impossible");
    809 #endif
    810 	return 0;
    811 }
    812 
    813 /*
    814  * We want to isolate the bits that have meaning...  This assumes that
    815  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
    816  * the size of the buffer, then we are screwed anyway.
    817  */
    818 static inline int
    819 ie_buflen(sc, head)
    820 	struct ie_softc *sc;
    821 	int head;
    822 {
    823 	register int len;
    824 
    825 	len = SWAP(sc->rbuffs[head]->ie_rbd_actual);
    826 	len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1));
    827 	return (len);
    828 }
    829 
    830 static inline int
    831 ie_packet_len(sc)
    832 	struct ie_softc *sc;
    833 {
    834 	int i;
    835 	int head = sc->rbhead;
    836 	int acc = 0;
    837 
    838 	do {
    839 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
    840 #ifdef IEDEBUG
    841 			print_rbd(sc->rbuffs[sc->rbhead]);
    842 #endif
    843 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
    844 			    sc->sc_dev.dv_xname, sc->rbhead);
    845 			iereset(sc);
    846 			return -1;
    847 		}
    848 
    849 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
    850 
    851 		acc += ie_buflen(sc, head);
    852 		head = (head + 1) % sc->nrxbuf;
    853 	} while (!i);
    854 
    855 	return acc;
    856 }
    857 
    858 /*
    859  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
    860  * command to the chip to be executed.  On the way, if we have a BPF listener
    861  * also give him a copy.
    862  */
    863 static void
    864 iexmit(sc)
    865 	struct ie_softc *sc;
    866 {
    867 	struct ifnet *ifp;
    868 
    869 	ifp = &sc->sc_if;
    870 
    871 #ifdef IEDEBUG
    872 	if (sc->sc_debug & IED_XMIT)
    873 		printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname,
    874 		    sc->xctail);
    875 #endif
    876 
    877 #if NBPFILTER > 0
    878 	/*
    879 	 * If BPF is listening on this interface, let it see the packet before
    880 	 * we push it on the wire.
    881 	 */
    882 	if (ifp->if_bpf)
    883 		bpf_tap(ifp->if_bpf,
    884 		    sc->xmit_cbuffs[sc->xctail],
    885 		    SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
    886 #endif
    887 
    888 	sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
    889 	sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
    890 	sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
    891 	    Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail]));
    892 
    893 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
    894 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
    895 	    IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
    896 
    897 	sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
    898 	sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
    899 	    vtop16sw(sc, (void*) sc->xmit_buffs[sc->xctail]);
    900 
    901 	sc->scb->ie_command_list =
    902 	    vtop16sw(sc, (void*) sc->xmit_cmds[sc->xctail]);
    903 	cmd_and_wait(sc, IE_CU_START, 0, 0);
    904 
    905 	ifp->if_timer = 5;
    906 }
    907 
    908 /*
    909  * Read data off the interface, and turn it into an mbuf chain.
    910  *
    911  * This code is DRAMATICALLY different from the previous version; this
    912  * version tries to allocate the entire mbuf chain up front, given the
    913  * length of the data available.  This enables us to allocate mbuf
    914  * clusters in many situations where before we would have had a long
    915  * chain of partially-full mbufs.  This should help to speed up the
    916  * operation considerably.  (Provided that it works, of course.)
    917  */
    918 static inline struct mbuf *
    919 ieget(sc, ehp, to_bpf)
    920 	struct ie_softc *sc;
    921 	struct ether_header *ehp;
    922 	int *to_bpf;
    923 {
    924 	struct mbuf *top, **mp, *m;
    925 	int len, totlen, resid;
    926 	int thisrboff, thismboff;
    927 	int head;
    928 
    929 	totlen = ie_packet_len(sc);
    930 	if (totlen <= 0)
    931 		return 0;
    932 
    933 	head = sc->rbhead;
    934 
    935 	/*
    936 	 * Snarf the Ethernet header.
    937 	 */
    938 	(sc->sc_bcopy)((caddr_t)sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp);
    939 
    940 	/*
    941 	 * As quickly as possible, check if this packet is for us.
    942 	 * If not, don't waste a single cycle copying the rest of the
    943 	 * packet in.
    944 	 * This is only a consideration when FILTER is defined; i.e., when
    945 	 * we are either running BPF or doing multicasting.
    946 	 */
    947 	if (!check_eh(sc, ehp, to_bpf)) {
    948 		/* just this case, it's not an error */
    949 		sc->sc_if.if_ierrors--;
    950 		return 0;
    951 	}
    952 
    953 	resid = totlen -= (thisrboff = sizeof *ehp);
    954 
    955 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    956 	if (m == 0)
    957 		return 0;
    958 
    959 	m->m_pkthdr.rcvif = &sc->sc_if;
    960 	m->m_pkthdr.len = totlen;
    961 	len = MHLEN;
    962 	top = 0;
    963 	mp = &top;
    964 
    965 	/*
    966 	 * This loop goes through and allocates mbufs for all the data we will
    967 	 * be copying in.  It does not actually do the copying yet.
    968 	 */
    969 	while (totlen > 0) {
    970 		if (top) {
    971 			MGET(m, M_DONTWAIT, MT_DATA);
    972 			if (m == 0) {
    973 				m_freem(top);
    974 				return 0;
    975 			}
    976 			len = MLEN;
    977 		}
    978 		if (totlen >= MINCLSIZE) {
    979 			MCLGET(m, M_DONTWAIT);
    980 			if (m->m_flags & M_EXT)
    981 				len = MCLBYTES;
    982 		}
    983 		m->m_len = len = min(totlen, len);
    984 		totlen -= len;
    985 		*mp = m;
    986 		mp = &m->m_next;
    987 	}
    988 
    989 	m = top;
    990 	thismboff = 0;
    991 
    992 	/*
    993 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
    994 	 * time) and stuff the data into it.  There are no possible failures
    995 	 * at or after this point.
    996 	 */
    997 	while (resid > 0) {
    998 		int thisrblen = ie_buflen(sc, head) - thisrboff;
    999 		int thismblen = m->m_len - thismboff;
   1000 
   1001 		len = min(thisrblen, thismblen);
   1002 		(sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + thisrboff),
   1003 		    mtod(m, caddr_t) + thismboff, (u_int)len);
   1004 		resid -= len;
   1005 
   1006 		if (len == thismblen) {
   1007 			m = m->m_next;
   1008 			thismboff = 0;
   1009 		} else
   1010 			thismboff += len;
   1011 
   1012 		if (len == thisrblen) {
   1013 			head = (head + 1) % sc->nrxbuf;
   1014 			thisrboff = 0;
   1015 		} else
   1016 			thisrboff += len;
   1017 	}
   1018 
   1019 	/*
   1020 	 * Unless something changed strangely while we were doing the copy,
   1021 	 * we have now copied everything in from the shared memory.
   1022 	 * This means that we are done.
   1023 	 */
   1024 	return top;
   1025 }
   1026 
   1027 /*
   1028  * Read frame NUM from unit UNIT (pre-cached as IE).
   1029  *
   1030  * This routine reads the RFD at NUM, and copies in the buffers from
   1031  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
   1032  * doesn't start complaining.  Trailers are DROPPED---there's no point
   1033  * in wasting time on confusing code to deal with them.  Hopefully,
   1034  * this machine will never ARP for trailers anyway.
   1035  */
   1036 static void
   1037 ie_readframe(sc, num)
   1038 	struct ie_softc *sc;
   1039 	int num;			/* frame number to read */
   1040 {
   1041 	int status;
   1042 	struct mbuf *m = 0;
   1043 	struct ether_header eh;
   1044 #if NBPFILTER > 0
   1045 	int bpf_gets_it = 0;
   1046 #endif
   1047 
   1048 	status = sc->rframes[num]->ie_fd_status;
   1049 
   1050 	/* Advance the RFD list, since we're done with this descriptor. */
   1051 	sc->rframes[num]->ie_fd_status = SWAP(0);
   1052 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
   1053 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
   1054 	sc->rftail = (sc->rftail + 1) % sc->nframes;
   1055 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
   1056 
   1057 	if (status & IE_FD_OK) {
   1058 #if NBPFILTER > 0
   1059 		m = ieget(sc, &eh, &bpf_gets_it);
   1060 #else
   1061 		m = ieget(sc, &eh, 0);
   1062 #endif
   1063 		ie_drop_packet_buffer(sc);
   1064 	}
   1065 	if (m == 0) {
   1066 		sc->sc_if.if_ierrors++;
   1067 		return;
   1068 	}
   1069 
   1070 #ifdef IEDEBUG
   1071 	if (sc->sc_debug & IED_READFRAME)
   1072 		printf("%s: frame from ether %s type 0x%x\n",
   1073 			sc->sc_dev.dv_xname,
   1074 		    ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
   1075 #endif
   1076 
   1077 #if NBPFILTER > 0
   1078 	/*
   1079 	 * Check for a BPF filter; if so, hand it up.
   1080 	 * Note that we have to stick an extra mbuf up front, because
   1081 	 * bpf_mtap expects to have the ether header at the front.
   1082 	 * It doesn't matter that this results in an ill-formatted mbuf chain,
   1083 	 * since BPF just looks at the data.  (It doesn't try to free the mbuf,
   1084 	 * tho' it will make a copy for tcpdump.)
   1085 	 */
   1086 	if (bpf_gets_it) {
   1087 		struct mbuf m0;
   1088 		m0.m_len = sizeof eh;
   1089 		m0.m_data = (caddr_t)&eh;
   1090 		m0.m_next = m;
   1091 
   1092 		/* Pass it up. */
   1093 		bpf_mtap(sc->sc_if.if_bpf, &m0);
   1094 
   1095 		/*
   1096 		 * A signal passed up from the filtering code indicating that
   1097 		 * the packet is intended for BPF but not for the protocol
   1098 		 * machinery.  We can save a few cycles by not handing it off
   1099 		 * to them.
   1100 		 */
   1101 		if (bpf_gets_it == 2) {
   1102 			m_freem(m);
   1103 			return;
   1104 		}
   1105 	}
   1106 #endif	/* NBPFILTER > 0 */
   1107 
   1108 	/*
   1109 	 * In here there used to be code to check destination addresses upon
   1110 	 * receipt of a packet.  We have deleted that code, and replaced it
   1111 	 * with code to check the address much earlier in the cycle, before
   1112 	 * copying the data in; this saves us valuable cycles when operating
   1113 	 * as a multicast router or when using BPF.
   1114 	 */
   1115 
   1116 	/*
   1117 	 * Finally pass this packet up to higher layers.
   1118 	 */
   1119 	ether_input(&sc->sc_if, &eh, m);
   1120 	sc->sc_if.if_ipackets++;
   1121 }
   1122 
   1123 static void
   1124 ie_drop_packet_buffer(sc)
   1125 	struct ie_softc *sc;
   1126 {
   1127 	int i;
   1128 
   1129 	do {
   1130 		/*
   1131 		 * This means we are somehow out of sync.  So, we reset the
   1132 		 * adapter.
   1133 		 */
   1134 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
   1135 #ifdef IEDEBUG
   1136 			print_rbd(sc->rbuffs[sc->rbhead]);
   1137 #endif
   1138 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
   1139 			    sc->sc_dev.dv_xname, sc->rbhead);
   1140 			iereset(sc);
   1141 			return;
   1142 		}
   1143 
   1144 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
   1145 
   1146 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
   1147 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
   1148 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
   1149 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
   1150 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
   1151 	} while (!i);
   1152 }
   1153 
   1154 /*
   1155  * Start transmission on an interface.
   1156  */
   1157 static void
   1158 iestart(ifp)
   1159 	struct ifnet *ifp;
   1160 {
   1161 	struct ie_softc *sc = ifp->if_softc;
   1162 	struct mbuf *m0, *m;
   1163 	u_char *buffer;
   1164 	u_short len;
   1165 
   1166 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   1167 		return;
   1168 
   1169 	for (;;) {
   1170 		if (sc->xmit_busy == sc->ntxbuf) {
   1171 			ifp->if_flags |= IFF_OACTIVE;
   1172 			break;
   1173 		}
   1174 
   1175 		IF_DEQUEUE(&ifp->if_snd, m0);
   1176 		if (m0 == 0)
   1177 			break;
   1178 
   1179 		/* We need to use m->m_pkthdr.len, so require the header */
   1180 		if ((m0->m_flags & M_PKTHDR) == 0)
   1181 			panic("iestart: no header mbuf");
   1182 
   1183 #if NBPFILTER > 0
   1184 		/* Tap off here if there is a BPF listener. */
   1185 		if (ifp->if_bpf)
   1186 			bpf_mtap(ifp->if_bpf, m0);
   1187 #endif
   1188 
   1189 #ifdef IEDEBUG
   1190 		if (sc->sc_debug & IED_ENQ)
   1191 			printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
   1192 			    sc->xchead);
   1193 #endif
   1194 
   1195 		buffer = sc->xmit_cbuffs[sc->xchead];
   1196 		for (m = m0; m != 0; m = m->m_next) {
   1197 			(sc->sc_bcopy)(mtod(m, caddr_t), buffer, m->m_len);
   1198 			buffer += m->m_len;
   1199 		}
   1200 		len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
   1201 
   1202 		m_freem(m0);
   1203 		sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
   1204 
   1205 		/* Start the first packet transmitting. */
   1206 		if (sc->xmit_busy == 0)
   1207 			iexmit(sc);
   1208 
   1209 		sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
   1210 		sc->xmit_busy++;
   1211 	}
   1212 }
   1213 
   1214 static void
   1215 iereset(sc)
   1216 	struct ie_softc *sc;
   1217 {
   1218 	int s = splnet();
   1219 
   1220 	/* No message here.  The caller does that. */
   1221 	iestop(sc);
   1222 
   1223 	/*
   1224 	 * Stop i82586 dead in its tracks.
   1225 	 */
   1226 	if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
   1227 		printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
   1228 
   1229 	if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
   1230 		printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
   1231 
   1232 	ieinit(sc);
   1233 
   1234 	splx(s);
   1235 }
   1236 
   1237 /*
   1238  * Send a command to the controller and wait for it to either
   1239  * complete or be accepted, depending on the command.  If the
   1240  * command pointer is null, then pretend that the command is
   1241  * not an action command.  If the command pointer is not null,
   1242  * and the command is an action command, wait for
   1243  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
   1244  * to become true.
   1245  */
   1246 static int
   1247 cmd_and_wait(sc, cmd, pcmd, mask)
   1248 	struct ie_softc *sc;
   1249 	int cmd;
   1250 	void *pcmd;	/* XXX - Was volatile */
   1251 	int mask;
   1252 {
   1253 	volatile struct ie_cmd_common *cc = pcmd;
   1254 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1255 	int tmo;
   1256 
   1257 	scb->ie_command = (u_short)cmd;
   1258 	(sc->chan_attn)(sc);
   1259 
   1260 	/* Wait for the command to be accepted by the CU. */
   1261 	tmo = 10;
   1262 	while (scb->ie_command && --tmo)
   1263 		delay(10);
   1264 	if (scb->ie_command) {
   1265 #ifdef	IEDEBUG
   1266 		printf("%s: cmd_and_wait, CU stuck (1)\n",
   1267 		    sc->sc_dev.dv_xname);
   1268 #endif
   1269 		return -1;	/* timed out */
   1270 	}
   1271 
   1272 	/*
   1273 	 * If asked, also wait for it to finish.
   1274 	 */
   1275 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
   1276 
   1277 		/*
   1278 		 * According to the packet driver, the minimum timeout should
   1279 		 * be .369 seconds, which we round up to .4.
   1280 		 */
   1281 		tmo = 36900;
   1282 
   1283 		/*
   1284 		 * Now spin-lock waiting for status.  This is not a very nice
   1285 		 * thing to do, but I haven't figured out how, or indeed if, we
   1286 		 * can put the process waiting for action to sleep.  (We may
   1287 		 * be getting called through some other timeout running in the
   1288 		 * kernel.)
   1289 		 */
   1290 		while (((cc->ie_cmd_status & mask) == 0) && --tmo)
   1291 			delay(10);
   1292 
   1293 		if ((cc->ie_cmd_status & mask) == 0) {
   1294 #ifdef	IEDEBUG
   1295 			printf("%s: cmd_and_wait, CU stuck (2)\n",
   1296 				   sc->sc_dev.dv_xname);
   1297 #endif
   1298 			return -1;	/* timed out */
   1299 		}
   1300 	}
   1301 	return 0;
   1302 }
   1303 
   1304 /*
   1305  * Run the time-domain reflectometer.
   1306  */
   1307 static void
   1308 run_tdr(sc, cmd)
   1309 	struct ie_softc *sc;
   1310 	struct ie_tdr_cmd *cmd;
   1311 {
   1312 	int result;
   1313 
   1314 	cmd->com.ie_cmd_status = SWAP(0);
   1315 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
   1316 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1317 
   1318 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1319 	cmd->ie_tdr_time = SWAP(0);
   1320 
   1321 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1322 	    !(cmd->com.ie_cmd_status & IE_STAT_OK))
   1323 		result = 0x10000;	/* impossible value */
   1324 	else
   1325 		result = cmd->ie_tdr_time;
   1326 
   1327 	ie_ack(sc, IE_ST_WHENCE);
   1328 
   1329 	if (result & IE_TDR_SUCCESS)
   1330 		return;
   1331 
   1332 	if (result & 0x10000) {
   1333 		printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
   1334 	} else if (result & IE_TDR_XCVR) {
   1335 		printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
   1336 	} else if (result & IE_TDR_OPEN) {
   1337 		printf("%s: TDR detected an open %d clocks away\n",
   1338 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1339 	} else if (result & IE_TDR_SHORT) {
   1340 		printf("%s: TDR detected a short %d clocks away\n",
   1341 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1342 	} else {
   1343 		printf("%s: TDR returned unknown status 0x%x\n",
   1344 		    sc->sc_dev.dv_xname, result);
   1345 	}
   1346 }
   1347 
   1348 /*
   1349  * iememinit: set up the buffers
   1350  *
   1351  * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1352  * this is to be used for the buffers.  the chip indexs its control data
   1353  * structures with 16 bit offsets, and it indexes actual buffers with
   1354  * 24 bit addresses.   so we should allocate control buffers first so that
   1355  * we don't overflow the 16 bit offset field.   The number of transmit
   1356  * buffers is fixed at compile time.
   1357  *
   1358  * note: this function was written to be easy to understand, rather than
   1359  *       highly efficient (it isn't in the critical path).
   1360  *
   1361  * The memory layout is: tbufs, rbufs, (gap), control blocks
   1362  * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
   1363  * XXX - This needs review...
   1364  */
   1365 static void
   1366 iememinit(sc)
   1367 	struct ie_softc *sc;
   1368 {
   1369 	char *ptr;
   1370 	int i;
   1371 	u_short nxt;
   1372 
   1373 	/* First, zero all the memory. */
   1374 	ptr = sc->buf_area;
   1375 	(sc->sc_bzero)(ptr, sc->buf_area_sz);
   1376 
   1377 	/* Allocate tx/rx buffers. */
   1378 	for (i = 0; i < NTXBUF; i++) {
   1379 		sc->xmit_cbuffs[i] = ptr;
   1380 		ptr += IE_TBUF_SIZE;
   1381 	}
   1382 	for (i = 0; i < sc->nrxbuf; i++) {
   1383 		sc->cbuffs[i] = ptr;
   1384 		ptr += IE_RBUF_SIZE;
   1385 	}
   1386 
   1387 	/* Small pad (Don't trust the chip...) */
   1388 	ptr += 16;
   1389 
   1390 	/* Allocate and fill in xmit buffer descriptors. */
   1391 	for (i = 0; i < NTXBUF; i++) {
   1392 		sc->xmit_buffs[i] = (volatile void *) ptr;
   1393 		ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
   1394 		sc->xmit_buffs[i]->ie_xmit_buf =
   1395 		    Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
   1396 		sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
   1397 	}
   1398 
   1399 	/* Allocate and fill in recv buffer descriptors. */
   1400 	for (i = 0; i < sc->nrxbuf; i++) {
   1401 		sc->rbuffs[i] = (volatile void *) ptr;
   1402 		ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
   1403 		sc->rbuffs[i]->ie_rbd_buffer =
   1404 			Swap32(vtop24(sc, sc->cbuffs[i]));
   1405 		sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
   1406 	}
   1407 
   1408 	/* link together recv bufs and set EOL on last */
   1409 	i = sc->nrxbuf - 1;
   1410 	sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
   1411 	nxt = vtop16sw(sc, (void*) sc->rbuffs[0]);
   1412 	do {
   1413 		sc->rbuffs[i]->ie_rbd_next = nxt;
   1414 		nxt = vtop16sw(sc, (void*) sc->rbuffs[i]);
   1415 	} while (--i >= 0);
   1416 
   1417 	/* Allocate transmit commands. */
   1418 	for (i = 0; i < NTXBUF; i++) {
   1419 		sc->xmit_cmds[i] = (volatile void *) ptr;
   1420 		ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
   1421 		sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
   1422 	}
   1423 
   1424 	/* Allocate receive frames. */
   1425 	for (i = 0; i < sc->nframes; i++) {
   1426 		sc->rframes[i] = (volatile void *) ptr;
   1427 		ptr = Align(ptr + sizeof(*sc->rframes[i]));
   1428 	}
   1429 
   1430 	/* Link together recv frames and set EOL on last */
   1431 	i = sc->nframes - 1;
   1432 	sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
   1433 	nxt = vtop16sw(sc, (void*) sc->rframes[0]);
   1434 	do {
   1435 		sc->rframes[i]->ie_fd_next = nxt;
   1436 		nxt = vtop16sw(sc, (void*) sc->rframes[i]);
   1437 	} while (--i >= 0);
   1438 
   1439 
   1440 	/* Pointers to last packet sent and next available transmit buffer. */
   1441 	sc->xchead = sc->xctail = 0;
   1442 
   1443 	/* Clear transmit-busy flag. */
   1444 	sc->xmit_busy = 0;
   1445 
   1446 	/*
   1447 	 * Set the head and tail pointers on receive to keep track of
   1448 	 * the order in which RFDs and RBDs are used.   link the
   1449 	 * recv frames and buffer into the scb.
   1450 	 */
   1451 	sc->rfhead = 0;
   1452 	sc->rftail = sc->nframes - 1;
   1453 	sc->rbhead = 0;
   1454 	sc->rbtail = sc->nrxbuf - 1;
   1455 
   1456 	sc->scb->ie_recv_list =
   1457 	    vtop16sw(sc, (void*) sc->rframes[0]);
   1458 	sc->rframes[0]->ie_fd_buf_desc =
   1459 	    vtop16sw(sc, (void*) sc->rbuffs[0]);
   1460 
   1461 	i = (ptr - sc->buf_area);
   1462 #ifdef IEDEBUG
   1463 	printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
   1464 #endif
   1465 	if (i > sc->buf_area_sz)
   1466 		panic("ie: iememinit, out of space");
   1467 }
   1468 
   1469 /*
   1470  * Run the multicast setup command.
   1471  * Called at splnet().
   1472  */
   1473 static int
   1474 mc_setup(sc, ptr)
   1475 	struct ie_softc *sc;
   1476 	void *ptr;
   1477 {
   1478 	struct ie_mcast_cmd *cmd = ptr;	/* XXX - Was volatile */
   1479 
   1480 	cmd->com.ie_cmd_status = SWAP(0);
   1481 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
   1482 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1483 
   1484 	(sc->sc_bcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
   1485 	    sc->mcast_count * sizeof *sc->mcast_addrs);
   1486 
   1487 	cmd->ie_mcast_bytes =
   1488 		SWAP(sc->mcast_count * ETHER_ADDR_LEN);	/* grrr... */
   1489 
   1490 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1491 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1492 	    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1493 		printf("%s: multicast address setup command failed\n",
   1494 		    sc->sc_dev.dv_xname);
   1495 		return 0;
   1496 	}
   1497 	return 1;
   1498 }
   1499 
   1500 static inline void
   1501 ie_setup_config(cmd, promiscuous, manchester)
   1502 	struct ie_config_cmd *cmd;	/* XXX - was volatile */
   1503 	int promiscuous, manchester;
   1504 {
   1505 
   1506 	/*
   1507 	 * these are all char's so no need to byte-swap
   1508 	 */
   1509 	cmd->ie_config_count = 0x0c;
   1510 	cmd->ie_fifo = 8;
   1511 	cmd->ie_save_bad = 0x40;
   1512 	cmd->ie_addr_len = 0x2e;
   1513 	cmd->ie_priority = 0;
   1514 	cmd->ie_ifs = 0x60;
   1515 	cmd->ie_slot_low = 0;
   1516 	cmd->ie_slot_high = 0xf2;
   1517 	cmd->ie_promisc = promiscuous | manchester << 2;
   1518 	cmd->ie_crs_cdt = 0;
   1519 	cmd->ie_min_len = 64;
   1520 	cmd->ie_junk = 0xff;
   1521 }
   1522 
   1523 /*
   1524  * This routine inits the ie.
   1525  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
   1526  * starting the receiver unit, and clearing interrupts.
   1527  *
   1528  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
   1529  */
   1530 static int
   1531 ieinit(sc)
   1532 	struct ie_softc *sc;
   1533 {
   1534 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1535 	void *ptr;
   1536 	struct ifnet *ifp;
   1537 
   1538 	ifp = &sc->sc_if;
   1539 	ptr = sc->buf_area;	/* XXX - Use scb instead? */
   1540 
   1541 	/*
   1542 	 * Send the configure command first.
   1543 	 */
   1544 	{
   1545 		struct ie_config_cmd *cmd = ptr;	/* XXX - Was volatile */
   1546 
   1547 		scb->ie_command_list = vtop16sw(sc, cmd);
   1548 		cmd->com.ie_cmd_status = SWAP(0);
   1549 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
   1550 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1551 
   1552 		ie_setup_config(cmd, (sc->promisc != 0), 0);
   1553 
   1554 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1555 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1556 			printf("%s: configure command failed\n",
   1557 			    sc->sc_dev.dv_xname);
   1558 			return 0;
   1559 		}
   1560 	}
   1561 
   1562 	/*
   1563 	 * Now send the Individual Address Setup command.
   1564 	 */
   1565 	{
   1566 		struct ie_iasetup_cmd *cmd = ptr;	/* XXX - Was volatile */
   1567 
   1568 		scb->ie_command_list = vtop16sw(sc, cmd);
   1569 		cmd->com.ie_cmd_status = SWAP(0);
   1570 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
   1571 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1572 
   1573 		(sc->sc_bcopy)(LLADDR(ifp->if_sadl),
   1574 		    (caddr_t)&cmd->ie_address, sizeof(cmd->ie_address));
   1575 
   1576 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1577 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1578 			printf("%s: individual address setup command failed\n",
   1579 			    sc->sc_dev.dv_xname);
   1580 			return 0;
   1581 		}
   1582 	}
   1583 
   1584 	/*
   1585 	 * Now run the time-domain reflectometer.
   1586 	 */
   1587 	if (ie_run_tdr)
   1588 		run_tdr(sc, ptr);
   1589 
   1590 	/*
   1591 	 * Acknowledge any interrupts we have generated thus far.
   1592 	 */
   1593 	ie_ack(sc, IE_ST_WHENCE);
   1594 
   1595 	/*
   1596 	 * Set up the transmit and recv buffers.
   1597 	 */
   1598 	iememinit(sc);
   1599 
   1600 	/* tell higher levels that we are here */
   1601 	ifp->if_flags |= IFF_RUNNING;
   1602 	ifp->if_flags &= ~IFF_OACTIVE;
   1603 
   1604 	sc->scb->ie_recv_list =
   1605 	    vtop16sw(sc, (void*) sc->rframes[0]);
   1606 	cmd_and_wait(sc, IE_RU_START, 0, 0);
   1607 
   1608 	ie_ack(sc, IE_ST_WHENCE);
   1609 
   1610 	if (sc->run_586)
   1611 		(sc->run_586)(sc);
   1612 
   1613 	return 0;
   1614 }
   1615 
   1616 static void
   1617 iestop(sc)
   1618 	struct ie_softc *sc;
   1619 {
   1620 
   1621 	cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
   1622 }
   1623 
   1624 static int
   1625 ieioctl(ifp, cmd, data)
   1626 	register struct ifnet *ifp;
   1627 	u_long cmd;
   1628 	caddr_t data;
   1629 {
   1630 	struct ie_softc *sc = ifp->if_softc;
   1631 	struct ifaddr *ifa = (struct ifaddr *)data;
   1632 	struct ifreq *ifr = (struct ifreq *)data;
   1633 	int s, error = 0;
   1634 
   1635 	s = splnet();
   1636 
   1637 	switch (cmd) {
   1638 
   1639 	case SIOCSIFADDR:
   1640 		ifp->if_flags |= IFF_UP;
   1641 
   1642 		switch (ifa->ifa_addr->sa_family) {
   1643 #ifdef INET
   1644 		case AF_INET:
   1645 			ieinit(sc);
   1646 			arp_ifinit(ifp, ifa);
   1647 			break;
   1648 #endif
   1649 #ifdef NS
   1650 		/* XXX - This code is probably wrong. */
   1651 		case AF_NS:
   1652 		    {
   1653 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
   1654 
   1655 			if (ns_nullhost(*ina))
   1656 				ina->x_host =
   1657 				    *(union ns_host *)LLADDR(ifp->if_sadl);
   1658 			else
   1659 				bcopy(ina->x_host.c_host,
   1660 				    LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   1661 			/* Set new address. */
   1662 			ieinit(sc);
   1663 			break;
   1664 		    }
   1665 #endif /* NS */
   1666 		default:
   1667 			ieinit(sc);
   1668 			break;
   1669 		}
   1670 		break;
   1671 
   1672 	case SIOCSIFFLAGS:
   1673 		sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
   1674 
   1675 		if ((ifp->if_flags & IFF_UP) == 0 &&
   1676 		    (ifp->if_flags & IFF_RUNNING) != 0) {
   1677 			/*
   1678 			 * If interface is marked down and it is running, then
   1679 			 * stop it.
   1680 			 */
   1681 			iestop(sc);
   1682 			ifp->if_flags &= ~IFF_RUNNING;
   1683 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
   1684 			(ifp->if_flags & IFF_RUNNING) == 0) {
   1685 			/*
   1686 			 * If interface is marked up and it is stopped, then
   1687 			 * start it.
   1688 			 */
   1689 			ieinit(sc);
   1690 		} else {
   1691 			/*
   1692 			 * Reset the interface to pick up changes in any other
   1693 			 * flags that affect hardware registers.
   1694 			 */
   1695 			iestop(sc);
   1696 			ieinit(sc);
   1697 		}
   1698 #ifdef IEDEBUG
   1699 		if (ifp->if_flags & IFF_DEBUG)
   1700 			sc->sc_debug = IED_ALL;
   1701 		else
   1702 			sc->sc_debug = ie_debug_flags;
   1703 #endif
   1704 		break;
   1705 
   1706 	case SIOCADDMULTI:
   1707 	case SIOCDELMULTI:
   1708 		error = (cmd == SIOCADDMULTI) ?
   1709 		    ether_addmulti(ifr, &sc->sc_ethercom) :
   1710 		    ether_delmulti(ifr, &sc->sc_ethercom);
   1711 
   1712 		if (error == ENETRESET) {
   1713 			/*
   1714 			 * Multicast list has changed; set the hardware filter
   1715 			 * accordingly.
   1716 			 */
   1717 			mc_reset(sc);
   1718 			error = 0;
   1719 		}
   1720 		break;
   1721 
   1722 	default:
   1723 		error = EINVAL;
   1724 	}
   1725 	splx(s);
   1726 	return error;
   1727 }
   1728 
   1729 static void
   1730 mc_reset(sc)
   1731 	struct ie_softc *sc;
   1732 {
   1733 	struct ether_multi *enm;
   1734 	struct ether_multistep step;
   1735 	struct ifnet *ifp;
   1736 
   1737 	ifp = &sc->sc_if;
   1738 
   1739 	/*
   1740 	 * Step through the list of addresses.
   1741 	 */
   1742 	sc->mcast_count = 0;
   1743 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1744 	while (enm) {
   1745 		if (sc->mcast_count >= MAXMCAST ||
   1746 		    bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
   1747 			ifp->if_flags |= IFF_ALLMULTI;
   1748 			ieioctl(ifp, SIOCSIFFLAGS, (void *)0);
   1749 			goto setflag;
   1750 		}
   1751 		bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
   1752 		sc->mcast_count++;
   1753 		ETHER_NEXT_MULTI(step, enm);
   1754 	}
   1755 setflag:
   1756 	sc->want_mcsetup = 1;
   1757 }
   1758 
   1759 #ifdef IEDEBUG
   1760 void
   1761 print_rbd(rbd)
   1762 	volatile struct ie_recv_buf_desc *rbd;
   1763 {
   1764 
   1765 	printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
   1766 	    "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
   1767 	    rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
   1768 	    rbd->mbz);
   1769 }
   1770 #endif
   1771