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