Home | History | Annotate | Line # | Download | only in ic
i82586.c revision 1.48
      1 /*	$NetBSD: i82586.c,v 1.48 2003/11/02 11:07:45 wiz Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Paul Kranenburg and Charles M. Hannum.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*-
     40  * Copyright (c) 1997 Paul Kranenburg.
     41  * Copyright (c) 1992, 1993, University of Vermont and State
     42  *  Agricultural College.
     43  * Copyright (c) 1992, 1993, Garrett A. Wollman.
     44  *
     45  * Portions:
     46  * Copyright (c) 1994, 1995, Rafal K. Boni
     47  * Copyright (c) 1990, 1991, William F. Jolitz
     48  * Copyright (c) 1990, The Regents of the University of California
     49  *
     50  * All rights reserved.
     51  *
     52  * Redistribution and use in source and binary forms, with or without
     53  * modification, are permitted provided that the following conditions
     54  * are met:
     55  * 1. Redistributions of source code must retain the above copyright
     56  *    notice, this list of conditions and the following disclaimer.
     57  * 2. Redistributions in binary form must reproduce the above copyright
     58  *    notice, this list of conditions and the following disclaimer in the
     59  *    documentation and/or other materials provided with the distribution.
     60  * 3. All advertising materials mentioning features or use of this software
     61  *    must display the following acknowledgement:
     62  *	This product includes software developed by the University of Vermont
     63  *	and State Agricultural College and Garrett A. Wollman, by William F.
     64  *	Jolitz, and by the University of California, Berkeley, Lawrence
     65  *	Berkeley Laboratory, and its contributors.
     66  * 4. Neither the names of the Universities nor the names of the authors
     67  *    may be used to endorse or promote products derived from this software
     68  *    without specific prior written permission.
     69  *
     70  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     71  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     72  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     73  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
     74  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     75  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     76  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     77  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     78  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     79  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     80  * SUCH DAMAGE.
     81  */
     82 
     83 /*
     84  * Intel 82586 Ethernet chip
     85  * Register, bit, and structure definitions.
     86  *
     87  * Original StarLAN driver written by Garrett Wollman with reference to the
     88  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
     89  *
     90  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
     91  *
     92  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
     93  *
     94  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
     95  *
     96  * Converted to SUN ie driver by Charles D. Cranor,
     97  *		October 1994, January 1995.
     98  * This sun version based on i386 version 1.30.
     99  */
    100 
    101 /*
    102  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
    103  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
    104  * SUN, making life difficult.  Programming this chip is mostly the same,
    105  * but certain details differ from system to system.  This driver is
    106  * written so that different "ie" interfaces can be controled by the same
    107  * driver.
    108  */
    109 
    110 /*
    111 Mode of operation:
    112 
    113    We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
    114    received frame descriptors around for the receiver to use, and
    115    NRXBUF associated receive buffer descriptors, both in a circular
    116    list.  Whenever a frame is received, we rotate both lists as
    117    necessary.  (The 586 treats both lists as a simple queue.)  We also
    118    keep a transmit command around so that packets can be sent off
    119    quickly.
    120 
    121    We configure the adapter in AL-LOC = 1 mode, which means that the
    122    Ethernet/802.3 MAC header is placed at the beginning of the receive
    123    buffer rather than being split off into various fields in the RFD.
    124    This also means that we must include this header in the transmit
    125    buffer as well.
    126 
    127    By convention, all transmit commands, and only transmit commands,
    128    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
    129    when an interrupt arrives at i82586_intr(), it is immediately possible
    130    to tell what precisely caused it.  ANY OTHER command-sending
    131    routines should run at splnet(), and should post an acknowledgement
    132    to every interrupt they generate.
    133 
    134    To save the expense of shipping a command to 82586 every time we
    135    want to send a frame, we use a linked list of commands consisting
    136    of alternate XMIT and NOP commands. The links of these elements
    137    are manipulated (in iexmit()) such that the NOP command loops back
    138    to itself whenever the following XMIT command is not yet ready to
    139    go. Whenever an XMIT is ready, the preceding NOP link is pointed
    140    at it, while its own link field points to the following NOP command.
    141    Thus, a single transmit command sets off an interlocked traversal
    142    of the xmit command chain, with the host processor in control of
    143    the synchronization.
    144 */
    145 
    146 #include <sys/cdefs.h>
    147 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.48 2003/11/02 11:07:45 wiz Exp $");
    148 
    149 #include "bpfilter.h"
    150 
    151 #include <sys/param.h>
    152 #include <sys/systm.h>
    153 #include <sys/mbuf.h>
    154 #include <sys/socket.h>
    155 #include <sys/ioctl.h>
    156 #include <sys/errno.h>
    157 #include <sys/syslog.h>
    158 #include <sys/device.h>
    159 
    160 #include <net/if.h>
    161 #include <net/if_dl.h>
    162 #include <net/if_types.h>
    163 #include <net/if_media.h>
    164 #include <net/if_ether.h>
    165 
    166 #if NBPFILTER > 0
    167 #include <net/bpf.h>
    168 #include <net/bpfdesc.h>
    169 #endif
    170 
    171 #include <machine/bus.h>
    172 
    173 #include <dev/ic/i82586reg.h>
    174 #include <dev/ic/i82586var.h>
    175 
    176 void	 	i82586_reset 	__P((struct ie_softc *, int));
    177 void 		i82586_watchdog	__P((struct ifnet *));
    178 int 		i82586_init 	__P((struct ifnet *));
    179 int 		i82586_ioctl 	__P((struct ifnet *, u_long, caddr_t));
    180 void 		i82586_start 	__P((struct ifnet *));
    181 void 		i82586_stop 	__P((struct ifnet *, int));
    182 
    183 
    184 int 		i82586_rint 	__P((struct ie_softc *, int));
    185 int 		i82586_tint 	__P((struct ie_softc *, int));
    186 
    187 int     	i82586_mediachange 	__P((struct ifnet *));
    188 void    	i82586_mediastatus 	__P((struct ifnet *,
    189 						struct ifmediareq *));
    190 
    191 static int 	ie_readframe		__P((struct ie_softc *, int));
    192 static struct mbuf *ieget 		__P((struct ie_softc *, int, int));
    193 static int	i82586_get_rbd_list	__P((struct ie_softc *,
    194 					     u_int16_t *, u_int16_t *, int *));
    195 static void	i82586_release_rbd_list	__P((struct ie_softc *,
    196 					     u_int16_t, u_int16_t));
    197 static int	i82586_drop_frames	__P((struct ie_softc *));
    198 static int	i82586_chk_rx_ring	__P((struct ie_softc *));
    199 
    200 static __inline__ void 	ie_ack 		__P((struct ie_softc *, u_int));
    201 static __inline__ void 	iexmit 		__P((struct ie_softc *));
    202 static void 		i82586_start_transceiver
    203 					__P((struct ie_softc *));
    204 
    205 static void	i82586_count_errors	__P((struct ie_softc *));
    206 static void	i82586_rx_errors	__P((struct ie_softc *, int, int));
    207 static void 	i82586_setup_bufs	__P((struct ie_softc *));
    208 static void	setup_simple_command	__P((struct ie_softc *, int, int));
    209 static int 	ie_cfg_setup		__P((struct ie_softc *, int, int, int));
    210 static int	ie_ia_setup		__P((struct ie_softc *, int));
    211 static void 	ie_run_tdr		__P((struct ie_softc *, int));
    212 static int 	ie_mc_setup 		__P((struct ie_softc *, int));
    213 static void 	ie_mc_reset 		__P((struct ie_softc *));
    214 static int 	i82586_start_cmd 	__P((struct ie_softc *,
    215 					    int, int, int, int));
    216 static int	i82586_cmd_wait		__P((struct ie_softc *));
    217 
    218 #if I82586_DEBUG
    219 void 		print_rbd 	__P((struct ie_softc *, int));
    220 #endif
    221 
    222 static char* padbuf = NULL;
    223 
    224 /*
    225  * Front-ends call this function to attach to the MI driver.
    226  *
    227  * The front-end has responsibility for managing the ICP and ISCP
    228  * structures. Both of these are opaque to us.  Also, the front-end
    229  * chooses a location for the SCB which is expected to be addressable
    230  * (through `sc->scb') as an offset against the shared-memory bus handle.
    231  *
    232  * The following MD interface function must be setup by the front-end
    233  * before calling here:
    234  *
    235  *	hwreset			- board dependent reset
    236  *	hwinit			- board dependent initialization
    237  *	chan_attn		- channel attention
    238  *	intrhook		- board dependent interrupt processing
    239  *	memcopyin		- shared memory copy: board to KVA
    240  *	memcopyout		- shared memory copy: KVA to board
    241  *	ie_bus_read16		- read a sixteen-bit i82586 pointer
    242  *	ie_bus_write16		- write a sixteen-bit i82586 pointer
    243  *	ie_bus_write24		- write a twenty-four-bit i82586 pointer
    244  *
    245  */
    246 void
    247 i82586_attach(sc, name, etheraddr, media, nmedia, defmedia)
    248 	struct ie_softc *sc;
    249 	char *name;
    250 	u_int8_t *etheraddr;
    251         int *media, nmedia, defmedia;
    252 {
    253 	int i;
    254 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    255 
    256 	strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
    257 	ifp->if_softc = sc;
    258 	ifp->if_start = i82586_start;
    259 	ifp->if_ioctl = i82586_ioctl;
    260 	ifp->if_init = i82586_init;
    261 	ifp->if_stop = i82586_stop;
    262 	ifp->if_watchdog = i82586_watchdog;
    263 	ifp->if_flags =
    264 		IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
    265 	IFQ_SET_READY(&ifp->if_snd);
    266 
    267         /* Initialize media goo. */
    268         ifmedia_init(&sc->sc_media, 0, i82586_mediachange, i82586_mediastatus);
    269         if (media != NULL) {
    270                 for (i = 0; i < nmedia; i++)
    271                         ifmedia_add(&sc->sc_media, media[i], 0, NULL);
    272                 ifmedia_set(&sc->sc_media, defmedia);
    273         } else {
    274                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
    275                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
    276         }
    277 
    278 	if (padbuf == NULL) {
    279 		padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
    280 		    M_ZERO | M_NOWAIT);
    281 		if (padbuf == NULL) {
    282 			 printf("%s: can't allocate pad buffer\n",
    283 			     sc->sc_dev.dv_xname);
    284 			 return;
    285 		}
    286 	}
    287 
    288 	/* Attach the interface. */
    289 	if_attach(ifp);
    290 	ether_ifattach(ifp, etheraddr);
    291 
    292 	printf(" address %s, type %s\n", ether_sprintf(etheraddr), name);
    293 }
    294 
    295 
    296 /*
    297  * Device timeout/watchdog routine.
    298  * Entered if the device neglects to generate an interrupt after a
    299  * transmit has been started on it.
    300  */
    301 void
    302 i82586_watchdog(ifp)
    303 	struct ifnet *ifp;
    304 {
    305 	struct ie_softc *sc = ifp->if_softc;
    306 
    307 	log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
    308 	++ifp->if_oerrors;
    309 
    310 	i82586_reset(sc, 1);
    311 }
    312 
    313 static int
    314 i82586_cmd_wait(sc)
    315 	struct ie_softc *sc;
    316 {
    317 	/* spin on i82586 command acknowledge; wait at most 0.9 (!) seconds */
    318 	int i, off;
    319 	u_int16_t cmd;
    320 
    321 	for (i = 0; i < 900000; i++) {
    322 		/* Read the command word */
    323 		off = IE_SCB_CMD(sc->scb);
    324 
    325 		IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    326 		if ((cmd = sc->ie_bus_read16(sc, off)) == 0)
    327 			return (0);
    328 		delay(1);
    329 	}
    330 
    331 	off = IE_SCB_STATUS(sc->scb);
    332 	printf("i82586_cmd_wait: timo(%ssync): scb status: 0x%x, cmd: 0x%x\n",
    333 		sc->async_cmd_inprogress?"a":"",
    334 		sc->ie_bus_read16(sc, off), cmd);
    335 
    336 	return (1);	/* Timeout */
    337 }
    338 
    339 /*
    340  * Send a command to the controller and wait for it to either complete
    341  * or be accepted, depending on the command.  If the command pointer
    342  * is null, then pretend that the command is not an action command.
    343  * If the command pointer is not null, and the command is an action
    344  * command, wait for one of the MASK bits to turn on in the command's
    345  * status field.
    346  * If ASYNC is set, we just call the chip's attention and return.
    347  * We may have to wait for the command's acceptance later though.
    348  */
    349 static int
    350 i82586_start_cmd(sc, cmd, iecmdbuf, mask, async)
    351 	struct ie_softc *sc;
    352 	int cmd;
    353 	int iecmdbuf;
    354 	int mask;
    355 	int async;
    356 {
    357 	int i;
    358 	int off;
    359 
    360 	if (sc->async_cmd_inprogress != 0) {
    361 		/*
    362 		 * If previous command was issued asynchronously, wait
    363 		 * for it now.
    364 		 */
    365 		if (i82586_cmd_wait(sc) != 0)
    366 			return (1);
    367 		sc->async_cmd_inprogress = 0;
    368 	}
    369 
    370 	off = IE_SCB_CMD(sc->scb);
    371 	sc->ie_bus_write16(sc, off, cmd);
    372 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
    373 	(sc->chan_attn)(sc, CARD_RESET);
    374 
    375 	if (async != 0) {
    376 		sc->async_cmd_inprogress = 1;
    377 		return (0);
    378 	}
    379 
    380 	if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
    381 		int status;
    382 		/*
    383 		 * Now spin-lock waiting for status.  This is not a very nice
    384 		 * thing to do, and can kill performance pretty well...
    385 		 * According to the packet driver, the minimum timeout
    386 		 * should be .369 seconds.
    387 		 */
    388 		for (i = 0; i < 369000; i++) {
    389 			/* Read the command status */
    390 			off = IE_CMD_COMMON_STATUS(iecmdbuf);
    391 			IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    392 			status = sc->ie_bus_read16(sc, off);
    393 			if (status & mask)
    394 				return (0);
    395 			delay(1);
    396 		}
    397 
    398 	} else {
    399 		/*
    400 		 * Otherwise, just wait for the command to be accepted.
    401 		 */
    402 		return (i82586_cmd_wait(sc));
    403 	}
    404 
    405 	/* Timeout */
    406 	return (1);
    407 }
    408 
    409 /*
    410  * Interrupt Acknowledge.
    411  */
    412 static __inline__ void
    413 ie_ack(sc, mask)
    414 	struct ie_softc *sc;
    415 	u_int mask;	/* in native byte-order */
    416 {
    417 	u_int status;
    418 
    419 	IE_BUS_BARRIER(sc, 0, 0, BUS_SPACE_BARRIER_READ);
    420 	status = sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb));
    421 	i82586_start_cmd(sc, status & mask, 0, 0, 0);
    422 	if (sc->intrhook)
    423 		sc->intrhook(sc, INTR_ACK);
    424 }
    425 
    426 /*
    427  * Transfer accumulated chip error counters to IF.
    428  */
    429 static __inline void
    430 i82586_count_errors(sc)
    431 	struct ie_softc *sc;
    432 {
    433 	int scb = sc->scb;
    434 
    435 	sc->sc_ethercom.ec_if.if_ierrors +=
    436 	    sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
    437 	    sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
    438 	    sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
    439 	    sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb));
    440 
    441 	/* Clear error counters */
    442 	sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
    443 	sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
    444 	sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
    445 	sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
    446 }
    447 
    448 static void
    449 i82586_rx_errors(sc, fn, status)
    450 	struct ie_softc *sc;
    451 	int fn;
    452 	int status;
    453 {
    454 	char bits[128];
    455 
    456 	log(LOG_ERR, "%s: rx error (frame# %d): %s\n", sc->sc_dev.dv_xname, fn,
    457 	    bitmask_snprintf(status, IE_FD_STATUSBITS, bits, sizeof(bits)));
    458 }
    459 
    460 /*
    461  * i82586 interrupt entry point.
    462  */
    463 int
    464 i82586_intr(v)
    465 	void *v;
    466 {
    467 	struct ie_softc *sc = v;
    468 	u_int status;
    469 	int off;
    470 
    471         /*
    472          * Implementation dependent interrupt handling.
    473          */
    474 	if (sc->intrhook)
    475 		(sc->intrhook)(sc, INTR_ENTER);
    476 
    477 	off = IE_SCB_STATUS(sc->scb);
    478 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    479 	status = sc->ie_bus_read16(sc, off) & IE_ST_WHENCE;
    480 
    481 	if ((status & IE_ST_WHENCE) == 0) {
    482 		if (sc->intrhook)
    483 			(sc->intrhook)(sc, INTR_EXIT);
    484 
    485 		return (0);
    486 	}
    487 
    488 loop:
    489 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    490 #if 0
    491 	ie_ack(sc, status & IE_ST_WHENCE);
    492 #endif
    493 	i82586_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1);
    494 
    495 	if (status & (IE_ST_FR | IE_ST_RNR))
    496 		if (i82586_rint(sc, status) != 0)
    497 			goto reset;
    498 
    499 	if (status & IE_ST_CX)
    500 		if (i82586_tint(sc, status) != 0)
    501 			goto reset;
    502 
    503 #if I82586_DEBUG
    504 	if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
    505 		printf("%s: cna; status=0x%x\n", sc->sc_dev.dv_xname, status);
    506 #endif
    507 	if (sc->intrhook)
    508 		(sc->intrhook)(sc, INTR_LOOP);
    509 
    510 	/*
    511 	 * Interrupt ACK was posted asynchronously; wait for
    512 	 * completion here before reading SCB status again.
    513 	 *
    514 	 * If ACK fails, try to reset the chip, in hopes that
    515 	 * it helps.
    516 	 */
    517 	if (i82586_cmd_wait(sc) != 0)
    518 		goto reset;
    519 
    520 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    521 	status = sc->ie_bus_read16(sc, off);
    522 	if ((status & IE_ST_WHENCE) != 0)
    523 		goto loop;
    524 
    525 out:
    526 	if (sc->intrhook)
    527 		(sc->intrhook)(sc, INTR_EXIT);
    528 	return (1);
    529 
    530 reset:
    531 	i82586_cmd_wait(sc);
    532 	i82586_reset(sc, 1);
    533 	goto out;
    534 
    535 }
    536 
    537 /*
    538  * Process a received-frame interrupt.
    539  */
    540 int
    541 i82586_rint(sc, scbstatus)
    542 	struct	ie_softc *sc;
    543 	int	scbstatus;
    544 {
    545 static	int timesthru = 1024;
    546 	int i, status, off;
    547 
    548 #if I82586_DEBUG
    549 	if (sc->sc_debug & IED_RINT)
    550 		printf("%s: rint: status 0x%x\n",
    551 			sc->sc_dev.dv_xname, scbstatus);
    552 #endif
    553 
    554 	for (;;) {
    555 		int drop = 0;
    556 
    557 		i = sc->rfhead;
    558 		off = IE_RFRAME_STATUS(sc->rframes, i);
    559 		IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    560 		status = sc->ie_bus_read16(sc, off);
    561 
    562 #if I82586_DEBUG
    563 		if (sc->sc_debug & IED_RINT)
    564 			printf("%s: rint: frame(%d) status 0x%x\n",
    565 				sc->sc_dev.dv_xname, i, status);
    566 #endif
    567 		if ((status & IE_FD_COMPLETE) == 0) {
    568 			if ((status & IE_FD_OK) != 0) {
    569 				printf("%s: rint: weird: ",
    570 					sc->sc_dev.dv_xname);
    571 				i82586_rx_errors(sc, i, status);
    572 				break;
    573 			}
    574 			if (--timesthru == 0) {
    575 				/* Account the accumulated errors */
    576 				i82586_count_errors(sc);
    577 				timesthru = 1024;
    578 			}
    579 			break;
    580 		} else if ((status & IE_FD_OK) == 0) {
    581 			/*
    582 			 * If the chip is configured to automatically
    583 			 * discard bad frames, the only reason we can
    584 			 * get here is an "out-of-resource" condition.
    585 			 */
    586 			i82586_rx_errors(sc, i, status);
    587 			drop = 1;
    588 		}
    589 
    590 #if I82586_DEBUG
    591 		if ((status & IE_FD_BUSY) != 0)
    592 			printf("%s: rint: frame(%d) busy; status=0x%x\n",
    593 				sc->sc_dev.dv_xname, i, status);
    594 #endif
    595 
    596 
    597 		/*
    598 		 * Advance the RFD list, since we're done with
    599 		 * this descriptor.
    600 		 */
    601 
    602 		/* Clear frame status */
    603 		sc->ie_bus_write16(sc, off, 0);
    604 
    605 		/* Put fence at this frame (the head) */
    606 		off = IE_RFRAME_LAST(sc->rframes, i);
    607 		sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP);
    608 
    609 		/* and clear RBD field */
    610 		off = IE_RFRAME_BUFDESC(sc->rframes, i);
    611 		sc->ie_bus_write16(sc, off, 0xffff);
    612 
    613 		/* Remove fence from current tail */
    614 		off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
    615 		sc->ie_bus_write16(sc, off, 0);
    616 
    617 		if (++sc->rftail == sc->nframes)
    618 			sc->rftail = 0;
    619 		if (++sc->rfhead == sc->nframes)
    620 			sc->rfhead = 0;
    621 
    622 		/* Pull the frame off the board */
    623 		if (drop) {
    624 			i82586_drop_frames(sc);
    625 			if ((status & IE_FD_RNR) != 0)
    626 				sc->rnr_expect = 1;
    627 			sc->sc_ethercom.ec_if.if_ierrors++;
    628 		} else if (ie_readframe(sc, i) != 0)
    629 			return (1);
    630 	}
    631 
    632 	if ((scbstatus & IE_ST_RNR) != 0) {
    633 
    634 		/*
    635 		 * Receiver went "Not Ready". We try to figure out
    636 		 * whether this was an expected event based on past
    637 		 * frame status values.
    638 		 */
    639 
    640 		if ((scbstatus & IE_RUS_SUSPEND) != 0) {
    641 			/*
    642 			 * We use the "suspend on last frame" flag.
    643 			 * Send a RU RESUME command in response, since
    644 			 * we should have dealt with all completed frames
    645 			 * by now.
    646 			 */
    647 			printf("RINT: SUSPENDED; scbstatus=0x%x\n",
    648 				scbstatus);
    649 			if (i82586_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
    650 				return (0);
    651 			printf("%s: RU RESUME command timed out\n",
    652 				sc->sc_dev.dv_xname);
    653 			return (1);	/* Ask for a reset */
    654 		}
    655 
    656 		if (sc->rnr_expect != 0) {
    657 			/*
    658 			 * The RNR condition was announced in the previously
    659 			 * completed frame.  Assume the receive ring is Ok,
    660 			 * so restart the receiver without further delay.
    661 			 */
    662 			i82586_start_transceiver(sc);
    663 			sc->rnr_expect = 0;
    664 			return (0);
    665 
    666 		} else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
    667 			/*
    668 			 * We saw no previous IF_FD_RNR flag.
    669 			 * We check our ring invariants and, if ok,
    670 			 * just restart the receiver at the current
    671 			 * point in the ring.
    672 			 */
    673 			if (i82586_chk_rx_ring(sc) != 0)
    674 				return (1);
    675 
    676 			i82586_start_transceiver(sc);
    677 			sc->sc_ethercom.ec_if.if_ierrors++;
    678 			return (0);
    679 		} else
    680 			printf("%s: receiver not ready; scbstatus=0x%x\n",
    681 				sc->sc_dev.dv_xname, scbstatus);
    682 
    683 		sc->sc_ethercom.ec_if.if_ierrors++;
    684 		return (1);	/* Ask for a reset */
    685 	}
    686 
    687 	return (0);
    688 }
    689 
    690 /*
    691  * Process a command-complete interrupt.  These are only generated by the
    692  * transmission of frames.  This routine is deceptively simple, since most
    693  * of the real work is done by i82586_start().
    694  */
    695 int
    696 i82586_tint(sc, scbstatus)
    697 	struct ie_softc *sc;
    698 	int	scbstatus;
    699 {
    700 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    701 	int status;
    702 
    703 	ifp->if_timer = 0;
    704 	ifp->if_flags &= ~IFF_OACTIVE;
    705 
    706 #if I82586_DEBUG
    707 	if (sc->xmit_busy <= 0) {
    708 	    printf("i82586_tint: WEIRD: xmit_busy=%d, xctail=%d, xchead=%d\n",
    709 		   sc->xmit_busy, sc->xctail, sc->xchead);
    710 		return (0);
    711 	}
    712 #endif
    713 
    714 	status = sc->ie_bus_read16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds,
    715 							  sc->xctail));
    716 
    717 #if I82586_DEBUG
    718 	if (sc->sc_debug & IED_TINT)
    719 		printf("%s: tint: SCB status 0x%x; xmit status 0x%x\n",
    720 			sc->sc_dev.dv_xname, scbstatus, status);
    721 #endif
    722 
    723 	if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) {
    724 	    printf("i82586_tint: command still busy; status=0x%x; tail=%d\n",
    725 		   status, sc->xctail);
    726 	    printf("iestatus = 0x%x\n", scbstatus);
    727 	}
    728 
    729 	if (status & IE_STAT_OK) {
    730 		ifp->if_opackets++;
    731 		ifp->if_collisions += (status & IE_XS_MAXCOLL);
    732 	} else {
    733 		ifp->if_oerrors++;
    734 		/*
    735 		 * Check SQE and DEFERRED?
    736 		 * What if more than one bit is set?
    737 		 */
    738 		if (status & IE_STAT_ABORT)
    739 			printf("%s: send aborted\n", sc->sc_dev.dv_xname);
    740 		else if (status & IE_XS_NOCARRIER)
    741 			printf("%s: no carrier\n", sc->sc_dev.dv_xname);
    742 		else if (status & IE_XS_LOSTCTS)
    743 			printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
    744 		else if (status & IE_XS_UNDERRUN)
    745 			printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
    746 		else if (status & IE_XS_EXCMAX) {
    747 			printf("%s: too many collisions\n",
    748 				sc->sc_dev.dv_xname);
    749 			sc->sc_ethercom.ec_if.if_collisions += 16;
    750 		}
    751 	}
    752 
    753 	/*
    754 	 * If multicast addresses were added or deleted while transmitting,
    755 	 * ie_mc_reset() set the want_mcsetup flag indicating that we
    756 	 * should do it.
    757 	 */
    758 	if (sc->want_mcsetup) {
    759 		ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
    760 		sc->want_mcsetup = 0;
    761 	}
    762 
    763 	/* Done with the buffer. */
    764 	sc->xmit_busy--;
    765 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    766 
    767 	/* Start the next packet, if any, transmitting. */
    768 	if (sc->xmit_busy > 0)
    769 		iexmit(sc);
    770 
    771 	i82586_start(ifp);
    772 	return (0);
    773 }
    774 
    775 /*
    776  * Get a range of receive buffer descriptors that represent one packet.
    777  */
    778 static int
    779 i82586_get_rbd_list(sc, start, end, pktlen)
    780 	struct ie_softc *sc;
    781 	u_int16_t	*start;
    782 	u_int16_t	*end;
    783 	int		*pktlen;
    784 {
    785 	int	off, rbbase = sc->rbds;
    786 	int	rbindex, count = 0;
    787 	int	plen = 0;
    788 	int	rbdstatus;
    789 
    790 	*start = rbindex = sc->rbhead;
    791 
    792 	do {
    793 		off = IE_RBD_STATUS(rbbase, rbindex);
    794 		IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
    795 		rbdstatus = sc->ie_bus_read16(sc, off);
    796 		if ((rbdstatus & IE_RBD_USED) == 0) {
    797 			/*
    798 			 * This means we are somehow out of sync.  So, we
    799 			 * reset the adapter.
    800 			 */
    801 #if I82586_DEBUG
    802 			print_rbd(sc, rbindex);
    803 #endif
    804 			log(LOG_ERR,
    805 			    "%s: receive descriptors out of sync at %d\n",
    806 			    sc->sc_dev.dv_xname, rbindex);
    807 			return (0);
    808 		}
    809 		plen += (rbdstatus & IE_RBD_CNTMASK);
    810 
    811 		if (++rbindex == sc->nrxbuf)
    812 			rbindex = 0;
    813 
    814 		++count;
    815 	} while ((rbdstatus & IE_RBD_LAST) == 0);
    816 	*end = rbindex;
    817 	*pktlen = plen;
    818 	return (count);
    819 }
    820 
    821 
    822 /*
    823  * Release a range of receive buffer descriptors after we've copied the packet.
    824  */
    825 static void
    826 i82586_release_rbd_list(sc, start, end)
    827 	struct ie_softc *sc;
    828 	u_int16_t	start;
    829 	u_int16_t	end;
    830 {
    831 	int	off, rbbase = sc->rbds;
    832 	int	rbindex = start;
    833 
    834 	do {
    835 		/* Clear buffer status */
    836 		off = IE_RBD_STATUS(rbbase, rbindex);
    837 		sc->ie_bus_write16(sc, off, 0);
    838 		if (++rbindex == sc->nrxbuf)
    839 			rbindex = 0;
    840 	} while (rbindex != end);
    841 
    842 	/* Mark EOL at new tail */
    843 	rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
    844 	off = IE_RBD_BUFLEN(rbbase, rbindex);
    845 	sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL);
    846 
    847 	/* Remove EOL from current tail */
    848 	off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
    849 	sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
    850 
    851 	/* New head & tail pointer */
    852 /* hmm, why have both? head is always (tail + 1) % NRXBUF */
    853 	sc->rbhead = end;
    854 	sc->rbtail = rbindex;
    855 }
    856 
    857 /*
    858  * Drop the packet at the head of the RX buffer ring.
    859  * Called if the frame descriptor reports an error on this packet.
    860  * Returns 1 if the buffer descriptor ring appears to be corrupt;
    861  * and 0 otherwise.
    862  */
    863 static int
    864 i82586_drop_frames(sc)
    865 	struct ie_softc *sc;
    866 {
    867 	u_int16_t bstart, bend;
    868 	int pktlen;
    869 
    870 	if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0)
    871 		return (1);
    872 	i82586_release_rbd_list(sc, bstart, bend);
    873 	return (0);
    874 }
    875 
    876 /*
    877  * Check the RX frame & buffer descriptor lists for our invariants,
    878  * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer.
    879  *
    880  * Called when the receive unit has stopped unexpectedly.
    881  * Returns 1 if an inconsistency is detected; 0 otherwise.
    882  *
    883  * The Receive Unit is expected to be NOT RUNNING.
    884  */
    885 static int
    886 i82586_chk_rx_ring(sc)
    887 	struct ie_softc *sc;
    888 {
    889 	int n, off, val;
    890 
    891 	for (n = 0; n < sc->nrxbuf; n++) {
    892 		off = IE_RBD_BUFLEN(sc->rbds, n);
    893 		val = sc->ie_bus_read16(sc, off);
    894 		if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
    895 			/* `rbtail' and EOL flag out of sync */
    896 			log(LOG_ERR,
    897 			    "%s: rx buffer descriptors out of sync at %d\n",
    898 			    sc->sc_dev.dv_xname, n);
    899 			return (1);
    900 		}
    901 
    902 		/* Take the opportunity to clear the status fields here ? */
    903 	}
    904 
    905 	for (n = 0; n < sc->nframes; n++) {
    906 		off = IE_RFRAME_LAST(sc->rframes, n);
    907 		val = sc->ie_bus_read16(sc, off);
    908 		if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) {
    909 			/* `rftail' and EOL flag out of sync */
    910 			log(LOG_ERR,
    911 			    "%s: rx frame list out of sync at %d\n",
    912 			    sc->sc_dev.dv_xname, n);
    913 			return (1);
    914 		}
    915 	}
    916 
    917 	return (0);
    918 }
    919 
    920 /*
    921  * Read data off the interface, and turn it into an mbuf chain.
    922  *
    923  * This code is DRAMATICALLY different from the previous version; this
    924  * version tries to allocate the entire mbuf chain up front, given the
    925  * length of the data available.  This enables us to allocate mbuf
    926  * clusters in many situations where before we would have had a long
    927  * chain of partially-full mbufs.  This should help to speed up the
    928  * operation considerably.  (Provided that it works, of course.)
    929  */
    930 static __inline struct mbuf *
    931 ieget(sc, head, totlen)
    932 	struct ie_softc *sc;
    933 	int head;
    934 	int totlen;
    935 {
    936 	struct mbuf *m, *m0, *newm;
    937 	int len, resid;
    938 	int thisrboff, thismboff;
    939 	struct ether_header eh;
    940 
    941 	/*
    942 	 * Snarf the Ethernet header.
    943 	 */
    944 	(sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
    945 	    sizeof(struct ether_header));
    946 
    947 	resid = totlen;
    948 
    949 	MGETHDR(m0, M_DONTWAIT, MT_DATA);
    950 	if (m0 == 0)
    951 		return (0);
    952 	m0->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if;
    953 	m0->m_pkthdr.len = totlen;
    954 	len = MHLEN;
    955 	m = m0;
    956 
    957 	/*
    958 	 * This loop goes through and allocates mbufs for all the data we will
    959 	 * be copying in.  It does not actually do the copying yet.
    960 	 */
    961 	while (totlen > 0) {
    962 		if (totlen >= MINCLSIZE) {
    963 			MCLGET(m, M_DONTWAIT);
    964 			if ((m->m_flags & M_EXT) == 0)
    965 				goto bad;
    966 			len = MCLBYTES;
    967 		}
    968 
    969 		if (m == m0) {
    970 			caddr_t newdata = (caddr_t)
    971 			    ALIGN(m->m_data + sizeof(struct ether_header)) -
    972 			    sizeof(struct ether_header);
    973 			len -= newdata - m->m_data;
    974 			m->m_data = newdata;
    975 		}
    976 
    977 		m->m_len = len = min(totlen, len);
    978 
    979 		totlen -= len;
    980 		if (totlen > 0) {
    981 			MGET(newm, M_DONTWAIT, MT_DATA);
    982 			if (newm == 0)
    983 				goto bad;
    984 			len = MLEN;
    985 			m = m->m_next = newm;
    986 		}
    987 	}
    988 
    989 	m = m0;
    990 	thismboff = 0;
    991 
    992 	/*
    993 	 * Copy the Ethernet header into the mbuf chain.
    994 	 */
    995 	memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header));
    996 	thismboff = sizeof(struct ether_header);
    997 	thisrboff = sizeof(struct ether_header);
    998 	resid -= sizeof(struct ether_header);
    999 
   1000 	/*
   1001 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
   1002 	 * time) and stuff the data into it.  There are no possible failures
   1003 	 * at or after this point.
   1004 	 */
   1005 	while (resid > 0) {
   1006 		int thisrblen = IE_RBUF_SIZE - thisrboff,
   1007 		    thismblen = m->m_len - thismboff;
   1008 		len = min(thisrblen, thismblen);
   1009 
   1010 		(sc->memcopyin)(sc, mtod(m, caddr_t) + thismboff,
   1011 				IE_RBUF_ADDR(sc,head) + thisrboff,
   1012 				(u_int)len);
   1013 		resid -= len;
   1014 
   1015 		if (len == thismblen) {
   1016 			m = m->m_next;
   1017 			thismboff = 0;
   1018 		} else
   1019 			thismboff += len;
   1020 
   1021 		if (len == thisrblen) {
   1022 			if (++head == sc->nrxbuf)
   1023 				head = 0;
   1024 			thisrboff = 0;
   1025 		} else
   1026 			thisrboff += len;
   1027 	}
   1028 
   1029 	/*
   1030 	 * Unless something changed strangely while we were doing the copy,
   1031 	 * we have now copied everything in from the shared memory.
   1032 	 * This means that we are done.
   1033 	 */
   1034 	return (m0);
   1035 
   1036 bad:
   1037 	m_freem(m0);
   1038 	return (0);
   1039 }
   1040 
   1041 /*
   1042  * Read frame NUM from unit UNIT (pre-cached as IE).
   1043  *
   1044  * This routine reads the RFD at NUM, and copies in the buffers from the list
   1045  * of RBD, then rotates the RBD list so that the receiver doesn't start
   1046  * complaining.  Trailers are DROPPED---there's no point in wasting time
   1047  * on confusing code to deal with them.  Hopefully, this machine will
   1048  * never ARP for trailers anyway.
   1049  */
   1050 static int
   1051 ie_readframe(sc, num)
   1052 	struct ie_softc *sc;
   1053 	int num;		/* frame number to read */
   1054 {
   1055 	struct mbuf *m;
   1056 	u_int16_t bstart, bend;
   1057 	int pktlen;
   1058 
   1059 	if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
   1060 		sc->sc_ethercom.ec_if.if_ierrors++;
   1061 		return (1);
   1062 	}
   1063 
   1064 	m = ieget(sc, bstart, pktlen);
   1065 	i82586_release_rbd_list(sc, bstart, bend);
   1066 
   1067 	if (m == 0) {
   1068 		sc->sc_ethercom.ec_if.if_ierrors++;
   1069 		return (0);
   1070 	}
   1071 
   1072 #if I82586_DEBUG
   1073 	if (sc->sc_debug & IED_READFRAME) {
   1074 		struct ether_header *eh = mtod(m, struct ether_header *);
   1075 
   1076 		printf("%s: frame from ether %s type 0x%x len %d\n",
   1077 			sc->sc_dev.dv_xname,
   1078 			ether_sprintf(eh->ether_shost),
   1079 			(u_int)ntohs(eh->ether_type),
   1080 			pktlen);
   1081 	}
   1082 #endif
   1083 
   1084 #if NBPFILTER > 0
   1085 	/* Check for a BPF filter; if so, hand it up. */
   1086 	if (sc->sc_ethercom.ec_if.if_bpf != 0)
   1087 		/* Pass it up. */
   1088 		bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, m);
   1089 #endif /* NBPFILTER > 0 */
   1090 
   1091 	/*
   1092 	 * Finally pass this packet up to higher layers.
   1093 	 */
   1094 	(*sc->sc_ethercom.ec_if.if_input)(&sc->sc_ethercom.ec_if, m);
   1095 	sc->sc_ethercom.ec_if.if_ipackets++;
   1096 	return (0);
   1097 }
   1098 
   1099 
   1100 /*
   1101  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
   1102  * command to the chip to be executed.
   1103  */
   1104 static __inline__ void
   1105 iexmit(sc)
   1106 	struct ie_softc *sc;
   1107 {
   1108 	int off;
   1109 	int cur, prev;
   1110 
   1111 	cur = sc->xctail;
   1112 
   1113 #if I82586_DEBUG
   1114 	if (sc->sc_debug & IED_XMIT)
   1115 		printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, cur);
   1116 #endif
   1117 
   1118 	/*
   1119 	 * Setup the transmit command.
   1120 	 */
   1121 	sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
   1122 			       IE_XBD_ADDR(sc->xbds, cur));
   1123 
   1124 	sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
   1125 
   1126 	if (sc->do_xmitnopchain) {
   1127 		/*
   1128 		 * Gate this XMIT command to the following NOP
   1129 		 */
   1130 		sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
   1131 				       IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
   1132 		sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
   1133 				       IE_CMD_XMIT | IE_CMD_INTR);
   1134 
   1135 		/*
   1136 		 * Loopback at following NOP
   1137 		 */
   1138 		sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
   1139 		sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
   1140 				       IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
   1141 
   1142 		/*
   1143 		 * Gate preceding NOP to this XMIT command
   1144 		 */
   1145 		prev = (cur + NTXBUF - 1) % NTXBUF;
   1146 		sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0);
   1147 		sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
   1148 				       IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
   1149 
   1150 		off = IE_SCB_STATUS(sc->scb);
   1151 		IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
   1152 		if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
   1153 			printf("iexmit: CU not active\n");
   1154 			i82586_start_transceiver(sc);
   1155 		}
   1156 	} else {
   1157 		sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur),
   1158 				       0xffff);
   1159 
   1160 		sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
   1161 				       IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
   1162 
   1163 		off = IE_SCB_CMDLST(sc->scb);
   1164 		sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
   1165 		IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
   1166 
   1167 		if (i82586_start_cmd(sc, IE_CUC_START, 0, 0, 1))
   1168 			printf("%s: iexmit: start xmit command timed out\n",
   1169 				sc->sc_dev.dv_xname);
   1170 	}
   1171 
   1172 	sc->sc_ethercom.ec_if.if_timer = 5;
   1173 }
   1174 
   1175 
   1176 /*
   1177  * Start transmission on an interface.
   1178  */
   1179 void
   1180 i82586_start(ifp)
   1181 	struct ifnet *ifp;
   1182 {
   1183 	struct ie_softc *sc = ifp->if_softc;
   1184 	struct mbuf *m0, *m;
   1185 	int	buffer, head, xbase;
   1186 	u_short	len;
   1187 	int	s;
   1188 
   1189 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   1190 		return;
   1191 
   1192 	for (;;) {
   1193 		if (sc->xmit_busy == NTXBUF) {
   1194 			ifp->if_flags |= IFF_OACTIVE;
   1195 			break;
   1196 		}
   1197 
   1198 		head = sc->xchead;
   1199 		xbase = sc->xbds;
   1200 
   1201 		IFQ_DEQUEUE(&ifp->if_snd, m0);
   1202 		if (m0 == 0)
   1203 			break;
   1204 
   1205 		/* We need to use m->m_pkthdr.len, so require the header */
   1206 		if ((m0->m_flags & M_PKTHDR) == 0)
   1207 			panic("i82586_start: no header mbuf");
   1208 
   1209 #if NBPFILTER > 0
   1210 		/* Tap off here if there is a BPF listener. */
   1211 		if (ifp->if_bpf)
   1212 			bpf_mtap(ifp->if_bpf, m0);
   1213 #endif
   1214 
   1215 #if I82586_DEBUG
   1216 		if (sc->sc_debug & IED_ENQ)
   1217 			printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
   1218 				sc->xchead);
   1219 #endif
   1220 
   1221 		if (m0->m_pkthdr.len > IE_TBUF_SIZE)
   1222 			printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
   1223 
   1224 		buffer = IE_XBUF_ADDR(sc, head);
   1225 		for (m = m0; m != 0; m = m->m_next) {
   1226 			(sc->memcopyout)(sc, mtod(m,caddr_t), buffer, m->m_len);
   1227 			buffer += m->m_len;
   1228 		}
   1229 		len = m0->m_pkthdr.len;
   1230 		if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
   1231 			(sc->memcopyout)(sc, padbuf, buffer,
   1232 			    ETHER_MIN_LEN - ETHER_CRC_LEN - len);
   1233 			buffer += ETHER_MIN_LEN -ETHER_CRC_LEN - len;
   1234 			len = ETHER_MIN_LEN - ETHER_CRC_LEN;
   1235 		}
   1236 		m_freem(m0);
   1237 
   1238 		/*
   1239 		 * Setup the transmit buffer descriptor here, while we
   1240 		 * know the packet's length.
   1241 		 */
   1242 		sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
   1243 				       len | IE_TBD_EOL);
   1244 		sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
   1245 		sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
   1246 				       IE_XBUF_ADDR(sc, head));
   1247 
   1248 		if (++head == NTXBUF)
   1249 			head = 0;
   1250 		sc->xchead = head;
   1251 
   1252 		s = splnet();
   1253 		/* Start the first packet transmitting. */
   1254 		if (sc->xmit_busy == 0)
   1255 			iexmit(sc);
   1256 
   1257 		sc->xmit_busy++;
   1258 		splx(s);
   1259 	}
   1260 }
   1261 
   1262 /*
   1263  * Probe IE's ram setup   [ Move all this into MD front-end!? ]
   1264  * Use only if SCP and ISCP represent offsets into shared ram space.
   1265  */
   1266 int
   1267 i82586_proberam(sc)
   1268 	struct ie_softc *sc;
   1269 {
   1270 	int result, off;
   1271 
   1272 	/* Put in 16-bit mode */
   1273 	off = IE_SCP_BUS_USE(sc->scp);
   1274 	sc->ie_bus_write16(sc, off, IE_SYSBUS_16BIT);
   1275 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
   1276 
   1277 	/* Set the ISCP `busy' bit */
   1278 	off = IE_ISCP_BUSY(sc->iscp);
   1279 	sc->ie_bus_write16(sc, off, 1);
   1280 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
   1281 
   1282 	if (sc->hwreset)
   1283 		(sc->hwreset)(sc, CHIP_PROBE);
   1284 
   1285 	(sc->chan_attn) (sc, CHIP_PROBE);
   1286 
   1287 	delay(100);		/* wait a while... */
   1288 
   1289 	/* Read back the ISCP `busy' bit; it should be clear by now */
   1290 	off = IE_ISCP_BUSY(sc->iscp);
   1291 	IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
   1292 	result = sc->ie_bus_read16(sc, off) == 0;
   1293 
   1294 	/* Acknowledge any interrupts we may have caused. */
   1295 	ie_ack(sc, IE_ST_WHENCE);
   1296 
   1297 	return (result);
   1298 }
   1299 
   1300 void
   1301 i82586_reset(sc, hard)
   1302 	struct ie_softc *sc;
   1303 	int hard;
   1304 {
   1305 	int s = splnet();
   1306 
   1307 	if (hard)
   1308 		printf("%s: reset\n", sc->sc_dev.dv_xname);
   1309 
   1310 	/* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
   1311 	sc->sc_ethercom.ec_if.if_timer = 0;
   1312 	sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
   1313 
   1314 	/*
   1315 	 * Stop i82586 dead in its tracks.
   1316 	 */
   1317 	if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0))
   1318 		printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
   1319 
   1320 	/*
   1321 	 * This can really slow down the i82586_reset() on some cards, but it's
   1322 	 * necessary to unwedge other ones (eg, the Sun VME ones) from certain
   1323 	 * lockups.
   1324 	 */
   1325 	if (hard && sc->hwreset)
   1326 		(sc->hwreset)(sc, CARD_RESET);
   1327 
   1328 	delay(100);
   1329 	ie_ack(sc, IE_ST_WHENCE);
   1330 
   1331 	if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) {
   1332 		int retries=0;	/* XXX - find out why init sometimes fails */
   1333 		while (retries++ < 2)
   1334 			if (i82586_init(&sc->sc_ethercom.ec_if) == 0)
   1335 				break;
   1336 	}
   1337 
   1338 	splx(s);
   1339 }
   1340 
   1341 
   1342 static void
   1343 setup_simple_command(sc, cmd, cmdbuf)
   1344 	struct ie_softc *sc;
   1345 	int cmd;
   1346 	int cmdbuf;
   1347 {
   1348 	/* Setup a simple command */
   1349 	sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
   1350 	sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
   1351 	sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
   1352 
   1353 	/* Assign the command buffer to the SCB command list */
   1354 	sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
   1355 }
   1356 
   1357 /*
   1358  * Run the time-domain reflectometer.
   1359  */
   1360 static void
   1361 ie_run_tdr(sc, cmd)
   1362 	struct ie_softc *sc;
   1363 	int cmd;
   1364 {
   1365 	int result;
   1366 
   1367 	setup_simple_command(sc, IE_CMD_TDR, cmd);
   1368 	sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0);
   1369 
   1370 	if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
   1371 	    (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0)
   1372 		result = 0x10000; /* XXX */
   1373 	else
   1374 		result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
   1375 
   1376 	/* Squash any pending interrupts */
   1377 	ie_ack(sc, IE_ST_WHENCE);
   1378 
   1379 	if (result & IE_TDR_SUCCESS)
   1380 		return;
   1381 
   1382 	if (result & 0x10000)
   1383 		printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
   1384 	else if (result & IE_TDR_XCVR)
   1385 		printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
   1386 	else if (result & IE_TDR_OPEN)
   1387 		printf("%s: TDR detected incorrect termination %d clocks away\n",
   1388 			sc->sc_dev.dv_xname, result & IE_TDR_TIME);
   1389 	else if (result & IE_TDR_SHORT)
   1390 		printf("%s: TDR detected a short circuit %d clocks away\n",
   1391 			sc->sc_dev.dv_xname, result & IE_TDR_TIME);
   1392 	else
   1393 		printf("%s: TDR returned unknown status 0x%x\n",
   1394 			sc->sc_dev.dv_xname, result);
   1395 }
   1396 
   1397 
   1398 /*
   1399  * i82586_setup_bufs: set up the buffers
   1400  *
   1401  * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1402  * this is to be used for the buffers.  The chip indexs its control data
   1403  * structures with 16 bit offsets, and it indexes actual buffers with
   1404  * 24 bit addresses.   So we should allocate control buffers first so that
   1405  * we don't overflow the 16 bit offset field.   The number of transmit
   1406  * buffers is fixed at compile time.
   1407  *
   1408  */
   1409 static void
   1410 i82586_setup_bufs(sc)
   1411 	struct ie_softc *sc;
   1412 {
   1413 	int	ptr = sc->buf_area;	/* memory pool */
   1414 	int     n, r;
   1415 
   1416 	/*
   1417 	 * step 0: zero memory and figure out how many recv buffers and
   1418 	 * frames we can have.
   1419 	 */
   1420 	ptr = (ptr + 3) & ~3;	/* set alignment and stick with it */
   1421 
   1422 
   1423 	/*
   1424 	 *  step 1: lay out data structures in the shared-memory area
   1425 	 */
   1426 
   1427 	/* The no-op commands; used if "nop-chaining" is in effect */
   1428 	sc->nop_cmds = ptr;
   1429 	ptr += NTXBUF * IE_CMD_NOP_SZ;
   1430 
   1431 	/* The transmit commands */
   1432 	sc->xmit_cmds = ptr;
   1433 	ptr += NTXBUF * IE_CMD_XMIT_SZ;
   1434 
   1435 	/* The transmit buffers descriptors */
   1436 	sc->xbds = ptr;
   1437 	ptr += NTXBUF * IE_XBD_SZ;
   1438 
   1439 	/* The transmit buffers */
   1440 	sc->xbufs = ptr;
   1441 	ptr += NTXBUF * IE_TBUF_SIZE;
   1442 
   1443 	ptr = (ptr + 3) & ~3;		/* re-align.. just in case */
   1444 
   1445 	/* Compute free space for RECV stuff */
   1446 	n = sc->buf_area_sz - (ptr - sc->buf_area);
   1447 
   1448 	/* Compute size of one RECV frame */
   1449 	r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F);
   1450 
   1451 	sc->nframes = n / r;
   1452 
   1453 	if (sc->nframes <= 0)
   1454 		panic("ie: bogus buffer calc");
   1455 
   1456 	sc->nrxbuf = sc->nframes * B_PER_F;
   1457 
   1458 	/* The receive frame descriptors */
   1459 	sc->rframes = ptr;
   1460 	ptr += sc->nframes * IE_RFRAME_SZ;
   1461 
   1462 	/* The receive buffer descriptors */
   1463 	sc->rbds = ptr;
   1464 	ptr += sc->nrxbuf * IE_RBD_SZ;
   1465 
   1466 	/* The receive buffers */
   1467 	sc->rbufs = ptr;
   1468 	ptr += sc->nrxbuf * IE_RBUF_SIZE;
   1469 
   1470 #if I82586_DEBUG
   1471 	printf("%s: %d frames %d bufs\n", sc->sc_dev.dv_xname, sc->nframes,
   1472 		sc->nrxbuf);
   1473 #endif
   1474 
   1475 	/*
   1476 	 * step 2: link together the recv frames and set EOL on last one
   1477 	 */
   1478 	for (n = 0; n < sc->nframes; n++) {
   1479 		int m = (n == sc->nframes - 1) ? 0 : n + 1;
   1480 
   1481 		/* Clear status */
   1482 		sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
   1483 
   1484 		/* RBD link = NULL */
   1485 		sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
   1486 				       0xffff);
   1487 
   1488 		/* Make a circular list */
   1489 		sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
   1490 				       IE_RFRAME_ADDR(sc->rframes,m));
   1491 
   1492 		/* Mark last as EOL */
   1493 		sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
   1494 				       ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
   1495 	}
   1496 
   1497 	/*
   1498 	 * step 3: link the RBDs and set EOL on last one
   1499 	 */
   1500 	for (n = 0; n < sc->nrxbuf; n++) {
   1501 		int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
   1502 
   1503 		/* Clear status */
   1504 		sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
   1505 
   1506 		/* Make a circular list */
   1507 		sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
   1508 				       IE_RBD_ADDR(sc->rbds,m));
   1509 
   1510 		/* Link to data buffers */
   1511 		sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
   1512 				       IE_RBUF_ADDR(sc, n));
   1513 		sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
   1514 				       IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
   1515 	}
   1516 
   1517 	/*
   1518 	 * step 4: all xmit no-op commands loopback onto themselves
   1519 	 */
   1520 	for (n = 0; n < NTXBUF; n++) {
   1521 		sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
   1522 
   1523 		sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
   1524 					 IE_CMD_NOP);
   1525 
   1526 		sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
   1527 					 IE_CMD_NOP_ADDR(sc->nop_cmds, n));
   1528 	}
   1529 
   1530 
   1531 	/*
   1532 	 * step 6: set the head and tail pointers on receive to keep track of
   1533 	 * the order in which RFDs and RBDs are used.
   1534 	 */
   1535 
   1536 	/* Pointers to last packet sent and next available transmit buffer. */
   1537 	sc->xchead = sc->xctail = 0;
   1538 
   1539 	/* Clear transmit-busy flag and set number of free transmit buffers. */
   1540 	sc->xmit_busy = 0;
   1541 
   1542 	/*
   1543 	 * Pointers to first and last receive frame.
   1544 	 * The RFD pointed to by rftail is the only one that has EOL set.
   1545 	 */
   1546 	sc->rfhead = 0;
   1547 	sc->rftail = sc->nframes - 1;
   1548 
   1549 	/*
   1550 	 * Pointers to first and last receive descriptor buffer.
   1551 	 * The RBD pointed to by rbtail is the only one that has EOL set.
   1552 	 */
   1553 	sc->rbhead = 0;
   1554 	sc->rbtail = sc->nrxbuf - 1;
   1555 
   1556 /* link in recv frames * and buffer into the scb. */
   1557 #if I82586_DEBUG
   1558 	printf("%s: reserved %d bytes\n",
   1559 		sc->sc_dev.dv_xname, ptr - sc->buf_area);
   1560 #endif
   1561 }
   1562 
   1563 static int
   1564 ie_cfg_setup(sc, cmd, promiscuous, manchester)
   1565 	struct ie_softc *sc;
   1566 	int cmd;
   1567 	int promiscuous, manchester;
   1568 {
   1569 	int cmdresult, status;
   1570 	u_int8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */
   1571 
   1572 	*IE_CMD_CFG_CNT(buf)       = 0x0c;
   1573 	*IE_CMD_CFG_FIFO(buf)      = 8;
   1574         *IE_CMD_CFG_SAVEBAD(buf)   = 0x40;
   1575 	*IE_CMD_CFG_ADDRLEN(buf)   = 0x2e;
   1576 	*IE_CMD_CFG_PRIORITY(buf)  = 0;
   1577 	*IE_CMD_CFG_IFS(buf)       = 0x60;
   1578 	*IE_CMD_CFG_SLOT_LOW(buf)  = 0;
   1579 	*IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2;
   1580 	*IE_CMD_CFG_PROMISC(buf)   = !!promiscuous | manchester << 2;
   1581 	*IE_CMD_CFG_CRSCDT(buf)    = 0;
   1582 	*IE_CMD_CFG_MINLEN(buf)    = 64;
   1583 	*IE_CMD_CFG_JUNK(buf)      = 0xff;
   1584 	sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ);
   1585 	setup_simple_command(sc, IE_CMD_CONFIG, cmd);
   1586 	IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE);
   1587 
   1588 	cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
   1589 	status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
   1590 	if (cmdresult != 0) {
   1591 		printf("%s: configure command timed out; status %x\n",
   1592 			sc->sc_dev.dv_xname, status);
   1593 		return (0);
   1594 	}
   1595 	if ((status & IE_STAT_OK) == 0) {
   1596 		printf("%s: configure command failed; status %x\n",
   1597 			sc->sc_dev.dv_xname, status);
   1598 		return (0);
   1599 	}
   1600 
   1601 	/* Squash any pending interrupts */
   1602 	ie_ack(sc, IE_ST_WHENCE);
   1603 	return (1);
   1604 }
   1605 
   1606 static int
   1607 ie_ia_setup(sc, cmdbuf)
   1608 	struct ie_softc *sc;
   1609 	int cmdbuf;
   1610 {
   1611 	int cmdresult, status;
   1612 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1613 
   1614 	setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
   1615 
   1616 	(sc->memcopyout)(sc, LLADDR(ifp->if_sadl),
   1617 			 IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
   1618 
   1619 	cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
   1620 	status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
   1621 	if (cmdresult != 0) {
   1622 		printf("%s: individual address command timed out; status %x\n",
   1623 			sc->sc_dev.dv_xname, status);
   1624 		return (0);
   1625 	}
   1626 	if ((status & IE_STAT_OK) == 0) {
   1627 		printf("%s: individual address command failed; status %x\n",
   1628 			sc->sc_dev.dv_xname, status);
   1629 		return (0);
   1630 	}
   1631 
   1632 	/* Squash any pending interrupts */
   1633 	ie_ack(sc, IE_ST_WHENCE);
   1634 	return (1);
   1635 }
   1636 
   1637 /*
   1638  * Run the multicast setup command.
   1639  * Called at splnet().
   1640  */
   1641 static int
   1642 ie_mc_setup(sc, cmdbuf)
   1643 	struct ie_softc *sc;
   1644 	int cmdbuf;
   1645 {
   1646 	int cmdresult, status;
   1647 
   1648 	if (sc->mcast_count == 0)
   1649 		return (1);
   1650 
   1651 	setup_simple_command(sc, IE_CMD_MCAST, cmdbuf);
   1652 
   1653 	(sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs,
   1654 			 IE_CMD_MCAST_MADDR(cmdbuf),
   1655 			 sc->mcast_count * ETHER_ADDR_LEN);
   1656 
   1657 	sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
   1658 			       sc->mcast_count * ETHER_ADDR_LEN);
   1659 
   1660 	/* Start the command */
   1661 	cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
   1662 	status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
   1663 	if (cmdresult != 0) {
   1664 		printf("%s: multicast setup command timed out; status %x\n",
   1665 			sc->sc_dev.dv_xname, status);
   1666 		return (0);
   1667 	}
   1668 	if ((status & IE_STAT_OK) == 0) {
   1669 		printf("%s: multicast setup command failed; status %x\n",
   1670 			sc->sc_dev.dv_xname, status);
   1671 		return (0);
   1672 	}
   1673 
   1674 	/* Squash any pending interrupts */
   1675 	ie_ack(sc, IE_ST_WHENCE);
   1676 	return (1);
   1677 }
   1678 
   1679 /*
   1680  * This routine takes the environment generated by check_ie_present() and adds
   1681  * to it all the other structures we need to operate the adapter.  This
   1682  * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
   1683  * the receiver unit, and clearing interrupts.
   1684  *
   1685  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
   1686  */
   1687 int
   1688 i82586_init(ifp)
   1689 	struct ifnet *ifp;
   1690 {
   1691 	struct ie_softc *sc = ifp->if_softc;
   1692 	int cmd;
   1693 
   1694 	sc->async_cmd_inprogress = 0;
   1695 
   1696 	cmd = sc->buf_area;
   1697 
   1698 	/*
   1699 	 * Send the configure command first.
   1700 	 */
   1701 	if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
   1702 		return EIO;
   1703 
   1704 	/*
   1705 	 * Send the Individual Address Setup command.
   1706 	 */
   1707 	if (ie_ia_setup(sc, cmd) == 0)
   1708 		return EIO;
   1709 
   1710 	/*
   1711 	 * Run the time-domain reflectometer.
   1712 	 */
   1713 	ie_run_tdr(sc, cmd);
   1714 
   1715 	/*
   1716 	 * Set the multi-cast filter, if any
   1717 	 */
   1718 	if (ie_mc_setup(sc, cmd) == 0)
   1719 		return EIO;
   1720 
   1721 	/*
   1722 	 * Acknowledge any interrupts we have generated thus far.
   1723 	 */
   1724 	ie_ack(sc, IE_ST_WHENCE);
   1725 
   1726 	/*
   1727 	 * Set up the transmit and recv buffers.
   1728 	 */
   1729 	i82586_setup_bufs(sc);
   1730 
   1731 	if (sc->hwinit)
   1732 		(sc->hwinit)(sc);
   1733 
   1734 	ifp->if_flags |= IFF_RUNNING;
   1735 	ifp->if_flags &= ~IFF_OACTIVE;
   1736 
   1737 	if (NTXBUF < 2)
   1738 		sc->do_xmitnopchain = 0;
   1739 
   1740 	i82586_start_transceiver(sc);
   1741 	return (0);
   1742 }
   1743 
   1744 /*
   1745  * Start the RU and possibly the CU unit
   1746  */
   1747 static void
   1748 i82586_start_transceiver(sc)
   1749 	struct ie_softc *sc;
   1750 {
   1751 
   1752 	/*
   1753 	 * Start RU at current position in frame & RBD lists.
   1754 	 */
   1755 	sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead),
   1756 			       IE_RBD_ADDR(sc->rbds, sc->rbhead));
   1757 
   1758 	sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
   1759 			       IE_RFRAME_ADDR(sc->rframes,sc->rfhead));
   1760 
   1761 	if (sc->do_xmitnopchain) {
   1762 		/* Stop transmit command chain */
   1763 		if (i82586_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0))
   1764 			printf("%s: CU/RU stop command timed out\n",
   1765 				sc->sc_dev.dv_xname);
   1766 
   1767 		/* Start the receiver & transmitter chain */
   1768 		/* sc->scb->ie_command_list =
   1769 			IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
   1770 		sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
   1771 				   IE_CMD_NOP_ADDR(
   1772 					sc->nop_cmds,
   1773 					(sc->xctail + NTXBUF - 1) % NTXBUF));
   1774 
   1775 		if (i82586_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
   1776 			printf("%s: CU/RU command timed out\n",
   1777 				sc->sc_dev.dv_xname);
   1778 	} else {
   1779 		if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0))
   1780 			printf("%s: RU command timed out\n",
   1781 				sc->sc_dev.dv_xname);
   1782 	}
   1783 }
   1784 
   1785 void
   1786 i82586_stop(ifp, disable)
   1787 	struct ifnet *ifp;
   1788 	int disable;
   1789 {
   1790 	struct ie_softc *sc = ifp->if_softc;
   1791 
   1792 	if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
   1793 		printf("%s: iestop: disable commands timed out\n",
   1794 			sc->sc_dev.dv_xname);
   1795 }
   1796 
   1797 int
   1798 i82586_ioctl(ifp, cmd, data)
   1799 	struct ifnet *ifp;
   1800 	u_long cmd;
   1801 	caddr_t data;
   1802 {
   1803 	struct ie_softc *sc = ifp->if_softc;
   1804 	struct ifreq *ifr = (struct ifreq *)data;
   1805 	int s, error = 0;
   1806 
   1807 	s = splnet();
   1808 	switch(cmd) {
   1809         case SIOCGIFMEDIA:
   1810         case SIOCSIFMEDIA:
   1811                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
   1812                 break;
   1813 	default:
   1814 		error = ether_ioctl(ifp, cmd, data);
   1815 		if (error == ENETRESET) {
   1816 			/*
   1817 			 * Multicast list has changed; set the hardware filter
   1818 			 * accordingly.
   1819 			 */
   1820 			ie_mc_reset(sc);
   1821 			error = 0;
   1822 		}
   1823 		break;
   1824 	}
   1825 #if I82586_DEBUG
   1826 	if (cmd == SIOCSIFFLAGS)
   1827 		sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0;
   1828 #endif
   1829 	splx(s);
   1830 	return (error);
   1831 }
   1832 
   1833 static void
   1834 ie_mc_reset(sc)
   1835 	struct ie_softc *sc;
   1836 {
   1837 	struct ether_multi *enm;
   1838 	struct ether_multistep step;
   1839 	int size;
   1840 
   1841 	/*
   1842 	 * Step through the list of addresses.
   1843 	 */
   1844 again:
   1845 	size = 0;
   1846 	sc->mcast_count = 0;
   1847 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1848 	while (enm) {
   1849 		size += 6;
   1850 		if (sc->mcast_count >= IE_MAXMCAST ||
   1851 		    memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
   1852 			sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
   1853 			i82586_ioctl(&sc->sc_ethercom.ec_if,
   1854 				     SIOCSIFFLAGS, (void *)0);
   1855 			return;
   1856 		}
   1857 		ETHER_NEXT_MULTI(step, enm);
   1858 	}
   1859 
   1860 	if (size > sc->mcast_addrs_size) {
   1861 		/* Need to allocate more space */
   1862 		if (sc->mcast_addrs_size)
   1863 			free(sc->mcast_addrs, M_IFMADDR);
   1864 		sc->mcast_addrs = (char *)
   1865 			malloc(size, M_IFMADDR, M_WAITOK);
   1866 		sc->mcast_addrs_size = size;
   1867 	}
   1868 
   1869 	/*
   1870 	 * We've got the space; now copy the addresses
   1871 	 */
   1872 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1873 	while (enm) {
   1874 		if (sc->mcast_count >= IE_MAXMCAST)
   1875 			goto again; /* Just in case */
   1876 
   1877 		memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6);
   1878 		sc->mcast_count++;
   1879 		ETHER_NEXT_MULTI(step, enm);
   1880 	}
   1881 	sc->want_mcsetup = 1;
   1882 }
   1883 
   1884 /*
   1885  * Media change callback.
   1886  */
   1887 int
   1888 i82586_mediachange(ifp)
   1889         struct ifnet *ifp;
   1890 {
   1891         struct ie_softc *sc = ifp->if_softc;
   1892 
   1893         if (sc->sc_mediachange)
   1894                 return ((*sc->sc_mediachange)(sc));
   1895         return (0);
   1896 }
   1897 
   1898 /*
   1899  * Media status callback.
   1900  */
   1901 void
   1902 i82586_mediastatus(ifp, ifmr)
   1903         struct ifnet *ifp;
   1904         struct ifmediareq *ifmr;
   1905 {
   1906         struct ie_softc *sc = ifp->if_softc;
   1907 
   1908         if (sc->sc_mediastatus)
   1909                 (*sc->sc_mediastatus)(sc, ifmr);
   1910 }
   1911 
   1912 #if I82586_DEBUG
   1913 void
   1914 print_rbd(sc, n)
   1915 	struct ie_softc *sc;
   1916 	int n;
   1917 {
   1918 
   1919 	printf("RBD at %08x:\n  status %04x, next %04x, buffer %lx\n"
   1920 		"length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
   1921 		sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)),
   1922 		sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
   1923 		(u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
   1924 		sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
   1925 }
   1926 #endif
   1927