xref: /original-bsd/sys/pmax/dev/if_le.c (revision ea3a8ee8)
1 /*-
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ralph Campbell and Rick Macklem.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)if_le.c	7.9 (Berkeley) 12/20/92
11  */
12 
13 #include <le.h>
14 #if NLE > 0
15 
16 #include <bpfilter.h>
17 
18 /*
19  * AMD 7990 LANCE
20  *
21  * This driver will generate and accept trailer encapsulated packets even
22  * though it buys us nothing.  The motivation was to avoid incompatibilities
23  * with VAXen, SUNs, and others that handle and benefit from them.
24  * This reasoning is dubious.
25  */
26 #include <sys/param.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 #ifdef RMP
54 #include <netrmp/rmp.h>
55 #include <netrmp/rmp_var.h>
56 #endif
57 
58 #include <machine/machConst.h>
59 
60 #include <pmax/pmax/pmaxtype.h>
61 #include <pmax/pmax/kn01.h>
62 #include <pmax/pmax/kmin.h>
63 #include <pmax/pmax/asic.h>
64 
65 #include <pmax/dev/device.h>
66 #include <pmax/dev/if_lereg.h>
67 
68 #if NBPFILTER > 0
69 #include <net/bpf.h>
70 #include <net/bpfdesc.h>
71 #endif
72 
73 int	leprobe();
74 void	leintr();
75 struct	driver ledriver = {
76 	"le", leprobe, 0, 0, leintr,
77 };
78 
79 int	ledebug = 1;		/* console error messages */
80 
81 /*
82  * Ethernet software status per interface.
83  *
84  * Each interface is referenced by a network interface structure,
85  * le_if, which the routing code uses to locate the interface.
86  * This structure contains the output queue for the interface, its address, ...
87  */
88 struct	le_softc {
89 	struct	arpcom sc_ac;	/* common Ethernet structures */
90 #define	sc_if	sc_ac.ac_if	/* network-visible interface */
91 #define	sc_addr	sc_ac.ac_enaddr	/* hardware Ethernet address */
92 	volatile struct	lereg1 *sc_r1;	/* LANCE registers */
93 	volatile void *sc_r2;	/* dual-port RAM */
94 	int	sc_ler2pad;	/* Do ring descriptors require short pads? */
95 	void	(*sc_copytobuf)(); /* Copy to buffer */
96 	void	(*sc_copyfrombuf)(); /* Copy from buffer */
97 	void	(*sc_zerobuf)(); /* and Zero bytes in buffer */
98 	int	sc_rmd;		/* predicted next rmd to process */
99 	int	sc_tmd;		/* last tmd processed */
100 	int	sc_tmdnext;	/* next tmd to transmit with */
101 	int	sc_runt;
102 	int	sc_jab;
103 	int	sc_merr;
104 	int	sc_babl;
105 	int	sc_cerr;
106 	int	sc_miss;
107 	int	sc_xint;
108 	int	sc_xown;
109 	int	sc_uflo;
110 	int	sc_rxlen;
111 	int	sc_rxoff;
112 	int	sc_txoff;
113 	int	sc_busy;
114 	short	sc_iflags;
115 #if NBPFILTER > 0
116 	caddr_t sc_bpf;
117 #endif
118 } le_softc[NLE];
119 
120 /* access LANCE registers */
121 static void lewritereg();
122 #define	LERDWR(cntl, src, dst)	{ (dst) = (src); DELAY(10); }
123 #define	LEWREG(src, dst)	lewritereg(&(dst), (src))
124 
125 #define CPU_TO_CHIP_ADDR(cpu) \
126 	((unsigned)(&(((struct lereg2 *)0)->cpu)))
127 
128 #define LE_OFFSET_RAM		0x0
129 #define LE_OFFSET_LANCE		0x100000
130 #define LE_OFFSET_ROM		0x1c0000
131 
132 void copytobuf_contig(), copyfrombuf_contig(), bzerobuf_contig();
133 void copytobuf_gap2(), copyfrombuf_gap2(), bzerobuf_gap2();
134 void copytobuf_gap16(), copyfrombuf_gap16(), bzerobuf_gap16();
135 
136 extern int pmax_boardtype;
137 extern u_long le_iomem;
138 extern u_long asic_base;
139 
140 /*
141  * Test to see if device is present.
142  * Return true if found and initialized ok.
143  * If interface exists, make available by filling in network interface
144  * record.  System will initialize the interface when it is ready
145  * to accept packets.
146  */
147 leprobe(dp)
148 	struct pmax_ctlr *dp;
149 {
150 	volatile struct lereg1 *ler1;
151 	struct le_softc *le = &le_softc[dp->pmax_unit];
152 	struct ifnet *ifp = &le->sc_if;
153 	u_char *cp;
154 	int i;
155 	extern int leinit(), leioctl(), lestart(), ether_output();
156 
157 	switch (pmax_boardtype) {
158 	case DS_PMAX:
159 		le->sc_r1 = ler1 = (volatile struct lereg1 *)dp->pmax_addr;
160 		le->sc_r2 = (volatile void *)MACH_PHYS_TO_UNCACHED(0x19000000);
161 		cp = (u_char *)(MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
162 		le->sc_ler2pad = 1;
163 		le->sc_copytobuf = copytobuf_gap2;
164 		le->sc_copyfrombuf = copyfrombuf_gap2;
165 		le->sc_zerobuf = bzerobuf_gap2;
166 		break;
167 	case DS_3MIN:
168 	case DS_MAXINE:
169 	case DS_3MAXPLUS:
170 		if (dp->pmax_unit == 0) {
171 			volatile u_int *ssr, *ldp;
172 
173 			le->sc_r1 = ler1 = (volatile struct lereg1 *)
174 				ASIC_SYS_LANCE(asic_base);
175 			cp = (u_char *)ASIC_SYS_ETHER_ADDRESS(asic_base);
176 			le->sc_r2 = (volatile void *)
177 				MACH_PHYS_TO_UNCACHED(le_iomem);
178 			le->sc_ler2pad = 1;
179 			le->sc_copytobuf = copytobuf_gap16;
180 			le->sc_copyfrombuf = copyfrombuf_gap16;
181 			le->sc_zerobuf = bzerobuf_gap16;
182 
183 			/*
184 			 * And enable Lance dma through the asic.
185 			 */
186 			ssr = (volatile u_int *)ASIC_REG_CSR(asic_base);
187 			ldp = (volatile u_int *)
188 				ASIC_REG_LANCE_DMAPTR(asic_base);
189 			*ldp = (le_iomem << 3);	/* phys addr << 3 */
190 			*ssr |= ASIC_CSR_DMAEN_LANCE;
191 			break;
192 		}
193 		/*
194 		 * Units other than 0 are turbochannel option boards and fall
195 		 * through to DS_3MAX.
196 		 */
197 	case DS_3MAX:
198 		le->sc_r1 = ler1 = (volatile struct lereg1 *)
199 			(dp->pmax_addr + LE_OFFSET_LANCE);
200 		le->sc_r2 = (volatile void *)(dp->pmax_addr + LE_OFFSET_RAM);
201 		cp = (u_char *)(dp->pmax_addr + LE_OFFSET_ROM + 2);
202 		le->sc_ler2pad = 0;
203 		le->sc_copytobuf = copytobuf_contig;
204 		le->sc_copyfrombuf = copyfrombuf_contig;
205 		le->sc_zerobuf = bzerobuf_contig;
206 		break;
207 	default:
208 		printf("Unknown CPU board type %d\n", pmax_boardtype);
209 		return (0);
210 	};
211 
212 	/*
213 	 * Get the ethernet address out of rom
214 	 */
215 	for (i = 0; i < sizeof(le->sc_addr); i++) {
216 		le->sc_addr[i] = *cp;
217 		cp += 4;
218 	}
219 
220 	/* make sure the chip is stopped */
221 	LEWREG(LE_CSR0, ler1->ler1_rap);
222 	LEWREG(LE_STOP, ler1->ler1_rdp);
223 
224 	ifp->if_unit = dp->pmax_unit;
225 	ifp->if_name = "le";
226 	ifp->if_mtu = ETHERMTU;
227 	ifp->if_init = leinit;
228 	ifp->if_ioctl = leioctl;
229 	ifp->if_output = ether_output;
230 	ifp->if_start = lestart;
231 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
232 #if NBPFILTER > 0
233 	bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
234 #endif
235 	if_attach(ifp);
236 
237 	printf("le%d at nexus0 csr 0x%x priority %d ethernet address %s\n",
238 		dp->pmax_unit, dp->pmax_addr, dp->pmax_pri,
239 		ether_sprintf(le->sc_addr));
240 	return (1);
241 }
242 
243 ledrinit(le)
244 	struct le_softc *le;
245 {
246 	register volatile void *rp;
247 	register int i;
248 
249 	for (i = 0; i < LERBUF; i++) {
250 		rp = LER2_RMDADDR(le->sc_r2, i);
251 		LER2_rmd0(rp, CPU_TO_CHIP_ADDR(ler2_rbuf[i][0]));
252 		LER2_rmd1(rp, LE_OWN);
253 		LER2_rmd2(rp, -LEMTU);
254 		LER2_rmd3(rp, 0);
255 	}
256 	for (i = 0; i < LETBUF; i++) {
257 		rp = LER2_TMDADDR(le->sc_r2, i);
258 		LER2_tmd0(rp, CPU_TO_CHIP_ADDR(ler2_tbuf[i][0]));
259 		LER2_tmd1(rp, 0);
260 		LER2_tmd2(rp, 0);
261 		LER2_tmd3(rp, 0);
262 	}
263 }
264 
265 lereset(unit)
266 	register int unit;
267 {
268 	register struct le_softc *le = &le_softc[unit];
269 	register volatile struct lereg1 *ler1 = le->sc_r1;
270 	register volatile void *ler2 = le->sc_r2;
271 	register int timo = 100000;
272 	register int stat;
273 
274 #ifdef lint
275 	stat = unit;
276 #endif
277 	LEWREG(LE_CSR0, ler1->ler1_rap);
278 	LEWREG(LE_STOP, ler1->ler1_rdp);
279 
280 	/*
281 	 * Setup for transmit/receive
282 	 */
283 #if NBPFILTER > 0
284 	if (le->sc_if.if_flags & IFF_PROMISC)
285 		/* set the promiscuous bit */
286 		LER2_mode(ler2, LE_MODE|0x8000);
287 	else
288 #endif
289 		LER2_mode(ler2, LE_MODE);
290 	LER2_padr0(ler2, (le->sc_addr[1] << 8) | le->sc_addr[0]);
291 	LER2_padr1(ler2, (le->sc_addr[3] << 8) | le->sc_addr[2]);
292 	LER2_padr2(ler2, (le->sc_addr[5] << 8) | le->sc_addr[4]);
293 #ifdef RMP
294 	/*
295 	 * Set up logical addr filter to accept multicast 9:0:9:0:0:4
296 	 * This should be an ioctl() to the driver.  (XXX)
297 	 */
298 	LER2_ladrf0(ler2, 0x0010);
299 	LER2_ladrf1(ler2, 0x0);
300 	LER2_ladrf2(ler2, 0x0);
301 	LER2_ladrf3(ler2, 0x0);
302 #else
303 	LER2_ladrf0(ler2, 0);
304 	LER2_ladrf1(ler2, 0);
305 	LER2_ladrf2(ler2, 0);
306 	LER2_ladrf3(ler2, 0);
307 #endif
308 	LER2_rlen(ler2, LE_RLEN);
309 	LER2_rdra(ler2, CPU_TO_CHIP_ADDR(ler2_rmd[0]));
310 	LER2_tlen(ler2, LE_TLEN);
311 	LER2_tdra(ler2, CPU_TO_CHIP_ADDR(ler2_tmd[0]));
312 	ledrinit(le);
313 	le->sc_rmd = 0;
314 	le->sc_tmd = LETBUF - 1;
315 	le->sc_tmdnext = 0;
316 
317 	LEWREG(LE_CSR1, ler1->ler1_rap);
318 	LEWREG(CPU_TO_CHIP_ADDR(ler2_mode), ler1->ler1_rdp);
319 	LEWREG(LE_CSR2, ler1->ler1_rap);
320 	LEWREG(0, ler1->ler1_rdp);
321 	LEWREG(LE_CSR3, ler1->ler1_rap);
322 	LEWREG(0, ler1->ler1_rdp);
323 	LEWREG(LE_CSR0, ler1->ler1_rap);
324 	LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
325 	do {
326 		if (--timo == 0) {
327 			printf("le%d: init timeout, stat = 0x%x\n",
328 			       unit, stat);
329 			break;
330 		}
331 		stat = ler1->ler1_rdp;
332 	} while ((stat & LE_IDON) == 0);
333 	LERDWR(ler0, LE_IDON, ler1->ler1_rdp);
334 	LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
335 	le->sc_if.if_flags &= ~IFF_OACTIVE;
336 }
337 
338 /*
339  * Initialization of interface
340  */
341 leinit(unit)
342 	int unit;
343 {
344 	struct le_softc *le = &le_softc[unit];
345 	register struct ifnet *ifp = &le->sc_if;
346 	int s;
347 
348 	/* not yet, if address still unknown */
349 	if (ifp->if_addrlist == (struct ifaddr *)0)
350 		return;
351 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
352 		s = splnet();
353 		ifp->if_flags |= IFF_RUNNING;
354 		lereset(unit);
355 	        (void) lestart(ifp);
356 		splx(s);
357 	}
358 }
359 
360 #define	LENEXTTMP \
361 	if (++bix == LETBUF) \
362 		bix = 0; \
363 	tmd = LER2_TMDADDR(le->sc_r2, bix)
364 
365 /*
366  * Start output on interface.  Get another datagram to send
367  * off of the interface queue, and copy it to the interface
368  * before starting the output.
369  */
370 lestart(ifp)
371 	struct ifnet *ifp;
372 {
373 	register struct le_softc *le = &le_softc[ifp->if_unit];
374 	register int bix = le->sc_tmdnext;
375 	register volatile void *tmd = LER2_TMDADDR(le->sc_r2, bix);
376 	register struct mbuf *m;
377 	int len = 0;
378 
379 	if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
380 		return (0);
381 	while (bix != le->sc_tmd) {
382 		if (LER2V_tmd1(tmd) & LE_OWN)
383 			panic("lestart");
384 		IF_DEQUEUE(&le->sc_if.if_snd, m);
385 		if (m == 0)
386 			break;
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 (le->sc_bpf)
393 			bpf_mtap(le->sc_bpf, m);
394 #endif
395 		len = leput(le, LER2_TBUFADDR(le->sc_r2, bix), m);
396 		LER2_tmd3(tmd, 0);
397 		LER2_tmd2(tmd, -len);
398 		LER2_tmd1(tmd, LE_OWN | LE_STP | LE_ENP);
399 		LENEXTTMP;
400 	}
401 	if (len != 0) {
402 		le->sc_if.if_flags |= IFF_OACTIVE;
403 		LERDWR(ler0, LE_TDMD | LE_INEA, le->sc_r1->ler1_rdp);
404 	}
405 	le->sc_tmdnext = bix;
406 	return (0);
407 }
408 
409 /*
410  * Process interrupts from the 7990 chip.
411  */
412 void
413 leintr(unit)
414 	int unit;
415 {
416 	register struct le_softc *le;
417 	register volatile struct lereg1 *ler1;
418 	register int stat;
419 
420 	le = &le_softc[unit];
421 	ler1 = le->sc_r1;
422 	stat = ler1->ler1_rdp;
423 	if (!(stat & LE_INTR)) {
424 		printf("le%d: spurrious interrupt\n", unit);
425 		return;
426 	}
427 	if (stat & LE_SERR) {
428 		leerror(unit, stat);
429 		if (stat & LE_MERR) {
430 			le->sc_merr++;
431 			lereset(unit);
432 			return;
433 		}
434 		if (stat & LE_BABL)
435 			le->sc_babl++;
436 		if (stat & LE_CERR)
437 			le->sc_cerr++;
438 		if (stat & LE_MISS)
439 			le->sc_miss++;
440 		LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
441 	}
442 	if ((stat & LE_RXON) == 0) {
443 		le->sc_rxoff++;
444 		lereset(unit);
445 		return;
446 	}
447 	if ((stat & LE_TXON) == 0) {
448 		le->sc_txoff++;
449 		lereset(unit);
450 		return;
451 	}
452 	if (stat & LE_RINT) {
453 		/* interrupt is cleared in lerint */
454 		lerint(unit);
455 	}
456 	if (stat & LE_TINT) {
457 		LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
458 		lexint(unit);
459 	}
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 int bix = le->sc_tmd;
471 	register volatile void *tmd;
472 
473 	if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) {
474 		le->sc_xint++;
475 		return;
476 	}
477 	LENEXTTMP;
478 	while (bix != le->sc_tmdnext && (LER2V_tmd1(tmd) & LE_OWN) == 0) {
479 		le->sc_tmd = bix;
480 		if ((LER2V_tmd1(tmd) & LE_ERR) || (LER2V_tmd3(tmd) & LE_TBUFF)) {
481 			lexerror(unit);
482 			le->sc_if.if_oerrors++;
483 			if (LER2V_tmd3(tmd) & (LE_TBUFF|LE_UFLO)) {
484 				le->sc_uflo++;
485 				lereset(unit);
486 				break;
487 			}
488 			else if (LER2V_tmd3(tmd) & LE_LCOL)
489 				le->sc_if.if_collisions++;
490 			else if (LER2V_tmd3(tmd) & LE_RTRY)
491 				le->sc_if.if_collisions += 16;
492 		}
493 		else if (LER2V_tmd1(tmd) & LE_ONE)
494 			le->sc_if.if_collisions++;
495 		else if (LER2V_tmd1(tmd) & LE_MORE)
496 			/* what is the real number? */
497 			le->sc_if.if_collisions += 2;
498 		else
499 			le->sc_if.if_opackets++;
500 		LENEXTTMP;
501 	}
502 	if (bix == le->sc_tmdnext)
503 		le->sc_if.if_flags &= ~IFF_OACTIVE;
504 	(void) lestart(&le->sc_if);
505 }
506 
507 #define	LENEXTRMP \
508 	if (++bix == LERBUF) \
509 		bix = 0; \
510 	rmd = LER2_RMDADDR(le->sc_r2, bix)
511 
512 /*
513  * Ethernet interface receiver interrupt.
514  * If input error just drop packet.
515  * Decapsulate packet based on type and pass to type specific
516  * higher-level input routine.
517  */
518 lerint(unit)
519 	int unit;
520 {
521 	register struct le_softc *le = &le_softc[unit];
522 	register int bix = le->sc_rmd;
523 	register volatile void *rmd = LER2_RMDADDR(le->sc_r2, bix);
524 
525 	/*
526 	 * Out of sync with hardware, should never happen?
527 	 */
528 	if (LER2V_rmd1(rmd) & LE_OWN) {
529 		LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
530 		return;
531 	}
532 
533 	/*
534 	 * Process all buffers with valid data
535 	 */
536 	while ((LER2V_rmd1(rmd) & LE_OWN) == 0) {
537 		int len = LER2V_rmd3(rmd);
538 
539 		/* Clear interrupt to avoid race condition */
540 		LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
541 
542 		if (LER2V_rmd1(rmd) & LE_ERR) {
543 			le->sc_rmd = bix;
544 			lererror(unit, "bad packet");
545 			le->sc_if.if_ierrors++;
546 		} else if ((LER2V_rmd1(rmd) & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
547 			/*
548 			 * Find the end of the packet so we can see how long
549 			 * it was.  We still throw it away.
550 			 */
551 			do {
552 				LERDWR(le->sc_r0, LE_RINT|LE_INEA,
553 				       le->sc_r1->ler1_rdp);
554 				LER2_rmd3(rmd, 0);
555 				LER2_rmd1(rmd, LE_OWN);
556 				LENEXTRMP;
557 			} while (!(LER2V_rmd1(rmd) & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
558 			le->sc_rmd = bix;
559 			lererror(unit, "chained buffer");
560 			le->sc_rxlen++;
561 			/*
562 			 * If search terminated without successful completion
563 			 * we reset the hardware (conservative).
564 			 */
565 			if ((LER2V_rmd1(rmd) & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
566 			    LE_ENP) {
567 				lereset(unit);
568 				return;
569 			}
570 		} else
571 			leread(unit, LER2_RBUFADDR(le->sc_r2, bix), len);
572 		LER2_rmd3(rmd, 0);
573 		LER2_rmd1(rmd, LE_OWN);
574 		LENEXTRMP;
575 	}
576 	MachEmptyWriteBuffer();		/* Paranoia */
577 	le->sc_rmd = bix;
578 }
579 
580 /*
581  * Look at the packet in network buffer memory so we can be smart about how
582  * we copy the data into mbufs.
583  * This needs work since we can't just read network buffer memory like
584  * regular memory.
585  */
586 leread(unit, buf, len)
587 	int unit;
588 	volatile void *buf;
589 	int len;
590 {
591 	register struct le_softc *le = &le_softc[unit];
592 	struct ether_header et;
593     	struct mbuf *m, **hdrmp, **tailmp;
594 	int off, resid;
595 	u_short sbuf[2], eth_type;
596 	extern struct mbuf *leget();
597 
598 	le->sc_if.if_ipackets++;
599 	(*le->sc_copyfrombuf)(buf, 0, (char *)&et, sizeof (et));
600 	eth_type = ntohs(et.ether_type);
601 	/* adjust input length to account for header and CRC */
602 	len = len - sizeof(struct ether_header) - 4;
603 
604 #ifdef RMP
605 	/*  (XXX)
606 	 *
607 	 *  If Ethernet Type field is < MaxPacketSize, we probably have
608 	 *  a IEEE802 packet here.  Make sure that the size is at least
609 	 *  that of the HP LLC.  Also do sanity checks on length of LLC
610 	 *  (old Ethernet Type field) and packet length.
611 	 *
612 	 *  Provided the above checks succeed, change `len' to reflect
613 	 *  the length of the LLC (i.e. et.ether_type) and change the
614 	 *  type field to ETHERTYPE_IEEE so we can switch() on it later.
615 	 *  Yes, this is a hack and will eventually be done "right".
616 	 */
617 	if (eth_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
618 	    len >= eth_type && len >= IEEE802LEN_MIN) {
619 		len = eth_type;
620 		eth_type = ETHERTYPE_IEEE;	/* hack! */
621 	}
622 #endif
623 
624 	if (eth_type >= ETHERTYPE_TRAIL &&
625 	    eth_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
626 		off = (eth_type - ETHERTYPE_TRAIL) * 512;
627 		if (off >= ETHERMTU)
628 			return;		/* sanity */
629 		(*le->sc_copyfrombuf)(buf, sizeof (et) + off, (char *)sbuf,
630 			sizeof (sbuf));
631 		eth_type = ntohs(sbuf[0]);
632 		resid = ntohs(sbuf[1]);
633 		if (off + resid > len)
634 			return;		/* sanity */
635 		len = off + resid;
636 	} else
637 		off = 0;
638 
639 	if (len <= 0) {
640 		if (ledebug)
641 			log(LOG_WARNING,
642 			    "le%d: ierror(runt packet): from %s: len=%d\n",
643 			    unit, ether_sprintf(et.ether_shost), len);
644 		le->sc_runt++;
645 		le->sc_if.if_ierrors++;
646 		return;
647 	}
648 
649 	/*
650 	 * Pull packet off interface.  Off is nonzero if packet
651 	 * has trailing header; leget will then force this header
652 	 * information to be at the front, but we still have to drop
653 	 * the type and length which are at the front of any trailer data.
654 	 * The hdrmp and tailmp pointers are used by lebpf_tap() to
655 	 * temporarily reorder the mbuf list. See the comment at the beginning
656 	 * of lebpf_tap() for all the ugly details.
657 	 */
658 	m = leget(le, buf, len, off, &le->sc_if, &hdrmp, &tailmp);
659 	if (m == 0)
660 		return;
661 #if NBPFILTER > 0
662 	if (le->sc_bpf)
663 		if (lebpf_tap(le, m, hdrmp, tailmp, off, &et, sbuf))
664 			return;
665 #endif
666 #ifdef RMP
667 	/*
668 	 * (XXX)
669 	 * This needs to be integrated with the ISO stuff in ether_input()
670 	 */
671 	if (eth_type == ETHERTYPE_IEEE) {
672 		/*
673 		 *  Snag the Logical Link Control header (IEEE 802.2).
674 		 */
675 		struct hp_llc *llc = &(mtod(m, struct rmp_packet *)->hp_llc);
676 
677 		/*
678 		 *  If the DSAP (and HP's extended DXSAP) indicate this
679 		 *  is an RMP packet, hand it to the raw input routine.
680 		 */
681 		if (llc->dsap == IEEE_DSAP_HP && llc->dxsap == HPEXT_DXSAP) {
682 			static struct sockproto rmp_sp = {AF_RMP,RMPPROTO_BOOT};
683 			static struct sockaddr rmp_src = {AF_RMP};
684 			static struct sockaddr rmp_dst = {AF_RMP};
685 
686 			bcopy(et.ether_shost, rmp_src.sa_data,
687 			      sizeof(et.ether_shost));
688 			bcopy(et.ether_dhost, rmp_dst.sa_data,
689 			      sizeof(et.ether_dhost));
690 
691 			raw_input(m, &rmp_sp, &rmp_src, &rmp_dst);
692 			return;
693 		}
694 	}
695 #endif
696 	et.ether_type = eth_type;
697 	ether_input(&le->sc_if, &et, m);
698 }
699 
700 /*
701  * Routine to copy from mbuf chain to transmit buffer in
702  * network buffer memory.
703  */
704 leput(le, lebuf, m)
705 	struct le_softc *le;
706 	register volatile void *lebuf;
707 	register struct mbuf *m;
708 {
709 	register struct mbuf *mp;
710 	register int len, tlen = 0;
711 	register int boff = 0;
712 
713 	for (mp = m; mp; mp = mp->m_next) {
714 		len = mp->m_len;
715 		if (len == 0)
716 			continue;
717 		(*le->sc_copytobuf)(mtod(mp, char *), lebuf, boff, len);
718 		tlen += len;
719 		boff += len;
720 	}
721 	m_freem(m);
722 	if (tlen < LEMINSIZE) {
723 		(*le->sc_zerobuf)(lebuf, boff, LEMINSIZE - tlen);
724 		tlen = LEMINSIZE;
725 	}
726 	return(tlen);
727 }
728 
729 /*
730  * Routine to copy from network buffer memory into mbufs.
731  */
732 struct mbuf *
733 leget(le, lebuf, totlen, off, ifp, hdrmp, tailmp)
734 	struct le_softc *le;
735 	volatile void *lebuf;
736 	int totlen, off;
737 	struct ifnet *ifp;
738 	struct mbuf ***hdrmp, ***tailmp;
739 {
740 	register struct mbuf *m;
741 	struct mbuf *top = 0, **mp = &top;
742 	register int len, resid, boff;
743 
744 	/* NOTE: sizeof(struct ether_header) should be even */
745 	boff = sizeof(struct ether_header);
746 	if (off) {
747 		/* NOTE: off should be even */
748 		boff += off + 2 * sizeof(u_short);
749 		totlen -= 2 * sizeof(u_short);
750 		resid = totlen - off;
751 	} else
752 		resid = totlen;
753 
754 	MGETHDR(m, M_DONTWAIT, MT_DATA);
755 	if (m == 0)
756 		return (0);
757 	m->m_pkthdr.rcvif = ifp;
758 	m->m_pkthdr.len = totlen;
759 	m->m_len = MHLEN;
760 
761 	while (totlen > 0) {
762 		if (top) {
763 			MGET(m, M_DONTWAIT, MT_DATA);
764 			if (m == 0) {
765 				m_freem(top);
766 				return (0);
767 			}
768 			m->m_len = MLEN;
769 		}
770 
771 		if (resid >= MINCLSIZE)
772 			MCLGET(m, M_DONTWAIT);
773 		if (m->m_flags & M_EXT)
774 			m->m_len = min(resid, MCLBYTES);
775 		else if (resid < m->m_len) {
776 			/*
777 			 * Place initial small packet/header at end of mbuf.
778 			 */
779 			if (top == 0 && resid + max_linkhdr <= m->m_len)
780 				m->m_data += max_linkhdr;
781 			m->m_len = resid;
782 		}
783 		len = m->m_len;
784 		(*le->sc_copyfrombuf)(lebuf, boff, mtod(m, char *), len);
785 		boff += len;
786 		*mp = m;
787 		mp = &m->m_next;
788 		totlen -= len;
789 		resid -= len;
790 		if (resid == 0) {
791 			boff = sizeof (struct ether_header);
792 			resid = totlen;
793 			*hdrmp = mp;
794 		}
795 	}
796 	*tailmp = mp;
797 	return (top);
798 }
799 
800 /*
801  * Process an ioctl request.
802  */
803 leioctl(ifp, cmd, data)
804 	register struct ifnet *ifp;
805 	int cmd;
806 	caddr_t data;
807 {
808 	register struct ifaddr *ifa = (struct ifaddr *)data;
809 	struct le_softc *le = &le_softc[ifp->if_unit];
810 	volatile struct lereg1 *ler1 = le->sc_r1;
811 	int s, error = 0;
812 
813 	s = splnet();
814 	switch (cmd) {
815 
816 	case SIOCSIFADDR:
817 		ifp->if_flags |= IFF_UP;
818 		switch (ifa->ifa_addr->sa_family) {
819 #ifdef INET
820 		case AF_INET:
821 			leinit(ifp->if_unit);	/* before arpwhohas */
822 			((struct arpcom *)ifp)->ac_ipaddr =
823 				IA_SIN(ifa)->sin_addr;
824 			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
825 			break;
826 #endif
827 #ifdef NS
828 		case AF_NS:
829 		    {
830 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
831 
832 			if (ns_nullhost(*ina))
833 				ina->x_host = *(union ns_host *)(le->sc_addr);
834 			else {
835 				/*
836 				 * The manual says we can't change the address
837 				 * while the receiver is armed,
838 				 * so reset everything
839 				 */
840 				ifp->if_flags &= ~IFF_RUNNING;
841 				bcopy((caddr_t)ina->x_host.c_host,
842 				    (caddr_t)le->sc_addr, sizeof(le->sc_addr));
843 			}
844 			leinit(ifp->if_unit); /* does le_setaddr() */
845 			break;
846 		    }
847 #endif
848 		default:
849 			leinit(ifp->if_unit);
850 			break;
851 		}
852 		break;
853 
854 	case SIOCSIFFLAGS:
855 		if ((ifp->if_flags & IFF_UP) == 0 &&
856 		    ifp->if_flags & IFF_RUNNING) {
857 			LEWREG(LE_STOP, ler1->ler1_rdp);
858 			ifp->if_flags &= ~IFF_RUNNING;
859 		} else if (ifp->if_flags & IFF_UP &&
860 		    (ifp->if_flags & IFF_RUNNING) == 0)
861 			leinit(ifp->if_unit);
862 		/*
863 		 * If the state of the promiscuous bit changes, the interface
864 		 * must be reset to effect the change.
865 		 */
866 		if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) &&
867 		    (ifp->if_flags & IFF_RUNNING)) {
868 			le->sc_iflags = ifp->if_flags;
869 			lereset(ifp->if_unit);
870 			lestart(ifp);
871 		}
872 		break;
873 
874 	default:
875 		error = EINVAL;
876 	}
877 	splx(s);
878 	return (error);
879 }
880 
881 leerror(unit, stat)
882 	int unit;
883 	int stat;
884 {
885 	if (!ledebug)
886 		return;
887 
888 	/*
889 	 * Not all transceivers implement heartbeat
890 	 * so we only log CERR once.
891 	 */
892 	if ((stat & LE_CERR) && le_softc[unit].sc_cerr)
893 		return;
894 	log(LOG_WARNING,
895 	    "le%d: error: stat=%b\n", unit,
896 	    stat,
897 	    "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");
898 }
899 
900 lererror(unit, msg)
901 	int unit;
902 	char *msg;
903 {
904 	register struct le_softc *le = &le_softc[unit];
905 	register volatile void *rmd;
906 	u_char eaddr[6];
907 	int len;
908 
909 	if (!ledebug)
910 		return;
911 
912 	rmd = LER2_RMDADDR(le->sc_r2, le->sc_rmd);
913 	len = LER2V_rmd3(rmd);
914 	if (len > 11)
915 		(*le->sc_copyfrombuf)(LER2_RBUFADDR(le->sc_r2, le->sc_rmd),
916 			6, eaddr, 6);
917 	log(LOG_WARNING,
918 	    "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
919 	    unit, msg,
920 	    len > 11 ? ether_sprintf(eaddr) : "unknown",
921 	    le->sc_rmd, len,
922 	    LER2V_rmd1(rmd),
923 	    "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
924 }
925 
926 lexerror(unit)
927 	int unit;
928 {
929 	register struct le_softc *le = &le_softc[unit];
930 	register volatile void *tmd;
931 	u_char eaddr[6];
932 	int len;
933 
934 	if (!ledebug)
935 		return;
936 
937 	tmd = LER2_TMDADDR(le->sc_r2, 0);
938 	len = -LER2V_tmd2(tmd);
939 	if (len > 5)
940 		(*le->sc_copyfrombuf)(LER2_TBUFADDR(le->sc_r2, 0), 0, eaddr, 6);
941 	log(LOG_WARNING,
942 	    "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
943 	    unit,
944 	    len > 5 ? ether_sprintf(eaddr) : "unknown",
945 	    0, len,
946 	    LER2V_tmd1(tmd),
947 	    "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
948 	    LER2V_tmd3(tmd),
949 	    "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
950 }
951 
952 /*
953  * Write a lance register port, reading it back to ensure success. This seems
954  * to be necessary during initialization, since the chip appears to be a bit
955  * pokey sometimes.
956  */
957 static void
958 lewritereg(regptr, val)
959 	register volatile u_short *regptr;
960 	register u_short val;
961 {
962 	register int i = 0;
963 
964 	while (*regptr != val) {
965 		*regptr = val;
966 		MachEmptyWriteBuffer();
967 		if (++i > 10000) {
968 			printf("le: Reg did not settle (to x%x): x%x\n",
969 			       val, *regptr);
970 			return;
971 		}
972 		DELAY(100);
973 	}
974 }
975 
976 /*
977  * Routines for accessing the transmit and receive buffers. Unfortunately,
978  * CPU addressing of these buffers is done in one of 3 ways:
979  * - contiguous (for the 3max and turbochannel option card)
980  * - gap2, which means shorts (2 bytes) interspersed with short (2 byte)
981  *   spaces (for the pmax)
982  * - gap16, which means 16bytes interspersed with 16byte spaces
983  *   for buffers which must begin on a 32byte boundary (for 3min and maxine)
984  * The buffer offset is the logical byte offset, assuming contiguous storage.
985  */
986 void
987 copytobuf_contig(from, lebuf, boff, len)
988 	char *from;
989 	volatile void *lebuf;
990 	int boff;
991 	int len;
992 {
993 
994 	/*
995 	 * Just call bcopy() to do the work.
996 	 */
997 	bcopy(from, ((char *)lebuf) + boff, len);
998 }
999 
1000 void
1001 copyfrombuf_contig(lebuf, boff, to, len)
1002 	volatile void *lebuf;
1003 	int boff;
1004 	char *to;
1005 	int len;
1006 {
1007 
1008 	/*
1009 	 * Just call bcopy() to do the work.
1010 	 */
1011 	bcopy(((char *)lebuf) + boff, to, len);
1012 }
1013 
1014 void
1015 bzerobuf_contig(lebuf, boff, len)
1016 	volatile void *lebuf;
1017 	int boff;
1018 	int len;
1019 {
1020 
1021 	/*
1022 	 * Just let bzero() do the work
1023 	 */
1024 	bzero(((char *)lebuf) + boff, len);
1025 }
1026 
1027 /*
1028  * For the pmax the buffer consists of shorts (2 bytes) interspersed with
1029  * short (2 byte) spaces and must be accessed with halfword load/stores.
1030  * (don't worry about doing an extra byte)
1031  */
1032 void
1033 copytobuf_gap2(from, lebuf, boff, len)
1034 	register char *from;
1035 	volatile void *lebuf;
1036 	int boff;
1037 	register int len;
1038 {
1039 	register volatile u_short *bptr;
1040 	register int xfer;
1041 
1042 	if (boff & 0x1) {
1043 		/* handle unaligned first byte */
1044 		bptr = ((volatile u_short *)lebuf) + (boff - 1);
1045 		*bptr = (*from++ << 8) | (*bptr & 0xff);
1046 		bptr += 2;
1047 		len--;
1048 	} else
1049 		bptr = ((volatile u_short *)lebuf) + boff;
1050 	if ((unsigned)from & 0x1) {
1051 		while (len > 1) {
1052 			*bptr = (from[1] << 8) | from[0];
1053 			bptr += 2;
1054 			from += 2;
1055 			len -= 2;
1056 		}
1057 	} else {
1058 		/* optimize for aligned transfers */
1059 		xfer = (int)((unsigned)len & ~0x1);
1060 		CopyToBuffer((u_short *)from, bptr, xfer);
1061 		bptr += xfer;
1062 		from += xfer;
1063 		len -= xfer;
1064 	}
1065 	if (len == 1)
1066 		*bptr = (u_short)*from;
1067 }
1068 
1069 void
1070 copyfrombuf_gap2(lebuf, boff, to, len)
1071 	volatile void *lebuf;
1072 	int boff;
1073 	register char *to;
1074 	register int len;
1075 {
1076 	register volatile u_short *bptr;
1077 	register u_short tmp;
1078 	register int xfer;
1079 
1080 	if (boff & 0x1) {
1081 		/* handle unaligned first byte */
1082 		bptr = ((volatile u_short *)lebuf) + (boff - 1);
1083 		*to++ = (*bptr >> 8) & 0xff;
1084 		bptr += 2;
1085 		len--;
1086 	} else
1087 		bptr = ((volatile u_short *)lebuf) + boff;
1088 	if ((unsigned)to & 0x1) {
1089 		while (len > 1) {
1090 			tmp = *bptr;
1091 			*to++ = tmp & 0xff;
1092 			*to++ = (tmp >> 8) & 0xff;
1093 			bptr += 2;
1094 			len -= 2;
1095 		}
1096 	} else {
1097 		/* optimize for aligned transfers */
1098 		xfer = (int)((unsigned)len & ~0x1);
1099 		CopyFromBuffer(bptr, to, xfer);
1100 		bptr += xfer;
1101 		to += xfer;
1102 		len -= xfer;
1103 	}
1104 	if (len == 1)
1105 		*to = *bptr & 0xff;
1106 }
1107 
1108 void
1109 bzerobuf_gap2(lebuf, boff, len)
1110 	volatile void *lebuf;
1111 	int boff;
1112 	int len;
1113 {
1114 	register volatile u_short *bptr;
1115 
1116 	if ((unsigned)boff & 0x1) {
1117 		bptr = ((volatile u_short *)lebuf) + (boff - 1);
1118 		*bptr &= 0xff;
1119 		bptr += 2;
1120 		len--;
1121 	} else
1122 		bptr = ((volatile u_short *)lebuf) + boff;
1123 	while (len > 0) {
1124 		*bptr = 0;
1125 		bptr += 2;
1126 		len -= 2;
1127 	}
1128 }
1129 
1130 /*
1131  * For the 3min and maxine, the buffers are in main memory filled in with
1132  * 16byte blocks interspersed with 16byte spaces.
1133  */
1134 void
1135 copytobuf_gap16(from, lebuf, boff, len)
1136 	register char *from;
1137 	volatile void *lebuf;
1138 	int boff;
1139 	register int len;
1140 {
1141 	register char *bptr;
1142 	register int xfer;
1143 
1144 	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
1145 	boff &= 0xf;
1146 	xfer = min(len, 16 - boff);
1147 	while (len > 0) {
1148 		bcopy(from, ((char *)bptr) + boff, xfer);
1149 		from += xfer;
1150 		bptr += 32;
1151 		boff = 0;
1152 		len -= xfer;
1153 		xfer = min(len, 16);
1154 	}
1155 }
1156 
1157 void
1158 copyfrombuf_gap16(lebuf, boff, to, len)
1159 	volatile void *lebuf;
1160 	int boff;
1161 	register char *to;
1162 	register int len;
1163 {
1164 	register char *bptr;
1165 	register int xfer;
1166 
1167 	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
1168 	boff &= 0xf;
1169 	xfer = min(len, 16 - boff);
1170 	while (len > 0) {
1171 		bcopy(((char *)bptr) + boff, to, xfer);
1172 		to += xfer;
1173 		bptr += 32;
1174 		boff = 0;
1175 		len -= xfer;
1176 		xfer = min(len, 16);
1177 	}
1178 }
1179 
1180 void
1181 bzerobuf_gap16(lebuf, boff, len)
1182 	volatile void *lebuf;
1183 	int boff;
1184 	register int len;
1185 {
1186 	register char *bptr;
1187 	register int xfer;
1188 
1189 	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);
1190 	boff &= 0xf;
1191 	xfer = min(len, 16 - boff);
1192 	while (len > 0) {
1193 		bzero(((char *)bptr) + boff, xfer);
1194 		bptr += 32;
1195 		boff = 0;
1196 		len -= xfer;
1197 		xfer = min(len, 16);
1198 	}
1199 }
1200 
1201 #if NBPFILTER > 0
1202 /*
1203  * This is exceptionally ugly, but since the lance buffers are not always
1204  * contiguous in cpu address space, this was the best I could think of.
1205  * Essentially build an mbuf list with the entire raw packet in it and
1206  * then dismantle it again if it is a local packet. I can't believe I am
1207  * rebuilding the trailer encapsulation, but...
1208  * Return true if the packet has been thrown away.
1209  */
1210 static int
1211 lebpf_tap(le, m, hdrmp, tailmp, off, ep, sbuf)
1212 	struct le_softc *le;
1213 	struct mbuf *m;
1214 	struct mbuf **hdrmp;
1215 	struct mbuf **tailmp;
1216 	int off;
1217 	struct ether_header *ep;
1218 	u_short *sbuf;
1219 {
1220 	register struct mbuf *em, *sm;
1221 	u_short *sp;
1222 
1223 	MGET(em, M_DONTWAIT, MT_DATA);
1224 	if (off && em) {
1225 		MGET(sm, M_DONTWAIT, MT_DATA);
1226 		if (sm == (struct mbuf *)0) {
1227 			m_freem(em);
1228 			em = (struct mbuf *)0;
1229 		}
1230 	}
1231 	if (em) {
1232 		bcopy((caddr_t)ep, mtod(em, caddr_t), sizeof (*ep));
1233 		em->m_len = sizeof (*ep);
1234 		if (off) {
1235 			sp = mtod(sm, u_short *);
1236 			*sp++ = *sbuf++;
1237 			*sp = *sbuf;
1238 			sm->m_len = 2 * sizeof (u_short);
1239 			em->m_next = *hdrmp;
1240 			*hdrmp = (struct mbuf *)0;
1241 			*tailmp = sm;
1242 			sm->m_next = m;
1243 		} else
1244 			em->m_next = m;
1245 		bpf_tap(le->sc_bpf, em);
1246 	}
1247 	/*
1248 	 * Note that the interface cannot be in promiscuous mode if
1249 	 * there are no bpf listeners.  And if we are in promiscuous
1250 	 * mode, we have to check if this packet is really ours.
1251 	 *
1252 	 * XXX This test does not support multicasts.
1253 	 */
1254 	if ((le->sc_if.if_flags & IFF_PROMISC)
1255 	    && bcmp(ep->ether_dhost, le->sc_addr,
1256 		    sizeof(ep->ether_dhost)) != 0
1257 	    && bcmp(ep->ether_dhost, etherbroadcastaddr,
1258 		    sizeof(ep->ether_dhost)) != 0) {
1259 		if (em)
1260 			m_freem(em);
1261 		else
1262 			m_freem(m);
1263 		return (1);
1264 	}
1265 	if (em == (struct mbuf *)0)
1266 		return (0);
1267 	if (off) {
1268 		MFREE(em, *hdrmp);
1269 		*tailmp = (struct mbuf *)0;
1270 		MFREE(sm, em);
1271 	} else {
1272 		MFREE(em, sm);
1273 	}
1274 	return (0);
1275 }
1276 #endif /* NBPFILTER */
1277 #endif /* NLE */
1278