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