Home | History | Annotate | Line # | Download | only in dev
if_ie.c revision 1.62
      1 /*	$NetBSD: if_ie.c,v 1.62 2017/02/22 09:45:16 nonaka Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1993, 1994, 1995 Charles M. Hannum.
      5  * Copyright (c) 1992, 1993, University of Vermont and State
      6  *  Agricultural College.
      7  * Copyright (c) 1992, 1993, Garrett A. Wollman.
      8  *
      9  * Portions:
     10  * Copyright (c) 1994, 1995, Rafal K. Boni
     11  * Copyright (c) 1990, 1991, William F. Jolitz
     12  * Copyright (c) 1990, The Regents of the University of California
     13  *
     14  * All rights reserved.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by Charles M. Hannum, by the
     27  *	University of Vermont and State Agricultural College and Garrett A.
     28  *	Wollman, by William F. Jolitz, and by the University of California,
     29  *	Berkeley, Lawrence Berkeley Laboratory, and its contributors.
     30  * 4. Neither the names of the Universities nor the names of the authors
     31  *    may be used to endorse or promote products derived from this software
     32  *    without specific prior written permission.
     33  *
     34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
     38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     44  * SUCH DAMAGE.
     45  */
     46 
     47 /*
     48  * Intel 82586 Ethernet chip
     49  * Register, bit, and structure definitions.
     50  *
     51  * Original StarLAN driver written by Garrett Wollman with reference to the
     52  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
     53  *
     54  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
     55  *
     56  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
     57  *
     58  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
     59  *
     60  * Converted to SUN ie driver by Charles D. Cranor,
     61  *		October 1994, January 1995.
     62  * This sun version based on i386 version 1.30.
     63  * [ see sys/dev/isa/if_ie.c ]
     64  */
     65 
     66 /*
     67  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
     68  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
     69  * SUN, making life difficult.  Programming this chip is mostly the same,
     70  * but certain details differ from system to system.  This driver is
     71  * written so that different "ie" interfaces can be controled by the same
     72  * driver.
     73  */
     74 
     75 /*
     76    Mode of operation:
     77 
     78    We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
     79    received frame descriptors around for the receiver to use, and
     80    NRXBUF associated receive buffer descriptors, both in a circular
     81    list.  Whenever a frame is received, we rotate both lists as
     82    necessary.  (The 586 treats both lists as a simple queue.)  We also
     83    keep a transmit command around so that packets can be sent off
     84    quickly.
     85 
     86    We configure the adapter in AL-LOC = 1 mode, which means that the
     87    Ethernet/802.3 MAC header is placed at the beginning of the receive
     88    buffer rather than being split off into various fields in the RFD.
     89    This also means that we must include this header in the transmit
     90    buffer as well.
     91 
     92    By convention, all transmit commands, and only transmit commands,
     93    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
     94    when an interrupt arrives at ieintr(), it is immediately possible
     95    to tell what precisely caused it.  ANY OTHER command-sending
     96    routines should run at splnet(), and should post an acknowledgement
     97    to every interrupt they generate.
     98 */
     99 
    100 #include <sys/cdefs.h>
    101 __KERNEL_RCSID(0, "$NetBSD: if_ie.c,v 1.62 2017/02/22 09:45:16 nonaka Exp $");
    102 
    103 #include "opt_inet.h"
    104 #include "opt_ns.h"
    105 
    106 #include <sys/param.h>
    107 #include <sys/systm.h>
    108 #include <sys/mbuf.h>
    109 #include <sys/buf.h>
    110 #include <sys/protosw.h>
    111 #include <sys/socket.h>
    112 #include <sys/ioctl.h>
    113 #include <sys/errno.h>
    114 #include <sys/syslog.h>
    115 #include <sys/device.h>
    116 
    117 #include <net/if.h>
    118 #include <net/if_types.h>
    119 #include <net/if_dl.h>
    120 #include <net/if_ether.h>
    121 
    122 #include <net/bpf.h>
    123 #include <net/bpfdesc.h>
    124 
    125 #ifdef INET
    126 #include <netinet/in.h>
    127 #include <netinet/in_systm.h>
    128 #include <netinet/in_var.h>
    129 #include <netinet/ip.h>
    130 #include <netinet/if_inarp.h>
    131 #endif
    132 
    133 #include <uvm/uvm_extern.h>
    134 
    135 #include <machine/autoconf.h>
    136 #include <machine/cpu.h>
    137 #include <machine/pmap.h>
    138 
    139 /*
    140  * ugly byte-order hack for SUNs
    141  */
    142 
    143 #define XSWAP(y)	( (((y) & 0xff00) >> 8) | (((y) & 0xff) << 8) )
    144 #define SWAP(x)		((u_short)(XSWAP((u_short)(x))))
    145 
    146 #include "i82586.h"
    147 #include "if_iereg.h"
    148 #include "if_ievar.h"
    149 
    150 /* #define	IEDEBUG	XXX */
    151 
    152 /*
    153  * IED: ie debug flags
    154  */
    155 
    156 #define	IED_RINT	0x01
    157 #define	IED_TINT	0x02
    158 #define	IED_RNR		0x04
    159 #define	IED_CNA		0x08
    160 #define	IED_READFRAME	0x10
    161 #define	IED_ENQ		0x20
    162 #define	IED_XMIT	0x40
    163 #define	IED_ALL		0x7f
    164 
    165 #ifdef	IEDEBUG
    166 #define	inline	/* not */
    167 void print_rbd(volatile struct ie_recv_buf_desc *);
    168 int     in_ierint = 0;
    169 int     in_ietint = 0;
    170 int     ie_debug_flags = 0;
    171 #endif
    172 
    173 /* XXX - Skip TDR for now - it always complains... */
    174 int 	ie_run_tdr = 0;
    175 
    176 static void iewatchdog(struct ifnet *);
    177 static int ieinit(struct ie_softc *);
    178 static int ieioctl(struct ifnet *, u_long, void *);
    179 static void iestart(struct ifnet *);
    180 static void iereset(struct ie_softc *);
    181 static int ie_setupram(struct ie_softc *);
    182 
    183 static int cmd_and_wait(struct ie_softc *, int, void *, int);
    184 
    185 static void ie_drop_packet_buffer(struct ie_softc *);
    186 static void ie_readframe(struct ie_softc *, int);
    187 static inline void ie_setup_config(struct ie_config_cmd *, int, int);
    188 
    189 static void ierint(struct ie_softc *);
    190 static void iestop(struct ie_softc *);
    191 static void ietint(struct ie_softc *);
    192 static void iexmit(struct ie_softc *);
    193 
    194 static int mc_setup(struct ie_softc *, void *);
    195 static void mc_reset(struct ie_softc *);
    196 static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *);
    197 static void iememinit(struct ie_softc *);
    198 
    199 static inline uint8_t *Align(char *);
    200 static inline u_int Swap32(u_int);
    201 static inline u_int vtop24(struct ie_softc *, void *);
    202 static inline uint16_t vtop16sw(struct ie_softc *, void *);
    203 
    204 static inline void ie_ack(struct ie_softc *, u_int);
    205 static inline u_short ether_cmp(u_char *, uint8_t *);
    206 static inline int ie_buflen(struct ie_softc *, int);
    207 static inline int ie_packet_len(struct ie_softc *);
    208 static inline struct mbuf * ieget(struct ie_softc *);
    209 
    210 
    211 /*
    212  * Here are a few useful functions.  We could have done these as macros,
    213  * but since we have the inline facility, it makes sense to use that
    214  * instead.
    215  */
    216 
    217 /* KVA to 24 bit device address */
    218 static inline u_int
    219 vtop24(struct ie_softc *sc, void *ptr)
    220 {
    221 	u_int pa;
    222 
    223 	pa = (vaddr_t)ptr - (vaddr_t)sc->sc_iobase;
    224 #ifdef	IEDEBUG
    225 	if (pa & ~0xffFFff)
    226 		panic("ie:vtop24");
    227 #endif
    228 	return pa;
    229 }
    230 
    231 /* KVA to 16 bit offset, swapped */
    232 static inline u_short
    233 vtop16sw(struct ie_softc *sc, void *ptr)
    234 {
    235 	u_int pa;
    236 
    237 	pa = (vaddr_t)ptr - (vaddr_t)sc->sc_maddr;
    238 #ifdef	IEDEBUG
    239 	if (pa & ~0xFFff)
    240 		panic("ie:vtop16");
    241 #endif
    242 
    243 	return SWAP(pa);
    244 }
    245 
    246 static inline u_int
    247 Swap32(u_int x)
    248 {
    249 	u_int y;
    250 
    251 	y = x & 0xFF;
    252 	y <<= 8; x >>= 8;
    253 	y |= x & 0xFF;
    254 	y <<= 8; x >>= 8;
    255 	y |= x & 0xFF;
    256 	y <<= 8; x >>= 8;
    257 	y |= x & 0xFF;
    258 
    259 	return y;
    260 }
    261 
    262 static inline uint8_t *
    263 Align(char *ptr)
    264 {
    265 	u_long  l = (u_long)ptr;
    266 
    267 	l = (l + 3) & ~3L;
    268 	return (uint8_t *)l;
    269 }
    270 
    271 
    272 static inline void
    273 ie_ack(struct ie_softc *sc, u_int mask)
    274 {
    275 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    276 
    277 	cmd_and_wait(sc, scb->ie_status & mask, 0, 0);
    278 }
    279 
    280 
    281 /*
    282  * Taken almost exactly from Bill's if_is.c,
    283  * then modified beyond recognition...
    284  */
    285 void
    286 ie_attach(struct ie_softc *sc)
    287 {
    288 	struct ifnet *ifp = &sc->sc_if;
    289 
    290 	/* MD code has done its part before calling this. */
    291 	printf(": macaddr %s\n", ether_sprintf(sc->sc_addr));
    292 
    293 	/*
    294 	 * Compute number of transmit and receive buffers.
    295 	 * Tx buffers take 1536 bytes, and fixed in number.
    296 	 * Rx buffers are 512 bytes each, variable number.
    297 	 * Need at least 1 frame for each 3 rx buffers.
    298 	 * The ratio 3bufs:2frames is a compromise.
    299 	 */
    300 	sc->ntxbuf = NTXBUF;	/* XXX - Fix me... */
    301 	switch (sc->sc_msize) {
    302 	case 16384:
    303 		sc->nframes = 8 * 4;
    304 		sc->nrxbuf  = 8 * 6;
    305 		break;
    306 	case 32768:
    307 		sc->nframes = 16 * 4;
    308 		sc->nrxbuf  = 16 * 6;
    309 		break;
    310 	case 65536:
    311 		sc->nframes = 32 * 4;
    312 		sc->nrxbuf  = 32 * 6;
    313 		break;
    314 	default:
    315 		sc->nframes = 0;
    316 	}
    317 	if (sc->nframes > MXFRAMES)
    318 		sc->nframes = MXFRAMES;
    319 	if (sc->nrxbuf > MXRXBUF)
    320 		sc->nrxbuf = MXRXBUF;
    321 
    322 #ifdef	IEDEBUG
    323 	aprint_debug_dev(sc->sc_dev,
    324 	    "%dK memory, %d tx frames, %d rx frames, %d rx bufs\n",
    325 	    (sc->sc_msize >> 10), sc->ntxbuf, sc->nframes, sc->nrxbuf);
    326 #endif
    327 
    328 	if ((sc->nframes <= 0) || (sc->nrxbuf <= 0))
    329 		panic("%s: weird memory size", __func__);
    330 
    331 	/*
    332 	 * Setup RAM for transmit/receive
    333 	 */
    334 	if (ie_setupram(sc) == 0) {
    335 		aprint_error(": RAM CONFIG FAILED!\n");
    336 		/* XXX should reclaim resources? */
    337 		return;
    338 	}
    339 
    340 	/*
    341 	 * Initialize and attach S/W interface
    342 	 */
    343 	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
    344 	ifp->if_softc = sc;
    345 	ifp->if_start = iestart;
    346 	ifp->if_ioctl = ieioctl;
    347 	ifp->if_watchdog = iewatchdog;
    348 	ifp->if_flags =
    349 	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
    350 
    351 	/* Attach the interface. */
    352 	if_attach(ifp);
    353 	if_deferred_start_init(ifp, NULL);
    354 	ether_ifattach(ifp, sc->sc_addr);
    355 }
    356 
    357 /*
    358  * Setup IE's ram space.
    359  */
    360 static int
    361 ie_setupram(struct ie_softc *sc)
    362 {
    363 	volatile struct ie_sys_conf_ptr *scp;
    364 	volatile struct ie_int_sys_conf_ptr *iscp;
    365 	volatile struct ie_sys_ctl_block *scb;
    366 	int off;
    367 
    368 	/*
    369 	 * Allocate from end of buffer space for
    370 	 * ISCP, SCB, and other small stuff.
    371 	 */
    372 	off = sc->buf_area_sz;
    373 	off &= ~3;
    374 
    375 	/* SCP (address already chosen). */
    376 	scp = sc->scp;
    377 	(sc->sc_memset)(__UNVOLATILE(scp), 0, sizeof(*scp));
    378 
    379 	/* ISCP */
    380 	off -= sizeof(*iscp);
    381 	iscp = (volatile void *)(sc->buf_area + off);
    382 	(sc->sc_memset)(__UNVOLATILE(iscp), 0, sizeof(*iscp));
    383 	sc->iscp = iscp;
    384 
    385 	/* SCB */
    386 	off -= sizeof(*scb);
    387 	scb  = (volatile void *)(sc->buf_area + off);
    388 	(sc->sc_memset)(__UNVOLATILE(scb), 0, sizeof(*scb));
    389 	sc->scb = scb;
    390 
    391 	/* Remainder is for buffers, etc. */
    392 	sc->buf_area_sz = off;
    393 
    394 	/*
    395 	 * Now fill in the structures we just allocated.
    396 	 */
    397 
    398 	/* SCP: main thing is 24-bit ptr to ISCP */
    399 	scp->ie_bus_use = 0;	/* 16-bit */
    400 	scp->ie_iscp_ptr = Swap32(vtop24(sc, __UNVOLATILE(iscp)));
    401 
    402 	/* ISCP */
    403 	iscp->ie_busy = 1;	/* ie_busy == char */
    404 	iscp->ie_scb_offset = vtop16sw(sc, __UNVOLATILE(scb));
    405 	iscp->ie_base = Swap32(vtop24(sc, sc->sc_maddr));
    406 
    407 	/* SCB */
    408 	scb->ie_command_list = SWAP(0xffff);
    409 	scb->ie_recv_list    = SWAP(0xffff);
    410 
    411 	/* Other stuff is done in ieinit() */
    412 	(sc->reset_586)(sc);
    413 	(sc->chan_attn)(sc);
    414 
    415 	delay(100);		/* wait a while... */
    416 
    417 	if (iscp->ie_busy) {
    418 		return 0;
    419 	}
    420 	/*
    421 	 * Acknowledge any interrupts we may have caused...
    422 	 */
    423 	ie_ack(sc, IE_ST_WHENCE);
    424 
    425 	return 1;
    426 }
    427 
    428 /*
    429  * Device timeout/watchdog routine.  Entered if the device neglects to
    430  * generate an interrupt after a transmit has been started on it.
    431  */
    432 static void
    433 iewatchdog(struct ifnet *ifp)
    434 {
    435 	struct ie_softc *sc = ifp->if_softc;
    436 
    437 	log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
    438 	++ifp->if_oerrors;
    439 	iereset(sc);
    440 }
    441 
    442 /*
    443  * What to do upon receipt of an interrupt.
    444  */
    445 int
    446 ie_intr(void *arg)
    447 {
    448 	struct ie_softc *sc = arg;
    449 	uint16_t status;
    450 	int loopcnt;
    451 
    452 	/*
    453 	 * check for parity error
    454 	 */
    455 	if (sc->hard_type == IE_VME) {
    456 		volatile struct ievme *iev =
    457 		    (volatile struct ievme *)sc->sc_reg;
    458 
    459 		if (iev->status & IEVME_PERR) {
    460 			printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
    461 			    device_xname(sc->sc_dev), iev->pectrl,
    462 			    iev->pectrl & IEVME_HADDR, iev->peaddr);
    463 			iev->pectrl = iev->pectrl | IEVME_PARACK;
    464 		}
    465 	}
    466 
    467 	status = sc->scb->ie_status;
    468 	if ((status & IE_ST_WHENCE) == 0)
    469 		return 0;
    470 
    471 	loopcnt = sc->nframes;
    472  loop:
    473 	/* Ack interrupts FIRST in case we receive more during the ISR. */
    474 	ie_ack(sc, IE_ST_WHENCE & status);
    475 
    476 	if (status & (IE_ST_RECV | IE_ST_RNR)) {
    477 #ifdef IEDEBUG
    478 		in_ierint++;
    479 		if (sc->sc_debug & IED_RINT)
    480 			printf("%s: rint\n", device_xname(sc->sc_dev));
    481 #endif
    482 		ierint(sc);
    483 #ifdef IEDEBUG
    484 		in_ierint--;
    485 #endif
    486 	}
    487 
    488 	if (status & IE_ST_DONE) {
    489 #ifdef IEDEBUG
    490 		in_ietint++;
    491 		if (sc->sc_debug & IED_TINT)
    492 			printf("%s: tint\n", device_xname(sc->sc_dev));
    493 #endif
    494 		ietint(sc);
    495 #ifdef IEDEBUG
    496 		in_ietint--;
    497 #endif
    498 	}
    499 
    500 	/*
    501 	 * Receiver not ready (RNR) just means it has
    502 	 * run out of resources (buffers or frames).
    503 	 * One can easily cause this with (i.e.) spray.
    504 	 * This is not a serious error, so be silent.
    505 	 */
    506 	if (status & IE_ST_RNR) {
    507 #ifdef IEDEBUG
    508 		printf("%s: receiver not ready\n", device_xname(sc->sc_dev));
    509 #endif
    510 		sc->sc_if.if_ierrors++;
    511 		iereset(sc);
    512 	}
    513 
    514 #ifdef IEDEBUG
    515 	if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
    516 		printf("%s: cna\n", device_xname(sc->sc_dev));
    517 #endif
    518 
    519 	status = sc->scb->ie_status;
    520 	if (status & IE_ST_WHENCE) {
    521 		/* It still wants service... */
    522 		if (--loopcnt > 0)
    523 			goto loop;
    524 		/* ... but we've been here long enough. */
    525 		log(LOG_ERR, "%s: interrupt stuck?\n",
    526 		    device_xname(sc->sc_dev));
    527 		iereset(sc);
    528 	}
    529 	return 1;
    530 }
    531 
    532 /*
    533  * Process a received-frame interrupt.
    534  */
    535 void
    536 ierint(struct ie_softc *sc)
    537 {
    538 	volatile struct ie_sys_ctl_block *scb = sc->scb;
    539 	int i, status;
    540 	static int timesthru = 1024;
    541 
    542 	i = sc->rfhead;
    543 	for (;;) {
    544 		status = sc->rframes[i]->ie_fd_status;
    545 
    546 		if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
    547 			if (!--timesthru) {
    548 				sc->sc_if.if_ierrors +=
    549 				    SWAP(scb->ie_err_crc) +
    550 				    SWAP(scb->ie_err_align) +
    551 				    SWAP(scb->ie_err_resource) +
    552 				    SWAP(scb->ie_err_overrun);
    553 				scb->ie_err_crc = 0;
    554 				scb->ie_err_align = 0;
    555 				scb->ie_err_resource = 0;
    556 				scb->ie_err_overrun = 0;
    557 				timesthru = 1024;
    558 			}
    559 			ie_readframe(sc, i);
    560 		} else {
    561 			if ((status & IE_FD_RNR) != 0 &&
    562 			    (scb->ie_status & IE_RU_READY) == 0) {
    563 				sc->rframes[0]->ie_fd_buf_desc = vtop16sw(sc,
    564 				    __UNVOLATILE(sc->rbuffs[0]));
    565 				scb->ie_recv_list = vtop16sw(sc,
    566 				    __UNVOLATILE(sc->rframes[0]));
    567 				cmd_and_wait(sc, IE_RU_START, 0, 0);
    568 			}
    569 			break;
    570 		}
    571 		i = (i + 1) % sc->nframes;
    572 	}
    573 }
    574 
    575 /*
    576  * Process a command-complete interrupt.  These are only generated by the
    577  * transmission of frames.  This routine is deceptively simple, since most
    578  * of the real work is done by iestart().
    579  */
    580 void
    581 ietint(struct ie_softc *sc)
    582 {
    583 	struct ifnet *ifp;
    584 	int status;
    585 
    586 	ifp = &sc->sc_if;
    587 
    588 	ifp->if_timer = 0;
    589 	ifp->if_flags &= ~IFF_OACTIVE;
    590 
    591 	status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
    592 
    593 	if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
    594 		printf("%s: command still busy!\n", __func__);
    595 
    596 	if (status & IE_STAT_OK) {
    597 		ifp->if_opackets++;
    598 		ifp->if_collisions +=
    599 		  SWAP(status & IE_XS_MAXCOLL);
    600 	} else {
    601 		ifp->if_oerrors++;
    602 		/*
    603 		 * XXX
    604 		 * Check SQE and DEFERRED?
    605 		 * What if more than one bit is set?
    606 		 */
    607 		if (status & IE_STAT_ABORT)
    608 			printf("%s: send aborted\n", device_xname(sc->sc_dev));
    609 		if (status & IE_XS_LATECOLL)
    610 			printf("%s: late collision\n",
    611 			    device_xname(sc->sc_dev));
    612 		if (status & IE_XS_NOCARRIER)
    613 			printf("%s: no carrier\n", device_xname(sc->sc_dev));
    614 		if (status & IE_XS_LOSTCTS)
    615 			printf("%s: lost CTS\n", device_xname(sc->sc_dev));
    616 		if (status & IE_XS_UNDERRUN)
    617 			printf("%s: DMA underrun\n", device_xname(sc->sc_dev));
    618 		if (status & IE_XS_EXCMAX) {
    619 			/* Do not print this one (too noisy). */
    620 			ifp->if_collisions += 16;
    621 		}
    622 	}
    623 
    624 	/*
    625 	 * If multicast addresses were added or deleted while we
    626 	 * were transmitting, mc_reset() set the want_mcsetup flag
    627 	 * indicating that we should do it.
    628 	 */
    629 	if (sc->want_mcsetup) {
    630 		mc_setup(sc, (void *)sc->xmit_cbuffs[sc->xctail]);
    631 		sc->want_mcsetup = 0;
    632 	}
    633 
    634 	/* Done with the buffer. */
    635 	sc->xmit_busy--;
    636 	sc->xctail = (sc->xctail + 1) % NTXBUF;
    637 
    638 	/* Start the next packet, if any, transmitting. */
    639 	if (sc->xmit_busy > 0)
    640 		iexmit(sc);
    641 
    642 	if_schedule_deferred_start(ifp);
    643 }
    644 
    645 /*
    646  * Compare two Ether/802 addresses for equality, inlined and
    647  * unrolled for speed.  I'd love to have an inline assembler
    648  * version of this...   XXX: Who wanted that? mycroft?
    649  * I wrote one, but the following is just as efficient.
    650  * This expands to 10 short m68k instructions! -gwr
    651  * Note: use this like memcmp()
    652  */
    653 static inline uint16_t
    654 ether_cmp(uint8_t *one, uint8_t *two)
    655 {
    656 	uint16_t *a = (uint16_t *)one;
    657 	uint16_t *b = (uint16_t *)two;
    658 	uint16_t diff;
    659 
    660 	diff  = *a++ - *b++;
    661 	diff |= *a++ - *b++;
    662 	diff |= *a++ - *b++;
    663 
    664 	return diff;
    665 }
    666 #define	ether_equal !ether_cmp
    667 
    668 /*
    669  * We want to isolate the bits that have meaning...  This assumes that
    670  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
    671  * the size of the buffer, then we are screwed anyway.
    672  */
    673 static inline int
    674 ie_buflen(struct ie_softc *sc, int head)
    675 {
    676 	int len;
    677 
    678 	len = SWAP(sc->rbuffs[head]->ie_rbd_actual);
    679 	len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1));
    680 	return len;
    681 }
    682 
    683 static inline int
    684 ie_packet_len(struct ie_softc *sc)
    685 {
    686 	int i;
    687 	int head = sc->rbhead;
    688 	int acc = 0;
    689 
    690 	do {
    691 		if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
    692 		    == 0) {
    693 #ifdef IEDEBUG
    694 			print_rbd(sc->rbuffs[sc->rbhead]);
    695 #endif
    696 			log(LOG_ERR,
    697 			    "%s: receive descriptors out of sync at %d\n",
    698 			    device_xname(sc->sc_dev), sc->rbhead);
    699 			iereset(sc);
    700 			return -1;
    701 		}
    702 
    703 		i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
    704 
    705 		acc += ie_buflen(sc, head);
    706 		head = (head + 1) % sc->nrxbuf;
    707 	} while (i == 0);
    708 
    709 	return acc;
    710 }
    711 
    712 /*
    713  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
    714  * command to the chip to be executed.  On the way, if we have a BPF listener
    715  * also give him a copy.
    716  */
    717 static void
    718 iexmit(struct ie_softc *sc)
    719 {
    720 	struct ifnet *ifp;
    721 
    722 	ifp = &sc->sc_if;
    723 
    724 #ifdef IEDEBUG
    725 	if (sc->sc_debug & IED_XMIT)
    726 		printf("%s: xmit buffer %d\n", device_xname(sc->sc_dev),
    727 		    sc->xctail);
    728 #endif
    729 
    730 	/*
    731 	 * If BPF is listening on this interface, let it see the packet before
    732 	 * we push it on the wire.
    733 	 */
    734 	bpf_tap(ifp, sc->xmit_cbuffs[sc->xctail],
    735 	    SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
    736 
    737 	sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
    738 	sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
    739 	sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
    740 	    Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail]));
    741 
    742 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
    743 	sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
    744 	    IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
    745 
    746 	sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
    747 	sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
    748 	    vtop16sw(sc, __UNVOLATILE(sc->xmit_buffs[sc->xctail]));
    749 
    750 	sc->scb->ie_command_list =
    751 	    vtop16sw(sc, __UNVOLATILE(sc->xmit_cmds[sc->xctail]));
    752 	cmd_and_wait(sc, IE_CU_START, 0, 0);
    753 
    754 	ifp->if_timer = 5;
    755 }
    756 
    757 /*
    758  * Read data off the interface, and turn it into an mbuf chain.
    759  *
    760  * This code is DRAMATICALLY different from the previous version; this
    761  * version tries to allocate the entire mbuf chain up front, given the
    762  * length of the data available.  This enables us to allocate mbuf
    763  * clusters in many situations where before we would have had a long
    764  * chain of partially-full mbufs.  This should help to speed up the
    765  * operation considerably.  (Provided that it works, of course.)
    766  */
    767 static inline struct mbuf *
    768 ieget(struct ie_softc *sc)
    769 {
    770 	struct mbuf *top, **mp, *m;
    771 	int len, totlen, resid;
    772 	int thisrboff, thismboff;
    773 	int head;
    774 	struct ether_header eh;
    775 
    776 	totlen = ie_packet_len(sc);
    777 	if (totlen <= 0)
    778 		return 0;
    779 
    780 	head = sc->rbhead;
    781 
    782 	/*
    783 	 * Snarf the Ethernet header.
    784 	 */
    785 	(sc->sc_memcpy)((void *)&eh, (void *)sc->cbuffs[head],
    786 	    sizeof(struct ether_header));
    787 
    788 	resid = totlen;
    789 
    790 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    791 	if (m == 0)
    792 		return 0;
    793 
    794 	m_set_rcvif(m, &sc->sc_if);
    795 	m->m_pkthdr.len = totlen;
    796 	len = MHLEN;
    797 	top = 0;
    798 	mp = &top;
    799 
    800 	/*
    801 	 * This loop goes through and allocates mbufs for all the data we will
    802 	 * be copying in.  It does not actually do the copying yet.
    803 	 */
    804 	while (totlen > 0) {
    805 		if (top) {
    806 			MGET(m, M_DONTWAIT, MT_DATA);
    807 			if (m == 0) {
    808 				m_freem(top);
    809 				return 0;
    810 			}
    811 			len = MLEN;
    812 		}
    813 		if (totlen >= MINCLSIZE) {
    814 			MCLGET(m, M_DONTWAIT);
    815 			if (m->m_flags & M_EXT)
    816 				len = MCLBYTES;
    817 		}
    818 
    819 		if (mp == &top) {
    820 			char *newdata = (char *)
    821 			    ALIGN(m->m_data + sizeof(struct ether_header)) -
    822 			    sizeof(struct ether_header);
    823 			len -= newdata - m->m_data;
    824 			m->m_data = newdata;
    825 		}
    826 
    827 		m->m_len = len = min(totlen, len);
    828 
    829 		totlen -= len;
    830 		*mp = m;
    831 		mp = &m->m_next;
    832 	}
    833 
    834 	m = top;
    835 	thismboff = 0;
    836 
    837 	/*
    838 	 * Copy the Ethernet header into the mbuf chain.
    839 	 */
    840 	memcpy(mtod(m, void *), &eh, sizeof(struct ether_header));
    841 	thismboff = sizeof(struct ether_header);
    842 	thisrboff = sizeof(struct ether_header);
    843 	resid -= sizeof(struct ether_header);
    844 
    845 	/*
    846 	 * Now we take the mbuf chain (hopefully only one mbuf most of the
    847 	 * time) and stuff the data into it.  There are no possible failures
    848 	 * at or after this point.
    849 	 */
    850 	while (resid > 0) {
    851 		int thisrblen = ie_buflen(sc, head) - thisrboff;
    852 		int thismblen = m->m_len - thismboff;
    853 
    854 		len = min(thisrblen, thismblen);
    855 		(sc->sc_memcpy)(mtod(m, char *) + thismboff,
    856 		    (void *)(sc->cbuffs[head] + thisrboff),
    857 		    (u_int)len);
    858 		resid -= len;
    859 
    860 		if (len == thismblen) {
    861 			m = m->m_next;
    862 			thismboff = 0;
    863 		} else
    864 			thismboff += len;
    865 
    866 		if (len == thisrblen) {
    867 			head = (head + 1) % sc->nrxbuf;
    868 			thisrboff = 0;
    869 		} else
    870 			thisrboff += len;
    871 	}
    872 
    873 	/*
    874 	 * Unless something changed strangely while we were doing the copy,
    875 	 * we have now copied everything in from the shared memory.
    876 	 * This means that we are done.
    877 	 */
    878 	return top;
    879 }
    880 
    881 /*
    882  * Read frame NUM from unit UNIT (pre-cached as IE).
    883  *
    884  * This routine reads the RFD at NUM, and copies in the buffers from
    885  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
    886  * doesn't start complaining.  Trailers are DROPPED---there's no point
    887  * in wasting time on confusing code to deal with them.  Hopefully,
    888  * this machine will never ARP for trailers anyway.
    889  */
    890 static void
    891 ie_readframe(struct ie_softc *sc, int num)
    892 {
    893 	int status;
    894 	struct mbuf *m = 0;
    895 
    896 	status = sc->rframes[num]->ie_fd_status;
    897 
    898 	/* Advance the RFD list, since we're done with this descriptor. */
    899 	sc->rframes[num]->ie_fd_status = SWAP(0);
    900 	sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
    901 	sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
    902 	sc->rftail = (sc->rftail + 1) % sc->nframes;
    903 	sc->rfhead = (sc->rfhead + 1) % sc->nframes;
    904 
    905 	if (status & IE_FD_OK) {
    906 		m = ieget(sc);
    907 		ie_drop_packet_buffer(sc);
    908 	}
    909 	if (m == 0) {
    910 		sc->sc_if.if_ierrors++;
    911 		return;
    912 	}
    913 
    914 #ifdef IEDEBUG
    915 	if (sc->sc_debug & IED_READFRAME) {
    916 		struct ether_header *eh = mtod(m, struct ether_header *);
    917 
    918 		printf("%s: frame from ether %s type 0x%x\n",
    919 		    device_xname(sc->sc_dev),
    920 		    ether_sprintf(eh->ether_shost), (u_int)eh->ether_type);
    921 	}
    922 #endif
    923 
    924 	/*
    925 	 * Finally pass this packet up to higher layers.
    926 	 */
    927 	if_percpuq_enqueue((&sc->sc_if)->if_percpuq, m);
    928 }
    929 
    930 static void
    931 ie_drop_packet_buffer(struct ie_softc *sc)
    932 {
    933 	int i;
    934 
    935 	do {
    936 		/*
    937 		 * This means we are somehow out of sync.  So, we reset the
    938 		 * adapter.
    939 		 */
    940 		if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
    941 		    == 0) {
    942 #ifdef IEDEBUG
    943 			print_rbd(sc->rbuffs[sc->rbhead]);
    944 #endif
    945 			log(LOG_ERR,
    946 			    "%s: receive descriptors out of sync at %d\n",
    947 			    device_xname(sc->sc_dev), sc->rbhead);
    948 			iereset(sc);
    949 			return;
    950 		}
    951 
    952 		i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
    953 
    954 		sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
    955 		sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
    956 		sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
    957 		sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
    958 		sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
    959 	} while (i == 0);
    960 }
    961 
    962 /*
    963  * Start transmission on an interface.
    964  */
    965 static void
    966 iestart(struct ifnet *ifp)
    967 {
    968 	struct ie_softc *sc = ifp->if_softc;
    969 	struct mbuf *m0, *m;
    970 	uint8_t *buffer;
    971 	uint16_t len;
    972 
    973 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
    974 		return;
    975 
    976 	for (;;) {
    977 		if (sc->xmit_busy == sc->ntxbuf) {
    978 			ifp->if_flags |= IFF_OACTIVE;
    979 			break;
    980 		}
    981 
    982 		IF_DEQUEUE(&ifp->if_snd, m0);
    983 		if (m0 == 0)
    984 			break;
    985 
    986 		/* We need to use m->m_pkthdr.len, so require the header */
    987 		if ((m0->m_flags & M_PKTHDR) == 0)
    988 			panic("%s: no header mbuf", __func__);
    989 
    990 		/* Tap off here if there is a BPF listener. */
    991 		bpf_mtap(ifp, m0);
    992 
    993 #ifdef IEDEBUG
    994 		if (sc->sc_debug & IED_ENQ)
    995 			printf("%s: fill buffer %d\n", device_xname(sc->sc_dev),
    996 			    sc->xchead);
    997 #endif
    998 
    999 		buffer = sc->xmit_cbuffs[sc->xchead];
   1000 		for (m = m0; m != 0; m = m->m_next) {
   1001 			(sc->sc_memcpy)(buffer, mtod(m, void *), m->m_len);
   1002 			buffer += m->m_len;
   1003 		}
   1004 		if (m0->m_pkthdr.len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
   1005 			sc->sc_memset(buffer, 0,
   1006 			    ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len);
   1007 			len = ETHER_MIN_LEN - ETHER_CRC_LEN;
   1008 		} else
   1009 			len = m0->m_pkthdr.len;
   1010 
   1011 		m_freem(m0);
   1012 		sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
   1013 
   1014 		/* Start the first packet transmitting. */
   1015 		if (sc->xmit_busy == 0)
   1016 			iexmit(sc);
   1017 
   1018 		sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
   1019 		sc->xmit_busy++;
   1020 	}
   1021 }
   1022 
   1023 static void
   1024 iereset(struct ie_softc *sc)
   1025 {
   1026 	int s;
   1027 
   1028 	s = splnet();
   1029 
   1030 	/* No message here.  The caller does that. */
   1031 	iestop(sc);
   1032 
   1033 	/*
   1034 	 * Stop i82586 dead in its tracks.
   1035 	 */
   1036 	if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
   1037 		printf("%s: abort commands timed out\n",
   1038 		    device_xname(sc->sc_dev));
   1039 
   1040 	if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
   1041 		printf("%s: disable commands timed out\n",
   1042 		    device_xname(sc->sc_dev));
   1043 
   1044 	ieinit(sc);
   1045 
   1046 	splx(s);
   1047 }
   1048 
   1049 /*
   1050  * Send a command to the controller and wait for it to either
   1051  * complete or be accepted, depending on the command.  If the
   1052  * command pointer is null, then pretend that the command is
   1053  * not an action command.  If the command pointer is not null,
   1054  * and the command is an action command, wait for
   1055  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
   1056  * to become true.
   1057  */
   1058 static int
   1059 cmd_and_wait(struct ie_softc *sc, int cmd, void *pcmd, int mask)
   1060 {
   1061 	volatile struct ie_cmd_common *cc = pcmd;
   1062 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1063 	int tmo;
   1064 
   1065 	scb->ie_command = (uint16_t)cmd;
   1066 	(sc->chan_attn)(sc);
   1067 
   1068 	/* Wait for the command to be accepted by the CU. */
   1069 	tmo = 10;
   1070 	while (scb->ie_command && --tmo)
   1071 		delay(10);
   1072 	if (scb->ie_command) {
   1073 #ifdef	IEDEBUG
   1074 		printf("%s: cmd_and_wait, CU stuck (1)\n",
   1075 		    device_xname(sc->sc_dev));
   1076 #endif
   1077 		return -1;	/* timed out */
   1078 	}
   1079 
   1080 	/*
   1081 	 * If asked, also wait for it to finish.
   1082 	 */
   1083 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
   1084 
   1085 		/*
   1086 		 * According to the packet driver, the minimum timeout should
   1087 		 * be .369 seconds, which we round up to .4.
   1088 		 */
   1089 		tmo = 36900;
   1090 
   1091 		/*
   1092 		 * Now spin-lock waiting for status.  This is not a very nice
   1093 		 * thing to do, but I haven't figured out how, or indeed if, we
   1094 		 * can put the process waiting for action to sleep.  (We may
   1095 		 * be getting called through some other timeout running in the
   1096 		 * kernel.)
   1097 		 */
   1098 		while (((cc->ie_cmd_status & mask) == 0) && --tmo)
   1099 			delay(10);
   1100 
   1101 		if ((cc->ie_cmd_status & mask) == 0) {
   1102 #ifdef	IEDEBUG
   1103 			printf("%s: cmd_and_wait, CU stuck (2)\n",
   1104 			    device_xname(sc->sc_dev));
   1105 #endif
   1106 			return -1;	/* timed out */
   1107 		}
   1108 	}
   1109 	return 0;
   1110 }
   1111 
   1112 /*
   1113  * Run the time-domain reflectometer.
   1114  */
   1115 static void
   1116 run_tdr(struct ie_softc *sc, struct ie_tdr_cmd *cmd)
   1117 {
   1118 	int result;
   1119 
   1120 	cmd->com.ie_cmd_status = SWAP(0);
   1121 	cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
   1122 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1123 
   1124 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1125 	cmd->ie_tdr_time = SWAP(0);
   1126 
   1127 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1128 	    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0)
   1129 		result = 0x10000;	/* impossible value */
   1130 	else
   1131 		result = cmd->ie_tdr_time;
   1132 
   1133 	ie_ack(sc, IE_ST_WHENCE);
   1134 
   1135 	if (result & IE_TDR_SUCCESS)
   1136 		return;
   1137 
   1138 	if (result & 0x10000) {
   1139 		printf("%s: TDR command failed\n", device_xname(sc->sc_dev));
   1140 	} else if (result & IE_TDR_XCVR) {
   1141 		printf("%s: transceiver problem\n", device_xname(sc->sc_dev));
   1142 	} else if (result & IE_TDR_OPEN) {
   1143 		printf("%s: TDR detected an open %d clocks away\n",
   1144 		    device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
   1145 	} else if (result & IE_TDR_SHORT) {
   1146 		printf("%s: TDR detected a short %d clocks away\n",
   1147 		    device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
   1148 	} else {
   1149 		printf("%s: TDR returned unknown status 0x%x\n",
   1150 		    device_xname(sc->sc_dev), result);
   1151 	}
   1152 }
   1153 
   1154 /*
   1155  * iememinit: set up the buffers
   1156  *
   1157  * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
   1158  * this is to be used for the buffers.  the chip indexs its control data
   1159  * structures with 16 bit offsets, and it indexes actual buffers with
   1160  * 24 bit addresses.   so we should allocate control buffers first so that
   1161  * we don't overflow the 16 bit offset field.   The number of transmit
   1162  * buffers is fixed at compile time.
   1163  *
   1164  * note: this function was written to be easy to understand, rather than
   1165  *       highly efficient (it isn't in the critical path).
   1166  *
   1167  * The memory layout is: tbufs, rbufs, (gap), control blocks
   1168  * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
   1169  * XXX - This needs review...
   1170  */
   1171 static void
   1172 iememinit(struct ie_softc *sc)
   1173 {
   1174 	uint8_t *ptr;
   1175 	int i;
   1176 	uint16_t nxt;
   1177 
   1178 	/* First, zero all the memory. */
   1179 	ptr = sc->buf_area;
   1180 	(sc->sc_memset)(ptr, 0, sc->buf_area_sz);
   1181 
   1182 	/* Allocate tx/rx buffers. */
   1183 	for (i = 0; i < NTXBUF; i++) {
   1184 		sc->xmit_cbuffs[i] = ptr;
   1185 		ptr += IE_TBUF_SIZE;
   1186 	}
   1187 	for (i = 0; i < sc->nrxbuf; i++) {
   1188 		sc->cbuffs[i] = ptr;
   1189 		ptr += IE_RBUF_SIZE;
   1190 	}
   1191 
   1192 	/* Small pad (Don't trust the chip...) */
   1193 	ptr += 16;
   1194 
   1195 	/* Allocate and fill in xmit buffer descriptors. */
   1196 	for (i = 0; i < NTXBUF; i++) {
   1197 		sc->xmit_buffs[i] = (volatile void *)ptr;
   1198 		ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
   1199 		sc->xmit_buffs[i]->ie_xmit_buf =
   1200 		    Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
   1201 		sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
   1202 	}
   1203 
   1204 	/* Allocate and fill in recv buffer descriptors. */
   1205 	for (i = 0; i < sc->nrxbuf; i++) {
   1206 		sc->rbuffs[i] = (volatile void *)ptr;
   1207 		ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
   1208 		sc->rbuffs[i]->ie_rbd_buffer =
   1209 		    Swap32(vtop24(sc, sc->cbuffs[i]));
   1210 		sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
   1211 	}
   1212 
   1213 	/* link together recv bufs and set EOL on last */
   1214 	i = sc->nrxbuf - 1;
   1215 	sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
   1216 	nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
   1217 	do {
   1218 		sc->rbuffs[i]->ie_rbd_next = nxt;
   1219 		nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[i]));
   1220 	} while (--i >= 0);
   1221 
   1222 	/* Allocate transmit commands. */
   1223 	for (i = 0; i < NTXBUF; i++) {
   1224 		sc->xmit_cmds[i] = (volatile void *)ptr;
   1225 		ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
   1226 		sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
   1227 	}
   1228 
   1229 	/* Allocate receive frames. */
   1230 	for (i = 0; i < sc->nframes; i++) {
   1231 		sc->rframes[i] = (volatile void *)ptr;
   1232 		ptr = Align(ptr + sizeof(*sc->rframes[i]));
   1233 	}
   1234 
   1235 	/* Link together recv frames and set EOL on last */
   1236 	i = sc->nframes - 1;
   1237 	sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
   1238 	nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1239 	do {
   1240 		sc->rframes[i]->ie_fd_next = nxt;
   1241 		nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[i]));
   1242 	} while (--i >= 0);
   1243 
   1244 
   1245 	/* Pointers to last packet sent and next available transmit buffer. */
   1246 	sc->xchead = sc->xctail = 0;
   1247 
   1248 	/* Clear transmit-busy flag. */
   1249 	sc->xmit_busy = 0;
   1250 
   1251 	/*
   1252 	 * Set the head and tail pointers on receive to keep track of
   1253 	 * the order in which RFDs and RBDs are used.   link the
   1254 	 * recv frames and buffer into the scb.
   1255 	 */
   1256 	sc->rfhead = 0;
   1257 	sc->rftail = sc->nframes - 1;
   1258 	sc->rbhead = 0;
   1259 	sc->rbtail = sc->nrxbuf - 1;
   1260 
   1261 	sc->scb->ie_recv_list =
   1262 	    vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1263 	sc->rframes[0]->ie_fd_buf_desc =
   1264 	    vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
   1265 
   1266 	i = (ptr - sc->buf_area);
   1267 #ifdef IEDEBUG
   1268 	printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
   1269 #endif
   1270 	if (i > sc->buf_area_sz)
   1271 		panic("ie: iememinit, out of space");
   1272 }
   1273 
   1274 /*
   1275  * Run the multicast setup command.
   1276  * Called at splnet().
   1277  */
   1278 static int
   1279 mc_setup(struct ie_softc *sc, void *ptr)
   1280 {
   1281 	struct ie_mcast_cmd *cmd = ptr;	/* XXX - Was volatile */
   1282 
   1283 	cmd->com.ie_cmd_status = SWAP(0);
   1284 	cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
   1285 	cmd->com.ie_cmd_link = SWAP(0xffff);
   1286 
   1287 	(sc->sc_memcpy)((void *)cmd->ie_mcast_addrs,
   1288 	    (void *)sc->mcast_addrs,
   1289 	    sc->mcast_count * sizeof *sc->mcast_addrs);
   1290 
   1291 	cmd->ie_mcast_bytes =
   1292 	    SWAP(sc->mcast_count * ETHER_ADDR_LEN);	/* grrr... */
   1293 
   1294 	sc->scb->ie_command_list = vtop16sw(sc, cmd);
   1295 	if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1296 	    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1297 		printf("%s: multicast address setup command failed\n",
   1298 		    device_xname(sc->sc_dev));
   1299 		return 0;
   1300 	}
   1301 	return 1;
   1302 }
   1303 
   1304 static inline void
   1305 ie_setup_config(struct ie_config_cmd *cmd, int promiscuous, int manchester)
   1306 {
   1307 
   1308 	/*
   1309 	 * these are all char's so no need to byte-swap
   1310 	 */
   1311 	cmd->ie_config_count = 0x0c;
   1312 	cmd->ie_fifo = 8;
   1313 	cmd->ie_save_bad = 0x40;
   1314 	cmd->ie_addr_len = 0x2e;
   1315 	cmd->ie_priority = 0;
   1316 	cmd->ie_ifs = 0x60;
   1317 	cmd->ie_slot_low = 0;
   1318 	cmd->ie_slot_high = 0xf2;
   1319 	cmd->ie_promisc = promiscuous | manchester << 2;
   1320 	cmd->ie_crs_cdt = 0;
   1321 	cmd->ie_min_len = 64;
   1322 	cmd->ie_junk = 0xff;
   1323 }
   1324 
   1325 /*
   1326  * This routine inits the ie.
   1327  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
   1328  * starting the receiver unit, and clearing interrupts.
   1329  *
   1330  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
   1331  */
   1332 static int
   1333 ieinit(struct ie_softc *sc)
   1334 {
   1335 	volatile struct ie_sys_ctl_block *scb = sc->scb;
   1336 	void *ptr;
   1337 	struct ifnet *ifp;
   1338 
   1339 	ifp = &sc->sc_if;
   1340 	ptr = sc->buf_area;	/* XXX - Use scb instead? */
   1341 
   1342 	/*
   1343 	 * Send the configure command first.
   1344 	 */
   1345 	{
   1346 		struct ie_config_cmd *cmd = ptr;	/* XXX - Was volatile */
   1347 
   1348 		scb->ie_command_list = vtop16sw(sc, cmd);
   1349 		cmd->com.ie_cmd_status = SWAP(0);
   1350 		cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
   1351 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1352 
   1353 		ie_setup_config(cmd, (sc->promisc != 0), 0);
   1354 
   1355 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1356 		    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1357 			printf("%s: configure command failed\n",
   1358 			    device_xname(sc->sc_dev));
   1359 			return 0;
   1360 		}
   1361 	}
   1362 
   1363 	/*
   1364 	 * Now send the Individual Address Setup command.
   1365 	 */
   1366 	{
   1367 		struct ie_iasetup_cmd *cmd = ptr;	/* XXX - Was volatile */
   1368 
   1369 		scb->ie_command_list = vtop16sw(sc, cmd);
   1370 		cmd->com.ie_cmd_status = SWAP(0);
   1371 		cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
   1372 		cmd->com.ie_cmd_link = SWAP(0xffff);
   1373 
   1374 		(sc->sc_memcpy)((void *)&cmd->ie_address,
   1375 		    CLLADDR(ifp->if_sadl), sizeof(cmd->ie_address));
   1376 
   1377 		if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
   1378 		    (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
   1379 			printf("%s: individual address setup command failed\n",
   1380 			    device_xname(sc->sc_dev));
   1381 			return 0;
   1382 		}
   1383 	}
   1384 
   1385 	/*
   1386 	 * Now run the time-domain reflectometer.
   1387 	 */
   1388 	if (ie_run_tdr)
   1389 		run_tdr(sc, ptr);
   1390 
   1391 	/*
   1392 	 * Acknowledge any interrupts we have generated thus far.
   1393 	 */
   1394 	ie_ack(sc, IE_ST_WHENCE);
   1395 
   1396 	/*
   1397 	 * Set up the transmit and recv buffers.
   1398 	 */
   1399 	iememinit(sc);
   1400 
   1401 	/* tell higher levels that we are here */
   1402 	ifp->if_flags |= IFF_RUNNING;
   1403 	ifp->if_flags &= ~IFF_OACTIVE;
   1404 
   1405 	sc->scb->ie_recv_list =
   1406 	    vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
   1407 	cmd_and_wait(sc, IE_RU_START, 0, 0);
   1408 
   1409 	ie_ack(sc, IE_ST_WHENCE);
   1410 
   1411 	if (sc->run_586)
   1412 		(sc->run_586)(sc);
   1413 
   1414 	return 0;
   1415 }
   1416 
   1417 static void
   1418 iestop(struct ie_softc *sc)
   1419 {
   1420 
   1421 	cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
   1422 }
   1423 
   1424 static int
   1425 ieioctl(struct ifnet *ifp, u_long cmd, void *data)
   1426 {
   1427 	struct ie_softc *sc = ifp->if_softc;
   1428 	struct ifaddr *ifa = (struct ifaddr *)data;
   1429 	int s, error = 0;
   1430 
   1431 	s = splnet();
   1432 
   1433 	switch (cmd) {
   1434 
   1435 	case SIOCINITIFADDR:
   1436 		ifp->if_flags |= IFF_UP;
   1437 
   1438 		switch (ifa->ifa_addr->sa_family) {
   1439 #ifdef INET
   1440 		case AF_INET:
   1441 			ieinit(sc);
   1442 			arp_ifinit(ifp, ifa);
   1443 			break;
   1444 #endif
   1445 		default:
   1446 			ieinit(sc);
   1447 			break;
   1448 		}
   1449 		break;
   1450 
   1451 	case SIOCSIFFLAGS:
   1452 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   1453 			break;
   1454 		sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
   1455 
   1456 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
   1457 		case IFF_RUNNING:
   1458 			/*
   1459 			 * If interface is marked down and it is running, then
   1460 			 * stop it.
   1461 			 */
   1462 			iestop(sc);
   1463 			ifp->if_flags &= ~IFF_RUNNING;
   1464 			break;
   1465 		case IFF_UP:
   1466 			/*
   1467 			 * If interface is marked up and it is stopped, then
   1468 			 * start it.
   1469 			 */
   1470 			ieinit(sc);
   1471 			break;
   1472 		default:
   1473 			/*
   1474 			 * Reset the interface to pick up changes in any other
   1475 			 * flags that affect hardware registers.
   1476 			 */
   1477 			iestop(sc);
   1478 			ieinit(sc);
   1479 			break;
   1480 		}
   1481 #ifdef IEDEBUG
   1482 		if (ifp->if_flags & IFF_DEBUG)
   1483 			sc->sc_debug = IED_ALL;
   1484 		else
   1485 			sc->sc_debug = ie_debug_flags;
   1486 #endif
   1487 		break;
   1488 
   1489 	case SIOCADDMULTI:
   1490 	case SIOCDELMULTI:
   1491 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
   1492 			/*
   1493 			 * Multicast list has changed; set the hardware filter
   1494 			 * accordingly.
   1495 			 */
   1496 			if (ifp->if_flags & IFF_RUNNING)
   1497 				mc_reset(sc);
   1498 			error = 0;
   1499 		}
   1500 		break;
   1501 
   1502 	default:
   1503 		error = ether_ioctl(ifp, cmd, data);
   1504 		break;
   1505 	}
   1506 	splx(s);
   1507 	return error;
   1508 }
   1509 
   1510 static void
   1511 mc_reset(struct ie_softc *sc)
   1512 {
   1513 	struct ether_multi *enm;
   1514 	struct ether_multistep step;
   1515 	struct ifnet *ifp;
   1516 
   1517 	ifp = &sc->sc_if;
   1518 
   1519 	/*
   1520 	 * Step through the list of addresses.
   1521 	 */
   1522 	sc->mcast_count = 0;
   1523 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
   1524 	while (enm) {
   1525 		if (sc->mcast_count >= MAXMCAST ||
   1526 		    ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) {
   1527 			ifp->if_flags |= IFF_ALLMULTI;
   1528 			ieioctl(ifp, SIOCSIFFLAGS, NULL);
   1529 			goto setflag;
   1530 		}
   1531 		memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo,
   1532 		    ETHER_ADDR_LEN);
   1533 		sc->mcast_count++;
   1534 		ETHER_NEXT_MULTI(step, enm);
   1535 	}
   1536 setflag:
   1537 	sc->want_mcsetup = 1;
   1538 }
   1539 
   1540 #ifdef IEDEBUG
   1541 void
   1542 print_rbd(volatile struct ie_recv_buf_desc *rbd)
   1543 {
   1544 
   1545 	printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
   1546 	    "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
   1547 	    rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
   1548 	    rbd->mbz);
   1549 }
   1550 #endif
   1551