if_ie.c revision 1.5 1 /* $NetBSD: if_ie.c,v 1.5 1995/04/11 06:05:11 mycroft Exp $ */
2
3 /*-
4 * Copyright (c) 1993, 1994, 1995 Charles Hannum.
5 * Copyright (c) 1992, 1993, University of Vermont and State
6 * Agricultural College.
7 * Copyright (c) 1992, 1993, Garrett A. Wollman.
8 *
9 * Portions:
10 * Copyright (c) 1994, 1995, Rafal K. Boni
11 * Copyright (c) 1990, 1991, William F. Jolitz
12 * Copyright (c) 1990, The Regents of the University of California
13 *
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by Charles Hannum, by the
27 * University of Vermont and State Agricultural College and Garrett A.
28 * Wollman, by William F. Jolitz, and by the University of California,
29 * Berkeley, Lawrence Berkeley Laboratory, and its contributors.
30 * 4. Neither the names of the Universities nor the names of the authors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 */
46
47 /*
48 * Intel 82586 Ethernet chip
49 * Register, bit, and structure definitions.
50 *
51 * Original StarLAN driver written by Garrett Wollman with reference to the
52 * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
53 *
54 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
55 *
56 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
57 *
58 * Majorly cleaned up and 3C507 code merged by Charles Hannum.
59 *
60 * Converted to SUN ie driver by Charles D. Cranor,
61 * October 1994, January 1995.
62 * This sun version based on i386 version 1.30.
63 */
64
65 /*
66 * The i82586 is a very painful chip, found in sun3's, sun-4/100's
67 * sun-4/200's, and VME based suns. The byte order is all wrong for a
68 * SUN, making life difficult. Programming this chip is mostly the same,
69 * but certain details differ from system to system. This driver is
70 * written so that different "ie" interfaces can be controled by the same
71 * driver.
72 */
73
74 /*
75 Mode of operation:
76
77 We run the 82586 in a standard Ethernet mode. We keep NFRAMES
78 received frame descriptors around for the receiver to use, and
79 NRXBUF associated receive buffer descriptors, both in a circular
80 list. Whenever a frame is received, we rotate both lists as
81 necessary. (The 586 treats both lists as a simple queue.) We also
82 keep a transmit command around so that packets can be sent off
83 quickly.
84
85 We configure the adapter in AL-LOC = 1 mode, which means that the
86 Ethernet/802.3 MAC header is placed at the beginning of the receive
87 buffer rather than being split off into various fields in the RFD.
88 This also means that we must include this header in the transmit
89 buffer as well.
90
91 By convention, all transmit commands, and only transmit commands,
92 shall have the I (IE_CMD_INTR) bit set in the command. This way,
93 when an interrupt arrives at ieintr(), it is immediately possible
94 to tell what precisely caused it. ANY OTHER command-sending
95 routines should run at splimp(), and should post an acknowledgement
96 to every interrupt they generate.
97 */
98
99 #include "bpfilter.h"
100
101 #include <sys/param.h>
102 #include <sys/systm.h>
103 #include <sys/mbuf.h>
104 #include <sys/buf.h>
105 #include <sys/protosw.h>
106 #include <sys/socket.h>
107 #include <sys/ioctl.h>
108 #include <sys/errno.h>
109 #include <sys/syslog.h>
110 #include <sys/device.h>
111
112 #include <net/if.h>
113 #include <net/if_types.h>
114 #include <net/if_dl.h>
115 #include <net/netisr.h>
116 #include <net/route.h>
117
118 #if NBPFILTER > 0
119 #include <net/bpf.h>
120 #include <net/bpfdesc.h>
121 #endif
122
123 #ifdef INET
124 #include <netinet/in.h>
125 #include <netinet/in_systm.h>
126 #include <netinet/in_var.h>
127 #include <netinet/ip.h>
128 #include <netinet/if_ether.h>
129 #endif
130
131 #ifdef NS
132 #include <netns/ns.h>
133 #include <netns/ns_if.h>
134 #endif
135
136 #include <vm/vm.h>
137
138 /*
139 * ugly byte-order hack for SUNs
140 */
141
142 #define SWAP(x) ((u_short)(XSWAP((u_short)(x))))
143 #define XSWAP(y) ( ((y) >> 8) | ((y) << 8) )
144
145 #include <machine/autoconf.h>
146 #include <machine/cpu.h>
147 #include <machine/pmap.h>
148
149 #include "i82586.h"
150 #include "if_ie.h"
151 #include "if_ie_subr.h"
152
153 static struct mbuf *last_not_for_us;
154
155 /*
156 * IED: ie debug flags
157 */
158
159 #define IED_RINT 0x01
160 #define IED_TINT 0x02
161 #define IED_RNR 0x04
162 #define IED_CNA 0x08
163 #define IED_READFRAME 0x10
164 #define IED_ALL 0x1f
165
166 #define ETHER_MIN_LEN 64
167 #define ETHER_MAX_LEN 1518
168 #define ETHER_ADDR_LEN 6
169
170 void iewatchdog __P(( /* short */ ));
171 int ieinit __P((struct ie_softc *));
172 int ieioctl __P((struct ifnet *, u_long, caddr_t));
173 void iestart __P((struct ifnet *));
174 void iereset __P((struct ie_softc *));
175 static void ie_readframe __P((struct ie_softc *, int));
176 static void ie_drop_packet_buffer __P((struct ie_softc *));
177 static int command_and_wait __P((struct ie_softc *, int,
178 void volatile *, int));
179 static void ierint __P((struct ie_softc *));
180 static void ietint __P((struct ie_softc *));
181 static int ieget __P((struct ie_softc *, struct mbuf **,
182 struct ether_header *, int *));
183 static void setup_bufs __P((struct ie_softc *));
184 static int mc_setup __P((struct ie_softc *, void *));
185 static void mc_reset __P((struct ie_softc *));
186
187 #ifdef IEDEBUG
188 void print_rbd __P((volatile struct ie_recv_buf_desc *));
189 int in_ierint = 0;
190 int in_ietint = 0;
191 #endif
192
193 void ie_attach();
194
195 struct cfdriver iecd = {
196 NULL, "ie", ie_md_match, ie_attach,
197 DV_IFNET, sizeof(struct ie_softc),
198 };
199
200 /*
201 * address generation macros
202 * MK_24 = KVA -> 24 bit address in SUN byte order
203 * MK_16 = KVA -> 16 bit address in INTEL byte order
204 * ST_24 = store a 24 bit address in SUN byte order to INTEL byte order
205 */
206 #define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
207 #define MK_16(base, ptr) SWAP((u_short)( ((u_long)(ptr)) - ((u_long)(base)) ))
208 #define ST_24(to, from) { \
209 u_long fval = (u_long)(from); \
210 u_char *t = (u_char *)&(to), *f = (u_char *)&fval; \
211 t[0] = f[3]; t[1] = f[2]; t[2] = f[1]; /*t[3] = f[0];*/ \
212 }
213
214 /*
215 * Here are a few useful functions. We could have done these as macros,
216 * but since we have the inline facility, it makes sense to use that
217 * instead.
218 */
219 static inline void
220 ie_setup_config(cmd, promiscuous, manchester)
221 volatile struct ie_config_cmd *cmd;
222 int promiscuous, manchester;
223 {
224
225 /*
226 * these are all char's so no need to byte-swap
227 */
228 cmd->ie_config_count = 0x0c;
229 cmd->ie_fifo = 8;
230 cmd->ie_save_bad = 0x40;
231 cmd->ie_addr_len = 0x2e;
232 cmd->ie_priority = 0;
233 cmd->ie_ifs = 0x60;
234 cmd->ie_slot_low = 0;
235 cmd->ie_slot_high = 0xf2;
236 cmd->ie_promisc = !!promiscuous | manchester << 2;
237 cmd->ie_crs_cdt = 0;
238 cmd->ie_min_len = 64;
239 cmd->ie_junk = 0xff;
240 }
241
242 static inline caddr_t
243 Align(ptr)
244 caddr_t ptr;
245 {
246 u_long l = (u_long)ptr;
247
248 l = (l + 3) & ~3L;
249 return (caddr_t)l;
250 }
251
252 static inline void
253 ie_ack(sc, mask)
254 struct ie_softc *sc;
255 u_int mask;
256 {
257 volatile struct ie_sys_ctl_block *scb = sc->scb;
258
259 command_and_wait(sc, scb->ie_status & mask, 0, 0);
260 }
261
262
263 /*
264 * Taken almost exactly from Bill's if_is.c,
265 * then modified beyond recognition...
266 */
267 void
268 ie_attach(parent, self, aux)
269 struct device *parent, *self;
270 void *aux;
271 {
272 struct ie_softc *sc = (void *) self;
273 struct ifnet *ifp = &sc->sc_if;
274
275 /*
276 * Do machine-dependent parts of attach.
277 */
278 ie_md_attach(parent, self, aux);
279 printf(" hwaddr %s\n", ether_sprintf(sc->sc_addr));
280
281 /*
282 * Setup for transmit/receive
283 */
284 if (ie_setupram(sc) == 0) {
285 printf(": RAM CONFIG FAILED!\n");
286 /* XXX should reclaim resources? */
287 return;
288 }
289
290 /*
291 * Initialize and attach S/W interface
292 */
293 ifp->if_unit = sc->sc_dev.dv_unit;
294 ifp->if_name = iecd.cd_name;
295 ifp->if_start = iestart;
296 ifp->if_ioctl = ieioctl;
297 ifp->if_watchdog = iewatchdog;
298 ifp->if_flags =
299 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
300
301 /* Attach the interface. */
302 if_attach(ifp);
303 ether_ifattach(ifp);
304 #if NBPFILTER > 0
305 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
306 #endif
307 }
308
309 /*
310 * Device timeout/watchdog routine. Entered if the device neglects to
311 * generate an interrupt after a transmit has been started on it.
312 */
313 void
314 iewatchdog(unit)
315 short unit;
316 {
317 struct ie_softc *sc = iecd.cd_devs[unit];
318
319 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
320 ++sc->sc_arpcom.ac_if.if_oerrors;
321
322 iereset(sc);
323 }
324
325 /*
326 * What to do upon receipt of an interrupt.
327 */
328 int
329 ie_intr(v)
330 void *v;
331 {
332 struct ie_softc *sc = v;
333 register u_short status;
334
335 status = sc->scb->ie_status;
336
337 /*
338 * check for parity error
339 */
340 if (sc->hard_type == IE_VME) {
341 volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg;
342 if (iev->status & IEVME_PERR) {
343 printf("%s: parity error (ctrl %x @ %02x%04x)\n",
344 iev->pectrl, iev->pectrl & IEVME_HADDR,
345 iev->peaddr);
346 iev->pectrl = iev->pectrl | IEVME_PARACK;
347 }
348 }
349
350 loop:
351 /* Ack interrupts FIRST in case we receive more during the ISR. */
352 ie_ack(sc, IE_ST_WHENCE & status);
353
354 if (status & (IE_ST_RECV | IE_ST_RNR)) {
355 #ifdef IEDEBUG
356 in_ierint++;
357 if (sc->sc_debug & IED_RINT)
358 printf("%s: rint\n", sc->sc_dev.dv_xname);
359 #endif
360 ierint(sc);
361 #ifdef IEDEBUG
362 in_ierint--;
363 #endif
364 }
365
366 if (status & IE_ST_DONE) {
367 #ifdef IEDEBUG
368 in_ietint++;
369 if (sc->sc_debug & IED_TINT)
370 printf("%s: tint\n", sc->sc_dev.dv_xname);
371 #endif
372 ietint(sc);
373 #ifdef IEDEBUG
374 in_ietint--;
375 #endif
376 }
377
378 if (status & IE_ST_RNR) {
379 printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
380 sc->sc_arpcom.ac_if.if_ierrors++;
381 iereset(sc);
382 }
383
384 #ifdef IEDEBUG
385 if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
386 printf("%s: cna\n", sc->sc_dev.dv_xname);
387 #endif
388
389 if ((status = sc->scb->ie_status) & IE_ST_WHENCE)
390 goto loop;
391
392 return 1;
393 }
394
395 /*
396 * Process a received-frame interrupt.
397 */
398 void
399 ierint(sc)
400 struct ie_softc *sc;
401 {
402 volatile struct ie_sys_ctl_block *scb = sc->scb;
403 int i, status;
404 static int timesthru = 1024;
405
406 i = sc->rfhead;
407 for (;;) {
408 status = sc->rframes[i]->ie_fd_status;
409
410 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
411 sc->sc_arpcom.ac_if.if_ipackets++;
412 if (!--timesthru) {
413 sc->sc_arpcom.ac_if.if_ierrors +=
414 SWAP(scb->ie_err_crc) +
415 SWAP(scb->ie_err_align) +
416 SWAP(scb->ie_err_resource) +
417 SWAP(scb->ie_err_overrun);
418 scb->ie_err_crc = 0;
419 scb->ie_err_align = 0;
420 scb->ie_err_resource = 0;
421 scb->ie_err_overrun = 0;
422 timesthru = 1024;
423 }
424 ie_readframe(sc, i);
425 } else {
426 if ((status & IE_FD_RNR) != 0 &&
427 (scb->ie_status & IE_RU_READY) == 0) {
428 sc->rframes[0]->ie_fd_buf_desc =
429 MK_16(sc->sc_maddr, sc->rbuffs[0]);
430 scb->ie_recv_list =
431 MK_16(sc->sc_maddr, sc->rframes[0]);
432 command_and_wait(sc, IE_RU_START, 0, 0);
433 }
434 break;
435 }
436 i = (i + 1) % sc->nframes;
437 }
438 }
439
440 /*
441 * Process a command-complete interrupt. These are only generated by
442 * the transmission of frames. This routine is deceptively simple, since
443 * most of the real work is done by iestart().
444 */
445 void
446 ietint(sc)
447 struct ie_softc *sc;
448 {
449 int status;
450 int i;
451
452 sc->sc_arpcom.ac_if.if_timer = 0;
453 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
454
455 status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
456
457 if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
458 printf("ietint: command still busy!\n");
459
460 if (status & IE_STAT_OK) {
461 sc->sc_arpcom.ac_if.if_opackets++;
462 sc->sc_arpcom.ac_if.if_collisions +=
463 SWAP(status & IE_XS_MAXCOLL);
464 } else if (status & IE_STAT_ABORT) {
465 printf("%s: send aborted\n", sc->sc_dev.dv_xname);
466 sc->sc_arpcom.ac_if.if_oerrors++;
467 } else if (status & IE_XS_NOCARRIER) {
468 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
469 sc->sc_arpcom.ac_if.if_oerrors++;
470 } else if (status & IE_XS_LOSTCTS) {
471 printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
472 sc->sc_arpcom.ac_if.if_oerrors++;
473 } else if (status & IE_XS_UNDERRUN) {
474 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
475 sc->sc_arpcom.ac_if.if_oerrors++;
476 } else if (status & IE_XS_EXCMAX) {
477 printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
478 sc->sc_arpcom.ac_if.if_collisions += 16;
479 sc->sc_arpcom.ac_if.if_oerrors++;
480 }
481
482 /*
483 * If multicast addresses were added or deleted while we
484 * were transmitting, mc_reset() set the want_mcsetup flag
485 * indicating that we should do it.
486 */
487 if (sc->want_mcsetup) {
488 mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
489 sc->want_mcsetup = 0;
490 }
491
492 /* Done with the buffer. */
493 sc->xmit_free++;
494 sc->xmit_busy = 0;
495 sc->xctail = (sc->xctail + 1) % NTXBUF;
496
497 iestart(&sc->sc_arpcom.ac_if);
498 }
499
500 /*
501 * Compare two Ether/802 addresses for equality, inlined and
502 * unrolled for speed. I'd love to have an inline assembler
503 * version of this...
504 */
505 static inline int
506 ether_equal(one, two)
507 u_char *one, *two;
508 {
509
510 if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
511 one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
512 return 0;
513 return 1;
514 }
515
516 /*
517 * Check for a valid address. to_bpf is filled in with one of the following:
518 * 0 -> BPF doesn't get this packet
519 * 1 -> BPF does get this packet
520 * 2 -> BPF does get this packet, but we don't
521 * Return value is true if the packet is for us, and false otherwise.
522 *
523 * This routine is a mess, but it's also critical that it be as fast
524 * as possible. It could be made cleaner if we can assume that the
525 * only client which will fiddle with IFF_PROMISC is BPF. This is
526 * probably a good assumption, but we do not make it here. (Yet.)
527 */
528 static inline int
529 check_eh(sc, eh, to_bpf)
530 struct ie_softc *sc;
531 struct ether_header *eh;
532 int *to_bpf;
533 {
534 int i;
535
536 switch (sc->promisc) {
537 case IFF_ALLMULTI:
538 /*
539 * Receiving all multicasts, but no unicasts except those
540 * destined for us.
541 */
542 #if NBPFILTER > 0
543 /* BPF gets this packet if anybody cares */
544 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
545 #endif
546 if (eh->ether_dhost[0] & 1)
547 return 1;
548 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
549 return 1;
550 return 0;
551
552 case IFF_PROMISC:
553 /*
554 * Receiving all packets. These need to be passed on to BPF.
555 */
556 #if NBPFILTER > 0
557 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
558 #endif
559 /* If for us, accept and hand up to BPF */
560 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
561 return 1;
562
563 #if NBPFILTER > 0
564 if (*to_bpf)
565 *to_bpf = 2; /* we don't need to see it */
566 #endif
567
568 /*
569 * Not a multicast, so BPF wants to see it but we don't.
570 */
571 if (!(eh->ether_dhost[0] & 1))
572 return 1;
573
574 /*
575 * If it's one of our multicast groups, accept it and pass it
576 * up.
577 */
578 for (i = 0; i < sc->mcast_count; i++) {
579 if (ether_equal(eh->ether_dhost,
580 (u_char *)&sc->mcast_addrs[i])) {
581 #if NBPFILTER > 0
582 if (*to_bpf)
583 *to_bpf = 1;
584 #endif
585 return 1;
586 }
587 }
588 return 1;
589
590 case IFF_ALLMULTI | IFF_PROMISC:
591 /*
592 * Acting as a multicast router, and BPF running at the same
593 * time. Whew! (Hope this is a fast machine...)
594 */
595 #if NBPFILTER > 0
596 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
597 #endif
598 /* We want to see multicasts. */
599 if (eh->ether_dhost[0] & 1)
600 return 1;
601
602 /* We want to see our own packets */
603 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
604 return 1;
605
606 /* Anything else goes to BPF but nothing else. */
607 #if NBPFILTER > 0
608 if (*to_bpf)
609 *to_bpf = 2;
610 #endif
611 return 1;
612
613 default:
614 /*
615 * Only accept unicast packets destined for us, or multicasts
616 * for groups that we belong to. For now, we assume that the
617 * '586 will only return packets that we asked it for. This
618 * isn't strictly true (it uses hashing for the multicast filter),
619 * but it will do in this case, and we want to get out of here
620 * as quickly as possible.
621 */
622 #if NBPFILTER > 0
623 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
624 #endif
625 return 1;
626 }
627 return 0;
628 }
629
630 /*
631 * We want to isolate the bits that have meaning... This assumes that
632 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
633 * the size of the buffer, then we are screwed anyway.
634 */
635 static inline int
636 ie_buflen(sc, head)
637 struct ie_softc *sc;
638 int head;
639 {
640
641 return (SWAP(sc->rbuffs[head]->ie_rbd_actual)
642 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
643 }
644
645 static inline int
646 ie_packet_len(sc)
647 struct ie_softc *sc;
648 {
649 int i;
650 int head = sc->rbhead;
651 int acc = 0;
652
653 do {
654 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
655 #ifdef IEDEBUG
656 print_rbd(sc->rbuffs[sc->rbhead]);
657 #endif
658 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
659 sc->sc_dev.dv_xname, sc->rbhead);
660 iereset(sc);
661 return -1;
662 }
663
664 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
665
666 acc += ie_buflen(sc, head);
667 head = (head + 1) % sc->nrxbuf;
668 } while (!i);
669
670 return acc;
671 }
672
673 /*
674 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
675 * command to the chip to be executed. On the way, if we have a BPF listener
676 * also give him a copy.
677 */
678 inline static void
679 iexmit(sc)
680 struct ie_softc *sc;
681 {
682
683 #if NBPFILTER > 0
684 /*
685 * If BPF is listening on this interface, let it see the packet before
686 * we push it on the wire.
687 */
688 if (sc->sc_arpcom.ac_if.if_bpf)
689 bpf_tap(sc->sc_arpcom.ac_if.if_bpf,
690 sc->xmit_cbuffs[sc->xctail],
691 SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
692 #endif
693
694 sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
695 sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
696 ST_24(sc->xmit_buffs[sc->xctail]->ie_xmit_buf,
697 MK_24(sc->sc_iobase, sc->xmit_cbuffs[sc->xctail]));
698
699 sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
700 sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
701 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
702
703 sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
704 sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
705 MK_16(sc->sc_maddr, sc->xmit_buffs[sc->xctail]);
706
707 sc->scb->ie_command_list =
708 MK_16(sc->sc_maddr, sc->xmit_cmds[sc->xctail]);
709 command_and_wait(sc, IE_CU_START, 0, 0);
710
711 sc->xmit_busy = 1;
712 sc->sc_arpcom.ac_if.if_timer = 5;
713 }
714
715 /*
716 * Read data off the interface, and turn it into an mbuf chain.
717 *
718 * This code is DRAMATICALLY different from the previous version; this
719 * version tries to allocate the entire mbuf chain up front, given the
720 * length of the data available. This enables us to allocate mbuf
721 * clusters in many situations where before we would have had a long
722 * chain of partially-full mbufs. This should help to speed up the
723 * operation considerably. (Provided that it works, of course.)
724 */
725 static inline int
726 ieget(sc, mp, ehp, to_bpf)
727 struct ie_softc *sc;
728 struct mbuf **mp;
729 struct ether_header *ehp;
730 int *to_bpf;
731 {
732 struct mbuf *m, *top, **mymp;
733 int i;
734 int offset;
735 int totlen, resid;
736 int thismboff;
737 int head;
738
739 totlen = ie_packet_len(sc);
740 if (totlen <= 0)
741 return -1;
742
743 i = sc->rbhead;
744
745 /*
746 * Snarf the Ethernet header.
747 */
748 (sc->sc_bcopy)((caddr_t)sc->cbuffs[i], (caddr_t)ehp, sizeof *ehp);
749
750 /*
751 * As quickly as possible, check if this packet is for us.
752 * If not, don't waste a single cycle copying the rest of the
753 * packet in.
754 * This is only a consideration when FILTER is defined; i.e., when
755 * we are either running BPF or doing multicasting.
756 */
757 if (!check_eh(sc, ehp, to_bpf)) {
758 ie_drop_packet_buffer(sc);
759 /* just this case, it's not an error */
760 sc->sc_arpcom.ac_if.if_ierrors--;
761 return -1;
762 }
763 totlen -= (offset = sizeof *ehp);
764
765 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
766 if (!*mp) {
767 ie_drop_packet_buffer(sc);
768 return -1;
769 }
770
771 m = *mp;
772 m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
773 m->m_len = MHLEN;
774 resid = m->m_pkthdr.len = totlen;
775 top = 0;
776 mymp = ⊤
777
778 /*
779 * This loop goes through and allocates mbufs for all the data we will
780 * be copying in. It does not actually do the copying yet.
781 */
782 do { /* while (resid > 0) */
783 /*
784 * Try to allocate an mbuf to hold the data that we have. If
785 * we already allocated one, just get another one and stick it
786 * on the end (eventually). If we don't already have one, try
787 * to allocate an mbuf cluster big enough to hold the whole
788 * packet, if we think it's reasonable, or a single mbuf which
789 * may or may not be big enough. Got that?
790 */
791 if (top) {
792 MGET(m, M_DONTWAIT, MT_DATA);
793 if (!m) {
794 m_freem(top);
795 ie_drop_packet_buffer(sc);
796 return -1;
797 }
798 m->m_len = MLEN;
799 }
800
801 if (resid >= MINCLSIZE) {
802 MCLGET(m, M_DONTWAIT);
803 if (m->m_flags & M_EXT)
804 m->m_len = min(resid, MCLBYTES);
805 } else {
806 if (resid < m->m_len) {
807 if (!top && resid + max_linkhdr <= m->m_len)
808 m->m_data += max_linkhdr;
809 m->m_len = resid;
810 }
811 }
812 resid -= m->m_len;
813 *mymp = m;
814 mymp = &m->m_next;
815 } while (resid > 0);
816
817 resid = totlen;
818 m = top;
819 thismboff = 0;
820 head = sc->rbhead;
821
822 /*
823 * Now we take the mbuf chain (hopefully only one mbuf most of the
824 * time) and stuff the data into it. There are no possible failures
825 * at or after this point.
826 */
827 while (resid > 0) { /* while there's stuff left */
828 int thislen = ie_buflen(sc, head) - offset;
829
830 /*
831 * If too much data for the current mbuf, then fill the current one
832 * up, go to the next one, and try again.
833 */
834 if (thislen > m->m_len - thismboff) {
835 int newlen = m->m_len - thismboff;
836 (sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
837 mtod(m, caddr_t) + thismboff, (u_int)newlen);
838 m = m->m_next;
839 thismboff = 0; /* new mbuf, so no offset */
840 offset += newlen; /* we are now this far into
841 * the packet */
842 resid -= newlen; /* so there is this much left
843 * to get */
844 continue;
845 }
846
847 /*
848 * If there is more than enough space in the mbuf to hold the
849 * contents of this buffer, copy everything in, advance pointers,
850 * and so on.
851 */
852 if (thislen < m->m_len - thismboff) {
853 (sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
854 mtod(m, caddr_t) + thismboff, (u_int)thislen);
855 thismboff += thislen; /* we are this far into the
856 * mbuf */
857 resid -= thislen; /* and this much is left */
858 goto nextbuf;
859 }
860
861 /*
862 * Otherwise, there is exactly enough space to put this buffer's
863 * contents into the current mbuf. Do the combination of the above
864 * actions.
865 */
866 (sc->sc_bcopy)((caddr_t)(sc->cbuffs[head] + offset),
867 mtod(m, caddr_t) + thismboff, (u_int)thislen);
868 m = m->m_next;
869 thismboff = 0; /* new mbuf, start at the beginning */
870 resid -= thislen; /* and we are this far through */
871
872 /*
873 * Advance all the pointers. We can get here from either of the
874 * last two cases, but never the first.
875 */
876 nextbuf:
877 offset = 0;
878 sc->rbuffs[head]->ie_rbd_actual = SWAP(0);
879 sc->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
880 sc->rbhead = head = (head + 1) % sc->nrxbuf;
881 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
882 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
883 }
884
885 /*
886 * Unless something changed strangely while we were doing the copy,
887 * we have now copied everything in from the shared memory.
888 * This means that we are done.
889 */
890 return 0;
891 }
892
893 /*
894 * Read frame NUM from unit UNIT (pre-cached as IE).
895 *
896 * This routine reads the RFD at NUM, and copies in the buffers from
897 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
898 * doesn't start complaining. Trailers are DROPPED---there's no point
899 * in wasting time on confusing code to deal with them. Hopefully,
900 * this machine will never ARP for trailers anyway.
901 */
902 static void
903 ie_readframe(sc, num)
904 struct ie_softc *sc;
905 int num; /* frame number to read */
906 {
907 int status;
908 struct mbuf *m = 0;
909 struct ether_header eh;
910 #if NBPFILTER > 0
911 int bpf_gets_it = 0;
912 #endif
913
914 status = sc->rframes[num]->ie_fd_status;
915
916 /* Immediately advance the RFD list, since we have copied ours now. */
917 sc->rframes[num]->ie_fd_status = SWAP(0);
918 sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
919 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
920 sc->rftail = (sc->rftail + 1) % sc->nframes;
921 sc->rfhead = (sc->rfhead + 1) % sc->nframes;
922
923 if (status & IE_FD_OK) {
924 #if NBPFILTER > 0
925 if (ieget(sc, &m, &eh, &bpf_gets_it)) {
926 #else
927 if (ieget(sc, &m, &eh, 0)) {
928 #endif
929 sc->sc_arpcom.ac_if.if_ierrors++;
930 return;
931 }
932 }
933
934 #ifdef IEDEBUG
935 if (sc->sc_debug & IED_READFRAME)
936 printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
937 ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
938 #endif
939
940 if (!m)
941 return;
942
943 if (last_not_for_us) {
944 m_freem(last_not_for_us);
945 last_not_for_us = 0;
946 }
947
948 #if NBPFILTER > 0
949 /*
950 * Check for a BPF filter; if so, hand it up.
951 * Note that we have to stick an extra mbuf up front, because
952 * bpf_mtap expects to have the ether header at the front.
953 * It doesn't matter that this results in an ill-formatted mbuf chain,
954 * since BPF just looks at the data. (It doesn't try to free the mbuf,
955 * tho' it will make a copy for tcpdump.)
956 */
957 if (bpf_gets_it) {
958 struct mbuf m0;
959 m0.m_len = sizeof eh;
960 m0.m_data = (caddr_t)&eh;
961 m0.m_next = m;
962
963 /* Pass it up */
964 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, &m0);
965 }
966 /*
967 * A signal passed up from the filtering code indicating that the
968 * packet is intended for BPF but not for the protocol machinery.
969 * We can save a few cycles by not handing it off to them.
970 */
971 if (bpf_gets_it == 2) {
972 last_not_for_us = m;
973 return;
974 }
975 #endif /* NBPFILTER > 0 */
976
977 /*
978 * In here there used to be code to check destination addresses upon
979 * receipt of a packet. We have deleted that code, and replaced it
980 * with code to check the address much earlier in the cycle, before
981 * copying the data in; this saves us valuable cycles when operating
982 * as a multicast router or when using BPF.
983 */
984
985 /*
986 * Finally pass this packet up to higher layers.
987 */
988 ether_input(&sc->sc_arpcom.ac_if, &eh, m);
989 }
990
991 static void
992 ie_drop_packet_buffer(sc)
993 struct ie_softc *sc;
994 {
995 int i;
996
997 do {
998 /*
999 * This means we are somehow out of sync. So, we reset the
1000 * adapter.
1001 */
1002 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1003 #ifdef IEDEBUG
1004 print_rbd(sc->rbuffs[sc->rbhead]);
1005 #endif
1006 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
1007 sc->sc_dev.dv_xname, sc->rbhead);
1008 iereset(sc);
1009 return;
1010 }
1011
1012 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1013
1014 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1015 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
1016 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
1017 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1018 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
1019 } while (!i);
1020 }
1021
1022 /*
1023 * Start transmission on an interface.
1024 */
1025 void
1026 iestart(ifp)
1027 struct ifnet *ifp;
1028 {
1029 struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
1030 struct mbuf *m0, *m;
1031 u_char *buffer;
1032 u_short len;
1033
1034 if ((ifp->if_flags & IFF_RUNNING) == 0)
1035 return;
1036
1037 if (sc->xmit_free == 0) {
1038 ifp->if_flags |= IFF_OACTIVE;
1039 if (!sc->xmit_busy)
1040 iexmit(sc);
1041 return;
1042 }
1043
1044 do {
1045 IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
1046 if (!m)
1047 break;
1048
1049 len = 0;
1050 buffer = sc->xmit_cbuffs[sc->xchead];
1051
1052 for (m0 = m; m && (len + m->m_len) < IE_TBUF_SIZE; m = m->m_next) {
1053 (sc->sc_bcopy)(mtod(m, caddr_t), buffer, m->m_len);
1054 buffer += m->m_len;
1055 len += m->m_len;
1056 }
1057 if (m)
1058 printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
1059
1060 m_freem(m0);
1061 len = max(len, ETHER_MIN_LEN);
1062 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
1063
1064 sc->xmit_free--;
1065 sc->xchead = (sc->xchead + 1) % NTXBUF;
1066 } while (sc->xmit_free > 0);
1067
1068 /* If we stuffed any packets into the card's memory, send now. */
1069 if ((sc->xmit_free < NTXBUF) && (!sc->xmit_busy))
1070 iexmit(sc);
1071
1072 return;
1073 }
1074
1075 /*
1076 * set up IE's ram space
1077 */
1078 int
1079 ie_setupram(sc)
1080 struct ie_softc *sc;
1081 {
1082 volatile struct ie_sys_conf_ptr *scp;
1083 volatile struct ie_int_sys_conf_ptr *iscp;
1084 volatile struct ie_sys_ctl_block *scb;
1085 int s;
1086
1087 s = splimp();
1088
1089 scp = sc->scp;
1090 (sc->sc_bzero)((char *) scp, sizeof *scp);
1091
1092 iscp = sc->iscp;
1093 (sc->sc_bzero)((char *) iscp, sizeof *iscp);
1094
1095 scb = sc->scb;
1096 (sc->sc_bzero)((char *) scb, sizeof *scb);
1097
1098 scp->ie_bus_use = 0; /* 16-bit */
1099 ST_24(scp->ie_iscp_ptr, MK_24(sc->sc_iobase, iscp));
1100
1101 iscp->ie_busy = 1; /* ie_busy == char */
1102 iscp->ie_scb_offset = MK_16(sc->sc_maddr, scb);
1103 ST_24(iscp->ie_base, MK_24(sc->sc_iobase, sc->sc_maddr));
1104
1105 (sc->reset_586) (sc);
1106 (sc->chan_attn) (sc);
1107
1108 delay(100); /* wait a while... */
1109
1110 if (iscp->ie_busy) {
1111 splx(s);
1112 return 0;
1113 }
1114 /*
1115 * Acknowledge any interrupts we may have caused...
1116 */
1117 ie_ack(sc, IE_ST_WHENCE);
1118 splx(s);
1119
1120 return 1;
1121 }
1122
1123 void
1124 iereset(sc)
1125 struct ie_softc *sc;
1126 {
1127 int s = splimp();
1128
1129 printf("%s: reset\n", sc->sc_dev.dv_xname);
1130
1131 /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
1132 sc->sc_arpcom.ac_if.if_flags &= ~(IFF_UP | IFF_OACTIVE);
1133 ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
1134
1135 /*
1136 * Stop i82586 dead in its tracks.
1137 */
1138 if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1139 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1140
1141 if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1142 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
1143
1144 #ifdef notdef
1145 if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
1146 panic("ie disappeared!\n");
1147 #endif
1148
1149 sc->sc_arpcom.ac_if.if_flags |= IFF_UP;
1150 ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, 0);
1151
1152 splx(s);
1153 }
1154
1155 /*
1156 * This is called if we time out.
1157 */
1158 static void
1159 chan_attn_timeout(rock)
1160 caddr_t rock;
1161 {
1162 *(int *) rock = 1;
1163 }
1164
1165 /*
1166 * Send a command to the controller and wait for it to either
1167 * complete or be accepted, depending on the command. If the
1168 * command pointer is null, then pretend that the command is
1169 * not an action command. If the command pointer is not null,
1170 * and the command is an action command, wait for
1171 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1172 * to become true.
1173 */
1174 static int
1175 command_and_wait(sc, cmd, pcmd, mask)
1176 struct ie_softc *sc;
1177 int cmd;
1178 volatile void *pcmd;
1179 int mask;
1180 {
1181 volatile struct ie_cmd_common *cc = pcmd;
1182 volatile struct ie_sys_ctl_block *scb = sc->scb;
1183 volatile int timedout = 0;
1184 extern int hz;
1185
1186 scb->ie_command = (u_short)cmd;
1187
1188 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1189 (sc->chan_attn)(sc);
1190
1191 /*
1192 * XXX
1193 * I don't think this timeout works on suns.
1194 * we are at splimp() in the loop, and the timeout
1195 * stuff runs at software spl (so it is masked off?).
1196 */
1197
1198 /*
1199 * According to the packet driver, the minimum timeout should be
1200 * .369 seconds, which we round up to .4.
1201 */
1202
1203 timeout(chan_attn_timeout, (caddr_t)&timedout, 2 * hz / 5);
1204
1205 /*
1206 * Now spin-lock waiting for status. This is not a very nice
1207 * thing to do, but I haven't figured out how, or indeed if, we
1208 * can put the process waiting for action to sleep. (We may
1209 * be getting called through some other timeout running in the
1210 * kernel.)
1211 */
1212 for (;;)
1213 if ((cc->ie_cmd_status & mask) || timedout)
1214 break;
1215
1216 untimeout(chan_attn_timeout, (caddr_t)&timedout);
1217
1218 return timedout;
1219 } else {
1220 /*
1221 * Otherwise, just wait for the command to be accepted.
1222 */
1223 (sc->chan_attn)(sc);
1224
1225 while (scb->ie_command)
1226 ; /* spin lock */
1227
1228 return 0;
1229 }
1230 }
1231
1232 /*
1233 * Run the time-domain reflectometer...
1234 */
1235 static void
1236 run_tdr(sc, cmd)
1237 struct ie_softc *sc;
1238 struct ie_tdr_cmd *cmd;
1239 {
1240 int result;
1241
1242 cmd->com.ie_cmd_status = SWAP(0);
1243 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1244 cmd->com.ie_cmd_link = SWAP(0xffff);
1245
1246 sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1247 cmd->ie_tdr_time = SWAP(0);
1248
1249 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1250 !(cmd->com.ie_cmd_status & IE_STAT_OK))
1251 result = 0x10000; /* XXX */
1252 else
1253 result = cmd->ie_tdr_time;
1254
1255 ie_ack(sc, IE_ST_WHENCE);
1256
1257 if (result & IE_TDR_SUCCESS)
1258 return;
1259
1260 if (result & 0x10000) {
1261 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1262 } else if (result & IE_TDR_XCVR) {
1263 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1264 } else if (result & IE_TDR_OPEN) {
1265 printf("%s: TDR detected an open %d clocks away\n",
1266 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
1267 } else if (result & IE_TDR_SHORT) {
1268 printf("%s: TDR detected a short %d clocks away\n",
1269 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
1270 } else {
1271 printf("%s: TDR returned unknown status %x\n",
1272 sc->sc_dev.dv_xname, result);
1273 }
1274 }
1275
1276 /*
1277 * setup_bufs: set up the buffers
1278 *
1279 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1280 * this is to be used for the buffers. the chip indexs its control data
1281 * structures with 16 bit offsets, and it indexes actual buffers with
1282 * 24 bit addresses. so we should allocate control buffers first so that
1283 * we don't overflow the 16 bit offset field. The number of transmit
1284 * buffers is fixed at compile time.
1285 *
1286 * note: this function was written to be easy to understand, rather than
1287 * highly efficient (it isn't in the critical path).
1288 */
1289 static void
1290 setup_bufs(sc)
1291 struct ie_softc *sc;
1292 {
1293 caddr_t ptr = sc->buf_area; /* memory pool */
1294 volatile struct ie_recv_frame_desc *rfd = (void *) ptr;
1295 volatile struct ie_recv_buf_desc *rbd;
1296 int n, r;
1297
1298 /*
1299 * step 0: zero memory and figure out how many recv buffers and
1300 * frames we can have. XXX CURRENTLY HARDWIRED AT MAX
1301 */
1302 (sc->sc_bzero)(ptr, sc->buf_area_sz);
1303 ptr = Align(ptr); /* set alignment and stick with it */
1304
1305 n = (int)Align(sizeof(struct ie_xmit_cmd)) +
1306 (int)Align(sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE;
1307 n *= NTXBUF; /* n = total size of xmit area */
1308
1309 n = sc->buf_area_sz - n;/* n = free space for recv stuff */
1310
1311 r = (int)Align(sizeof(struct ie_recv_frame_desc)) +
1312 (((int)Align(sizeof(struct ie_recv_buf_desc)) + IE_RBUF_SIZE) * B_PER_F);
1313
1314 /* r = size of one R frame */
1315
1316 sc->nframes = n / r;
1317 if (sc->nframes <= 0)
1318 panic("ie: bogus buffer calc\n");
1319 if (sc->nframes > MXFRAMES)
1320 sc->nframes = MXFRAMES;
1321
1322 sc->nrxbuf = sc->nframes * B_PER_F;
1323
1324 #ifdef IEDEBUG
1325 printf("IEDEBUG: %d frames %d bufs\n", sc->nframes, sc->nrxbuf);
1326 #endif
1327
1328 /*
1329 * step 1a: lay out and zero frame data structures for transmit and recv
1330 */
1331 for (n = 0; n < NTXBUF; n++) {
1332 sc->xmit_cmds[n] = (volatile struct ie_xmit_cmd *) ptr;
1333 ptr = Align(ptr + sizeof(struct ie_xmit_cmd));
1334 }
1335
1336 for (n = 0; n < sc->nframes; n++) {
1337 sc->rframes[n] = (volatile struct ie_recv_frame_desc *) ptr;
1338 ptr = Align(ptr + sizeof(struct ie_recv_frame_desc));
1339 }
1340
1341 /*
1342 * step 1b: link together the recv frames and set EOL on last one
1343 */
1344 for (n = 0; n < sc->nframes; n++) {
1345 sc->rframes[n]->ie_fd_next =
1346 MK_16(sc->sc_maddr, sc->rframes[(n + 1) % sc->nframes]);
1347 }
1348 sc->rframes[sc->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1349
1350 /*
1351 * step 2a: lay out and zero frame buffer structures for xmit and recv
1352 */
1353 for (n = 0; n < NTXBUF; n++) {
1354 sc->xmit_buffs[n] = (volatile struct ie_xmit_buf *) ptr;
1355 ptr = Align(ptr + sizeof(struct ie_xmit_buf));
1356 }
1357
1358 for (n = 0; n < sc->nrxbuf; n++) {
1359 sc->rbuffs[n] = (volatile struct ie_recv_buf_desc *) ptr;
1360 ptr = Align(ptr + sizeof(struct ie_recv_buf_desc));
1361 }
1362
1363 /*
1364 * step 2b: link together recv bufs and set EOL on last one
1365 */
1366 for (n = 0; n < sc->nrxbuf; n++) {
1367 sc->rbuffs[n]->ie_rbd_next =
1368 MK_16(sc->sc_maddr, sc->rbuffs[(n + 1) % sc->nrxbuf]);
1369 }
1370 sc->rbuffs[sc->nrxbuf - 1]->ie_rbd_length |= IE_RBD_LAST;
1371
1372 /*
1373 * step 3: allocate the actual data buffers for xmit and recv
1374 * recv buffer gets linked into recv_buf_desc list here
1375 */
1376 for (n = 0; n < NTXBUF; n++) {
1377 sc->xmit_cbuffs[n] = (u_char *) ptr;
1378 ptr = Align(ptr + IE_TBUF_SIZE);
1379 }
1380
1381 /* Pointers to last packet sent and next available transmit buffer. */
1382 sc->xchead = sc->xctail = 0;
1383
1384 /* Clear transmit-busy flag and set number of free transmit buffers. */
1385 sc->xmit_busy = 0;
1386 sc->xmit_free = NTXBUF;
1387
1388 for (n = 0; n < sc->nrxbuf; n++) {
1389 sc->cbuffs[n] = (char *) ptr; /* XXX why char vs uchar? */
1390 sc->rbuffs[n]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
1391 ST_24(sc->rbuffs[n]->ie_rbd_buffer, MK_24(sc->sc_iobase, ptr));
1392 ptr = Align(ptr + IE_RBUF_SIZE);
1393 }
1394
1395 /*
1396 * step 4: set the head and tail pointers on receive to keep track of
1397 * the order in which RFDs and RBDs are used. link in recv frames
1398 * and buffer into the scb.
1399 */
1400
1401 sc->rfhead = 0;
1402 sc->rftail = sc->nframes - 1;
1403 sc->rbhead = 0;
1404 sc->rbtail = sc->nrxbuf - 1;
1405
1406 sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
1407 sc->rframes[0]->ie_fd_buf_desc = MK_16(sc->sc_maddr, sc->rbuffs[0]);
1408
1409 #ifdef IEDEBUG
1410 printf("IE_DEBUG: reserved %d bytes\n", ptr - sc->buf_area);
1411 #endif
1412 }
1413
1414 /*
1415 * Run the multicast setup command.
1416 * Called at splimp().
1417 */
1418 static int
1419 mc_setup(sc, ptr)
1420 struct ie_softc *sc;
1421 void *ptr;
1422 {
1423 volatile struct ie_mcast_cmd *cmd = ptr;
1424
1425 cmd->com.ie_cmd_status = SWAP(0);
1426 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1427 cmd->com.ie_cmd_link = SWAP(0xffff);
1428
1429 (sc->sc_bcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
1430 sc->mcast_count * sizeof *sc->mcast_addrs);
1431
1432 cmd->ie_mcast_bytes =
1433 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */
1434
1435 sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1436 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1437 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1438 printf("%s: multicast address setup command failed\n",
1439 sc->sc_dev.dv_xname);
1440 return 0;
1441 }
1442 return 1;
1443 }
1444
1445 /*
1446 * This routine inits the ie.
1447 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1448 * starting the receiver unit, and clearing interrupts.
1449 *
1450 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
1451 */
1452 int
1453 ieinit(sc)
1454 struct ie_softc *sc;
1455 {
1456 volatile struct ie_sys_ctl_block *scb = sc->scb;
1457 void *ptr;
1458 int n;
1459
1460 ptr = sc->buf_area;
1461
1462 /*
1463 * Send the configure command first.
1464 */
1465 {
1466 volatile struct ie_config_cmd *cmd = ptr;
1467
1468 scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1469 cmd->com.ie_cmd_status = SWAP(0);
1470 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1471 cmd->com.ie_cmd_link = SWAP(0xffff);
1472
1473 ie_setup_config(cmd, sc->promisc, 0);
1474
1475 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1476 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1477 printf("%s: configure command failed\n",
1478 sc->sc_dev.dv_xname);
1479 return 0;
1480 }
1481 }
1482
1483 /*
1484 * Now send the Individual Address Setup command.
1485 */
1486 {
1487 volatile struct ie_iasetup_cmd *cmd = ptr;
1488
1489 scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1490 cmd->com.ie_cmd_status = SWAP(0);
1491 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1492 cmd->com.ie_cmd_link = SWAP(0xffff);
1493
1494 (sc->sc_bcopy)(sc->sc_arpcom.ac_enaddr,
1495 (caddr_t)&cmd->ie_address, sizeof cmd->ie_address);
1496
1497 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1498 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1499 printf("%s: individual address setup command failed\n",
1500 sc->sc_dev.dv_xname);
1501 return 0;
1502 }
1503 }
1504
1505 /*
1506 * Now run the time-domain reflectometer.
1507 */
1508 run_tdr(sc, ptr);
1509
1510 /*
1511 * Acknowledge any interrupts we have generated thus far.
1512 */
1513 ie_ack(sc, IE_ST_WHENCE);
1514
1515 /*
1516 * Set up the transmit and recv buffers.
1517 */
1518 setup_bufs(sc);
1519
1520 /* tell higher levels that we are here */
1521 sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING;
1522
1523 sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
1524 command_and_wait(sc, IE_RU_START, 0, 0);
1525
1526 ie_ack(sc, IE_ST_WHENCE);
1527
1528 if (sc->run_586)
1529 (sc->run_586)(sc);
1530
1531 return 0;
1532 }
1533
1534 static void
1535 iestop(sc)
1536 struct ie_softc *sc;
1537 {
1538
1539 command_and_wait(sc, IE_RU_DISABLE, 0, 0);
1540 }
1541
1542 int
1543 ieioctl(ifp, cmd, data)
1544 register struct ifnet *ifp;
1545 u_long cmd;
1546 caddr_t data;
1547 {
1548 struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
1549 struct ifaddr *ifa = (struct ifaddr *) data;
1550 struct ifreq *ifr = (struct ifreq *) data;
1551 int s, error = 0;
1552
1553 s = splimp();
1554
1555 switch (cmd) {
1556
1557 case SIOCSIFADDR:
1558 ifp->if_flags |= IFF_UP;
1559
1560 switch (ifa->ifa_addr->sa_family) {
1561 #ifdef INET
1562 case AF_INET:
1563 ieinit(sc);
1564 arp_ifinit(&sc->sc_arpcom, ifa);
1565 break;
1566 #endif
1567 #ifdef NS
1568 /* XXX - This code is probably wrong. */
1569 case AF_NS:
1570 {
1571 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1572
1573 if (ns_nullhost(*ina))
1574 ina->x_host =
1575 *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
1576 else
1577 bcopy(ina->x_host.c_host,
1578 sc->sc_arpcom.ac_enaddr,
1579 sizeof(sc->sc_arpcom.ac_enaddr));
1580 /* Set new address. */
1581 ieinit(sc);
1582 break;
1583 }
1584 #endif /* NS */
1585 default:
1586 ieinit(sc);
1587 break;
1588 }
1589 break;
1590
1591 case SIOCSIFFLAGS:
1592 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1593
1594 if ((ifp->if_flags & IFF_UP) == 0 &&
1595 (ifp->if_flags & IFF_RUNNING) != 0) {
1596 /*
1597 * If interface is marked down and it is running, then
1598 * stop it.
1599 */
1600 iestop(sc);
1601 ifp->if_flags &= ~IFF_RUNNING;
1602 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1603 (ifp->if_flags & IFF_RUNNING) == 0) {
1604 /*
1605 * If interface is marked up and it is stopped, then
1606 * start it.
1607 */
1608 ieinit(sc);
1609 } else {
1610 /*
1611 * Reset the interface to pick up changes in any other
1612 * flags that affect hardware registers.
1613 */
1614 iestop(sc);
1615 ieinit(sc);
1616 }
1617 #ifdef IEDEBUG
1618 if (ifp->if_flags & IFF_DEBUG)
1619 sc->sc_debug = IED_ALL;
1620 else
1621 sc->sc_debug = 0;
1622 #endif
1623 break;
1624
1625 case SIOCADDMULTI:
1626 case SIOCDELMULTI:
1627 error = (cmd == SIOCADDMULTI) ?
1628 ether_addmulti(ifr, &sc->sc_arpcom) :
1629 ether_delmulti(ifr, &sc->sc_arpcom);
1630
1631 if (error == ENETRESET) {
1632 /*
1633 * Multicast list has changed; set the hardware filter
1634 * accordingly.
1635 */
1636 mc_reset(sc);
1637 error = 0;
1638 }
1639 break;
1640
1641 default:
1642 error = EINVAL;
1643 }
1644 splx(s);
1645 return error;
1646 }
1647
1648 static void
1649 mc_reset(sc)
1650 struct ie_softc *sc;
1651 {
1652 struct ether_multi *enm;
1653 struct ether_multistep step;
1654
1655 /*
1656 * Step through the list of addresses.
1657 */
1658 sc->mcast_count = 0;
1659 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
1660 while (enm) {
1661 if (sc->mcast_count >= MAXMCAST ||
1662 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1663 sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
1664 ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, (void *)0);
1665 goto setflag;
1666 }
1667 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
1668 sc->mcast_count++;
1669 ETHER_NEXT_MULTI(step, enm);
1670 }
1671 setflag:
1672 sc->want_mcsetup = 1;
1673 }
1674
1675 #ifdef IEDEBUG
1676 void
1677 print_rbd(rbd)
1678 volatile struct ie_recv_buf_desc *rbd;
1679 {
1680
1681 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
1682 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
1683 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
1684 rbd->mbz);
1685 }
1686 #endif
1687