xref: /original-bsd/sys/luna68k/dev/if_le.c (revision df23cbe6)
1 /*
2  * Copyright (c) 1982, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  * from: hp300/dev/if_le.c	7.15 (Berkeley) 12/28/92
8  *
9  *	@(#)if_le.c	7.4 (Berkeley) 01/13/93
10  */
11 
12 #include "le.h"
13 #if NLE > 0
14 
15 #include "bpfilter.h"
16 
17 /*
18  * AMD 7990 LANCE
19  *
20  * This driver will accept tailer encapsulated packets even
21  * though it buys us nothing.  The motivation was to avoid incompatibilities
22  * with VAXen, SUNs, and others that handle and benefit from them.
23  * This reasoning is dubious.
24  */
25 #include <sys/param.h>
26 #include <sys/proc.h>
27 #include <sys/systm.h>
28 #include <sys/mbuf.h>
29 #include <sys/buf.h>
30 #include <sys/protosw.h>
31 #include <sys/socket.h>
32 #include <sys/syslog.h>
33 #include <sys/ioctl.h>
34 #include <sys/errno.h>
35 
36 #include <net/if.h>
37 #include <net/netisr.h>
38 #include <net/route.h>
39 
40 #ifdef INET
41 #include <netinet/in.h>
42 #include <netinet/in_systm.h>
43 #include <netinet/in_var.h>
44 #include <netinet/ip.h>
45 #include <netinet/if_ether.h>
46 #endif
47 
48 #ifdef NS
49 #include <netns/ns.h>
50 #include <netns/ns_if.h>
51 #endif
52 
53 #if defined (CCITT) && defined (LLC)
54 #include <sys/socketvar.h>
55 #include <netccitt/x25.h>
56 extern llc_ctlinput(), cons_rtrequest();
57 #endif
58 
59 #include <machine/cpu.h>
60 #include <machine/mtpr.h>
61 #include <luna68k/dev/device.h>
62 #include <luna68k/dev/if_lereg.h>
63 
64 #if NBPFILTER > 0
65 #include <net/bpf.h>
66 #include <net/bpfdesc.h>
67 #endif
68 
69 int	leattach();
70 struct	driver ledriver = {
71 	leattach, "le",
72 };
73 
74 int	ledebug = 0;		/* console error messages */
75 
76 int	leintr(), leinit(), leioctl(), lestart(), ether_output(), lereset();
77 struct	mbuf *m_devget();
78 extern	struct ifnet loif;
79 
80 /*
81  * Ethernet software status per interface.
82  *
83  * Each interface is referenced by a network interface structure,
84  * le_if, which the routing code uses to locate the interface.
85  * This structure contains the output queue for the interface, its address, ...
86  */
87 struct	le_softc {
88 	struct	arpcom sc_ac;	/* common Ethernet structures */
89 #define	sc_if	sc_ac.ac_if	/* network-visible interface */
90 #define	sc_addr	sc_ac.ac_enaddr	/* hardware Ethernet address */
91 	struct	lereg1 *sc_r1;	/* LANCE registers */
92 	struct	lereg2 *sc_r2;	/* dual-port RAM */
93 	int	sc_rmd;		/* predicted next rmd to process */
94 	int	sc_tmd;		/* next available tmd */
95 	int	sc_txcnt;	/* # of transmit buffers in use */
96 	/* stats */
97 	int	sc_runt;
98 	int	sc_jab;
99 	int	sc_merr;
100 	int	sc_babl;
101 	int	sc_cerr;
102 	int	sc_miss;
103 	int	sc_rown;
104 	int	sc_xown;
105 	int	sc_xown2;
106 	int	sc_uflo;
107 	int	sc_rxlen;
108 	int	sc_rxoff;
109 	int	sc_txoff;
110 	int	sc_busy;
111 	short	sc_iflags;
112 } le_softc[NLE];
113 
114 /* access LANCE registers */
115 #define	LERDWR(cntl, src, dst)	(dst) = (src)
116 
117 #define LE_IPL		3
118 
119 /*
120  * Interface exists: make available by filling in network interface
121  * record.  System will initialize the interface when it is ready
122  * to accept packets.
123  */
124 leattach(hd)
125 	struct hp_device *hd;
126 {
127 	register struct lereg2 *ler2;
128 	struct lereg2 *lemem = (struct lereg2 *) 0;
129 	struct le_softc *le = &le_softc[hd->hp_unit];
130 	struct ifnet *ifp = &le->sc_if;
131 	char *cp;
132 	int i;
133 
134 	le->sc_r1 = (struct lereg1 *) hd->hp_addr;
135 	ler2 = le->sc_r2 = (struct lereg2 *) 0x71000000;
136 
137 	hd->hp_ipl = LE_IPL;
138 
139 	/*
140 	 * Read the ethernet address off the board, one nibble at a time.
141 	 */
142 #ifdef NOROM
143 	cp = "00000a02456c";
144 #else
145 	cp = (char *) 0x4101FFE0;
146 #endif
147 	for (i = 0; i < sizeof(le->sc_addr); i++) {
148 		le->sc_addr[i]  = (*cp < 'A' ? (*cp & 0xF) : (*cp & 0xF) + 9) << 4;
149 		cp++;
150 		le->sc_addr[i] |= (*cp < 'A' ? (*cp & 0xF) : (*cp & 0xF) + 9);
151 		cp++;
152 	}
153 	printf("le%d: hardware address %s\n", hd->hp_unit,
154 		ether_sprintf(le->sc_addr));
155 
156 	/*
157 	 * Setup for transmit/receive
158 	 */
159 	ler2->ler2_mode = LE_MODE;
160 	ler2->ler2_ladrf[0] = 0;
161 	ler2->ler2_ladrf[1] = 0;
162 	ler2->ler2_rlen = LE_RLEN;
163 	ler2->ler2_rdra = (int)lemem->ler2_rmd;
164 	ler2->ler2_tlen = LE_TLEN;
165 	ler2->ler2_tdra = (int)lemem->ler2_tmd;
166 
167 	ifp->if_unit = hd->hp_unit;
168 	ifp->if_name = "le";
169 	ifp->if_mtu = ETHERMTU;
170 	ifp->if_init = leinit;
171 	ifp->if_reset = lereset;
172 	ifp->if_ioctl = leioctl;
173 	ifp->if_output = ether_output;
174 	ifp->if_start = lestart;
175 #ifdef MULTICAST
176 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
177 #else
178 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
179 #endif
180 #if NBPFILTER > 0
181 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
182 #endif
183 	if_attach(ifp);
184 	return (1);
185 }
186 
187 #ifdef MULTICAST
188 /*
189  * Setup the logical address filter
190  */
191 void
192 lesetladrf(sc)
193 	register struct le_softc *sc;
194 {
195 	register volatile struct lereg2 *ler2 = sc->sc_r2;
196 	register struct ifnet *ifp = &sc->sc_if;
197 	register struct ether_multi *enm;
198 	register u_char *cp;
199 	register u_long crc;
200 	register u_long c;
201 	register int i, len;
202 	struct ether_multistep step;
203 
204 	/*
205 	 * Set up multicast address filter by passing all multicast
206 	 * addresses through a crc generator, and then using the high
207 	 * order 6 bits as a index into the 64 bit logical address
208 	 * filter. The high order two bits select the word, while the
209 	 * rest of the bits select the bit within the word.
210 	 */
211 
212 	ler2->ler2_ladrf[0] = 0;
213 	ler2->ler2_ladrf[1] = 0;
214 	ifp->if_flags &= ~IFF_ALLMULTI;
215 	ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
216 	while (enm != NULL) {
217 		if (bcmp((caddr_t)&enm->enm_addrlo,
218 		    (caddr_t)&enm->enm_addrhi, sizeof(enm->enm_addrlo)) == 0) {
219 			/*
220 			 * We must listen to a range of multicast
221 			 * addresses. For now, just accept all
222 			 * multicasts, rather than trying to set only
223 			 * those filter bits needed to match the range.
224 			 * (At this time, the only use of address
225 			 * ranges is for IP multicast routing, for
226 			 * which the range is big enough to require all
227 			 * bits set.)
228 			 */
229 			ler2->ler2_ladrf[0] = 0xffffffff;
230 			ler2->ler2_ladrf[1] = 0xffffffff;
231 			ifp->if_flags |= IFF_ALLMULTI;
232 			return;
233 		}
234 
235 		cp = (unsigned char *)&enm->enm_addrlo;
236 		c = *cp;
237 		crc = 0xffffffff;
238 		len = 6;
239 		while (len-- > 0) {
240 			c = *cp;
241 			for (i = 0; i < 8; i++) {
242 				if ((c & 0x01) ^ (crc & 0x01)) {
243 					crc >>= 1;
244 					crc = crc ^ 0xedb88320;
245 				}
246 				else
247 					crc >>= 1;
248 				c >>= 1;
249 			}
250 			cp++;
251 		}
252 		/* Just want the 6 most significant bits. */
253 		crc = crc >> 26;
254 
255 		/* Turn on the corresponding bit in the filter. */
256 		ler2->ler2_ladrf[crc >> 5] |= 1 << (crc & 0x1f);
257 
258 		ETHER_NEXT_MULTI(step, enm);
259 	}
260 }
261 #endif
262 
263 ledrinit(ler2, le)
264 	register struct lereg2 *ler2;
265 	register struct le_softc *le;
266 {
267 	register struct lereg2 *lemem = (struct lereg2 *) 0;
268 	register int i;
269 
270 	ler2->ler2_padr[0] = le->sc_addr[1];
271 	ler2->ler2_padr[1] = le->sc_addr[0];
272 	ler2->ler2_padr[2] = le->sc_addr[3];
273 	ler2->ler2_padr[3] = le->sc_addr[2];
274 	ler2->ler2_padr[4] = le->sc_addr[5];
275 	ler2->ler2_padr[5] = le->sc_addr[4];
276 	for (i = 0; i < LERBUF; i++) {
277 		ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i];
278 		ler2->ler2_rmd[i].rmd1 = LE_OWN;
279 		ler2->ler2_rmd[i].rmd2 = -LEMTU;
280 		ler2->ler2_rmd[i].rmd3 = 0;
281 	}
282 	for (i = 0; i < LETBUF; i++) {
283 		ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i];
284 		ler2->ler2_tmd[i].tmd1 = 0;
285 		ler2->ler2_tmd[i].tmd2 = 0;
286 		ler2->ler2_tmd[i].tmd3 = 0;
287 	}
288 	/* Setup the logical address filter */
289 #ifdef MULTICAST
290 	lesetladrf(le);
291 #else
292 	ler2->ler2_ladrf[0] = 0;
293 	ler2->ler2_ladrf[1] = 0;
294 #endif
295 }
296 
297 lereset(unit)
298 	register int unit;
299 {
300 	register struct le_softc *le = &le_softc[unit];
301 	register struct lereg1 *ler1 = le->sc_r1;
302 	register struct lereg2 *lemem = (struct lereg2 *) 0;
303 	register int timo = 100000;
304 	register int stat;
305 
306 #ifdef lint
307 	stat = unit;
308 #endif
309 #if NBPFILTER > 0
310 	if (le->sc_if.if_flags & IFF_PROMISC)
311 		/* set the promiscuous bit */
312 		le->sc_r2->ler2_mode = LE_MODE|0x8000;
313 	else
314 		le->sc_r2->ler2_mode = LE_MODE;
315 #endif
316 	LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
317 	LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
318 	ledrinit(le->sc_r2, le);
319 	le->sc_rmd = le->sc_tmd = 0;
320 	LERDWR(ler0, LE_CSR1, ler1->ler1_rap);
321 	LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp);
322 	LERDWR(ler0, LE_CSR2, ler1->ler1_rap);
323 	LERDWR(ler0, 0, ler1->ler1_rdp);
324 	LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
325 	LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
326 	do {
327 		if (--timo == 0) {
328 			printf("le%d: init timeout, stat = 0x%x\n",
329 			       unit, stat);
330 			break;
331 		}
332 		LERDWR(ler0, ler1->ler1_rdp, stat);
333 	} while ((stat & LE_IDON) == 0);
334 	LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
335 	LERDWR(ler0, LE_CSR3, ler1->ler1_rap);
336 	LERDWR(ler0, LE_BSWP, ler1->ler1_rdp);
337 	LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
338 	LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
339 	le->sc_if.if_flags &= ~IFF_OACTIVE;
340 	le->sc_txcnt = 0;
341 }
342 
343 /*
344  * Initialization of interface
345  */
346 leinit(unit)
347 	int unit;
348 {
349 	register struct ifnet *ifp = &le_softc[unit].sc_if;
350 	register struct ifaddr *ifa;
351 	int s;
352 
353 	/* not yet, if address still unknown */
354 	for (ifa = ifp->if_addrlist;; ifa = ifa->ifa_next)
355 		if (ifa == 0)
356 			return;
357 		else if (ifa->ifa_addr && ifa->ifa_addr->sa_family != AF_LINK)
358 			break;
359 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
360 		s = splimp();
361 		ifp->if_flags |= IFF_RUNNING;
362 		lereset(unit);
363 	        (void) lestart(ifp);
364 		splx(s);
365 	}
366 }
367 
368 /*
369  * Start output on interface.  Get another datagram to send
370  * off of the interface queue, and copy it to the interface
371  * before starting the output.
372  */
373 lestart(ifp)
374 	struct ifnet *ifp;
375 {
376 	register struct le_softc *le = &le_softc[ifp->if_unit];
377 	register struct letmd *tmd;
378 	register struct mbuf *m;
379 	int len;
380 
381 	if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
382 		return (0);
383 	tmd = &le->sc_r2->ler2_tmd[le->sc_tmd];
384 	do {
385 		if (tmd->tmd1 & LE_OWN) {
386 			le->sc_xown2++;
387 			return (0);
388 		}
389 		IF_DEQUEUE(&le->sc_if.if_snd, m);
390 		if (m == 0)
391 			return (0);
392 		len = leput(le->sc_r2->ler2_tbuf[le->sc_tmd], m);
393 #if NBPFILTER > 0
394 		/*
395 		 * If bpf is listening on this interface, let it
396 		 * see the packet before we commit it to the wire.
397 		 */
398 		if (ifp->if_bpf)
399 			bpf_tap(ifp->if_bpf, le->sc_r2->ler2_tbuf[le->sc_tmd],
400 				len);
401 #endif
402 
403 		tmd->tmd3 = 0;
404 		tmd->tmd2 = -len;
405 		tmd->tmd1 = LE_OWN | LE_STP | LE_ENP;
406 		if (++le->sc_tmd == LETBUF) {
407 			le->sc_tmd = 0;
408 			tmd = le->sc_r2->ler2_tmd;
409 		} else
410 			tmd++;
411 	} while (++le->sc_txcnt < LETBUF);
412 	le->sc_if.if_flags |= IFF_OACTIVE;
413 	return (0);
414 }
415 
416 void
417 _leintr()
418 {
419 	register int i;
420 
421 	for (i = 0; i < NLE; i++) {
422 		leintr(i);
423 	}
424 }
425 
426 int
427 leintr(unit)
428 	register int unit;
429 {
430 	register struct le_softc *le = &le_softc[unit];
431 	register struct lereg1 *ler1;
432 	register int stat;
433 
434 	ler1 = le->sc_r1;
435 	LERDWR(ler0, ler1->ler1_rdp, stat);
436 	if (stat & LE_SERR) {
437 		leerror(unit, stat);
438 		if (stat & LE_MERR) {
439 			le->sc_merr++;
440 			lereset(unit);
441 			return(1);
442 		}
443 		if (stat & LE_BABL)
444 			le->sc_babl++;
445 		if (stat & LE_CERR)
446 			le->sc_cerr++;
447 		if (stat & LE_MISS)
448 			le->sc_miss++;
449 		LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
450 	}
451 	if ((stat & LE_RXON) == 0) {
452 		le->sc_rxoff++;
453 		lereset(unit);
454 		return(1);
455 	}
456 	if ((stat & LE_TXON) == 0) {
457 		le->sc_txoff++;
458 		lereset(unit);
459 		return(1);
460 	}
461 	if (stat & LE_RINT)
462 		lerint(unit);
463 	if (stat & LE_TINT)
464 		lexint(unit);
465 	return(1);
466 }
467 
468 /*
469  * Ethernet interface transmitter interrupt.
470  * Start another output if more data to send.
471  */
472 lexint(unit)
473 	register int unit;
474 {
475 	register struct le_softc *le = &le_softc[unit];
476 	register struct letmd *tmd;
477 	int i, gotone = 0;
478 
479 	do {
480 		if ((i = le->sc_tmd - le->sc_txcnt) < 0)
481 			i += LETBUF;
482 		tmd = &le->sc_r2->ler2_tmd[i];
483 		if (tmd->tmd1 & LE_OWN) {
484 			if (gotone)
485 				break;
486 			le->sc_xown++;
487 			return;
488 		}
489 
490 		/* clear interrupt */
491 		LERDWR(le->sc_r0, LE_TINT|LE_INEA, le->sc_r1->ler1_rdp);
492 
493 		/* XXX documentation says BUFF not included in ERR */
494 		if ((tmd->tmd1 & LE_ERR) || (tmd->tmd3 & LE_TBUFF)) {
495 			lexerror(unit);
496 			le->sc_if.if_oerrors++;
497 			if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) {
498 				le->sc_uflo++;
499 				lereset(unit);
500 			} else if (tmd->tmd3 & LE_LCOL)
501 				le->sc_if.if_collisions++;
502 			else if (tmd->tmd3 & LE_RTRY)
503 				le->sc_if.if_collisions += 16;
504 		} else if (tmd->tmd1 & LE_ONE)
505 			le->sc_if.if_collisions++;
506 		else if (tmd->tmd1 & LE_MORE)
507 			/* what is the real number? */
508 			le->sc_if.if_collisions += 2;
509 		else
510 			le->sc_if.if_opackets++;
511 		gotone++;
512 	} while (--le->sc_txcnt > 0);
513 	le->sc_if.if_flags &= ~IFF_OACTIVE;
514 	(void) lestart(&le->sc_if);
515 }
516 
517 #define	LENEXTRMP \
518 	if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd
519 
520 /*
521  * Ethernet interface receiver interrupt.
522  * If input error just drop packet.
523  * Decapsulate packet based on type and pass to type specific
524  * higher-level input routine.
525  */
526 lerint(unit)
527 	int unit;
528 {
529 	register struct le_softc *le = &le_softc[unit];
530 	register int bix = le->sc_rmd;
531 	register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix];
532 
533 	/*
534 	 * Out of sync with hardware, should never happen?
535 	 */
536 	if (rmd->rmd1 & LE_OWN) {
537 		le->sc_rown++;
538 		LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
539 		return;
540 	}
541 
542 	/*
543 	 * Process all buffers with valid data
544 	 */
545 	while ((rmd->rmd1 & LE_OWN) == 0) {
546 		int len = rmd->rmd3;
547 
548 		/* Clear interrupt to avoid race condition */
549 		LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
550 
551 		if (rmd->rmd1 & LE_ERR) {
552 			le->sc_rmd = bix;
553 			lererror(unit, "bad packet");
554 			le->sc_if.if_ierrors++;
555 		} else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
556 			/*
557 			 * Find the end of the packet so we can see how long
558 			 * it was.  We still throw it away.
559 			 */
560 			do {
561 				LERDWR(le->sc_r0, LE_RINT|LE_INEA,
562 				       le->sc_r1->ler1_rdp);
563 				rmd->rmd3 = 0;
564 				rmd->rmd1 = LE_OWN;
565 				LENEXTRMP;
566 			} while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
567 			le->sc_rmd = bix;
568 			lererror(unit, "chained buffer");
569 			le->sc_rxlen++;
570 			/*
571 			 * If search terminated without successful completion
572 			 * we reset the hardware (conservative).
573 			 */
574 			if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
575 			    LE_ENP) {
576 				lereset(unit);
577 				return;
578 			}
579 		} else
580 			leread(unit, le->sc_r2->ler2_rbuf[bix], len);
581 		rmd->rmd3 = 0;
582 		rmd->rmd1 = LE_OWN;
583 		LENEXTRMP;
584 	}
585 	le->sc_rmd = bix;
586 }
587 
588 leread(unit, buf, len)
589 	int unit;
590 	char *buf;
591 	int len;
592 {
593 	register struct le_softc *le = &le_softc[unit];
594 	register struct ether_header *et;
595     	struct mbuf *m;
596 	int off, resid, flags;
597 
598 	le->sc_if.if_ipackets++;
599 	et = (struct ether_header *)buf;
600 	et->ether_type = ntohs((u_short)et->ether_type);
601 	/* adjust input length to account for header and CRC */
602 	len = len - sizeof(struct ether_header) - 4;
603 
604 #define	ledataaddr(et, off, type)	((type)(((caddr_t)((et)+1)+(off))))
605 	if (et->ether_type >= ETHERTYPE_TRAIL &&
606 	    et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
607 		off = (et->ether_type - ETHERTYPE_TRAIL) * 512;
608 		if (off >= ETHERMTU)
609 			return;		/* sanity */
610 		et->ether_type = ntohs(*ledataaddr(et, off, u_short *));
611 		resid = ntohs(*(ledataaddr(et, off+2, u_short *)));
612 		if (off + resid > len)
613 			return;		/* sanity */
614 		len = off + resid;
615 	} else
616 		off = 0;
617 
618 	if (len <= 0) {
619 		if (ledebug)
620 			log(LOG_WARNING,
621 			    "le%d: ierror(runt packet): from %s: len=%d\n",
622 			    unit, ether_sprintf(et->ether_shost), len);
623 		le->sc_runt++;
624 		le->sc_if.if_ierrors++;
625 		return;
626 	}
627 	flags = 0;
628 	if (bcmp((caddr_t)etherbroadcastaddr,
629 	    (caddr_t)et->ether_dhost, sizeof(etherbroadcastaddr)) == 0)
630 		flags |= M_BCAST;
631 	if (et->ether_dhost[0] & 1)
632 		flags |= M_MCAST;
633 
634 #if NBPFILTER > 0
635 	/*
636 	 * Check if there's a bpf filter listening on this interface.
637 	 * If so, hand off the raw packet to enet.
638 	 */
639 	if (le->sc_if.if_bpf) {
640 		bpf_tap(le->sc_if.if_bpf, buf, len + sizeof(struct ether_header));
641 
642 		/*
643 		 * Keep the packet if it's a broadcast or has our
644 		 * physical ethernet address (or if we support
645 		 * multicast and it's one).
646 		 */
647 		if (
648 #ifdef MULTICAST
649 		    (flags & (M_BCAST | M_MCAST)) == 0 &&
650 #else
651 		    (flags & M_BCAST) == 0 &&
652 #endif
653 		    bcmp(et->ether_dhost, le->sc_addr,
654 			sizeof(et->ether_dhost)) != 0)
655 			return;
656 	}
657 #endif
658 	/*
659 	 * Pull packet off interface.  Off is nonzero if packet
660 	 * has trailing header; m_devget will then force this header
661 	 * information to be at the front, but we still have to drop
662 	 * the type and length which are at the front of any trailer data.
663 	 */
664 	m = m_devget((char *)(et + 1), len, off, &le->sc_if, 0);
665 	m->m_flags |= flags;
666 	if (m == 0)
667 		return;
668 	ether_input(&le->sc_if, et, m);
669 }
670 
671 /*
672  * Routine to copy from mbuf chain to transmit
673  * buffer in board local memory.
674  */
675 leput(lebuf, m)
676 	register char *lebuf;
677 	register struct mbuf *m;
678 {
679 	register struct mbuf *mp;
680 	register int len, tlen = 0;
681 
682 	for (mp = m; mp; mp = mp->m_next) {
683 		len = mp->m_len;
684 		if (len == 0)
685 			continue;
686 		tlen += len;
687 		bcopy(mtod(mp, char *), lebuf, len);
688 		lebuf += len;
689 	}
690 	m_freem(m);
691 	if (tlen < LEMINSIZE) {
692 		bzero(lebuf, LEMINSIZE - tlen);
693 		tlen = LEMINSIZE;
694 	}
695 	return(tlen);
696 }
697 
698 /*
699  * Process an ioctl request.
700  */
701 leioctl(ifp, cmd, data)
702 	register struct ifnet *ifp;
703 	int cmd;
704 	caddr_t data;
705 {
706 	register struct ifaddr *ifa = (struct ifaddr *)data;
707 	struct le_softc *le = &le_softc[ifp->if_unit];
708 	struct lereg1 *ler1 = le->sc_r1;
709 	int s = splimp(), error = 0;
710 
711 	switch (cmd) {
712 
713 	case SIOCSIFADDR:
714 		ifp->if_flags |= IFF_UP;
715 		switch (ifa->ifa_addr->sa_family) {
716 #ifdef INET
717 		case AF_INET:
718 			leinit(ifp->if_unit);	/* before arpwhohas */
719 			((struct arpcom *)ifp)->ac_ipaddr =
720 				IA_SIN(ifa)->sin_addr;
721 			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
722 			break;
723 #endif
724 #ifdef NS
725 		case AF_NS:
726 		    {
727 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
728 
729 			if (ns_nullhost(*ina))
730 				ina->x_host = *(union ns_host *)(le->sc_addr);
731 			else {
732 				/*
733 				 * The manual says we can't change the address
734 				 * while the receiver is armed,
735 				 * so reset everything
736 				 */
737 				ifp->if_flags &= ~IFF_RUNNING;
738 				LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
739 				bcopy((caddr_t)ina->x_host.c_host,
740 				    (caddr_t)le->sc_addr, sizeof(le->sc_addr));
741 			}
742 			leinit(ifp->if_unit); /* does le_setaddr() */
743 			break;
744 		    }
745 #endif
746 		default:
747 			leinit(ifp->if_unit);
748 			break;
749 		}
750 		break;
751 
752 #if defined (CCITT) && defined (LLC)
753 	case SIOCSIFCONF_X25:
754 		ifp -> if_flags |= IFF_UP;
755 		ifa -> ifa_rtrequest = cons_rtrequest;
756 		error = x25_llcglue(PRC_IFUP, ifa -> ifa_addr);
757 		if (error == 0)
758 			leinit(ifp -> if_unit);
759 		break;
760 #endif /* CCITT && LLC */
761 
762 
763 	case SIOCSIFFLAGS:
764 		if ((ifp->if_flags & IFF_UP) == 0 &&
765 		    ifp->if_flags & IFF_RUNNING) {
766 			LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
767 			ifp->if_flags &= ~IFF_RUNNING;
768 		} else if (ifp->if_flags & IFF_UP &&
769 		    (ifp->if_flags & IFF_RUNNING) == 0)
770 			leinit(ifp->if_unit);
771 		/*
772 		 * If the state of the promiscuous bit changes, the interface
773 		 * must be reset to effect the change.
774 		 */
775 		if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) &&
776 		    (ifp->if_flags & IFF_RUNNING)) {
777 			le->sc_iflags = ifp->if_flags;
778 			lereset(ifp->if_unit);
779 			lestart(ifp);
780 		}
781 		break;
782 
783 #ifdef MULTICAST
784 	case SIOCADDMULTI:
785 	case SIOCDELMULTI:
786 		/* Update our multicast list  */
787 		error = (cmd == SIOCADDMULTI) ?
788 		    ether_addmulti((struct ifreq *)data, &le->sc_ac) :
789 		    ether_delmulti((struct ifreq *)data, &le->sc_ac);
790 
791 		if (error == ENETRESET) {
792 			/*
793 			 * Multicast list has changed; set the hardware
794 			 * filter accordingly.
795 			 */
796 			lereset(ifp->if_unit);
797 			error = 0;
798 		}
799 		break;
800 #endif
801 	default:
802 		error = EINVAL;
803 	}
804 	splx(s);
805 	return (error);
806 }
807 
808 leerror(unit, stat)
809 	int unit;
810 	int stat;
811 {
812 	if (!ledebug)
813 		return;
814 
815 	/*
816 	 * Not all transceivers implement heartbeat
817 	 * so we only log CERR once.
818 	 */
819 	if ((stat & LE_CERR) && le_softc[unit].sc_cerr)
820 		return;
821 	log(LOG_WARNING,
822 	    "le%d: error: stat=%b\n", unit,
823 	    stat,
824 	    "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");
825 }
826 
827 lererror(unit, msg)
828 	int unit;
829 	char *msg;
830 {
831 	register struct le_softc *le = &le_softc[unit];
832 	register struct lermd *rmd;
833 	int len;
834 
835 	if (!ledebug)
836 		return;
837 
838 	rmd = &le->sc_r2->ler2_rmd[le->sc_rmd];
839 	len = rmd->rmd3;
840 	log(LOG_WARNING,
841 	    "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
842 	    unit, msg,
843 	    len > 11 ?
844 		ether_sprintf((u_char *)&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) :
845 		"unknown",
846 	    le->sc_rmd, len,
847 	    rmd->rmd1,
848 	    "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
849 }
850 
851 lexerror(unit)
852 	int unit;
853 {
854 	register struct le_softc *le = &le_softc[unit];
855 	register struct letmd *tmd;
856 	int len;
857 
858 	if (!ledebug)
859 		return;
860 
861 	tmd = le->sc_r2->ler2_tmd;
862 	len = -tmd->tmd2;
863 	log(LOG_WARNING,
864 	    "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
865 	    unit,
866 	    len > 5 ?
867 		ether_sprintf((u_char *)&le->sc_r2->ler2_tbuf[0][0]) :
868 		"unknown",
869 	    0, len,
870 	    tmd->tmd1,
871 	    "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
872 	    tmd->tmd3,
873 	    "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
874 }
875 #endif
876