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