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