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