Home | History | Annotate | Line # | Download | only in dev
if_ie.c revision 1.4
      1 /*	$NetBSD: if_ie.c,v 1.4 1995/04/09 05:08:33 gwr Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1993, 1994, 1995 Charles Hannum.
      5  * Copyright (c) 1992, 1993, University of Vermont and State
      6  *  Agricultural College.
      7  * Copyright (c) 1992, 1993, Garrett A. Wollman.
      8  *
      9  * Portions:
     10  * Copyright (c) 1994, 1995, Rafal K. Boni
     11  * Copyright (c) 1990, 1991, William F. Jolitz
     12  * Copyright (c) 1990, The Regents of the University of California
     13  *
     14  * All rights reserved.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by Charles Hannum, by the
     27  *	University of Vermont and State Agricultural College and Garrett A.
     28  *	Wollman, by William F. Jolitz, and by the University of California,
     29  *	Berkeley, Lawrence Berkeley Laboratory, and its contributors.
     30  * 4. Neither the names of the Universities nor the names of the authors
     31  *    may be used to endorse or promote products derived from this software
     32  *    without specific prior written permission.
     33  *
     34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
     38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     44  * SUCH DAMAGE.
     45  */
     46 
     47 /*
     48  * Intel 82586 Ethernet chip
     49  * Register, bit, and structure definitions.
     50  *
     51  * Original StarLAN driver written by Garrett Wollman with reference to the
     52  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
     53  *
     54  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
     55  *
     56  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
     57  *
     58  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
     59  *
     60  * Converted to SUN ie driver by Charles D. Cranor,
     61  *		October 1994, January 1995.
     62  * This sun version based on i386 version 1.30.
     63  */
     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_output = ether_output;
    296 	ifp->if_start = iestart;
    297 	ifp->if_ioctl = ieioctl;
    298 	ifp->if_watchdog = iewatchdog;
    299 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    300 #ifdef IFF_NOTRAILERS
    301 	/* XXX still compile when the blasted things are gone... */
    302 	ifp->if_flags |= IFF_NOTRAILERS;
    303 #endif
    304 
    305 	/* Attach the interface. */
    306 	if_attach(ifp);
    307 	ether_ifattach(ifp);
    308 #if NBPFILTER > 0
    309 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB,
    310 	    sizeof(struct ether_header));
    311 #endif
    312 }
    313 
    314 /*
    315  * Device timeout/watchdog routine.  Entered if the device neglects to
    316  * generate an interrupt after a transmit has been started on it.
    317  */
    318 void
    319 iewatchdog(unit)
    320 	short   unit;
    321 {
    322 	struct ie_softc *sc = iecd.cd_devs[unit];
    323 
    324 	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
    325 	++sc->sc_arpcom.ac_if.if_oerrors;
    326 
    327 	iereset(sc);
    328 }
    329 
    330 /*
    331  * What to do upon receipt of an interrupt.
    332  */
    333 int
    334 ie_intr(v)
    335 	void   *v;
    336 {
    337 	struct ie_softc *sc = v;
    338 	register u_short status;
    339 
    340 	status = sc->scb->ie_status;
    341 
    342 	/*
    343 	 * check for parity error
    344 	 */
    345 	if (sc->hard_type == IE_VME) {
    346 		volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg;
    347 		if (iev->status & IEVME_PERR) {
    348 			printf("%s: parity error (ctrl %x @ %02x%04x)\n",
    349 			    iev->pectrl, iev->pectrl & IEVME_HADDR,
    350 			    iev->peaddr);
    351 			iev->pectrl = iev->pectrl | IEVME_PARACK;
    352 		}
    353 	}
    354 
    355 loop:
    356 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    357 	ie_ack(sc, IE_ST_WHENCE & status);
    358 
    359 	if (status & (IE_ST_RECV | IE_ST_RNR)) {
    360 #ifdef IEDEBUG
    361 		in_ierint++;
    362 		if (sc->sc_debug & IED_RINT)
    363 			printf("%s: rint\n", sc->sc_dev.dv_xname);
    364 #endif
    365 		ierint(sc);
    366 #ifdef IEDEBUG
    367 		in_ierint--;
    368 #endif
    369 	}
    370 
    371 	if (status & IE_ST_DONE) {
    372 #ifdef IEDEBUG
    373 		in_ietint++;
    374 		if (sc->sc_debug & IED_TINT)
    375 			printf("%s: tint\n", sc->sc_dev.dv_xname);
    376 #endif
    377 		ietint(sc);
    378 #ifdef IEDEBUG
    379 		in_ietint--;
    380 #endif
    381 	}
    382 
    383 	if (status & IE_ST_RNR) {
    384 		printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
    385 		sc->sc_arpcom.ac_if.if_ierrors++;
    386 		iereset(sc);
    387 	}
    388 
    389 #ifdef IEDEBUG
    390 	if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
    391 		printf("%s: cna\n", sc->sc_dev.dv_xname);
    392 #endif
    393 
    394 	if ((status = sc->scb->ie_status) & IE_ST_WHENCE)
    395 		goto loop;
    396 
    397 	return 1;
    398 }
    399 
    400 /*
    401  * Process a received-frame interrupt.
    402  */
    403 void
    404 ierint(sc)
    405 	struct ie_softc *sc;
    406 {
    407 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    408 	int     i, status;
    409 	static int timesthru = 1024;
    410 
    411 	i = sc->rfhead;
    412 	for (;;) {
    413 		status = sc->rframes[i]->ie_fd_status;
    414 
    415 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
    416 			sc->sc_arpcom.ac_if.if_ipackets++;
    417 			if (!--timesthru) {
    418 				sc->sc_arpcom.ac_if.if_ierrors +=
    419 				    SWAP(scb->ie_err_crc) +
    420 				    SWAP(scb->ie_err_align) +
    421 				    SWAP(scb->ie_err_resource) +
    422 				    SWAP(scb->ie_err_overrun);
    423 				scb->ie_err_crc = 0;
    424 				scb->ie_err_align = 0;
    425 				scb->ie_err_resource = 0;
    426 				scb->ie_err_overrun = 0;
    427 				timesthru = 1024;
    428 			}
    429 			ie_readframe(sc, i);
    430 		} else {
    431 			if ((status & IE_FD_RNR) != 0 &&
    432 			    (scb->ie_status & IE_RU_READY) == 0) {
    433 				sc->rframes[0]->ie_fd_buf_desc =
    434 					MK_16(sc->sc_maddr, sc->rbuffs[0]);
    435 				scb->ie_recv_list =
    436 					MK_16(sc->sc_maddr, sc->rframes[0]);
    437 				command_and_wait(sc, IE_RU_START, 0, 0);
    438 			}
    439 			break;
    440 		}
    441 		i = (i + 1) % sc->nframes;
    442 	}
    443 }
    444 
    445 /*
    446  * Process a command-complete interrupt.  These are only generated by
    447  * the transmission of frames.  This routine is deceptively simple, since
    448  * most of the real work is done by iestart().
    449  */
    450 void
    451 ietint(sc)
    452 	struct ie_softc *sc;
    453 {
    454 	int     status;
    455 	int     i;
    456 
    457 	sc->sc_arpcom.ac_if.if_timer = 0;
    458 	sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
    459 
    460 	status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
    461 
    462 	if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
    463 		printf("ietint: command still busy!\n");
    464 
    465 	if (status & IE_STAT_OK) {
    466 		sc->sc_arpcom.ac_if.if_opackets++;
    467 		sc->sc_arpcom.ac_if.if_collisions +=
    468 		  SWAP(status & IE_XS_MAXCOLL);
    469 	} else if (status & IE_STAT_ABORT) {
    470 		printf("%s: send aborted\n", sc->sc_dev.dv_xname);
    471 		sc->sc_arpcom.ac_if.if_oerrors++;
    472 	} else if (status & IE_XS_NOCARRIER) {
    473 		printf("%s: no carrier\n", sc->sc_dev.dv_xname);
    474 		sc->sc_arpcom.ac_if.if_oerrors++;
    475 	} else if (status & IE_XS_LOSTCTS) {
    476 		printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
    477 		sc->sc_arpcom.ac_if.if_oerrors++;
    478 	} else if (status & IE_XS_UNDERRUN) {
    479 		printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
    480 		sc->sc_arpcom.ac_if.if_oerrors++;
    481 	} else if (status & IE_XS_EXCMAX) {
    482 		printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
    483 		sc->sc_arpcom.ac_if.if_collisions += 16;
    484 		sc->sc_arpcom.ac_if.if_oerrors++;
    485 	}
    486 
    487 	/*
    488 	 * If multicast addresses were added or deleted while we
    489 	 * were transmitting, mc_reset() set the want_mcsetup flag
    490 	 * indicating that we should do it.
    491 	 */
    492 	if (sc->want_mcsetup) {
    493 		mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
    494 		sc->want_mcsetup = 0;
    495 	}
    496 
    497 	/* Done with the buffer. */
    498 	sc->xmit_free++;
    499 	sc->xmit_busy = 0;
    500 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    501 
    502 	iestart(&sc->sc_arpcom.ac_if);
    503 }
    504 
    505 /*
    506  * Compare two Ether/802 addresses for equality, inlined and
    507  * unrolled for speed.  I'd love to have an inline assembler
    508  * version of this...
    509  */
    510 static inline int
    511 ether_equal(one, two)
    512 	u_char *one, *two;
    513 {
    514 
    515 	if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
    516 	    one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
    517 		return 0;
    518 	return 1;
    519 }
    520 
    521 /*
    522  * Check for a valid address.  to_bpf is filled in with one of the following:
    523  *   0 -> BPF doesn't get this packet
    524  *   1 -> BPF does get this packet
    525  *   2 -> BPF does get this packet, but we don't
    526  * Return value is true if the packet is for us, and false otherwise.
    527  *
    528  * This routine is a mess, but it's also critical that it be as fast
    529  * as possible.  It could be made cleaner if we can assume that the
    530  * only client which will fiddle with IFF_PROMISC is BPF.  This is
    531  * probably a good assumption, but we do not make it here.  (Yet.)
    532  */
    533 static inline int
    534 check_eh(sc, eh, to_bpf)
    535 	struct ie_softc *sc;
    536 	struct ether_header *eh;
    537 	int    *to_bpf;
    538 {
    539 	int     i;
    540 
    541 	switch (sc->promisc) {
    542 	case IFF_ALLMULTI:
    543 		/*
    544 		 * Receiving all multicasts, but no unicasts except those
    545 		 * destined for us.
    546 		 */
    547 #if NBPFILTER > 0
    548 		/* BPF gets this packet if anybody cares */
    549 		*to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
    550 #endif
    551 		if (eh->ether_dhost[0] & 1)
    552 			return 1;
    553 		if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
    554 			return 1;
    555 		return 0;
    556 
    557 	case IFF_PROMISC:
    558 		/*
    559 		 * Receiving all packets.  These need to be passed on to BPF.
    560 		 */
    561 #if NBPFILTER > 0
    562 		*to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
    563 #endif
    564 		/* If for us, accept and hand up to BPF */
    565 		if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
    566 			return 1;
    567 
    568 #if NBPFILTER > 0
    569 		if (*to_bpf)
    570 			*to_bpf = 2;	/* we don't need to see it */
    571 #endif
    572 
    573 		/*
    574 		 * Not a multicast, so BPF wants to see it but we don't.
    575 		 */
    576 		if (!(eh->ether_dhost[0] & 1))
    577 			return 1;
    578 
    579 		/*
    580 		 * If it's one of our multicast groups, accept it and pass it
    581 		 * up.
    582 		 */
    583 		for (i = 0; i < sc->mcast_count; i++) {
    584 			if (ether_equal(eh->ether_dhost,
    585 			    (u_char *)&sc->mcast_addrs[i])) {
    586 #if NBPFILTER > 0
    587 				if (*to_bpf)
    588 					*to_bpf = 1;
    589 #endif
    590 				return 1;
    591 			}
    592 		}
    593 		return 1;
    594 
    595 	case IFF_ALLMULTI | IFF_PROMISC:
    596 		/*
    597 		 * Acting as a multicast router, and BPF running at the same
    598 		 * time.  Whew!  (Hope this is a fast machine...)
    599 		 */
    600 #if NBPFILTER > 0
    601 		*to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
    602 #endif
    603 		/* We want to see multicasts. */
    604 		if (eh->ether_dhost[0] & 1)
    605 			return 1;
    606 
    607 		/* We want to see our own packets */
    608 		if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
    609 			return 1;
    610 
    611 		/* Anything else goes to BPF but nothing else. */
    612 #if NBPFILTER > 0
    613 		if (*to_bpf)
    614 			*to_bpf = 2;
    615 #endif
    616 		return 1;
    617 
    618 	default:
    619 		/*
    620 		 * Only accept unicast packets destined for us, or multicasts
    621 		 * for groups that we belong to.  For now, we assume that the
    622 		 * '586 will only return packets that we asked it for.  This
    623 		 * isn't strictly true (it uses hashing for the multicast filter),
    624 		 * but it will do in this case, and we want to get out of here
    625 		 * as quickly as possible.
    626 		 */
    627 #if NBPFILTER > 0
    628 		*to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
    629 #endif
    630 		return 1;
    631 	}
    632 	return 0;
    633 }
    634 
    635 /*
    636  * We want to isolate the bits that have meaning...  This assumes that
    637  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
    638  * the size of the buffer, then we are screwed anyway.
    639  */
    640 static inline int
    641 ie_buflen(sc, head)
    642 	struct ie_softc *sc;
    643 	int     head;
    644 {
    645 
    646 	return (SWAP(sc->rbuffs[head]->ie_rbd_actual)
    647 	    & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
    648 }
    649 
    650 static inline int
    651 ie_packet_len(sc)
    652 	struct ie_softc *sc;
    653 {
    654 	int     i;
    655 	int     head = sc->rbhead;
    656 	int     acc = 0;
    657 
    658 	do {
    659 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
    660 #ifdef IEDEBUG
    661 			print_rbd(sc->rbuffs[sc->rbhead]);
    662 #endif
    663 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
    664 			    sc->sc_dev.dv_xname, sc->rbhead);
    665 			iereset(sc);
    666 			return -1;
    667 		}
    668 
    669 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
    670 
    671 		acc += ie_buflen(sc, head);
    672 		head = (head + 1) % sc->nrxbuf;
    673 	} while (!i);
    674 
    675 	return acc;
    676 }
    677 
    678 /*
    679  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
    680  * command to the chip to be executed.  On the way, if we have a BPF listener
    681  * also give him a copy.
    682  */
    683 inline static void
    684 iexmit(sc)
    685 	struct ie_softc *sc;
    686 {
    687 
    688 #if NBPFILTER > 0
    689 	/*
    690 	 * If BPF is listening on this interface, let it see the packet before
    691 	 * we push it on the wire.
    692 	 */
    693 	if (sc->sc_arpcom.ac_if.if_bpf)
    694 		bpf_tap(sc->sc_arpcom.ac_if.if_bpf,
    695 		    sc->xmit_cbuffs[sc->xctail],
    696 		    SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
    697 #endif
    698 
    699 	sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
    700 	sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
    701 	ST_24(sc->xmit_buffs[sc->xctail]->ie_xmit_buf,
    702 	    MK_24(sc->sc_iobase, sc->xmit_cbuffs[sc->xctail]));
    703 
    704 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
    705 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
    706 	  IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
    707 
    708 	sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
    709 	sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
    710 	    MK_16(sc->sc_maddr, sc->xmit_buffs[sc->xctail]);
    711 
    712 	sc->scb->ie_command_list =
    713 	  MK_16(sc->sc_maddr, sc->xmit_cmds[sc->xctail]);
    714 	command_and_wait(sc, IE_CU_START, 0, 0);
    715 
    716 	sc->xmit_busy = 1;
    717 	sc->sc_arpcom.ac_if.if_timer = 5;
    718 }
    719 
    720 /*
    721  * Read data off the interface, and turn it into an mbuf chain.
    722  *
    723  * This code is DRAMATICALLY different from the previous version; this
    724  * version tries to allocate the entire mbuf chain up front, given the
    725  * length of the data available.  This enables us to allocate mbuf
    726  * clusters in many situations where before we would have had a long
    727  * chain of partially-full mbufs.  This should help to speed up the
    728  * operation considerably.  (Provided that it works, of course.)
    729  */
    730 static inline int
    731 ieget(sc, mp, ehp, to_bpf)
    732 	struct ie_softc *sc;
    733 	struct mbuf **mp;
    734 	struct ether_header *ehp;
    735 	int    *to_bpf;
    736 {
    737 	struct mbuf *m, *top, **mymp;
    738 	int     i;
    739 	int     offset;
    740 	int     totlen, resid;
    741 	int     thismboff;
    742 	int     head;
    743 
    744 	totlen = ie_packet_len(sc);
    745 	if (totlen <= 0)
    746 		return -1;
    747 
    748 	i = sc->rbhead;
    749 
    750 	/*
    751 	 * Snarf the Ethernet header.
    752 	 */
    753 	(sc->sc_bcopy)((caddr_t)sc->cbuffs[i], (caddr_t)ehp, sizeof *ehp);
    754 
    755 	/*
    756 	 * As quickly as possible, check if this packet is for us.
    757 	 * If not, don't waste a single cycle copying the rest of the
    758 	 * packet in.
    759 	 * This is only a consideration when FILTER is defined; i.e., when
    760 	 * we are either running BPF or doing multicasting.
    761 	 */
    762 	if (!check_eh(sc, ehp, to_bpf)) {
    763 		ie_drop_packet_buffer(sc);
    764 		/* just this case, it's not an error */
    765 		sc->sc_arpcom.ac_if.if_ierrors--;
    766 		return -1;
    767 	}
    768 	totlen -= (offset = sizeof *ehp);
    769 
    770 	MGETHDR(*mp, M_DONTWAIT, MT_DATA);
    771 	if (!*mp) {
    772 		ie_drop_packet_buffer(sc);
    773 		return -1;
    774 	}
    775 
    776 	m = *mp;
    777 	m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
    778 	m->m_len = MHLEN;
    779 	resid = m->m_pkthdr.len = totlen;
    780 	top = 0;
    781 	mymp = &top;
    782 
    783 	/*
    784 	 * This loop goes through and allocates mbufs for all the data we will
    785 	 * be copying in.  It does not actually do the copying yet.
    786 	 */
    787 	do {			/* while (resid > 0) */
    788 		/*
    789 		 * Try to allocate an mbuf to hold the data that we have.  If
    790 		 * we already allocated one, just get another one and stick it
    791 		 * on the end (eventually).  If we don't already have one, try
    792 		 * to allocate an mbuf cluster big enough to hold the whole
    793 		 * packet, if we think it's reasonable, or a single mbuf which
    794 		 * may or may not be big enough. Got that?
    795 		 */
    796 		if (top) {
    797 			MGET(m, M_DONTWAIT, MT_DATA);
    798 			if (!m) {
    799 				m_freem(top);
    800 				ie_drop_packet_buffer(sc);
    801 				return -1;
    802 			}
    803 			m->m_len = MLEN;
    804 		}
    805 
    806 		if (resid >= MINCLSIZE) {
    807 			MCLGET(m, M_DONTWAIT);
    808 			if (m->m_flags & M_EXT)
    809 				m->m_len = min(resid, MCLBYTES);
    810 		} else {
    811 			if (resid < m->m_len) {
    812 				if (!top && resid + max_linkhdr <= m->m_len)
    813 					m->m_data += max_linkhdr;
    814 				m->m_len = resid;
    815 			}
    816 		}
    817 		resid -= m->m_len;
    818 		*mymp = m;
    819 		mymp = &m->m_next;
    820 	} while (resid > 0);
    821 
    822 	resid = totlen;
    823 	m = top;
    824 	thismboff = 0;
    825 	head = sc->rbhead;
    826 
    827 	/*
    828 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
    829 	 * time) and stuff the data into it.  There are no possible failures
    830 	 * at or after this point.
    831 	 */
    832 	while (resid > 0) {	/* while there's stuff left */
    833 		int     thislen = ie_buflen(sc, head) - offset;
    834 
    835 		/*
    836 		 * If too much data for the current mbuf, then fill the current one
    837 		 * up, go to the next one, and try again.
    838 		 */
    839 		if (thislen > m->m_len - thismboff) {
    840 			int     newlen = m->m_len - thismboff;
    841 			(sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
    842 			    mtod(m, caddr_t) + thismboff, (u_int)newlen);
    843 			m = m->m_next;
    844 			thismboff = 0;	/* new mbuf, so no offset */
    845 			offset += newlen;	/* we are now this far into
    846 						 * the packet */
    847 			resid -= newlen;	/* so there is this much left
    848 						 * to get */
    849 			continue;
    850 		}
    851 
    852 		/*
    853 		 * If there is more than enough space in the mbuf to hold the
    854 		 * contents of this buffer, copy everything in, advance pointers,
    855 		 * and so on.
    856 		 */
    857 		if (thislen < m->m_len - thismboff) {
    858 			(sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
    859 			    mtod(m, caddr_t) + thismboff, (u_int)thislen);
    860 			thismboff += thislen;	/* we are this far into the
    861 						 * mbuf */
    862 			resid -= thislen;	/* and this much is left */
    863 			goto nextbuf;
    864 		}
    865 
    866 		/*
    867 		 * Otherwise, there is exactly enough space to put this buffer's
    868 		 * contents into the current mbuf.  Do the combination of the above
    869 		 * actions.
    870 		 */
    871 		(sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
    872 		    mtod(m, caddr_t) + thismboff, (u_int)thislen);
    873 		m = m->m_next;
    874 		thismboff = 0;	/* new mbuf, start at the beginning */
    875 		resid -= thislen;	/* and we are this far through */
    876 
    877 		/*
    878 		 * Advance all the pointers.  We can get here from either of the
    879 		 * last two cases, but never the first.
    880 		 */
    881 	nextbuf:
    882 		offset = 0;
    883 		sc->rbuffs[head]->ie_rbd_actual = SWAP(0);
    884 		sc->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
    885 		sc->rbhead = head = (head + 1) % sc->nrxbuf;
    886 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
    887 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
    888 	}
    889 
    890 	/*
    891 	 * Unless something changed strangely while we were doing the copy,
    892 	 * we have now copied everything in from the shared memory.
    893 	 * This means that we are done.
    894 	 */
    895 	return 0;
    896 }
    897 
    898 /*
    899  * Read frame NUM from unit UNIT (pre-cached as IE).
    900  *
    901  * This routine reads the RFD at NUM, and copies in the buffers from
    902  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
    903  * doesn't start complaining.  Trailers are DROPPED---there's no point
    904  * in wasting time on confusing code to deal with them.  Hopefully,
    905  * this machine will never ARP for trailers anyway.
    906  */
    907 static void
    908 ie_readframe(sc, num)
    909 	struct ie_softc *sc;
    910 	int     num;		/* frame number to read */
    911 {
    912 	int status;
    913 	struct mbuf *m = 0;
    914 	struct ether_header eh;
    915 #if NBPFILTER > 0
    916 	int     bpf_gets_it = 0;
    917 #endif
    918 
    919 	status = sc->rframes[num]->ie_fd_status;
    920 
    921 	/* Immediately advance the RFD list, since we have copied ours now. */
    922 	sc->rframes[num]->ie_fd_status = SWAP(0);
    923 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
    924 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
    925 	sc->rftail = (sc->rftail + 1) % sc->nframes;
    926 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
    927 
    928 	if (status & IE_FD_OK) {
    929 #if NBPFILTER > 0
    930 		if (ieget(sc, &m, &eh, &bpf_gets_it)) {
    931 #else
    932 		if (ieget(sc, &m, &eh, 0)) {
    933 #endif
    934 			sc->sc_arpcom.ac_if.if_ierrors++;
    935 			return;
    936 		}
    937 	}
    938 
    939 #ifdef IEDEBUG
    940 	if (sc->sc_debug & IED_READFRAME)
    941 		printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
    942 		    ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
    943 #endif
    944 
    945 	if (!m)
    946 		return;
    947 
    948 	if (last_not_for_us) {
    949 		m_freem(last_not_for_us);
    950 		last_not_for_us = 0;
    951 	}
    952 
    953 #if NBPFILTER > 0
    954 	/*
    955 	 * Check for a BPF filter; if so, hand it up.
    956 	 * Note that we have to stick an extra mbuf up front, because
    957 	 * bpf_mtap expects to have the ether header at the front.
    958 	 * It doesn't matter that this results in an ill-formatted mbuf chain,
    959 	 * since BPF just looks at the data.  (It doesn't try to free the mbuf,
    960 	 * tho' it will make a copy for tcpdump.)
    961 	 */
    962 	if (bpf_gets_it) {
    963 		struct mbuf m0;
    964 		m0.m_len = sizeof eh;
    965 		m0.m_data = (caddr_t)&eh;
    966 		m0.m_next = m;
    967 
    968 		/* Pass it up */
    969 		bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, &m0);
    970 	}
    971 	/*
    972 	 * A signal passed up from the filtering code indicating that the
    973 	 * packet is intended for BPF but not for the protocol machinery.
    974 	 * We can save a few cycles by not handing it off to them.
    975 	 */
    976 	if (bpf_gets_it == 2) {
    977 		last_not_for_us = m;
    978 		return;
    979 	}
    980 #endif	/* NBPFILTER > 0 */
    981 
    982 	/*
    983 	 * In here there used to be code to check destination addresses upon
    984 	 * receipt of a packet.  We have deleted that code, and replaced it
    985 	 * with code to check the address much earlier in the cycle, before
    986 	 * copying the data in; this saves us valuable cycles when operating
    987 	 * as a multicast router or when using BPF.
    988 	 */
    989 
    990 	/*
    991 	 * Finally pass this packet up to higher layers.
    992 	 */
    993 	ether_input(&sc->sc_arpcom.ac_if, &eh, m);
    994 }
    995 
    996 static void
    997 ie_drop_packet_buffer(sc)
    998 	struct ie_softc *sc;
    999 {
   1000 	int i;
   1001 
   1002 	do {
   1003 		/*
   1004 		 * This means we are somehow out of sync.  So, we reset the
   1005 		 * adapter.
   1006 		 */
   1007 		if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
   1008 #ifdef IEDEBUG
   1009 			print_rbd(sc->rbuffs[sc->rbhead]);
   1010 #endif
   1011 			log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
   1012 			    sc->sc_dev.dv_xname, sc->rbhead);
   1013 			iereset(sc);
   1014 			return;
   1015 		}
   1016 
   1017 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
   1018 
   1019 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
   1020 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
   1021 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
   1022 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
   1023 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
   1024 	} while (!i);
   1025 }
   1026 
   1027 /*
   1028  * Start transmission on an interface.
   1029  */
   1030 void
   1031 iestart(ifp)
   1032 	struct ifnet *ifp;
   1033 {
   1034 	struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
   1035 	struct mbuf *m0, *m;
   1036 	u_char *buffer;
   1037 	u_short len;
   1038 
   1039 	if ((ifp->if_flags & IFF_RUNNING) == 0)
   1040 		return;
   1041 
   1042 	if (sc->xmit_free == 0) {
   1043 		ifp->if_flags |= IFF_OACTIVE;
   1044 		if (!sc->xmit_busy)
   1045 			iexmit(sc);
   1046 		return;
   1047 	}
   1048 
   1049 	do {
   1050 		IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
   1051 		if (!m)
   1052 			break;
   1053 
   1054 		len = 0;
   1055 		buffer = sc->xmit_cbuffs[sc->xchead];
   1056 
   1057 		for (m0 = m; m && (len + m->m_len) < IE_TBUF_SIZE; m = m->m_next) {
   1058 			(sc->sc_bcopy)(mtod(m, caddr_t), buffer, m->m_len);
   1059 			buffer += m->m_len;
   1060 			len += m->m_len;
   1061 		}
   1062 		if (m)
   1063 		  printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
   1064 
   1065 		m_freem(m0);
   1066 		len = max(len, ETHER_MIN_LEN);
   1067 		sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
   1068 
   1069 		sc->xmit_free--;
   1070 		sc->xchead = (sc->xchead + 1) % NTXBUF;
   1071 	} while (sc->xmit_free > 0);
   1072 
   1073 	/* If we stuffed any packets into the card's memory, send now. */
   1074 	if ((sc->xmit_free < NTXBUF) && (!sc->xmit_busy))
   1075 		iexmit(sc);
   1076 
   1077 	return;
   1078 }
   1079 
   1080 /*
   1081  * set up IE's ram space
   1082  */
   1083 int
   1084 ie_setupram(sc)
   1085 	struct ie_softc *sc;
   1086 {
   1087 	volatile struct ie_sys_conf_ptr *scp;
   1088 	volatile struct ie_int_sys_conf_ptr *iscp;
   1089 	volatile struct ie_sys_ctl_block *scb;
   1090 	int     s;
   1091 
   1092 	s = splimp();
   1093 
   1094 	scp = sc->scp;
   1095 	(sc->sc_bzero)((char *) scp, sizeof *scp);
   1096 
   1097 	iscp = sc->iscp;
   1098 	(sc->sc_bzero)((char *) iscp, sizeof *iscp);
   1099 
   1100 	scb = sc->scb;
   1101 	(sc->sc_bzero)((char *) scb, sizeof *scb);
   1102 
   1103 	scp->ie_bus_use = 0;	/* 16-bit */
   1104 	ST_24(scp->ie_iscp_ptr, MK_24(sc->sc_iobase, iscp));
   1105 
   1106 	iscp->ie_busy = 1;	/* ie_busy == char */
   1107 	iscp->ie_scb_offset = MK_16(sc->sc_maddr, scb);
   1108 	ST_24(iscp->ie_base, MK_24(sc->sc_iobase, sc->sc_maddr));
   1109 
   1110 	(sc->reset_586) (sc);
   1111 	(sc->chan_attn) (sc);
   1112 
   1113 	delay(100);		/* wait a while... */
   1114 
   1115 	if (iscp->ie_busy) {
   1116 		splx(s);
   1117 		return 0;
   1118 	}
   1119 	/*
   1120 	 * Acknowledge any interrupts we may have caused...
   1121 	 */
   1122 	ie_ack(sc, IE_ST_WHENCE);
   1123 	splx(s);
   1124 
   1125 	return 1;
   1126 }
   1127 
   1128 void
   1129 iereset(sc)
   1130 	struct ie_softc *sc;
   1131 {
   1132 	int s = splimp();
   1133 
   1134 	printf("%s: reset\n", sc->sc_dev.dv_xname);
   1135 
   1136 	/* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
   1137 	sc->sc_arpcom.ac_if.if_flags &= ~(IFF_UP | IFF_OACTIVE);
   1138 	ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
   1139 
   1140 	/*
   1141 	 * Stop i82586 dead in its tracks.
   1142 	 */
   1143 	if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
   1144 		printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
   1145 
   1146 	if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
   1147 		printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
   1148 
   1149 #ifdef notdef
   1150 	if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
   1151 		panic("ie disappeared!\n");
   1152 #endif
   1153 
   1154 	sc->sc_arpcom.ac_if.if_flags |= IFF_UP;
   1155 	ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
   1156 
   1157 	splx(s);
   1158 }
   1159 
   1160 /*
   1161  * This is called if we time out.
   1162  */
   1163 static void
   1164 chan_attn_timeout(rock)
   1165 	caddr_t rock;
   1166 {
   1167 	*(int *) rock = 1;
   1168 }
   1169 
   1170 /*
   1171  * Send a command to the controller and wait for it to either
   1172  * complete or be accepted, depending on the command.  If the
   1173  * command pointer is null, then pretend that the command is
   1174  * not an action command.  If the command pointer is not null,
   1175  * and the command is an action command, wait for
   1176  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
   1177  * to become true.
   1178  */
   1179 static int
   1180 command_and_wait(sc, cmd, pcmd, mask)
   1181 	struct ie_softc *sc;
   1182 	int     cmd;
   1183 	volatile void *pcmd;
   1184 	int     mask;
   1185 {
   1186 	volatile struct ie_cmd_common *cc = pcmd;
   1187 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1188 	volatile int timedout = 0;
   1189 	extern int hz;
   1190 
   1191 	scb->ie_command = (u_short)cmd;
   1192 
   1193 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
   1194 		(sc->chan_attn)(sc);
   1195 
   1196 		/*
   1197 		 * XXX
   1198 		 * I don't think this timeout works on suns.
   1199 		 * we are at splimp() in the loop, and the timeout
   1200 		 * stuff runs at software spl (so it is masked off?).
   1201 		 */
   1202 
   1203 		/*
   1204 		 * According to the packet driver, the minimum timeout should be
   1205 		 * .369 seconds, which we round up to .4.
   1206 		 */
   1207 
   1208 		timeout(chan_attn_timeout, (caddr_t)&timedout, 2 * hz / 5);
   1209 
   1210 		/*
   1211 		 * Now spin-lock waiting for status.  This is not a very nice
   1212 		 * thing to do, but I haven't figured out how, or indeed if, we
   1213 		 * can put the process waiting for action to sleep.  (We may
   1214 		 * be getting called through some other timeout running in the
   1215 		 * kernel.)
   1216 		 */
   1217 		for (;;)
   1218 			if ((cc->ie_cmd_status & mask) || timedout)
   1219 				break;
   1220 
   1221 		untimeout(chan_attn_timeout, (caddr_t)&timedout);
   1222 
   1223 		return timedout;
   1224 	} else {
   1225 		/*
   1226 		 * Otherwise, just wait for the command to be accepted.
   1227 		 */
   1228 		(sc->chan_attn)(sc);
   1229 
   1230 		while (scb->ie_command)
   1231 			;	/* spin lock */
   1232 
   1233 		return 0;
   1234 	}
   1235 }
   1236 
   1237 /*
   1238  * Run the time-domain reflectometer...
   1239  */
   1240 static void
   1241 run_tdr(sc, cmd)
   1242 	struct ie_softc *sc;
   1243 	struct ie_tdr_cmd *cmd;
   1244 {
   1245 	int result;
   1246 
   1247 	cmd->com.ie_cmd_status = SWAP(0);
   1248 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
   1249 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1250 
   1251 	sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
   1252 	cmd->ie_tdr_time = SWAP(0);
   1253 
   1254 	if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1255 	    !(cmd->com.ie_cmd_status & IE_STAT_OK))
   1256 		result = 0x10000;	/* XXX */
   1257 	else
   1258 		result = cmd->ie_tdr_time;
   1259 
   1260 	ie_ack(sc, IE_ST_WHENCE);
   1261 
   1262 	if (result & IE_TDR_SUCCESS)
   1263 		return;
   1264 
   1265 	if (result & 0x10000) {
   1266 		printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
   1267 	} else if (result & IE_TDR_XCVR) {
   1268 		printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
   1269 	} else if (result & IE_TDR_OPEN) {
   1270 		printf("%s: TDR detected an open %d clocks away\n",
   1271 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1272 	} else if (result & IE_TDR_SHORT) {
   1273 		printf("%s: TDR detected a short %d clocks away\n",
   1274 		    sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
   1275 	} else {
   1276 		printf("%s: TDR returned unknown status %x\n",
   1277 		    sc->sc_dev.dv_xname, result);
   1278 	}
   1279 }
   1280 
   1281 /*
   1282  * setup_bufs: set up the buffers
   1283  *
   1284  * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1285  * this is to be used for the buffers.  the chip indexs its control data
   1286  * structures with 16 bit offsets, and it indexes actual buffers with
   1287  * 24 bit addresses.   so we should allocate control buffers first so that
   1288  * we don't overflow the 16 bit offset field.   The number of transmit
   1289  * buffers is fixed at compile time.
   1290  *
   1291  * note: this function was written to be easy to understand, rather than
   1292  *       highly efficient (it isn't in the critical path).
   1293  */
   1294 static void
   1295 setup_bufs(sc)
   1296 	struct ie_softc *sc;
   1297 {
   1298 	caddr_t ptr = sc->buf_area;	/* memory pool */
   1299 	volatile struct ie_recv_frame_desc *rfd = (void *) ptr;
   1300 	volatile struct ie_recv_buf_desc *rbd;
   1301 	int     n, r;
   1302 
   1303 	/*
   1304 	 * step 0: zero memory and figure out how many recv buffers and
   1305 	 * frames we can have.   XXX CURRENTLY HARDWIRED AT MAX
   1306 	 */
   1307 	(sc->sc_bzero)(ptr, sc->buf_area_sz);
   1308 	ptr = Align(ptr);	/* set alignment and stick with it */
   1309 
   1310 	n = (int)Align(sizeof(struct ie_xmit_cmd)) +
   1311 	    (int)Align(sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE;
   1312 	n *= NTXBUF;		/* n = total size of xmit area */
   1313 
   1314 	n = sc->buf_area_sz - n;/* n = free space for recv stuff */
   1315 
   1316 	r = (int)Align(sizeof(struct ie_recv_frame_desc)) +
   1317 	    (((int)Align(sizeof(struct ie_recv_buf_desc)) + IE_RBUF_SIZE) * B_PER_F);
   1318 
   1319 	/* r = size of one R frame */
   1320 
   1321 	sc->nframes = n / r;
   1322 	if (sc->nframes <= 0)
   1323 		panic("ie: bogus buffer calc\n");
   1324 	if (sc->nframes > MXFRAMES)
   1325 		sc->nframes = MXFRAMES;
   1326 
   1327 	sc->nrxbuf = sc->nframes * B_PER_F;
   1328 
   1329 #ifdef IEDEBUG
   1330 	printf("IEDEBUG: %d frames %d bufs\n", sc->nframes, sc->nrxbuf);
   1331 #endif
   1332 
   1333 	/*
   1334 	 *  step 1a: lay out and zero frame data structures for transmit and recv
   1335 	 */
   1336 	for (n = 0; n < NTXBUF; n++) {
   1337 		sc->xmit_cmds[n] = (volatile struct ie_xmit_cmd *) ptr;
   1338 		ptr = Align(ptr + sizeof(struct ie_xmit_cmd));
   1339 	}
   1340 
   1341 	for (n = 0; n < sc->nframes; n++) {
   1342 		sc->rframes[n] = (volatile struct ie_recv_frame_desc *) ptr;
   1343 		ptr = Align(ptr + sizeof(struct ie_recv_frame_desc));
   1344 	}
   1345 
   1346 	/*
   1347 	 * step 1b: link together the recv frames and set EOL on last one
   1348 	 */
   1349 	for (n = 0; n < sc->nframes; n++) {
   1350 		sc->rframes[n]->ie_fd_next =
   1351 		    MK_16(sc->sc_maddr, sc->rframes[(n + 1) % sc->nframes]);
   1352 	}
   1353 	sc->rframes[sc->nframes - 1]->ie_fd_last |= IE_FD_LAST;
   1354 
   1355 	/*
   1356 	 * step 2a: lay out and zero frame buffer structures for xmit and recv
   1357 	 */
   1358 	for (n = 0; n < NTXBUF; n++) {
   1359 		sc->xmit_buffs[n] = (volatile struct ie_xmit_buf *) ptr;
   1360 		ptr = Align(ptr + sizeof(struct ie_xmit_buf));
   1361 	}
   1362 
   1363 	for (n = 0; n < sc->nrxbuf; n++) {
   1364 		sc->rbuffs[n] = (volatile struct ie_recv_buf_desc *) ptr;
   1365 		ptr = Align(ptr + sizeof(struct ie_recv_buf_desc));
   1366 	}
   1367 
   1368 	/*
   1369 	 * step 2b: link together recv bufs and set EOL on last one
   1370 	 */
   1371 	for (n = 0; n < sc->nrxbuf; n++) {
   1372 		sc->rbuffs[n]->ie_rbd_next =
   1373 		    MK_16(sc->sc_maddr, sc->rbuffs[(n + 1) % sc->nrxbuf]);
   1374 	}
   1375 	sc->rbuffs[sc->nrxbuf - 1]->ie_rbd_length |= IE_RBD_LAST;
   1376 
   1377 	/*
   1378 	 * step 3: allocate the actual data buffers for xmit and recv
   1379 	 * recv buffer gets linked into recv_buf_desc list here
   1380 	 */
   1381 	for (n = 0; n < NTXBUF; n++) {
   1382 		sc->xmit_cbuffs[n] = (u_char *) ptr;
   1383 		ptr = Align(ptr + IE_TBUF_SIZE);
   1384 	}
   1385 
   1386 	/* Pointers to last packet sent and next available transmit buffer. */
   1387 	sc->xchead = sc->xctail = 0;
   1388 
   1389 	/* Clear transmit-busy flag and set number of free transmit buffers. */
   1390 	sc->xmit_busy = 0;
   1391 	sc->xmit_free = NTXBUF;
   1392 
   1393 	for (n = 0; n < sc->nrxbuf; n++) {
   1394 		sc->cbuffs[n] = (char *) ptr;	/* XXX why char vs uchar? */
   1395 		sc->rbuffs[n]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
   1396 		ST_24(sc->rbuffs[n]->ie_rbd_buffer, MK_24(sc->sc_iobase, ptr));
   1397 		ptr = Align(ptr + IE_RBUF_SIZE);
   1398 	}
   1399 
   1400 	/*
   1401 	 * step 4: set the head and tail pointers on receive to keep track of
   1402 	 * the order in which RFDs and RBDs are used.   link in recv frames
   1403 	 * and buffer into the scb.
   1404 	 */
   1405 
   1406 	sc->rfhead = 0;
   1407 	sc->rftail = sc->nframes - 1;
   1408 	sc->rbhead = 0;
   1409 	sc->rbtail = sc->nrxbuf - 1;
   1410 
   1411 	sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
   1412 	sc->rframes[0]->ie_fd_buf_desc = MK_16(sc->sc_maddr, sc->rbuffs[0]);
   1413 
   1414 #ifdef IEDEBUG
   1415 	printf("IE_DEBUG: reserved %d bytes\n", ptr - sc->buf_area);
   1416 #endif
   1417 }
   1418 
   1419 /*
   1420  * Run the multicast setup command.
   1421  * Called at splimp().
   1422  */
   1423 static int
   1424 mc_setup(sc, ptr)
   1425 	struct ie_softc *sc;
   1426 	void *ptr;
   1427 {
   1428 	volatile struct ie_mcast_cmd *cmd = ptr;
   1429 
   1430 	cmd->com.ie_cmd_status = SWAP(0);
   1431 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
   1432 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1433 
   1434 	(sc->sc_bcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
   1435 	    sc->mcast_count * sizeof *sc->mcast_addrs);
   1436 
   1437 	cmd->ie_mcast_bytes =
   1438 		SWAP(sc->mcast_count * ETHER_ADDR_LEN);	/* grrr... */
   1439 
   1440 	sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
   1441 	if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1442 	    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1443 		printf("%s: multicast address setup command failed\n",
   1444 		    sc->sc_dev.dv_xname);
   1445 		return 0;
   1446 	}
   1447 	return 1;
   1448 }
   1449 
   1450 /*
   1451  * This routine inits the ie.
   1452  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
   1453  * starting the receiver unit, and clearing interrupts.
   1454  *
   1455  * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
   1456  */
   1457 int
   1458 ieinit(sc)
   1459 	struct ie_softc *sc;
   1460 {
   1461 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1462 	void *ptr;
   1463 	int     n;
   1464 
   1465 	ptr = sc->buf_area;
   1466 
   1467 	/*
   1468 	 * Send the configure command first.
   1469 	 */
   1470 	{
   1471 		volatile struct ie_config_cmd *cmd = ptr;
   1472 
   1473 		scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
   1474 		cmd->com.ie_cmd_status = SWAP(0);
   1475 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
   1476 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1477 
   1478 		ie_setup_config(cmd, sc->promisc, 0);
   1479 
   1480 		if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1481 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1482 			printf("%s: configure command failed\n",
   1483 			    sc->sc_dev.dv_xname);
   1484 			return 0;
   1485 		}
   1486 	}
   1487 
   1488 	/*
   1489 	 * Now send the Individual Address Setup command.
   1490 	 */
   1491 	{
   1492 		volatile struct ie_iasetup_cmd *cmd = ptr;
   1493 
   1494 		scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
   1495 		cmd->com.ie_cmd_status = SWAP(0);
   1496 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
   1497 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1498 
   1499 		(sc->sc_bcopy)(sc->sc_arpcom.ac_enaddr,
   1500 		    (caddr_t)&cmd->ie_address, sizeof cmd->ie_address);
   1501 
   1502 		if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1503 		    !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
   1504 			printf("%s: individual address setup command failed\n",
   1505 			    sc->sc_dev.dv_xname);
   1506 			return 0;
   1507 		}
   1508 	}
   1509 
   1510 	/*
   1511 	 * Now run the time-domain reflectometer.
   1512 	 */
   1513 	run_tdr(sc, ptr);
   1514 
   1515 	/*
   1516 	 * Acknowledge any interrupts we have generated thus far.
   1517 	 */
   1518 	ie_ack(sc, IE_ST_WHENCE);
   1519 
   1520 	/*
   1521 	 * Set up the transmit and recv buffers.
   1522 	 */
   1523 	setup_bufs(sc);
   1524 
   1525 	/* tell higher levels that we are here */
   1526 	sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING;
   1527 
   1528 	sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
   1529 	command_and_wait(sc, IE_RU_START, 0, 0);
   1530 
   1531 	ie_ack(sc, IE_ST_WHENCE);
   1532 
   1533 	if (sc->run_586)
   1534 		(sc->run_586)(sc);
   1535 
   1536 	return 0;
   1537 }
   1538 
   1539 static void
   1540 iestop(sc)
   1541 	struct ie_softc *sc;
   1542 {
   1543 
   1544 	command_and_wait(sc, IE_RU_DISABLE, 0, 0);
   1545 }
   1546 
   1547 int
   1548 ieioctl(ifp, cmd, data)
   1549 	register struct ifnet *ifp;
   1550 	u_long	cmd;
   1551 	caddr_t data;
   1552 {
   1553 	struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
   1554 	struct ifaddr *ifa = (struct ifaddr *) data;
   1555 	struct ifreq *ifr = (struct ifreq *) data;
   1556 	int     s, error = 0;
   1557 
   1558 	s = splimp();
   1559 
   1560 	switch (cmd) {
   1561 
   1562 	case SIOCSIFADDR:
   1563 		ifp->if_flags |= IFF_UP;
   1564 
   1565 		switch (ifa->ifa_addr->sa_family) {
   1566 #ifdef INET
   1567 		case AF_INET:
   1568 			ieinit(sc);
   1569 			/*
   1570 			 * See if another station has *our* IP address.
   1571 			 * i.e.: There is an address conflict! If a
   1572 			 * conflict exists, a message is sent to the
   1573 			 * console.
   1574 			 */
   1575 			sc->sc_arpcom.ac_ipaddr = IA_SIN(ifa)->sin_addr;
   1576 			arpwhohas(&sc->sc_arpcom, &IA_SIN(ifa)->sin_addr);
   1577 			break;
   1578 #endif
   1579 #ifdef NS
   1580 		/* XXX - This code is probably wrong. */
   1581 		case AF_NS:
   1582 		    {
   1583 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
   1584 
   1585 			if (ns_nullhost(*ina))
   1586 				ina->x_host =
   1587 				    *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
   1588 			else
   1589 				bcopy(ina->x_host.c_host,
   1590 				    sc->sc_arpcom.ac_enaddr,
   1591 				    sizeof(sc->sc_arpcom.ac_enaddr));
   1592 			/* Set new address. */
   1593 			ieinit(sc);
   1594 			break;
   1595 		    }
   1596 #endif /* NS */
   1597 		default:
   1598 			ieinit(sc);
   1599 			break;
   1600 		}
   1601 		break;
   1602 
   1603 	case SIOCSIFFLAGS:
   1604 		sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
   1605 
   1606 		if ((ifp->if_flags & IFF_UP) == 0 &&
   1607 		    (ifp->if_flags & IFF_RUNNING) != 0) {
   1608 			/*
   1609 			 * If interface is marked down and it is running, then
   1610 			 * stop it.
   1611 			 */
   1612 			iestop(sc);
   1613 			ifp->if_flags &= ~IFF_RUNNING;
   1614 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
   1615 			(ifp->if_flags & IFF_RUNNING) == 0) {
   1616 			/*
   1617 			 * If interface is marked up and it is stopped, then
   1618 			 * start it.
   1619 			 */
   1620 			ieinit(sc);
   1621 		} else {
   1622 			/*
   1623 			 * Reset the interface to pick up changes in any other
   1624 			 * flags that affect hardware registers.
   1625 			 */
   1626 			iestop(sc);
   1627 			ieinit(sc);
   1628 		}
   1629 #ifdef IEDEBUG
   1630 		if (ifp->if_flags & IFF_DEBUG)
   1631 			sc->sc_debug = IED_ALL;
   1632 		else
   1633 			sc->sc_debug = 0;
   1634 #endif
   1635 		break;
   1636 
   1637 	case SIOCADDMULTI:
   1638 	case SIOCDELMULTI:
   1639 		error = (cmd == SIOCADDMULTI) ?
   1640 		    ether_addmulti(ifr, &sc->sc_arpcom) :
   1641 		    ether_delmulti(ifr, &sc->sc_arpcom);
   1642 
   1643 		if (error == ENETRESET) {
   1644 			/*
   1645 			 * Multicast list has changed; set the hardware filter
   1646 			 * accordingly.
   1647 			 */
   1648 			mc_reset(sc);
   1649 			error = 0;
   1650 		}
   1651 		break;
   1652 
   1653 	default:
   1654 		error = EINVAL;
   1655 	}
   1656 	splx(s);
   1657 	return error;
   1658 }
   1659 
   1660 static void
   1661 mc_reset(sc)
   1662 	struct ie_softc *sc;
   1663 {
   1664 	struct ether_multi *enm;
   1665 	struct ether_multistep step;
   1666 
   1667 	/*
   1668 	 * Step through the list of addresses.
   1669 	 */
   1670 	sc->mcast_count = 0;
   1671 	ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
   1672 	while (enm) {
   1673 		if (sc->mcast_count >= MAXMCAST ||
   1674 		    bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
   1675 			sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
   1676 			ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, (void *)0);
   1677 			goto setflag;
   1678 		}
   1679 		bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
   1680 		sc->mcast_count++;
   1681 		ETHER_NEXT_MULTI(step, enm);
   1682 	}
   1683 setflag:
   1684 	sc->want_mcsetup = 1;
   1685 }
   1686 
   1687 #ifdef IEDEBUG
   1688 void
   1689 print_rbd(rbd)
   1690 	volatile struct ie_recv_buf_desc *rbd;
   1691 {
   1692 
   1693 	printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
   1694 	    "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
   1695 	    rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
   1696 	    rbd->mbz);
   1697 }
   1698 #endif
   1699