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