FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/i82586.c
1 /* $NetBSD: i82586.c,v 1.62 2008/04/28 20:23:50 martin 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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*-
33 * Copyright (c) 1997 Paul Kranenburg.
34 * Copyright (c) 1992, 1993, University of Vermont and State
35 * Agricultural College.
36 * Copyright (c) 1992, 1993, Garrett A. Wollman.
37 *
38 * Portions:
39 * Copyright (c) 1994, 1995, Rafal K. Boni
40 * Copyright (c) 1990, 1991, William F. Jolitz
41 * Copyright (c) 1990, The Regents of the University of California
42 *
43 * All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by the University of Vermont
56 * and State Agricultural College and Garrett A. Wollman, by William F.
57 * Jolitz, and by the University of California, Berkeley, Lawrence
58 * Berkeley Laboratory, and its contributors.
59 * 4. Neither the names of the Universities nor the names of the authors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 */
75
76 /*
77 * Intel 82586 Ethernet chip
78 * Register, bit, and structure definitions.
79 *
80 * Original StarLAN driver written by Garrett Wollman with reference to the
81 * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
82 *
83 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
84 *
85 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
86 *
87 * Majorly cleaned up and 3C507 code merged by Charles Hannum.
88 *
89 * Converted to SUN ie driver by Charles D. Cranor,
90 * October 1994, January 1995.
91 * This sun version based on i386 version 1.30.
92 */
93
94 /*
95 * The i82586 is a very painful chip, found in sun3's, sun-4/100's
96 * sun-4/200's, and VME based suns. The byte order is all wrong for a
97 * SUN, making life difficult. Programming this chip is mostly the same,
98 * but certain details differ from system to system. This driver is
99 * written so that different "ie" interfaces can be controled by the same
100 * driver.
101 */
102
103 /*
104 Mode of operation:
105
106 We run the 82586 in a standard Ethernet mode. We keep NFRAMES
107 received frame descriptors around for the receiver to use, and
108 NRXBUF associated receive buffer descriptors, both in a circular
109 list. Whenever a frame is received, we rotate both lists as
110 necessary. (The 586 treats both lists as a simple queue.) We also
111 keep a transmit command around so that packets can be sent off
112 quickly.
113
114 We configure the adapter in AL-LOC = 1 mode, which means that the
115 Ethernet/802.3 MAC header is placed at the beginning of the receive
116 buffer rather than being split off into various fields in the RFD.
117 This also means that we must include this header in the transmit
118 buffer as well.
119
120 By convention, all transmit commands, and only transmit commands,
121 shall have the I (IE_CMD_INTR) bit set in the command. This way,
122 when an interrupt arrives at i82586_intr(), it is immediately possible
123 to tell what precisely caused it. ANY OTHER command-sending
124 routines should run at splnet(), and should post an acknowledgement
125 to every interrupt they generate.
126
127 To save the expense of shipping a command to 82586 every time we
128 want to send a frame, we use a linked list of commands consisting
129 of alternate XMIT and NOP commands. The links of these elements
130 are manipulated (in iexmit()) such that the NOP command loops back
131 to itself whenever the following XMIT command is not yet ready to
132 go. Whenever an XMIT is ready, the preceding NOP link is pointed
133 at it, while its own link field points to the following NOP command.
134 Thus, a single transmit command sets off an interlocked traversal
135 of the xmit command chain, with the host processor in control of
136 the synchronization.
137 */
138
139 #include <sys/cdefs.h>
140 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.62 2008/04/28 20:23:50 martin Exp $");
141
142 #include "bpfilter.h"
143
144 #include <sys/param.h>
145 #include <sys/systm.h>
146 #include <sys/mbuf.h>
147 #include <sys/socket.h>
148 #include <sys/ioctl.h>
149 #include <sys/errno.h>
150 #include <sys/syslog.h>
151 #include <sys/device.h>
152
153 #include <net/if.h>
154 #include <net/if_dl.h>
155 #include <net/if_types.h>
156 #include <net/if_media.h>
157 #include <net/if_ether.h>
158
159 #if NBPFILTER > 0
160 #include <net/bpf.h>
161 #include <net/bpfdesc.h>
162 #endif
163
164 #include <sys/bus.h>
165
166 #include <dev/ic/i82586reg.h>
167 #include <dev/ic/i82586var.h>
168
169 void i82586_reset(struct ie_softc *, int);
170 void i82586_watchdog(struct ifnet *);
171 int i82586_init(struct ifnet *);
172 int i82586_ioctl(struct ifnet *, u_long, void *);
173 void i82586_start(struct ifnet *);
174 void i82586_stop(struct ifnet *, int);
175
176
177 int i82586_rint(struct ie_softc *, int);
178 int i82586_tint(struct ie_softc *, int);
179
180 int i82586_mediachange(struct ifnet *);
181 void i82586_mediastatus(struct ifnet *, struct ifmediareq *);
182
183 static int ie_readframe(struct ie_softc *, int);
184 static struct mbuf *ieget(struct ie_softc *, int, int);
185 static int i82586_get_rbd_list(struct ie_softc *,
186 u_int16_t *, u_int16_t *, int *);
187 static void i82586_release_rbd_list(struct ie_softc *,
188 u_int16_t, u_int16_t);
189 static int i82586_drop_frames(struct ie_softc *);
190 static int i82586_chk_rx_ring(struct ie_softc *);
191
192 static inline void ie_ack(struct ie_softc *, u_int);
193 static inline void iexmit(struct ie_softc *);
194 static void i82586_start_transceiver(struct ie_softc *);
195
196 static void i82586_count_errors(struct ie_softc *);
197 static void i82586_rx_errors(struct ie_softc *, int, int);
198 static void i82586_setup_bufs(struct ie_softc *);
199 static void setup_simple_command(struct ie_softc *, int, int);
200 static int ie_cfg_setup(struct ie_softc *, int, int, int);
201 static int ie_ia_setup(struct ie_softc *, int);
202 static void ie_run_tdr(struct ie_softc *, int);
203 static int ie_mc_setup(struct ie_softc *, int);
204 static void ie_mc_reset(struct ie_softc *);
205 static int i82586_start_cmd(struct ie_softc *, int, int, int, int);
206 static int i82586_cmd_wait(struct ie_softc *);
207
208 #if I82586_DEBUG
209 void print_rbd(struct ie_softc *, int);
210 #endif
211
212 static char* padbuf = NULL;
213
214 /*
215 * Front-ends call this function to attach to the MI driver.
216 *
217 * The front-end has responsibility for managing the ICP and ISCP
218 * structures. Both of these are opaque to us. Also, the front-end
219 * chooses a location for the SCB which is expected to be addressable
220 * (through `sc->scb') as an offset against the shared-memory bus handle.
221 *
222 * The following MD interface function must be setup by the front-end
223 * before calling here:
224 *
225 * hwreset - board dependent reset
226 * hwinit - board dependent initialization
227 * chan_attn - channel attention
228 * intrhook - board dependent interrupt processing
229 * memcopyin - shared memory copy: board to KVA
230 * memcopyout - shared memory copy: KVA to board
231 * ie_bus_read16 - read a sixteen-bit i82586 pointer
232 * ie_bus_write16 - write a sixteen-bit i82586 pointer
233 * ie_bus_write24 - write a twenty-four-bit i82586 pointer
234 *
235 */
236 void
237 i82586_attach(sc, name, etheraddr, media, nmedia, defmedia)
238 struct ie_softc *sc;
239 const char *name;
240 u_int8_t *etheraddr;
241 int *media, nmedia, defmedia;
242 {
243 int i;
244 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
245
246 strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
247 ifp->if_softc = sc;
248 ifp->if_start = i82586_start;
249 ifp->if_ioctl = i82586_ioctl;
250 ifp->if_init = i82586_init;
251 ifp->if_stop = i82586_stop;
252 ifp->if_watchdog = i82586_watchdog;
253 ifp->if_flags =
254 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
255 IFQ_SET_READY(&ifp->if_snd);
256
257 /* Initialize media goo. */
258 ifmedia_init(&sc->sc_media, 0, i82586_mediachange, i82586_mediastatus);
259 if (media != NULL) {
260 for (i = 0; i < nmedia; i++)
261 ifmedia_add(&sc->sc_media, media[i], 0, NULL);
262 ifmedia_set(&sc->sc_media, defmedia);
263 } else {
264 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
265 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
266 }
267
268 if (padbuf == NULL) {
269 padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
270 M_ZERO | M_NOWAIT);
271 if (padbuf == NULL) {
272 aprint_error_dev(&sc->sc_dev, "can't allocate pad buffer\n");
273 return;
274 }
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", device_xname(&sc->sc_dev));
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 u_int16_t cmd;
309
310 for (i = 0; i < 900000; i++) {
311 /* Read the command word */
312 off = IE_SCB_CMD(sc->scb);
313
314 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
315 if ((cmd = sc->ie_bus_read16(sc, off)) == 0)
316 return (0);
317 delay(1);
318 }
319
320 off = IE_SCB_STATUS(sc->scb);
321 printf("i82586_cmd_wait: timo(%ssync): scb status: 0x%x, cmd: 0x%x\n",
322 sc->async_cmd_inprogress?"a":"",
323 sc->ie_bus_read16(sc, off), cmd);
324
325 return (1); /* Timeout */
326 }
327
328 /*
329 * Send a command to the controller and wait for it to either complete
330 * or be accepted, depending on the command. If the command pointer
331 * is null, then pretend that the command is not an action command.
332 * If the command pointer is not null, and the command is an action
333 * command, wait for one of the MASK bits to turn on in the command's
334 * status field.
335 * If ASYNC is set, we just call the chip's attention and return.
336 * We may have to wait for the command's acceptance later though.
337 */
338 static int
339 i82586_start_cmd(sc, cmd, iecmdbuf, mask, async)
340 struct ie_softc *sc;
341 int cmd;
342 int iecmdbuf;
343 int mask;
344 int async;
345 {
346 int i;
347 int off;
348
349 if (sc->async_cmd_inprogress != 0) {
350 /*
351 * If previous command was issued asynchronously, wait
352 * for it now.
353 */
354 if (i82586_cmd_wait(sc) != 0)
355 return (1);
356 sc->async_cmd_inprogress = 0;
357 }
358
359 off = IE_SCB_CMD(sc->scb);
360 sc->ie_bus_write16(sc, off, cmd);
361 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
362 (sc->chan_attn)(sc, CARD_RESET);
363
364 if (async != 0) {
365 sc->async_cmd_inprogress = 1;
366 return (0);
367 }
368
369 if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
370 int status;
371 /*
372 * Now spin-lock waiting for status. This is not a very nice
373 * thing to do, and can kill performance pretty well...
374 * According to the packet driver, the minimum timeout
375 * should be .369 seconds.
376 */
377 for (i = 0; i < 369000; i++) {
378 /* Read the command status */
379 off = IE_CMD_COMMON_STATUS(iecmdbuf);
380 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
381 status = sc->ie_bus_read16(sc, off);
382 if (status & mask)
383 return (0);
384 delay(1);
385 }
386
387 } else {
388 /*
389 * Otherwise, just wait for the command to be accepted.
390 */
391 return (i82586_cmd_wait(sc));
392 }
393
394 /* Timeout */
395 return (1);
396 }
397
398 /*
399 * Interrupt Acknowledge.
400 */
401 static inline void
402 ie_ack(sc, mask)
403 struct ie_softc *sc;
404 u_int mask; /* in native byte-order */
405 {
406 u_int status;
407
408 IE_BUS_BARRIER(sc, 0, 0, BUS_SPACE_BARRIER_READ);
409 status = sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb));
410 i82586_start_cmd(sc, status & mask, 0, 0, 0);
411 if (sc->intrhook)
412 sc->intrhook(sc, INTR_ACK);
413 }
414
415 /*
416 * Transfer accumulated chip error counters to IF.
417 */
418 static inline void
419 i82586_count_errors(sc)
420 struct ie_softc *sc;
421 {
422 int scb = sc->scb;
423
424 sc->sc_ethercom.ec_if.if_ierrors +=
425 sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
426 sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
427 sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
428 sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb));
429
430 /* Clear error counters */
431 sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
432 sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
433 sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
434 sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
435 }
436
437 static void
438 i82586_rx_errors(sc, fn, status)
439 struct ie_softc *sc;
440 int fn;
441 int status;
442 {
443 char bits[128];
444
445 log(LOG_ERR, "%s: rx error (frame# %d): %s\n", device_xname(&sc->sc_dev), fn,
446 bitmask_snprintf(status, IE_FD_STATUSBITS, bits, sizeof(bits)));
447 }
448
449 /*
450 * i82586 interrupt entry point.
451 */
452 int
453 i82586_intr(v)
454 void *v;
455 {
456 struct ie_softc *sc = v;
457 u_int status;
458 int off;
459
460 /*
461 * Implementation dependent interrupt handling.
462 */
463 if (sc->intrhook)
464 (sc->intrhook)(sc, INTR_ENTER);
465
466 off = IE_SCB_STATUS(sc->scb);
467 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
468 status = sc->ie_bus_read16(sc, off) & IE_ST_WHENCE;
469
470 if ((status & IE_ST_WHENCE) == 0) {
471 if (sc->intrhook)
472 (sc->intrhook)(sc, INTR_EXIT);
473
474 return (0);
475 }
476
477 loop:
478 /* Ack interrupts FIRST in case we receive more during the ISR. */
479 #if 0
480 ie_ack(sc, status & IE_ST_WHENCE);
481 #endif
482 i82586_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1);
483
484 if (status & (IE_ST_FR | IE_ST_RNR))
485 if (i82586_rint(sc, status) != 0)
486 goto reset;
487
488 if (status & IE_ST_CX)
489 if (i82586_tint(sc, status) != 0)
490 goto reset;
491
492 #if I82586_DEBUG
493 if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
494 printf("%s: cna; status=0x%x\n", device_xname(&sc->sc_dev), status);
495 #endif
496 if (sc->intrhook)
497 (sc->intrhook)(sc, INTR_LOOP);
498
499 /*
500 * Interrupt ACK was posted asynchronously; wait for
501 * completion here before reading SCB status again.
502 *
503 * If ACK fails, try to reset the chip, in hopes that
504 * it helps.
505 */
506 if (i82586_cmd_wait(sc) != 0)
507 goto reset;
508
509 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
510 status = sc->ie_bus_read16(sc, off);
511 if ((status & IE_ST_WHENCE) != 0)
512 goto loop;
513
514 out:
515 if (sc->intrhook)
516 (sc->intrhook)(sc, INTR_EXIT);
517 return (1);
518
519 reset:
520 i82586_cmd_wait(sc);
521 i82586_reset(sc, 1);
522 goto out;
523
524 }
525
526 /*
527 * Process a received-frame interrupt.
528 */
529 int
530 i82586_rint(sc, scbstatus)
531 struct ie_softc *sc;
532 int scbstatus;
533 {
534 static int timesthru = 1024;
535 int i, status, off;
536
537 #if I82586_DEBUG
538 if (sc->sc_debug & IED_RINT)
539 printf("%s: rint: status 0x%x\n",
540 device_xname(&sc->sc_dev), scbstatus);
541 #endif
542
543 for (;;) {
544 int drop = 0;
545
546 i = sc->rfhead;
547 off = IE_RFRAME_STATUS(sc->rframes, i);
548 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
549 status = sc->ie_bus_read16(sc, off);
550
551 #if I82586_DEBUG
552 if (sc->sc_debug & IED_RINT)
553 printf("%s: rint: frame(%d) status 0x%x\n",
554 device_xname(&sc->sc_dev), i, status);
555 #endif
556 if ((status & IE_FD_COMPLETE) == 0) {
557 if ((status & IE_FD_OK) != 0) {
558 printf("%s: rint: weird: ",
559 device_xname(&sc->sc_dev));
560 i82586_rx_errors(sc, i, status);
561 break;
562 }
563 if (--timesthru == 0) {
564 /* Account the accumulated errors */
565 i82586_count_errors(sc);
566 timesthru = 1024;
567 }
568 break;
569 } else if ((status & IE_FD_OK) == 0) {
570 /*
571 * If the chip is configured to automatically
572 * discard bad frames, the only reason we can
573 * get here is an "out-of-resource" condition.
574 */
575 i82586_rx_errors(sc, i, status);
576 drop = 1;
577 }
578
579 #if I82586_DEBUG
580 if ((status & IE_FD_BUSY) != 0)
581 printf("%s: rint: frame(%d) busy; status=0x%x\n",
582 device_xname(&sc->sc_dev), i, status);
583 #endif
584
585
586 /*
587 * Advance the RFD list, since we're done with
588 * this descriptor.
589 */
590
591 /* Clear frame status */
592 sc->ie_bus_write16(sc, off, 0);
593
594 /* Put fence at this frame (the head) */
595 off = IE_RFRAME_LAST(sc->rframes, i);
596 sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP);
597
598 /* and clear RBD field */
599 off = IE_RFRAME_BUFDESC(sc->rframes, i);
600 sc->ie_bus_write16(sc, off, 0xffff);
601
602 /* Remove fence from current tail */
603 off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
604 sc->ie_bus_write16(sc, off, 0);
605
606 if (++sc->rftail == sc->nframes)
607 sc->rftail = 0;
608 if (++sc->rfhead == sc->nframes)
609 sc->rfhead = 0;
610
611 /* Pull the frame off the board */
612 if (drop) {
613 i82586_drop_frames(sc);
614 if ((status & IE_FD_RNR) != 0)
615 sc->rnr_expect = 1;
616 sc->sc_ethercom.ec_if.if_ierrors++;
617 } else if (ie_readframe(sc, i) != 0)
618 return (1);
619 }
620
621 if ((scbstatus & IE_ST_RNR) != 0) {
622
623 /*
624 * Receiver went "Not Ready". We try to figure out
625 * whether this was an expected event based on past
626 * frame status values.
627 */
628
629 if ((scbstatus & IE_RUS_SUSPEND) != 0) {
630 /*
631 * We use the "suspend on last frame" flag.
632 * Send a RU RESUME command in response, since
633 * we should have dealt with all completed frames
634 * by now.
635 */
636 printf("RINT: SUSPENDED; scbstatus=0x%x\n",
637 scbstatus);
638 if (i82586_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
639 return (0);
640 aprint_error_dev(&sc->sc_dev, "RU RESUME command timed out\n");
641 return (1); /* Ask for a reset */
642 }
643
644 if (sc->rnr_expect != 0) {
645 /*
646 * The RNR condition was announced in the previously
647 * completed frame. Assume the receive ring is Ok,
648 * so restart the receiver without further delay.
649 */
650 i82586_start_transceiver(sc);
651 sc->rnr_expect = 0;
652 return (0);
653
654 } else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
655 /*
656 * We saw no previous IF_FD_RNR flag.
657 * We check our ring invariants and, if ok,
658 * just restart the receiver at the current
659 * point in the ring.
660 */
661 if (i82586_chk_rx_ring(sc) != 0)
662 return (1);
663
664 i82586_start_transceiver(sc);
665 sc->sc_ethercom.ec_if.if_ierrors++;
666 return (0);
667 } else
668 printf("%s: receiver not ready; scbstatus=0x%x\n",
669 device_xname(&sc->sc_dev), scbstatus);
670
671 sc->sc_ethercom.ec_if.if_ierrors++;
672 return (1); /* Ask for a reset */
673 }
674
675 return (0);
676 }
677
678 /*
679 * Process a command-complete interrupt. These are only generated by the
680 * transmission of frames. This routine is deceptively simple, since most
681 * of the real work is done by i82586_start().
682 */
683 int
684 i82586_tint(sc, scbstatus)
685 struct ie_softc *sc;
686 int scbstatus;
687 {
688 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
689 int status;
690
691 ifp->if_timer = 0;
692 ifp->if_flags &= ~IFF_OACTIVE;
693
694 #if I82586_DEBUG
695 if (sc->xmit_busy <= 0) {
696 printf("i82586_tint: WEIRD: xmit_busy=%d, xctail=%d, xchead=%d\n",
697 sc->xmit_busy, sc->xctail, sc->xchead);
698 return (0);
699 }
700 #endif
701
702 status = sc->ie_bus_read16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds,
703 sc->xctail));
704
705 #if I82586_DEBUG
706 if (sc->sc_debug & IED_TINT)
707 printf("%s: tint: SCB status 0x%x; xmit status 0x%x\n",
708 device_xname(&sc->sc_dev), scbstatus, status);
709 #endif
710
711 if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) {
712 printf("i82586_tint: command still busy; status=0x%x; tail=%d\n",
713 status, sc->xctail);
714 printf("iestatus = 0x%x\n", scbstatus);
715 }
716
717 if (status & IE_STAT_OK) {
718 ifp->if_opackets++;
719 ifp->if_collisions += (status & IE_XS_MAXCOLL);
720 } else {
721 ifp->if_oerrors++;
722 /*
723 * Check SQE and DEFERRED?
724 * What if more than one bit is set?
725 */
726 if (status & IE_STAT_ABORT)
727 aprint_error_dev(&sc->sc_dev, "send aborted\n");
728 else if (status & IE_XS_NOCARRIER)
729 aprint_error_dev(&sc->sc_dev, "no carrier\n");
730 else if (status & IE_XS_LOSTCTS)
731 aprint_error_dev(&sc->sc_dev, "lost CTS\n");
732 else if (status & IE_XS_UNDERRUN)
733 aprint_error_dev(&sc->sc_dev, "DMA underrun\n");
734 else if (status & IE_XS_EXCMAX) {
735 aprint_error_dev(&sc->sc_dev, "too many collisions\n");
736 sc->sc_ethercom.ec_if.if_collisions += 16;
737 }
738 }
739
740 /*
741 * If multicast addresses were added or deleted while transmitting,
742 * ie_mc_reset() set the want_mcsetup flag indicating that we
743 * should do it.
744 */
745 if (sc->want_mcsetup) {
746 ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
747 sc->want_mcsetup = 0;
748 }
749
750 /* Done with the buffer. */
751 sc->xmit_busy--;
752 sc->xctail = (sc->xctail + 1) % NTXBUF;
753
754 /* Start the next packet, if any, transmitting. */
755 if (sc->xmit_busy > 0)
756 iexmit(sc);
757
758 i82586_start(ifp);
759 return (0);
760 }
761
762 /*
763 * Get a range of receive buffer descriptors that represent one packet.
764 */
765 static int
766 i82586_get_rbd_list(sc, start, end, pktlen)
767 struct ie_softc *sc;
768 u_int16_t *start;
769 u_int16_t *end;
770 int *pktlen;
771 {
772 int off, rbbase = sc->rbds;
773 int rbindex, count = 0;
774 int plen = 0;
775 int rbdstatus;
776
777 *start = rbindex = sc->rbhead;
778
779 do {
780 off = IE_RBD_STATUS(rbbase, rbindex);
781 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
782 rbdstatus = sc->ie_bus_read16(sc, off);
783 if ((rbdstatus & IE_RBD_USED) == 0) {
784 /*
785 * This means we are somehow out of sync. So, we
786 * reset the adapter.
787 */
788 #if I82586_DEBUG
789 print_rbd(sc, rbindex);
790 #endif
791 log(LOG_ERR,
792 "%s: receive descriptors out of sync at %d\n",
793 device_xname(&sc->sc_dev), rbindex);
794 return (0);
795 }
796 plen += (rbdstatus & IE_RBD_CNTMASK);
797
798 if (++rbindex == sc->nrxbuf)
799 rbindex = 0;
800
801 ++count;
802 } while ((rbdstatus & IE_RBD_LAST) == 0);
803 *end = rbindex;
804 *pktlen = plen;
805 return (count);
806 }
807
808
809 /*
810 * Release a range of receive buffer descriptors after we've copied the packet.
811 */
812 static void
813 i82586_release_rbd_list(sc, start, end)
814 struct ie_softc *sc;
815 u_int16_t start;
816 u_int16_t end;
817 {
818 int off, rbbase = sc->rbds;
819 int rbindex = start;
820
821 do {
822 /* Clear buffer status */
823 off = IE_RBD_STATUS(rbbase, rbindex);
824 sc->ie_bus_write16(sc, off, 0);
825 if (++rbindex == sc->nrxbuf)
826 rbindex = 0;
827 } while (rbindex != end);
828
829 /* Mark EOL at new tail */
830 rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
831 off = IE_RBD_BUFLEN(rbbase, rbindex);
832 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL);
833
834 /* Remove EOL from current tail */
835 off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
836 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
837
838 /* New head & tail pointer */
839 /* hmm, why have both? head is always (tail + 1) % NRXBUF */
840 sc->rbhead = end;
841 sc->rbtail = rbindex;
842 }
843
844 /*
845 * Drop the packet at the head of the RX buffer ring.
846 * Called if the frame descriptor reports an error on this packet.
847 * Returns 1 if the buffer descriptor ring appears to be corrupt;
848 * and 0 otherwise.
849 */
850 static int
851 i82586_drop_frames(sc)
852 struct ie_softc *sc;
853 {
854 u_int16_t bstart, bend;
855 int pktlen;
856
857 if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0)
858 return (1);
859 i82586_release_rbd_list(sc, bstart, bend);
860 return (0);
861 }
862
863 /*
864 * Check the RX frame & buffer descriptor lists for our invariants,
865 * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer.
866 *
867 * Called when the receive unit has stopped unexpectedly.
868 * Returns 1 if an inconsistency is detected; 0 otherwise.
869 *
870 * The Receive Unit is expected to be NOT RUNNING.
871 */
872 static int
873 i82586_chk_rx_ring(sc)
874 struct ie_softc *sc;
875 {
876 int n, off, val;
877
878 for (n = 0; n < sc->nrxbuf; n++) {
879 off = IE_RBD_BUFLEN(sc->rbds, n);
880 val = sc->ie_bus_read16(sc, off);
881 if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
882 /* `rbtail' and EOL flag out of sync */
883 log(LOG_ERR,
884 "%s: rx buffer descriptors out of sync at %d\n",
885 device_xname(&sc->sc_dev), n);
886 return (1);
887 }
888
889 /* Take the opportunity to clear the status fields here ? */
890 }
891
892 for (n = 0; n < sc->nframes; n++) {
893 off = IE_RFRAME_LAST(sc->rframes, n);
894 val = sc->ie_bus_read16(sc, off);
895 if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) {
896 /* `rftail' and EOL flag out of sync */
897 log(LOG_ERR,
898 "%s: rx frame list out of sync at %d\n",
899 device_xname(&sc->sc_dev), n);
900 return (1);
901 }
902 }
903
904 return (0);
905 }
906
907 /*
908 * Read data off the interface, and turn it into an mbuf chain.
909 *
910 * This code is DRAMATICALLY different from the previous version; this
911 * version tries to allocate the entire mbuf chain up front, given the
912 * length of the data available. This enables us to allocate mbuf
913 * clusters in many situations where before we would have had a long
914 * chain of partially-full mbufs. This should help to speed up the
915 * operation considerably. (Provided that it works, of course.)
916 */
917 static inline struct mbuf *
918 ieget(sc, head, totlen)
919 struct ie_softc *sc;
920 int head;
921 int totlen;
922 {
923 struct mbuf *m, *m0, *newm;
924 int len, resid;
925 int thisrboff, thismboff;
926 struct ether_header eh;
927
928 /*
929 * Snarf the Ethernet header.
930 */
931 (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
932 sizeof(struct ether_header));
933
934 resid = totlen;
935
936 MGETHDR(m0, M_DONTWAIT, MT_DATA);
937 if (m0 == 0)
938 return (0);
939 m0->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if;
940 m0->m_pkthdr.len = totlen;
941 len = MHLEN;
942 m = m0;
943
944 /*
945 * This loop goes through and allocates mbufs for all the data we will
946 * be copying in. It does not actually do the copying yet.
947 */
948 while (totlen > 0) {
949 if (totlen >= MINCLSIZE) {
950 MCLGET(m, M_DONTWAIT);
951 if ((m->m_flags & M_EXT) == 0)
952 goto bad;
953 len = MCLBYTES;
954 }
955
956 if (m == m0) {
957 char *newdata = (char *)
958 ALIGN(m->m_data + sizeof(struct ether_header)) -
959 sizeof(struct ether_header);
960 len -= newdata - m->m_data;
961 m->m_data = newdata;
962 }
963
964 m->m_len = len = min(totlen, len);
965
966 totlen -= len;
967 if (totlen > 0) {
968 MGET(newm, M_DONTWAIT, MT_DATA);
969 if (newm == 0)
970 goto bad;
971 len = MLEN;
972 m = m->m_next = newm;
973 }
974 }
975
976 m = m0;
977 thismboff = 0;
978
979 /*
980 * Copy the Ethernet header into the mbuf chain.
981 */
982 memcpy(mtod(m, void *), &eh, sizeof(struct ether_header));
983 thismboff = sizeof(struct ether_header);
984 thisrboff = sizeof(struct ether_header);
985 resid -= sizeof(struct ether_header);
986
987 /*
988 * Now we take the mbuf chain (hopefully only one mbuf most of the
989 * time) and stuff the data into it. There are no possible failures
990 * at or after this point.
991 */
992 while (resid > 0) {
993 int thisrblen = IE_RBUF_SIZE - thisrboff,
994 thismblen = m->m_len - thismboff;
995 len = min(thisrblen, thismblen);
996
997 (sc->memcopyin)(sc, mtod(m, char *) + thismboff,
998 IE_RBUF_ADDR(sc,head) + thisrboff,
999 (u_int)len);
1000 resid -= len;
1001
1002 if (len == thismblen) {
1003 m = m->m_next;
1004 thismboff = 0;
1005 } else
1006 thismboff += len;
1007
1008 if (len == thisrblen) {
1009 if (++head == sc->nrxbuf)
1010 head = 0;
1011 thisrboff = 0;
1012 } else
1013 thisrboff += len;
1014 }
1015
1016 /*
1017 * Unless something changed strangely while we were doing the copy,
1018 * we have now copied everything in from the shared memory.
1019 * This means that we are done.
1020 */
1021 return (m0);
1022
1023 bad:
1024 m_freem(m0);
1025 return (0);
1026 }
1027
1028 /*
1029 * Read frame NUM from unit UNIT (pre-cached as IE).
1030 *
1031 * This routine reads the RFD at NUM, and copies in the buffers from the list
1032 * of RBD, then rotates the RBD list so that the receiver doesn't start
1033 * complaining. Trailers are DROPPED---there's no point in wasting time
1034 * on confusing code to deal with them. Hopefully, this machine will
1035 * never ARP for trailers anyway.
1036 */
1037 static int
1038 ie_readframe(
1039 struct ie_softc *sc,
1040 int num) /* frame number to read */
1041 {
1042 struct mbuf *m;
1043 u_int16_t bstart, bend;
1044 int pktlen;
1045
1046 if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
1047 sc->sc_ethercom.ec_if.if_ierrors++;
1048 return (1);
1049 }
1050
1051 m = ieget(sc, bstart, pktlen);
1052 i82586_release_rbd_list(sc, bstart, bend);
1053
1054 if (m == 0) {
1055 sc->sc_ethercom.ec_if.if_ierrors++;
1056 return (0);
1057 }
1058
1059 #if I82586_DEBUG
1060 if (sc->sc_debug & IED_READFRAME) {
1061 struct ether_header *eh = mtod(m, struct ether_header *);
1062
1063 printf("%s: frame from ether %s type 0x%x len %d\n",
1064 device_xname(&sc->sc_dev),
1065 ether_sprintf(eh->ether_shost),
1066 (u_int)ntohs(eh->ether_type),
1067 pktlen);
1068 }
1069 #endif
1070
1071 #if NBPFILTER > 0
1072 /* Check for a BPF filter; if so, hand it up. */
1073 if (sc->sc_ethercom.ec_if.if_bpf != 0)
1074 /* Pass it up. */
1075 bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, m);
1076 #endif /* NBPFILTER > 0 */
1077
1078 /*
1079 * Finally pass this packet up to higher layers.
1080 */
1081 (*sc->sc_ethercom.ec_if.if_input)(&sc->sc_ethercom.ec_if, m);
1082 sc->sc_ethercom.ec_if.if_ipackets++;
1083 return (0);
1084 }
1085
1086
1087 /*
1088 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
1089 * command to the chip to be executed.
1090 */
1091 static inline void
1092 iexmit(sc)
1093 struct ie_softc *sc;
1094 {
1095 int off;
1096 int cur, prev;
1097
1098 cur = sc->xctail;
1099
1100 #if I82586_DEBUG
1101 if (sc->sc_debug & IED_XMIT)
1102 printf("%s: xmit buffer %d\n", device_xname(&sc->sc_dev), cur);
1103 #endif
1104
1105 /*
1106 * Setup the transmit command.
1107 */
1108 sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
1109 IE_XBD_ADDR(sc->xbds, cur));
1110
1111 sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
1112
1113 if (sc->do_xmitnopchain) {
1114 /*
1115 * Gate this XMIT command to the following NOP
1116 */
1117 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
1118 IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1119 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1120 IE_CMD_XMIT | IE_CMD_INTR);
1121
1122 /*
1123 * Loopback at following NOP
1124 */
1125 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
1126 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
1127 IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1128
1129 /*
1130 * Gate preceding NOP to this XMIT command
1131 */
1132 prev = (cur + NTXBUF - 1) % NTXBUF;
1133 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0);
1134 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
1135 IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
1136
1137 off = IE_SCB_STATUS(sc->scb);
1138 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1139 if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
1140 printf("iexmit: CU not active\n");
1141 i82586_start_transceiver(sc);
1142 }
1143 } else {
1144 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur),
1145 0xffff);
1146
1147 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1148 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
1149
1150 off = IE_SCB_CMDLST(sc->scb);
1151 sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
1152 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1153
1154 if (i82586_start_cmd(sc, IE_CUC_START, 0, 0, 1))
1155 aprint_error_dev(&sc->sc_dev, "iexmit: start xmit command timed out\n");
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", device_xname(&sc->sc_dev),
1204 sc->xchead);
1205 #endif
1206
1207 if (m0->m_pkthdr.len > IE_TBUF_SIZE)
1208 printf("%s: tbuf overflow\n", device_xname(&sc->sc_dev));
1209
1210 buffer = IE_XBUF_ADDR(sc, head);
1211 for (m = m0; m != 0; m = m->m_next) {
1212 (sc->memcopyout)(sc, mtod(m,void *), buffer, m->m_len);
1213 buffer += m->m_len;
1214 }
1215 len = m0->m_pkthdr.len;
1216 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1217 (sc->memcopyout)(sc, padbuf, buffer,
1218 ETHER_MIN_LEN - ETHER_CRC_LEN - len);
1219 buffer += ETHER_MIN_LEN -ETHER_CRC_LEN - len;
1220 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1221 }
1222 m_freem(m0);
1223
1224 /*
1225 * Setup the transmit buffer descriptor here, while we
1226 * know the packet's length.
1227 */
1228 sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
1229 len | IE_TBD_EOL);
1230 sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
1231 sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
1232 IE_XBUF_ADDR(sc, head));
1233
1234 if (++head == NTXBUF)
1235 head = 0;
1236 sc->xchead = head;
1237
1238 s = splnet();
1239 /* Start the first packet transmitting. */
1240 if (sc->xmit_busy == 0)
1241 iexmit(sc);
1242
1243 sc->xmit_busy++;
1244 splx(s);
1245 }
1246 }
1247
1248 /*
1249 * Probe IE's ram setup [ Move all this into MD front-end!? ]
1250 * Use only if SCP and ISCP represent offsets into shared ram space.
1251 */
1252 int
1253 i82586_proberam(sc)
1254 struct ie_softc *sc;
1255 {
1256 int result, off;
1257
1258 /* Put in 16-bit mode */
1259 off = IE_SCP_BUS_USE(sc->scp);
1260 sc->ie_bus_write16(sc, off, IE_SYSBUS_16BIT);
1261 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1262
1263 /* Set the ISCP `busy' bit */
1264 off = IE_ISCP_BUSY(sc->iscp);
1265 sc->ie_bus_write16(sc, off, 1);
1266 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1267
1268 if (sc->hwreset)
1269 (sc->hwreset)(sc, CHIP_PROBE);
1270
1271 (sc->chan_attn) (sc, CHIP_PROBE);
1272
1273 delay(100); /* wait a while... */
1274
1275 /* Read back the ISCP `busy' bit; it should be clear by now */
1276 off = IE_ISCP_BUSY(sc->iscp);
1277 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1278 result = sc->ie_bus_read16(sc, off) == 0;
1279
1280 /* Acknowledge any interrupts we may have caused. */
1281 ie_ack(sc, IE_ST_WHENCE);
1282
1283 return (result);
1284 }
1285
1286 void
1287 i82586_reset(sc, hard)
1288 struct ie_softc *sc;
1289 int hard;
1290 {
1291 int s = splnet();
1292
1293 if (hard)
1294 printf("%s: reset\n", device_xname(&sc->sc_dev));
1295
1296 /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
1297 sc->sc_ethercom.ec_if.if_timer = 0;
1298 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
1299
1300 /*
1301 * Stop i82586 dead in its tracks.
1302 */
1303 if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0))
1304 aprint_error_dev(&sc->sc_dev, "abort commands timed out\n");
1305
1306 /*
1307 * This can really slow down the i82586_reset() on some cards, but it's
1308 * necessary to unwedge other ones (eg, the Sun VME ones) from certain
1309 * lockups.
1310 */
1311 if (hard && sc->hwreset)
1312 (sc->hwreset)(sc, CARD_RESET);
1313
1314 delay(100);
1315 ie_ack(sc, IE_ST_WHENCE);
1316
1317 if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) {
1318 int retries=0; /* XXX - find out why init sometimes fails */
1319 while (retries++ < 2)
1320 if (i82586_init(&sc->sc_ethercom.ec_if) == 0)
1321 break;
1322 }
1323
1324 splx(s);
1325 }
1326
1327
1328 static void
1329 setup_simple_command(sc, cmd, cmdbuf)
1330 struct ie_softc *sc;
1331 int cmd;
1332 int cmdbuf;
1333 {
1334 /* Setup a simple command */
1335 sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
1336 sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
1337 sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
1338
1339 /* Assign the command buffer to the SCB command list */
1340 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
1341 }
1342
1343 /*
1344 * Run the time-domain reflectometer.
1345 */
1346 static void
1347 ie_run_tdr(sc, cmd)
1348 struct ie_softc *sc;
1349 int cmd;
1350 {
1351 int result;
1352
1353 setup_simple_command(sc, IE_CMD_TDR, cmd);
1354 sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0);
1355
1356 if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
1357 (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0)
1358 result = 0x10000; /* XXX */
1359 else
1360 result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
1361
1362 /* Squash any pending interrupts */
1363 ie_ack(sc, IE_ST_WHENCE);
1364
1365 if (result & IE_TDR_SUCCESS)
1366 return;
1367
1368 if (result & 0x10000)
1369 aprint_error_dev(&sc->sc_dev, "TDR command failed\n");
1370 else if (result & IE_TDR_XCVR)
1371 aprint_error_dev(&sc->sc_dev, "transceiver problem\n");
1372 else if (result & IE_TDR_OPEN)
1373 aprint_error_dev(&sc->sc_dev, "TDR detected incorrect termination %d clocks away\n",
1374 result & IE_TDR_TIME);
1375 else if (result & IE_TDR_SHORT)
1376 aprint_error_dev(&sc->sc_dev, "TDR detected a short circuit %d clocks away\n",
1377 result & IE_TDR_TIME);
1378 else
1379 aprint_error_dev(&sc->sc_dev, "TDR returned unknown status 0x%x\n",
1380 result);
1381 }
1382
1383
1384 /*
1385 * i82586_setup_bufs: set up the buffers
1386 *
1387 * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1388 * this is to be used for the buffers. The chip indexs its control data
1389 * structures with 16 bit offsets, and it indexes actual buffers with
1390 * 24 bit addresses. So we should allocate control buffers first so that
1391 * we don't overflow the 16 bit offset field. The number of transmit
1392 * buffers is fixed at compile time.
1393 *
1394 */
1395 static void
1396 i82586_setup_bufs(sc)
1397 struct ie_softc *sc;
1398 {
1399 int ptr = sc->buf_area; /* memory pool */
1400 int n, r;
1401
1402 /*
1403 * step 0: zero memory and figure out how many recv buffers and
1404 * frames we can have.
1405 */
1406 ptr = (ptr + 3) & ~3; /* set alignment and stick with it */
1407
1408
1409 /*
1410 * step 1: lay out data structures in the shared-memory area
1411 */
1412
1413 /* The no-op commands; used if "nop-chaining" is in effect */
1414 sc->nop_cmds = ptr;
1415 ptr += NTXBUF * IE_CMD_NOP_SZ;
1416
1417 /* The transmit commands */
1418 sc->xmit_cmds = ptr;
1419 ptr += NTXBUF * IE_CMD_XMIT_SZ;
1420
1421 /* The transmit buffers descriptors */
1422 sc->xbds = ptr;
1423 ptr += NTXBUF * IE_XBD_SZ;
1424
1425 /* The transmit buffers */
1426 sc->xbufs = ptr;
1427 ptr += NTXBUF * IE_TBUF_SIZE;
1428
1429 ptr = (ptr + 3) & ~3; /* re-align.. just in case */
1430
1431 /* Compute free space for RECV stuff */
1432 n = sc->buf_area_sz - (ptr - sc->buf_area);
1433
1434 /* Compute size of one RECV frame */
1435 r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F);
1436
1437 sc->nframes = n / r;
1438
1439 if (sc->nframes <= 0)
1440 panic("ie: bogus buffer calc");
1441
1442 sc->nrxbuf = sc->nframes * B_PER_F;
1443
1444 /* The receive frame descriptors */
1445 sc->rframes = ptr;
1446 ptr += sc->nframes * IE_RFRAME_SZ;
1447
1448 /* The receive buffer descriptors */
1449 sc->rbds = ptr;
1450 ptr += sc->nrxbuf * IE_RBD_SZ;
1451
1452 /* The receive buffers */
1453 sc->rbufs = ptr;
1454 ptr += sc->nrxbuf * IE_RBUF_SIZE;
1455
1456 #if I82586_DEBUG
1457 printf("%s: %d frames %d bufs\n", device_xname(&sc->sc_dev), sc->nframes,
1458 sc->nrxbuf);
1459 #endif
1460
1461 /*
1462 * step 2: link together the recv frames and set EOL on last one
1463 */
1464 for (n = 0; n < sc->nframes; n++) {
1465 int m = (n == sc->nframes - 1) ? 0 : n + 1;
1466
1467 /* Clear status */
1468 sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
1469
1470 /* RBD link = NULL */
1471 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
1472 0xffff);
1473
1474 /* Make a circular list */
1475 sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
1476 IE_RFRAME_ADDR(sc->rframes,m));
1477
1478 /* Mark last as EOL */
1479 sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
1480 ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
1481 }
1482
1483 /*
1484 * step 3: link the RBDs and set EOL on last one
1485 */
1486 for (n = 0; n < sc->nrxbuf; n++) {
1487 int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
1488
1489 /* Clear status */
1490 sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
1491
1492 /* Make a circular list */
1493 sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
1494 IE_RBD_ADDR(sc->rbds,m));
1495
1496 /* Link to data buffers */
1497 sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
1498 IE_RBUF_ADDR(sc, n));
1499 sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
1500 IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
1501 }
1502
1503 /*
1504 * step 4: all xmit no-op commands loopback onto themselves
1505 */
1506 for (n = 0; n < NTXBUF; n++) {
1507 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
1508
1509 sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
1510 IE_CMD_NOP);
1511
1512 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
1513 IE_CMD_NOP_ADDR(sc->nop_cmds, n));
1514 }
1515
1516
1517 /*
1518 * step 6: set the head and tail pointers on receive to keep track of
1519 * the order in which RFDs and RBDs are used.
1520 */
1521
1522 /* Pointers to last packet sent and next available transmit buffer. */
1523 sc->xchead = sc->xctail = 0;
1524
1525 /* Clear transmit-busy flag and set number of free transmit buffers. */
1526 sc->xmit_busy = 0;
1527
1528 /*
1529 * Pointers to first and last receive frame.
1530 * The RFD pointed to by rftail is the only one that has EOL set.
1531 */
1532 sc->rfhead = 0;
1533 sc->rftail = sc->nframes - 1;
1534
1535 /*
1536 * Pointers to first and last receive descriptor buffer.
1537 * The RBD pointed to by rbtail is the only one that has EOL set.
1538 */
1539 sc->rbhead = 0;
1540 sc->rbtail = sc->nrxbuf - 1;
1541
1542 /* link in recv frames * and buffer into the scb. */
1543 #if I82586_DEBUG
1544 printf("%s: reserved %d bytes\n",
1545 device_xname(&sc->sc_dev), ptr - sc->buf_area);
1546 #endif
1547 }
1548
1549 static int
1550 ie_cfg_setup(sc, cmd, promiscuous, manchester)
1551 struct ie_softc *sc;
1552 int cmd;
1553 int promiscuous, manchester;
1554 {
1555 int cmdresult, status;
1556 u_int8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */
1557
1558 *IE_CMD_CFG_CNT(buf) = 0x0c;
1559 *IE_CMD_CFG_FIFO(buf) = 8;
1560 *IE_CMD_CFG_SAVEBAD(buf) = 0x40;
1561 *IE_CMD_CFG_ADDRLEN(buf) = 0x2e;
1562 *IE_CMD_CFG_PRIORITY(buf) = 0;
1563 *IE_CMD_CFG_IFS(buf) = 0x60;
1564 *IE_CMD_CFG_SLOT_LOW(buf) = 0;
1565 *IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2;
1566 *IE_CMD_CFG_PROMISC(buf) = !!promiscuous | manchester << 2;
1567 *IE_CMD_CFG_CRSCDT(buf) = 0;
1568 *IE_CMD_CFG_MINLEN(buf) = 64;
1569 *IE_CMD_CFG_JUNK(buf) = 0xff;
1570 sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ);
1571 setup_simple_command(sc, IE_CMD_CONFIG, cmd);
1572 IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE);
1573
1574 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
1575 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
1576 if (cmdresult != 0) {
1577 aprint_error_dev(&sc->sc_dev, "configure command timed out; status %x\n", status);
1578 return (0);
1579 }
1580 if ((status & IE_STAT_OK) == 0) {
1581 aprint_error_dev(&sc->sc_dev, "configure command failed; status %x\n", status);
1582 return (0);
1583 }
1584
1585 /* Squash any pending interrupts */
1586 ie_ack(sc, IE_ST_WHENCE);
1587 return (1);
1588 }
1589
1590 static int
1591 ie_ia_setup(sc, cmdbuf)
1592 struct ie_softc *sc;
1593 int cmdbuf;
1594 {
1595 int cmdresult, status;
1596 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1597
1598 setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
1599
1600 (sc->memcopyout)(sc, CLLADDR(ifp->if_sadl),
1601 IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
1602
1603 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1604 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1605 if (cmdresult != 0) {
1606 aprint_error_dev(&sc->sc_dev, "individual address command timed out; status %x\n", status);
1607 return (0);
1608 }
1609 if ((status & IE_STAT_OK) == 0) {
1610 aprint_error_dev(&sc->sc_dev, "individual address command failed; status %x\n", 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, (void *)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 aprint_error_dev(&sc->sc_dev, "multicast setup command timed out; status %x\n", status);
1647 return (0);
1648 }
1649 if ((status & IE_STAT_OK) == 0) {
1650 aprint_error_dev(&sc->sc_dev, "multicast setup command failed; status %x\n",
1651 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 EIO;
1684
1685 /*
1686 * Send the Individual Address Setup command.
1687 */
1688 if (ie_ia_setup(sc, cmd) == 0)
1689 return EIO;
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 EIO;
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 aprint_error_dev(&sc->sc_dev, "CU/RU stop command timed out\n");
1746
1747 /* Start the receiver & transmitter chain */
1748 /* sc->scb->ie_command_list =
1749 IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
1750 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
1751 IE_CMD_NOP_ADDR(
1752 sc->nop_cmds,
1753 (sc->xctail + NTXBUF - 1) % NTXBUF));
1754
1755 if (i82586_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
1756 aprint_error_dev(&sc->sc_dev, "CU/RU command timed out\n");
1757 } else {
1758 if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0))
1759 aprint_error_dev(&sc->sc_dev, "RU command timed out\n");
1760 }
1761 }
1762
1763 void
1764 i82586_stop(
1765 struct ifnet *ifp,
1766 int disable)
1767 {
1768 struct ie_softc *sc = ifp->if_softc;
1769
1770 if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
1771 aprint_error_dev(&sc->sc_dev, "iestop: disable commands timed out\n");
1772 }
1773
1774 int
1775 i82586_ioctl(ifp, cmd, data)
1776 struct ifnet *ifp;
1777 u_long cmd;
1778 void *data;
1779 {
1780 struct ie_softc *sc = ifp->if_softc;
1781 struct ifreq *ifr = (struct ifreq *)data;
1782 int s, error = 0;
1783
1784 s = splnet();
1785 switch(cmd) {
1786 case SIOCGIFMEDIA:
1787 case SIOCSIFMEDIA:
1788 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1789 break;
1790 default:
1791 error = ether_ioctl(ifp, cmd, data);
1792 if (error == ENETRESET) {
1793 /*
1794 * Multicast list has changed; set the hardware filter
1795 * accordingly.
1796 */
1797 if (ifp->if_flags & IFF_RUNNING)
1798 ie_mc_reset(sc);
1799 error = 0;
1800 }
1801 break;
1802 }
1803 #if I82586_DEBUG
1804 if (cmd == SIOCSIFFLAGS)
1805 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0;
1806 #endif
1807 splx(s);
1808 return (error);
1809 }
1810
1811 static void
1812 ie_mc_reset(sc)
1813 struct ie_softc *sc;
1814 {
1815 struct ether_multi *enm;
1816 struct ether_multistep step;
1817 int size;
1818
1819 /*
1820 * Step through the list of addresses.
1821 */
1822 again:
1823 size = 0;
1824 sc->mcast_count = 0;
1825 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1826 while (enm) {
1827 size += 6;
1828 if (sc->mcast_count >= IE_MAXMCAST ||
1829 memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1830 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
1831 i82586_ioctl(&sc->sc_ethercom.ec_if,
1832 SIOCSIFFLAGS, (void *)0);
1833 return;
1834 }
1835 ETHER_NEXT_MULTI(step, enm);
1836 }
1837
1838 if (size > sc->mcast_addrs_size) {
1839 /* Need to allocate more space */
1840 if (sc->mcast_addrs_size)
1841 free(sc->mcast_addrs, M_IFMADDR);
1842 sc->mcast_addrs = (char *)
1843 malloc(size, M_IFMADDR, M_WAITOK);
1844 sc->mcast_addrs_size = size;
1845 }
1846
1847 /*
1848 * We've got the space; now copy the addresses
1849 */
1850 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1851 while (enm) {
1852 if (sc->mcast_count >= IE_MAXMCAST)
1853 goto again; /* Just in case */
1854
1855 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6);
1856 sc->mcast_count++;
1857 ETHER_NEXT_MULTI(step, enm);
1858 }
1859 sc->want_mcsetup = 1;
1860 }
1861
1862 /*
1863 * Media change callback.
1864 */
1865 int
1866 i82586_mediachange(ifp)
1867 struct ifnet *ifp;
1868 {
1869 struct ie_softc *sc = ifp->if_softc;
1870
1871 if (sc->sc_mediachange)
1872 return ((*sc->sc_mediachange)(sc));
1873 return (0);
1874 }
1875
1876 /*
1877 * Media status callback.
1878 */
1879 void
1880 i82586_mediastatus(ifp, ifmr)
1881 struct ifnet *ifp;
1882 struct ifmediareq *ifmr;
1883 {
1884 struct ie_softc *sc = ifp->if_softc;
1885
1886 if (sc->sc_mediastatus)
1887 (*sc->sc_mediastatus)(sc, ifmr);
1888 }
1889
1890 #if I82586_DEBUG
1891 void
1892 print_rbd(sc, n)
1893 struct ie_softc *sc;
1894 int n;
1895 {
1896
1897 printf("RBD at %08x:\n status %04x, next %04x, buffer %lx\n"
1898 "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
1899 sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)),
1900 sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
1901 (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
1902 sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
1903 }
1904 #endif
Cache object: 98997f636ecaab7691fb5f40c37fd5f3
|