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