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