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