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