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