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