if_ie.c revision 1.28 1 /* $NetBSD: if_ie.c,v 1.28 1998/10/01 20:05:09 thorpej 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_memset)((char *) scp, 0, sizeof(*scp));
402
403 /* ISCP */
404 off -= sizeof(*iscp);
405 iscp = (volatile void *) (sc->buf_area + off);
406 (sc->sc_memset)((char *) iscp, 0, sizeof(*iscp));
407 sc->iscp = iscp;
408
409 /* SCB */
410 off -= sizeof(*scb);
411 scb = (volatile void *) (sc->buf_area + off);
412 (sc->sc_memset)((char *) scb, 0, 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_memcpy)((caddr_t)ehp, (caddr_t)sc->cbuffs[head], 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_memcpy)(mtod(m, caddr_t) + thismboff,
1004 (caddr_t)(sc->cbuffs[head] + thisrboff),
1005 (u_int)len);
1006 resid -= len;
1007
1008 if (len == thismblen) {
1009 m = m->m_next;
1010 thismboff = 0;
1011 } else
1012 thismboff += len;
1013
1014 if (len == thisrblen) {
1015 head = (head + 1) % sc->nrxbuf;
1016 thisrboff = 0;
1017 } else
1018 thisrboff += len;
1019 }
1020
1021 /*
1022 * Unless something changed strangely while we were doing the copy,
1023 * we have now copied everything in from the shared memory.
1024 * This means that we are done.
1025 */
1026 return top;
1027 }
1028
1029 /*
1030 * Read frame NUM from unit UNIT (pre-cached as IE).
1031 *
1032 * This routine reads the RFD at NUM, and copies in the buffers from
1033 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1034 * doesn't start complaining. Trailers are DROPPED---there's no point
1035 * in wasting time on confusing code to deal with them. Hopefully,
1036 * this machine will never ARP for trailers anyway.
1037 */
1038 static void
1039 ie_readframe(sc, num)
1040 struct ie_softc *sc;
1041 int num; /* frame number to read */
1042 {
1043 int status;
1044 struct mbuf *m = 0;
1045 struct ether_header eh;
1046 #if NBPFILTER > 0
1047 int bpf_gets_it = 0;
1048 #endif
1049
1050 status = sc->rframes[num]->ie_fd_status;
1051
1052 /* Advance the RFD list, since we're done with this descriptor. */
1053 sc->rframes[num]->ie_fd_status = SWAP(0);
1054 sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
1055 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
1056 sc->rftail = (sc->rftail + 1) % sc->nframes;
1057 sc->rfhead = (sc->rfhead + 1) % sc->nframes;
1058
1059 if (status & IE_FD_OK) {
1060 #if NBPFILTER > 0
1061 m = ieget(sc, &eh, &bpf_gets_it);
1062 #else
1063 m = ieget(sc, &eh, 0);
1064 #endif
1065 ie_drop_packet_buffer(sc);
1066 }
1067 if (m == 0) {
1068 sc->sc_if.if_ierrors++;
1069 return;
1070 }
1071
1072 #ifdef IEDEBUG
1073 if (sc->sc_debug & IED_READFRAME)
1074 printf("%s: frame from ether %s type 0x%x\n",
1075 sc->sc_dev.dv_xname,
1076 ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
1077 #endif
1078
1079 #if NBPFILTER > 0
1080 /*
1081 * Check for a BPF filter; if so, hand it up.
1082 * Note that we have to stick an extra mbuf up front, because
1083 * bpf_mtap expects to have the ether header at the front.
1084 * It doesn't matter that this results in an ill-formatted mbuf chain,
1085 * since BPF just looks at the data. (It doesn't try to free the mbuf,
1086 * tho' it will make a copy for tcpdump.)
1087 */
1088 if (bpf_gets_it) {
1089 struct mbuf m0;
1090 m0.m_len = sizeof eh;
1091 m0.m_data = (caddr_t)&eh;
1092 m0.m_next = m;
1093
1094 /* Pass it up. */
1095 bpf_mtap(sc->sc_if.if_bpf, &m0);
1096
1097 /*
1098 * A signal passed up from the filtering code indicating that
1099 * the packet is intended for BPF but not for the protocol
1100 * machinery. We can save a few cycles by not handing it off
1101 * to them.
1102 */
1103 if (bpf_gets_it == 2) {
1104 m_freem(m);
1105 return;
1106 }
1107 }
1108 #endif /* NBPFILTER > 0 */
1109
1110 /*
1111 * In here there used to be code to check destination addresses upon
1112 * receipt of a packet. We have deleted that code, and replaced it
1113 * with code to check the address much earlier in the cycle, before
1114 * copying the data in; this saves us valuable cycles when operating
1115 * as a multicast router or when using BPF.
1116 */
1117
1118 /*
1119 * Finally pass this packet up to higher layers.
1120 */
1121 ether_input(&sc->sc_if, &eh, m);
1122 sc->sc_if.if_ipackets++;
1123 }
1124
1125 static void
1126 ie_drop_packet_buffer(sc)
1127 struct ie_softc *sc;
1128 {
1129 int i;
1130
1131 do {
1132 /*
1133 * This means we are somehow out of sync. So, we reset the
1134 * adapter.
1135 */
1136 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1137 #ifdef IEDEBUG
1138 print_rbd(sc->rbuffs[sc->rbhead]);
1139 #endif
1140 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
1141 sc->sc_dev.dv_xname, sc->rbhead);
1142 iereset(sc);
1143 return;
1144 }
1145
1146 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1147
1148 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1149 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
1150 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
1151 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1152 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
1153 } while (!i);
1154 }
1155
1156 /*
1157 * Start transmission on an interface.
1158 */
1159 static void
1160 iestart(ifp)
1161 struct ifnet *ifp;
1162 {
1163 struct ie_softc *sc = ifp->if_softc;
1164 struct mbuf *m0, *m;
1165 u_char *buffer;
1166 u_short len;
1167
1168 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1169 return;
1170
1171 for (;;) {
1172 if (sc->xmit_busy == sc->ntxbuf) {
1173 ifp->if_flags |= IFF_OACTIVE;
1174 break;
1175 }
1176
1177 IF_DEQUEUE(&ifp->if_snd, m0);
1178 if (m0 == 0)
1179 break;
1180
1181 /* We need to use m->m_pkthdr.len, so require the header */
1182 if ((m0->m_flags & M_PKTHDR) == 0)
1183 panic("iestart: no header mbuf");
1184
1185 #if NBPFILTER > 0
1186 /* Tap off here if there is a BPF listener. */
1187 if (ifp->if_bpf)
1188 bpf_mtap(ifp->if_bpf, m0);
1189 #endif
1190
1191 #ifdef IEDEBUG
1192 if (sc->sc_debug & IED_ENQ)
1193 printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
1194 sc->xchead);
1195 #endif
1196
1197 buffer = sc->xmit_cbuffs[sc->xchead];
1198 for (m = m0; m != 0; m = m->m_next) {
1199 (sc->sc_memcpy)(buffer, mtod(m, caddr_t), m->m_len);
1200 buffer += m->m_len;
1201 }
1202 len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
1203
1204 m_freem(m0);
1205 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
1206
1207 /* Start the first packet transmitting. */
1208 if (sc->xmit_busy == 0)
1209 iexmit(sc);
1210
1211 sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
1212 sc->xmit_busy++;
1213 }
1214 }
1215
1216 static void
1217 iereset(sc)
1218 struct ie_softc *sc;
1219 {
1220 int s = splnet();
1221
1222 /* No message here. The caller does that. */
1223 iestop(sc);
1224
1225 /*
1226 * Stop i82586 dead in its tracks.
1227 */
1228 if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1229 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1230
1231 if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1232 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
1233
1234 ieinit(sc);
1235
1236 splx(s);
1237 }
1238
1239 /*
1240 * Send a command to the controller and wait for it to either
1241 * complete or be accepted, depending on the command. If the
1242 * command pointer is null, then pretend that the command is
1243 * not an action command. If the command pointer is not null,
1244 * and the command is an action command, wait for
1245 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1246 * to become true.
1247 */
1248 static int
1249 cmd_and_wait(sc, cmd, pcmd, mask)
1250 struct ie_softc *sc;
1251 int cmd;
1252 void *pcmd; /* XXX - Was volatile */
1253 int mask;
1254 {
1255 volatile struct ie_cmd_common *cc = pcmd;
1256 volatile struct ie_sys_ctl_block *scb = sc->scb;
1257 int tmo;
1258
1259 scb->ie_command = (u_short)cmd;
1260 (sc->chan_attn)(sc);
1261
1262 /* Wait for the command to be accepted by the CU. */
1263 tmo = 10;
1264 while (scb->ie_command && --tmo)
1265 delay(10);
1266 if (scb->ie_command) {
1267 #ifdef IEDEBUG
1268 printf("%s: cmd_and_wait, CU stuck (1)\n",
1269 sc->sc_dev.dv_xname);
1270 #endif
1271 return -1; /* timed out */
1272 }
1273
1274 /*
1275 * If asked, also wait for it to finish.
1276 */
1277 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1278
1279 /*
1280 * According to the packet driver, the minimum timeout should
1281 * be .369 seconds, which we round up to .4.
1282 */
1283 tmo = 36900;
1284
1285 /*
1286 * Now spin-lock waiting for status. This is not a very nice
1287 * thing to do, but I haven't figured out how, or indeed if, we
1288 * can put the process waiting for action to sleep. (We may
1289 * be getting called through some other timeout running in the
1290 * kernel.)
1291 */
1292 while (((cc->ie_cmd_status & mask) == 0) && --tmo)
1293 delay(10);
1294
1295 if ((cc->ie_cmd_status & mask) == 0) {
1296 #ifdef IEDEBUG
1297 printf("%s: cmd_and_wait, CU stuck (2)\n",
1298 sc->sc_dev.dv_xname);
1299 #endif
1300 return -1; /* timed out */
1301 }
1302 }
1303 return 0;
1304 }
1305
1306 /*
1307 * Run the time-domain reflectometer.
1308 */
1309 static void
1310 run_tdr(sc, cmd)
1311 struct ie_softc *sc;
1312 struct ie_tdr_cmd *cmd;
1313 {
1314 int result;
1315
1316 cmd->com.ie_cmd_status = SWAP(0);
1317 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1318 cmd->com.ie_cmd_link = SWAP(0xffff);
1319
1320 sc->scb->ie_command_list = vtop16sw(sc, cmd);
1321 cmd->ie_tdr_time = SWAP(0);
1322
1323 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1324 !(cmd->com.ie_cmd_status & IE_STAT_OK))
1325 result = 0x10000; /* impossible value */
1326 else
1327 result = cmd->ie_tdr_time;
1328
1329 ie_ack(sc, IE_ST_WHENCE);
1330
1331 if (result & IE_TDR_SUCCESS)
1332 return;
1333
1334 if (result & 0x10000) {
1335 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1336 } else if (result & IE_TDR_XCVR) {
1337 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1338 } else if (result & IE_TDR_OPEN) {
1339 printf("%s: TDR detected an open %d clocks away\n",
1340 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
1341 } else if (result & IE_TDR_SHORT) {
1342 printf("%s: TDR detected a short %d clocks away\n",
1343 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME));
1344 } else {
1345 printf("%s: TDR returned unknown status 0x%x\n",
1346 sc->sc_dev.dv_xname, result);
1347 }
1348 }
1349
1350 /*
1351 * iememinit: set up the buffers
1352 *
1353 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1354 * this is to be used for the buffers. the chip indexs its control data
1355 * structures with 16 bit offsets, and it indexes actual buffers with
1356 * 24 bit addresses. so we should allocate control buffers first so that
1357 * we don't overflow the 16 bit offset field. The number of transmit
1358 * buffers is fixed at compile time.
1359 *
1360 * note: this function was written to be easy to understand, rather than
1361 * highly efficient (it isn't in the critical path).
1362 *
1363 * The memory layout is: tbufs, rbufs, (gap), control blocks
1364 * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
1365 * XXX - This needs review...
1366 */
1367 static void
1368 iememinit(sc)
1369 struct ie_softc *sc;
1370 {
1371 char *ptr;
1372 int i;
1373 u_short nxt;
1374
1375 /* First, zero all the memory. */
1376 ptr = sc->buf_area;
1377 (sc->sc_memset)(ptr, 0, sc->buf_area_sz);
1378
1379 /* Allocate tx/rx buffers. */
1380 for (i = 0; i < NTXBUF; i++) {
1381 sc->xmit_cbuffs[i] = ptr;
1382 ptr += IE_TBUF_SIZE;
1383 }
1384 for (i = 0; i < sc->nrxbuf; i++) {
1385 sc->cbuffs[i] = ptr;
1386 ptr += IE_RBUF_SIZE;
1387 }
1388
1389 /* Small pad (Don't trust the chip...) */
1390 ptr += 16;
1391
1392 /* Allocate and fill in xmit buffer descriptors. */
1393 for (i = 0; i < NTXBUF; i++) {
1394 sc->xmit_buffs[i] = (volatile void *) ptr;
1395 ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
1396 sc->xmit_buffs[i]->ie_xmit_buf =
1397 Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
1398 sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
1399 }
1400
1401 /* Allocate and fill in recv buffer descriptors. */
1402 for (i = 0; i < sc->nrxbuf; i++) {
1403 sc->rbuffs[i] = (volatile void *) ptr;
1404 ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
1405 sc->rbuffs[i]->ie_rbd_buffer =
1406 Swap32(vtop24(sc, sc->cbuffs[i]));
1407 sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
1408 }
1409
1410 /* link together recv bufs and set EOL on last */
1411 i = sc->nrxbuf - 1;
1412 sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
1413 nxt = vtop16sw(sc, (void*) sc->rbuffs[0]);
1414 do {
1415 sc->rbuffs[i]->ie_rbd_next = nxt;
1416 nxt = vtop16sw(sc, (void*) sc->rbuffs[i]);
1417 } while (--i >= 0);
1418
1419 /* Allocate transmit commands. */
1420 for (i = 0; i < NTXBUF; i++) {
1421 sc->xmit_cmds[i] = (volatile void *) ptr;
1422 ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
1423 sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
1424 }
1425
1426 /* Allocate receive frames. */
1427 for (i = 0; i < sc->nframes; i++) {
1428 sc->rframes[i] = (volatile void *) ptr;
1429 ptr = Align(ptr + sizeof(*sc->rframes[i]));
1430 }
1431
1432 /* Link together recv frames and set EOL on last */
1433 i = sc->nframes - 1;
1434 sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
1435 nxt = vtop16sw(sc, (void*) sc->rframes[0]);
1436 do {
1437 sc->rframes[i]->ie_fd_next = nxt;
1438 nxt = vtop16sw(sc, (void*) sc->rframes[i]);
1439 } while (--i >= 0);
1440
1441
1442 /* Pointers to last packet sent and next available transmit buffer. */
1443 sc->xchead = sc->xctail = 0;
1444
1445 /* Clear transmit-busy flag. */
1446 sc->xmit_busy = 0;
1447
1448 /*
1449 * Set the head and tail pointers on receive to keep track of
1450 * the order in which RFDs and RBDs are used. link the
1451 * recv frames and buffer into the scb.
1452 */
1453 sc->rfhead = 0;
1454 sc->rftail = sc->nframes - 1;
1455 sc->rbhead = 0;
1456 sc->rbtail = sc->nrxbuf - 1;
1457
1458 sc->scb->ie_recv_list =
1459 vtop16sw(sc, (void*) sc->rframes[0]);
1460 sc->rframes[0]->ie_fd_buf_desc =
1461 vtop16sw(sc, (void*) sc->rbuffs[0]);
1462
1463 i = (ptr - sc->buf_area);
1464 #ifdef IEDEBUG
1465 printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
1466 #endif
1467 if (i > sc->buf_area_sz)
1468 panic("ie: iememinit, out of space");
1469 }
1470
1471 /*
1472 * Run the multicast setup command.
1473 * Called at splnet().
1474 */
1475 static int
1476 mc_setup(sc, ptr)
1477 struct ie_softc *sc;
1478 void *ptr;
1479 {
1480 struct ie_mcast_cmd *cmd = ptr; /* XXX - Was volatile */
1481
1482 cmd->com.ie_cmd_status = SWAP(0);
1483 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1484 cmd->com.ie_cmd_link = SWAP(0xffff);
1485
1486 (sc->sc_memcpy)((caddr_t)cmd->ie_mcast_addrs,
1487 (caddr_t)sc->mcast_addrs,
1488 sc->mcast_count * sizeof *sc->mcast_addrs);
1489
1490 cmd->ie_mcast_bytes =
1491 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */
1492
1493 sc->scb->ie_command_list = vtop16sw(sc, cmd);
1494 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1495 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1496 printf("%s: multicast address setup command failed\n",
1497 sc->sc_dev.dv_xname);
1498 return 0;
1499 }
1500 return 1;
1501 }
1502
1503 static inline void
1504 ie_setup_config(cmd, promiscuous, manchester)
1505 struct ie_config_cmd *cmd; /* XXX - was volatile */
1506 int promiscuous, manchester;
1507 {
1508
1509 /*
1510 * these are all char's so no need to byte-swap
1511 */
1512 cmd->ie_config_count = 0x0c;
1513 cmd->ie_fifo = 8;
1514 cmd->ie_save_bad = 0x40;
1515 cmd->ie_addr_len = 0x2e;
1516 cmd->ie_priority = 0;
1517 cmd->ie_ifs = 0x60;
1518 cmd->ie_slot_low = 0;
1519 cmd->ie_slot_high = 0xf2;
1520 cmd->ie_promisc = promiscuous | manchester << 2;
1521 cmd->ie_crs_cdt = 0;
1522 cmd->ie_min_len = 64;
1523 cmd->ie_junk = 0xff;
1524 }
1525
1526 /*
1527 * This routine inits the ie.
1528 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1529 * starting the receiver unit, and clearing interrupts.
1530 *
1531 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
1532 */
1533 static int
1534 ieinit(sc)
1535 struct ie_softc *sc;
1536 {
1537 volatile struct ie_sys_ctl_block *scb = sc->scb;
1538 void *ptr;
1539 struct ifnet *ifp;
1540
1541 ifp = &sc->sc_if;
1542 ptr = sc->buf_area; /* XXX - Use scb instead? */
1543
1544 /*
1545 * Send the configure command first.
1546 */
1547 {
1548 struct ie_config_cmd *cmd = ptr; /* XXX - Was volatile */
1549
1550 scb->ie_command_list = vtop16sw(sc, cmd);
1551 cmd->com.ie_cmd_status = SWAP(0);
1552 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1553 cmd->com.ie_cmd_link = SWAP(0xffff);
1554
1555 ie_setup_config(cmd, (sc->promisc != 0), 0);
1556
1557 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1558 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1559 printf("%s: configure command failed\n",
1560 sc->sc_dev.dv_xname);
1561 return 0;
1562 }
1563 }
1564
1565 /*
1566 * Now send the Individual Address Setup command.
1567 */
1568 {
1569 struct ie_iasetup_cmd *cmd = ptr; /* XXX - Was volatile */
1570
1571 scb->ie_command_list = vtop16sw(sc, cmd);
1572 cmd->com.ie_cmd_status = SWAP(0);
1573 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1574 cmd->com.ie_cmd_link = SWAP(0xffff);
1575
1576 (sc->sc_memcpy)((caddr_t)&cmd->ie_address,
1577 LLADDR(ifp->if_sadl), sizeof(cmd->ie_address));
1578
1579 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1580 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1581 printf("%s: individual address setup command failed\n",
1582 sc->sc_dev.dv_xname);
1583 return 0;
1584 }
1585 }
1586
1587 /*
1588 * Now run the time-domain reflectometer.
1589 */
1590 if (ie_run_tdr)
1591 run_tdr(sc, ptr);
1592
1593 /*
1594 * Acknowledge any interrupts we have generated thus far.
1595 */
1596 ie_ack(sc, IE_ST_WHENCE);
1597
1598 /*
1599 * Set up the transmit and recv buffers.
1600 */
1601 iememinit(sc);
1602
1603 /* tell higher levels that we are here */
1604 ifp->if_flags |= IFF_RUNNING;
1605 ifp->if_flags &= ~IFF_OACTIVE;
1606
1607 sc->scb->ie_recv_list =
1608 vtop16sw(sc, (void*) sc->rframes[0]);
1609 cmd_and_wait(sc, IE_RU_START, 0, 0);
1610
1611 ie_ack(sc, IE_ST_WHENCE);
1612
1613 if (sc->run_586)
1614 (sc->run_586)(sc);
1615
1616 return 0;
1617 }
1618
1619 static void
1620 iestop(sc)
1621 struct ie_softc *sc;
1622 {
1623
1624 cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
1625 }
1626
1627 static int
1628 ieioctl(ifp, cmd, data)
1629 register struct ifnet *ifp;
1630 u_long cmd;
1631 caddr_t data;
1632 {
1633 struct ie_softc *sc = ifp->if_softc;
1634 struct ifaddr *ifa = (struct ifaddr *)data;
1635 struct ifreq *ifr = (struct ifreq *)data;
1636 int s, error = 0;
1637
1638 s = splnet();
1639
1640 switch (cmd) {
1641
1642 case SIOCSIFADDR:
1643 ifp->if_flags |= IFF_UP;
1644
1645 switch (ifa->ifa_addr->sa_family) {
1646 #ifdef INET
1647 case AF_INET:
1648 ieinit(sc);
1649 arp_ifinit(ifp, ifa);
1650 break;
1651 #endif
1652 #ifdef NS
1653 /* XXX - This code is probably wrong. */
1654 case AF_NS:
1655 {
1656 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1657
1658 if (ns_nullhost(*ina))
1659 ina->x_host =
1660 *(union ns_host *)LLADDR(ifp->if_sadl);
1661 else
1662 bcopy(ina->x_host.c_host,
1663 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
1664 /* Set new address. */
1665 ieinit(sc);
1666 break;
1667 }
1668 #endif /* NS */
1669 default:
1670 ieinit(sc);
1671 break;
1672 }
1673 break;
1674
1675 case SIOCSIFFLAGS:
1676 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1677
1678 if ((ifp->if_flags & IFF_UP) == 0 &&
1679 (ifp->if_flags & IFF_RUNNING) != 0) {
1680 /*
1681 * If interface is marked down and it is running, then
1682 * stop it.
1683 */
1684 iestop(sc);
1685 ifp->if_flags &= ~IFF_RUNNING;
1686 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1687 (ifp->if_flags & IFF_RUNNING) == 0) {
1688 /*
1689 * If interface is marked up and it is stopped, then
1690 * start it.
1691 */
1692 ieinit(sc);
1693 } else {
1694 /*
1695 * Reset the interface to pick up changes in any other
1696 * flags that affect hardware registers.
1697 */
1698 iestop(sc);
1699 ieinit(sc);
1700 }
1701 #ifdef IEDEBUG
1702 if (ifp->if_flags & IFF_DEBUG)
1703 sc->sc_debug = IED_ALL;
1704 else
1705 sc->sc_debug = ie_debug_flags;
1706 #endif
1707 break;
1708
1709 case SIOCADDMULTI:
1710 case SIOCDELMULTI:
1711 error = (cmd == SIOCADDMULTI) ?
1712 ether_addmulti(ifr, &sc->sc_ethercom) :
1713 ether_delmulti(ifr, &sc->sc_ethercom);
1714
1715 if (error == ENETRESET) {
1716 /*
1717 * Multicast list has changed; set the hardware filter
1718 * accordingly.
1719 */
1720 mc_reset(sc);
1721 error = 0;
1722 }
1723 break;
1724
1725 default:
1726 error = EINVAL;
1727 }
1728 splx(s);
1729 return error;
1730 }
1731
1732 static void
1733 mc_reset(sc)
1734 struct ie_softc *sc;
1735 {
1736 struct ether_multi *enm;
1737 struct ether_multistep step;
1738 struct ifnet *ifp;
1739
1740 ifp = &sc->sc_if;
1741
1742 /*
1743 * Step through the list of addresses.
1744 */
1745 sc->mcast_count = 0;
1746 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1747 while (enm) {
1748 if (sc->mcast_count >= MAXMCAST ||
1749 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1750 ifp->if_flags |= IFF_ALLMULTI;
1751 ieioctl(ifp, SIOCSIFFLAGS, (void *)0);
1752 goto setflag;
1753 }
1754 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
1755 sc->mcast_count++;
1756 ETHER_NEXT_MULTI(step, enm);
1757 }
1758 setflag:
1759 sc->want_mcsetup = 1;
1760 }
1761
1762 #ifdef IEDEBUG
1763 void
1764 print_rbd(rbd)
1765 volatile struct ie_recv_buf_desc *rbd;
1766 {
1767
1768 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
1769 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
1770 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
1771 rbd->mbz);
1772 }
1773 #endif
1774