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