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