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