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