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