i82586.c revision 1.46 1 /* $NetBSD: i82586.c,v 1.46 2003/01/27 10:35:08 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.46 2003/01/27 10:35:08 bouyer Exp $");
148
149 #include "bpfilter.h"
150
151 #include <sys/cdefs.h>
152 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.46 2003/01/27 10:35:08 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 len = m0->m_pkthdr.len;
1233 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1234 (sc->memcopyout)(sc, padbuf, buffer,
1235 ETHER_MIN_LEN - ETHER_CRC_LEN - len);
1236 buffer += ETHER_MIN_LEN -ETHER_CRC_LEN - len;
1237 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1238 }
1239 m_freem(m0);
1240
1241 /*
1242 * Setup the transmit buffer descriptor here, while we
1243 * know the packet's length.
1244 */
1245 sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
1246 len | IE_TBD_EOL);
1247 sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
1248 sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
1249 IE_XBUF_ADDR(sc, head));
1250
1251 if (++head == NTXBUF)
1252 head = 0;
1253 sc->xchead = head;
1254
1255 s = splnet();
1256 /* Start the first packet transmitting. */
1257 if (sc->xmit_busy == 0)
1258 iexmit(sc);
1259
1260 sc->xmit_busy++;
1261 splx(s);
1262 }
1263 }
1264
1265 /*
1266 * Probe IE's ram setup [ Move all this into MD front-end!? ]
1267 * Use only if SCP and ISCP represent offsets into shared ram space.
1268 */
1269 int
1270 i82586_proberam(sc)
1271 struct ie_softc *sc;
1272 {
1273 int result, off;
1274
1275 /* Put in 16-bit mode */
1276 off = IE_SCP_BUS_USE(sc->scp);
1277 sc->ie_bus_write16(sc, off, IE_SYSBUS_16BIT);
1278 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1279
1280 /* Set the ISCP `busy' bit */
1281 off = IE_ISCP_BUSY(sc->iscp);
1282 sc->ie_bus_write16(sc, off, 1);
1283 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1284
1285 if (sc->hwreset)
1286 (sc->hwreset)(sc, CHIP_PROBE);
1287
1288 (sc->chan_attn) (sc, CHIP_PROBE);
1289
1290 delay(100); /* wait a while... */
1291
1292 /* Read back the ISCP `busy' bit; it should be clear by now */
1293 off = IE_ISCP_BUSY(sc->iscp);
1294 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1295 result = sc->ie_bus_read16(sc, off) == 0;
1296
1297 /* Acknowledge any interrupts we may have caused. */
1298 ie_ack(sc, IE_ST_WHENCE);
1299
1300 return (result);
1301 }
1302
1303 void
1304 i82586_reset(sc, hard)
1305 struct ie_softc *sc;
1306 int hard;
1307 {
1308 int s = splnet();
1309
1310 if (hard)
1311 printf("%s: reset\n", sc->sc_dev.dv_xname);
1312
1313 /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
1314 sc->sc_ethercom.ec_if.if_timer = 0;
1315 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
1316
1317 /*
1318 * Stop i82586 dead in its tracks.
1319 */
1320 if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0))
1321 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1322
1323 /*
1324 * This can really slow down the i82586_reset() on some cards, but it's
1325 * necessary to unwedge other ones (eg, the Sun VME ones) from certain
1326 * lockups.
1327 */
1328 if (hard && sc->hwreset)
1329 (sc->hwreset)(sc, CARD_RESET);
1330
1331 delay(100);
1332 ie_ack(sc, IE_ST_WHENCE);
1333
1334 if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) {
1335 int retries=0; /* XXX - find out why init sometimes fails */
1336 while (retries++ < 2)
1337 if (i82586_init(&sc->sc_ethercom.ec_if) == 0)
1338 break;
1339 }
1340
1341 splx(s);
1342 }
1343
1344
1345 static void
1346 setup_simple_command(sc, cmd, cmdbuf)
1347 struct ie_softc *sc;
1348 int cmd;
1349 int cmdbuf;
1350 {
1351 /* Setup a simple command */
1352 sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
1353 sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
1354 sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
1355
1356 /* Assign the command buffer to the SCB command list */
1357 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
1358 }
1359
1360 /*
1361 * Run the time-domain reflectometer.
1362 */
1363 static void
1364 ie_run_tdr(sc, cmd)
1365 struct ie_softc *sc;
1366 int cmd;
1367 {
1368 int result;
1369
1370 setup_simple_command(sc, IE_CMD_TDR, cmd);
1371 sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0);
1372
1373 if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
1374 (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0)
1375 result = 0x10000; /* XXX */
1376 else
1377 result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
1378
1379 /* Squash any pending interrupts */
1380 ie_ack(sc, IE_ST_WHENCE);
1381
1382 if (result & IE_TDR_SUCCESS)
1383 return;
1384
1385 if (result & 0x10000)
1386 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1387 else if (result & IE_TDR_XCVR)
1388 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1389 else if (result & IE_TDR_OPEN)
1390 printf("%s: TDR detected incorrect termination %d clocks away\n",
1391 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1392 else if (result & IE_TDR_SHORT)
1393 printf("%s: TDR detected a short circuit %d clocks away\n",
1394 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1395 else
1396 printf("%s: TDR returned unknown status 0x%x\n",
1397 sc->sc_dev.dv_xname, result);
1398 }
1399
1400
1401 /*
1402 * i82586_setup_bufs: set up the buffers
1403 *
1404 * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1405 * this is to be used for the buffers. The chip indexs its control data
1406 * structures with 16 bit offsets, and it indexes actual buffers with
1407 * 24 bit addresses. So we should allocate control buffers first so that
1408 * we don't overflow the 16 bit offset field. The number of transmit
1409 * buffers is fixed at compile time.
1410 *
1411 */
1412 static void
1413 i82586_setup_bufs(sc)
1414 struct ie_softc *sc;
1415 {
1416 int ptr = sc->buf_area; /* memory pool */
1417 int n, r;
1418
1419 /*
1420 * step 0: zero memory and figure out how many recv buffers and
1421 * frames we can have.
1422 */
1423 ptr = (ptr + 3) & ~3; /* set alignment and stick with it */
1424
1425
1426 /*
1427 * step 1: lay out data structures in the shared-memory area
1428 */
1429
1430 /* The no-op commands; used if "nop-chaining" is in effect */
1431 sc->nop_cmds = ptr;
1432 ptr += NTXBUF * IE_CMD_NOP_SZ;
1433
1434 /* The transmit commands */
1435 sc->xmit_cmds = ptr;
1436 ptr += NTXBUF * IE_CMD_XMIT_SZ;
1437
1438 /* The transmit buffers descriptors */
1439 sc->xbds = ptr;
1440 ptr += NTXBUF * IE_XBD_SZ;
1441
1442 /* The transmit buffers */
1443 sc->xbufs = ptr;
1444 ptr += NTXBUF * IE_TBUF_SIZE;
1445
1446 ptr = (ptr + 3) & ~3; /* re-align.. just in case */
1447
1448 /* Compute free space for RECV stuff */
1449 n = sc->buf_area_sz - (ptr - sc->buf_area);
1450
1451 /* Compute size of one RECV frame */
1452 r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F);
1453
1454 sc->nframes = n / r;
1455
1456 if (sc->nframes <= 0)
1457 panic("ie: bogus buffer calc");
1458
1459 sc->nrxbuf = sc->nframes * B_PER_F;
1460
1461 /* The receice frame descriptors */
1462 sc->rframes = ptr;
1463 ptr += sc->nframes * IE_RFRAME_SZ;
1464
1465 /* The receive buffer descriptors */
1466 sc->rbds = ptr;
1467 ptr += sc->nrxbuf * IE_RBD_SZ;
1468
1469 /* The receive buffers */
1470 sc->rbufs = ptr;
1471 ptr += sc->nrxbuf * IE_RBUF_SIZE;
1472
1473 #if I82586_DEBUG
1474 printf("%s: %d frames %d bufs\n", sc->sc_dev.dv_xname, sc->nframes,
1475 sc->nrxbuf);
1476 #endif
1477
1478 /*
1479 * step 2: link together the recv frames and set EOL on last one
1480 */
1481 for (n = 0; n < sc->nframes; n++) {
1482 int m = (n == sc->nframes - 1) ? 0 : n + 1;
1483
1484 /* Clear status */
1485 sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
1486
1487 /* RBD link = NULL */
1488 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
1489 0xffff);
1490
1491 /* Make a circular list */
1492 sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
1493 IE_RFRAME_ADDR(sc->rframes,m));
1494
1495 /* Mark last as EOL */
1496 sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
1497 ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
1498 }
1499
1500 /*
1501 * step 3: link the RBDs and set EOL on last one
1502 */
1503 for (n = 0; n < sc->nrxbuf; n++) {
1504 int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
1505
1506 /* Clear status */
1507 sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
1508
1509 /* Make a circular list */
1510 sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
1511 IE_RBD_ADDR(sc->rbds,m));
1512
1513 /* Link to data buffers */
1514 sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
1515 IE_RBUF_ADDR(sc, n));
1516 sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
1517 IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
1518 }
1519
1520 /*
1521 * step 4: all xmit no-op commands loopback onto themselves
1522 */
1523 for (n = 0; n < NTXBUF; n++) {
1524 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
1525
1526 sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
1527 IE_CMD_NOP);
1528
1529 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
1530 IE_CMD_NOP_ADDR(sc->nop_cmds, n));
1531 }
1532
1533
1534 /*
1535 * step 6: set the head and tail pointers on receive to keep track of
1536 * the order in which RFDs and RBDs are used.
1537 */
1538
1539 /* Pointers to last packet sent and next available transmit buffer. */
1540 sc->xchead = sc->xctail = 0;
1541
1542 /* Clear transmit-busy flag and set number of free transmit buffers. */
1543 sc->xmit_busy = 0;
1544
1545 /*
1546 * Pointers to first and last receive frame.
1547 * The RFD pointed to by rftail is the only one that has EOL set.
1548 */
1549 sc->rfhead = 0;
1550 sc->rftail = sc->nframes - 1;
1551
1552 /*
1553 * Pointers to first and last receive descriptor buffer.
1554 * The RBD pointed to by rbtail is the only one that has EOL set.
1555 */
1556 sc->rbhead = 0;
1557 sc->rbtail = sc->nrxbuf - 1;
1558
1559 /* link in recv frames * and buffer into the scb. */
1560 #if I82586_DEBUG
1561 printf("%s: reserved %d bytes\n",
1562 sc->sc_dev.dv_xname, ptr - sc->buf_area);
1563 #endif
1564 }
1565
1566 static int
1567 ie_cfg_setup(sc, cmd, promiscuous, manchester)
1568 struct ie_softc *sc;
1569 int cmd;
1570 int promiscuous, manchester;
1571 {
1572 int cmdresult, status;
1573 u_int8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */
1574
1575 *IE_CMD_CFG_CNT(buf) = 0x0c;
1576 *IE_CMD_CFG_FIFO(buf) = 8;
1577 *IE_CMD_CFG_SAVEBAD(buf) = 0x40;
1578 *IE_CMD_CFG_ADDRLEN(buf) = 0x2e;
1579 *IE_CMD_CFG_PRIORITY(buf) = 0;
1580 *IE_CMD_CFG_IFS(buf) = 0x60;
1581 *IE_CMD_CFG_SLOT_LOW(buf) = 0;
1582 *IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2;
1583 *IE_CMD_CFG_PROMISC(buf) = !!promiscuous | manchester << 2;
1584 *IE_CMD_CFG_CRSCDT(buf) = 0;
1585 *IE_CMD_CFG_MINLEN(buf) = 64;
1586 *IE_CMD_CFG_JUNK(buf) = 0xff;
1587 sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ);
1588 setup_simple_command(sc, IE_CMD_CONFIG, cmd);
1589 IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE);
1590
1591 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
1592 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
1593 if (cmdresult != 0) {
1594 printf("%s: configure command timed out; status %x\n",
1595 sc->sc_dev.dv_xname, status);
1596 return (0);
1597 }
1598 if ((status & IE_STAT_OK) == 0) {
1599 printf("%s: configure command failed; status %x\n",
1600 sc->sc_dev.dv_xname, status);
1601 return (0);
1602 }
1603
1604 /* Squash any pending interrupts */
1605 ie_ack(sc, IE_ST_WHENCE);
1606 return (1);
1607 }
1608
1609 static int
1610 ie_ia_setup(sc, cmdbuf)
1611 struct ie_softc *sc;
1612 int cmdbuf;
1613 {
1614 int cmdresult, status;
1615 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1616
1617 setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
1618
1619 (sc->memcopyout)(sc, LLADDR(ifp->if_sadl),
1620 IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
1621
1622 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1623 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1624 if (cmdresult != 0) {
1625 printf("%s: individual address command timed out; status %x\n",
1626 sc->sc_dev.dv_xname, status);
1627 return (0);
1628 }
1629 if ((status & IE_STAT_OK) == 0) {
1630 printf("%s: individual address command failed; status %x\n",
1631 sc->sc_dev.dv_xname, status);
1632 return (0);
1633 }
1634
1635 /* Squash any pending interrupts */
1636 ie_ack(sc, IE_ST_WHENCE);
1637 return (1);
1638 }
1639
1640 /*
1641 * Run the multicast setup command.
1642 * Called at splnet().
1643 */
1644 static int
1645 ie_mc_setup(sc, cmdbuf)
1646 struct ie_softc *sc;
1647 int cmdbuf;
1648 {
1649 int cmdresult, status;
1650
1651 if (sc->mcast_count == 0)
1652 return (1);
1653
1654 setup_simple_command(sc, IE_CMD_MCAST, cmdbuf);
1655
1656 (sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs,
1657 IE_CMD_MCAST_MADDR(cmdbuf),
1658 sc->mcast_count * ETHER_ADDR_LEN);
1659
1660 sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
1661 sc->mcast_count * ETHER_ADDR_LEN);
1662
1663 /* Start the command */
1664 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1665 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1666 if (cmdresult != 0) {
1667 printf("%s: multicast setup command timed out; status %x\n",
1668 sc->sc_dev.dv_xname, status);
1669 return (0);
1670 }
1671 if ((status & IE_STAT_OK) == 0) {
1672 printf("%s: multicast setup command failed; status %x\n",
1673 sc->sc_dev.dv_xname, status);
1674 return (0);
1675 }
1676
1677 /* Squash any pending interrupts */
1678 ie_ack(sc, IE_ST_WHENCE);
1679 return (1);
1680 }
1681
1682 /*
1683 * This routine takes the environment generated by check_ie_present() and adds
1684 * to it all the other structures we need to operate the adapter. This
1685 * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
1686 * the receiver unit, and clearing interrupts.
1687 *
1688 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
1689 */
1690 int
1691 i82586_init(ifp)
1692 struct ifnet *ifp;
1693 {
1694 struct ie_softc *sc = ifp->if_softc;
1695 int cmd;
1696
1697 sc->async_cmd_inprogress = 0;
1698
1699 cmd = sc->buf_area;
1700
1701 /*
1702 * Send the configure command first.
1703 */
1704 if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
1705 return EIO;
1706
1707 /*
1708 * Send the Individual Address Setup command.
1709 */
1710 if (ie_ia_setup(sc, cmd) == 0)
1711 return EIO;
1712
1713 /*
1714 * Run the time-domain reflectometer.
1715 */
1716 ie_run_tdr(sc, cmd);
1717
1718 /*
1719 * Set the multi-cast filter, if any
1720 */
1721 if (ie_mc_setup(sc, cmd) == 0)
1722 return EIO;
1723
1724 /*
1725 * Acknowledge any interrupts we have generated thus far.
1726 */
1727 ie_ack(sc, IE_ST_WHENCE);
1728
1729 /*
1730 * Set up the transmit and recv buffers.
1731 */
1732 i82586_setup_bufs(sc);
1733
1734 if (sc->hwinit)
1735 (sc->hwinit)(sc);
1736
1737 ifp->if_flags |= IFF_RUNNING;
1738 ifp->if_flags &= ~IFF_OACTIVE;
1739
1740 if (NTXBUF < 2)
1741 sc->do_xmitnopchain = 0;
1742
1743 i82586_start_transceiver(sc);
1744 return (0);
1745 }
1746
1747 /*
1748 * Start the RU and possibly the CU unit
1749 */
1750 static void
1751 i82586_start_transceiver(sc)
1752 struct ie_softc *sc;
1753 {
1754
1755 /*
1756 * Start RU at current position in frame & RBD lists.
1757 */
1758 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead),
1759 IE_RBD_ADDR(sc->rbds, sc->rbhead));
1760
1761 sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
1762 IE_RFRAME_ADDR(sc->rframes,sc->rfhead));
1763
1764 if (sc->do_xmitnopchain) {
1765 /* Stop transmit command chain */
1766 if (i82586_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0))
1767 printf("%s: CU/RU stop command timed out\n",
1768 sc->sc_dev.dv_xname);
1769
1770 /* Start the receiver & transmitter chain */
1771 /* sc->scb->ie_command_list =
1772 IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
1773 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
1774 IE_CMD_NOP_ADDR(
1775 sc->nop_cmds,
1776 (sc->xctail + NTXBUF - 1) % NTXBUF));
1777
1778 if (i82586_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
1779 printf("%s: CU/RU command timed out\n",
1780 sc->sc_dev.dv_xname);
1781 } else {
1782 if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0))
1783 printf("%s: RU command timed out\n",
1784 sc->sc_dev.dv_xname);
1785 }
1786 }
1787
1788 void
1789 i82586_stop(ifp, disable)
1790 struct ifnet *ifp;
1791 int disable;
1792 {
1793 struct ie_softc *sc = ifp->if_softc;
1794
1795 if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
1796 printf("%s: iestop: disable commands timed out\n",
1797 sc->sc_dev.dv_xname);
1798 }
1799
1800 int
1801 i82586_ioctl(ifp, cmd, data)
1802 struct ifnet *ifp;
1803 u_long cmd;
1804 caddr_t data;
1805 {
1806 struct ie_softc *sc = ifp->if_softc;
1807 struct ifreq *ifr = (struct ifreq *)data;
1808 int s, error = 0;
1809
1810 s = splnet();
1811 switch(cmd) {
1812 case SIOCGIFMEDIA:
1813 case SIOCSIFMEDIA:
1814 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1815 break;
1816 default:
1817 error = ether_ioctl(ifp, cmd, data);
1818 if (error == ENETRESET) {
1819 /*
1820 * Multicast list has changed; set the hardware filter
1821 * accordingly.
1822 */
1823 ie_mc_reset(sc);
1824 error = 0;
1825 }
1826 break;
1827 }
1828 #if I82586_DEBUG
1829 if (cmd == SIOCSIFFLAGS)
1830 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0;
1831 #endif
1832 splx(s);
1833 return (error);
1834 }
1835
1836 static void
1837 ie_mc_reset(sc)
1838 struct ie_softc *sc;
1839 {
1840 struct ether_multi *enm;
1841 struct ether_multistep step;
1842 int size;
1843
1844 /*
1845 * Step through the list of addresses.
1846 */
1847 again:
1848 size = 0;
1849 sc->mcast_count = 0;
1850 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1851 while (enm) {
1852 size += 6;
1853 if (sc->mcast_count >= IE_MAXMCAST ||
1854 memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1855 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
1856 i82586_ioctl(&sc->sc_ethercom.ec_if,
1857 SIOCSIFFLAGS, (void *)0);
1858 return;
1859 }
1860 ETHER_NEXT_MULTI(step, enm);
1861 }
1862
1863 if (size > sc->mcast_addrs_size) {
1864 /* Need to allocate more space */
1865 if (sc->mcast_addrs_size)
1866 free(sc->mcast_addrs, M_IFMADDR);
1867 sc->mcast_addrs = (char *)
1868 malloc(size, M_IFMADDR, M_WAITOK);
1869 sc->mcast_addrs_size = size;
1870 }
1871
1872 /*
1873 * We've got the space; now copy the addresses
1874 */
1875 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1876 while (enm) {
1877 if (sc->mcast_count >= IE_MAXMCAST)
1878 goto again; /* Just in case */
1879
1880 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6);
1881 sc->mcast_count++;
1882 ETHER_NEXT_MULTI(step, enm);
1883 }
1884 sc->want_mcsetup = 1;
1885 }
1886
1887 /*
1888 * Media change callback.
1889 */
1890 int
1891 i82586_mediachange(ifp)
1892 struct ifnet *ifp;
1893 {
1894 struct ie_softc *sc = ifp->if_softc;
1895
1896 if (sc->sc_mediachange)
1897 return ((*sc->sc_mediachange)(sc));
1898 return (0);
1899 }
1900
1901 /*
1902 * Media status callback.
1903 */
1904 void
1905 i82586_mediastatus(ifp, ifmr)
1906 struct ifnet *ifp;
1907 struct ifmediareq *ifmr;
1908 {
1909 struct ie_softc *sc = ifp->if_softc;
1910
1911 if (sc->sc_mediastatus)
1912 (*sc->sc_mediastatus)(sc, ifmr);
1913 }
1914
1915 #if I82586_DEBUG
1916 void
1917 print_rbd(sc, n)
1918 struct ie_softc *sc;
1919 int n;
1920 {
1921
1922 printf("RBD at %08x:\n status %04x, next %04x, buffer %lx\n"
1923 "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
1924 sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)),
1925 sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
1926 (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
1927 sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
1928 }
1929 #endif
1930