xref: /csrg-svn/sys/vax/if/if_ec.c (revision 25271)
1 /*
2  * Copyright (c) 1982 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)if_ec.c	6.13 (Berkeley) 10/24/85
7  */
8 
9 #include "ec.h"
10 #if NEC > 0
11 
12 /*
13  * 3Com Ethernet Controller interface
14  */
15 #include "../machine/pte.h"
16 
17 #include "param.h"
18 #include "systm.h"
19 #include "mbuf.h"
20 #include "buf.h"
21 #include "protosw.h"
22 #include "socket.h"
23 #include "vmmac.h"
24 #include "ioctl.h"
25 #include "errno.h"
26 
27 #include "../net/if.h"
28 #include "../net/netisr.h"
29 #include "../net/route.h"
30 
31 #ifdef	BBNNET
32 #define	INET
33 #endif
34 #ifdef INET
35 #include "../netinet/in.h"
36 #include "../netinet/in_systm.h"
37 #include "../netinet/in_var.h"
38 #include "../netinet/ip.h"
39 #include "../netinet/if_ether.h"
40 #endif
41 
42 #ifdef PUP
43 #include "../netpup/pup.h"
44 #endif PUP
45 
46 #ifdef NS
47 #include "../netns/ns.h"
48 #include "../netns/ns_if.h"
49 #endif
50 
51 #include "../vax/cpu.h"
52 #include "../vax/mtpr.h"
53 #include "if_ecreg.h"
54 #include "if_uba.h"
55 #include "../vaxuba/ubareg.h"
56 #include "../vaxuba/ubavar.h"
57 
58 #if CLSIZE == 2
59 #define ECBUFSIZE	32		/* on-board memory, clusters */
60 #endif
61 
62 int	ecubamem(), ecprobe(), ecattach(), ecrint(), ecxint(), eccollide();
63 struct	uba_device *ecinfo[NEC];
64 u_short ecstd[] = { 0 };
65 struct	uba_driver ecdriver =
66 	{ ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo, 0, 0, 0, ecubamem };
67 
68 int	ecinit(),ecioctl(),ecoutput(),ecreset();
69 struct	mbuf *ecget();
70 
71 extern struct ifnet loif;
72 
73 /*
74  * Ethernet software status per interface.
75  *
76  * Each interface is referenced by a network interface structure,
77  * es_if, which the routing code uses to locate the interface.
78  * This structure contains the output queue for the interface, its address, ...
79  * We also have, for each interface, a UBA interface structure, which
80  * contains information about the UNIBUS resources held by the interface:
81  * map registers, buffered data paths, etc.  Information is cached in this
82  * structure for use by the if_uba.c routines in running the interface
83  * efficiently.
84  */
85 struct	ec_softc {
86 	struct	arpcom es_ac;		/* common Ethernet structures */
87 #define	es_if	es_ac.ac_if		/* network-visible interface */
88 #define	es_addr	es_ac.ac_enaddr		/* hardware Ethernet address */
89 	struct	ifuba es_ifuba;		/* UNIBUS resources */
90 	short	es_mask;		/* mask for current output delay */
91 	short	es_oactive;		/* is output active? */
92 	u_char	*es_buf[16];		/* virtual addresses of buffers */
93 } ec_softc[NEC];
94 
95 #ifdef DEBUG
96 ether_addr(s)
97 char *s;
98 {
99 
100 	printf("%x:%x:%x:%x:%x:%x\n",
101 		s[0]&0xff, s[1]&0xff, s[2]&0xff,
102 		s[3]&0xff, s[4]&0xff, s[5]&0xff);
103 }
104 #endif
105 
106 /*
107  * Configure on-board memory for an interface.
108  * Called from autoconfig and after a uba reset.
109  * The address of the memory on the uba is supplied in the device flags.
110  */
111 ecubamem(ui, uban)
112 	register struct uba_device *ui;
113 {
114 	register caddr_t ecbuf = (caddr_t) &umem[uban][ui->ui_flags];
115 	register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
116 
117 	/*
118 	 * Make sure csr is there (we run before ecprobe).
119 	 */
120 	if (badaddr((caddr_t)addr, 2))
121 		return (-1);
122 #if VAX780
123 	if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) {
124 		uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr;
125 		return (-1);
126 	}
127 #endif
128 	/*
129 	 * Make sure memory is turned on
130 	 */
131 	addr->ec_rcr = EC_AROM;
132 	/*
133 	 * Tell the system that the board has memory here, so it won't
134 	 * attempt to allocate the addresses later.
135 	 */
136 	if (ubamem(uban, ui->ui_flags, ECBUFSIZE*CLSIZE, 1) == 0) {
137 		printf("ec%d: cannot reserve uba addresses\n", ui->ui_unit);
138 		addr->ec_rcr = EC_MDISAB;	/* disable memory */
139 		return (-1);
140 	}
141 	/*
142 	 * Check for existence of buffers on Unibus.
143 	 */
144 	if (badaddr((caddr_t)ecbuf, 2)) {
145 bad:
146 		printf("ec%d: buffer mem not found\n", ui->ui_unit);
147 		(void) ubamem(uban, ui->ui_flags, ECBUFSIZE*2, 0);
148 		addr->ec_rcr = EC_MDISAB;	/* disable memory */
149 		return (-1);
150 	}
151 #if VAX780
152 	if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) {
153 		uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr;
154 		goto bad;
155 	}
156 #endif
157 	if (ui->ui_alive == 0)		/* Only printf from autoconfig */
158 		printf("ec%d: mem %x-%x\n", ui->ui_unit,
159 			ui->ui_flags, ui->ui_flags + ECBUFSIZE*CLBYTES - 1);
160 	ui->ui_type = 1;		/* Memory on, allocated */
161 	return (0);
162 }
163 
164 /*
165  * Do output DMA to determine interface presence and
166  * interrupt vector.  DMA is too short to disturb other hosts.
167  */
168 ecprobe(reg, ui)
169 	caddr_t reg;
170 	struct uba_device *ui;
171 {
172 	register int br, cvec;		/* r11, r10 value-result */
173 	register struct ecdevice *addr = (struct ecdevice *)reg;
174 	register caddr_t ecbuf = (caddr_t) &umem[ui->ui_ubanum][ui->ui_flags];
175 
176 #ifdef lint
177 	br = 0; cvec = br; br = cvec;
178 	ecrint(0); ecxint(0); eccollide(0);
179 #endif
180 
181 	/*
182 	 * Check that buffer memory was found and enabled.
183 	 */
184 	if (ui->ui_type == 0)
185 		return(0);
186 	/*
187 	 * Make a one byte packet in what should be buffer #0.
188 	 * Submit it for sending.  This should cause an xmit interrupt.
189 	 * The xmit interrupt vector is 8 bytes after the receive vector,
190 	 * so adjust for this before returning.
191 	 */
192 	*(u_short *)ecbuf = (u_short) 03777;
193 	ecbuf[03777] = '\0';
194 	addr->ec_xcr = EC_XINTEN|EC_XWBN;
195 	DELAY(100000);
196 	addr->ec_xcr = EC_XCLR;
197 	if (cvec > 0 && cvec != 0x200) {
198 		if (cvec & 04) {	/* collision interrupt */
199 			cvec -= 04;
200 			br += 1;		/* rcv is collision + 1 */
201 		} else {		/* xmit interrupt */
202 			cvec -= 010;
203 			br += 2;		/* rcv is xmit + 2 */
204 		}
205 	}
206 	return (1);
207 }
208 
209 /*
210  * Interface exists: make available by filling in network interface
211  * record.  System will initialize the interface when it is ready
212  * to accept packets.
213  */
214 ecattach(ui)
215 	struct uba_device *ui;
216 {
217 	struct ec_softc *es = &ec_softc[ui->ui_unit];
218 	register struct ifnet *ifp = &es->es_if;
219 	register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
220 	int i, j;
221 	u_char *cp;
222 
223 	ifp->if_unit = ui->ui_unit;
224 	ifp->if_name = "ec";
225 	ifp->if_mtu = ETHERMTU;
226 
227 	/*
228 	 * Read the ethernet address off the board, one nibble at a time.
229 	 */
230 	addr->ec_xcr = EC_UECLR; /* zero address pointer */
231 	addr->ec_rcr = EC_AROM;
232 	cp = es->es_addr;
233 #define	NEXTBIT	addr->ec_rcr = EC_AROM|EC_ASTEP; addr->ec_rcr = EC_AROM
234 	for (i=0; i < sizeof (es->es_addr); i++) {
235 		*cp = 0;
236 		for (j=0; j<=4; j+=4) {
237 			*cp |= ((addr->ec_rcr >> 8) & 0xf) << j;
238 			NEXTBIT; NEXTBIT; NEXTBIT; NEXTBIT;
239 		}
240 		cp++;
241 	}
242 #ifdef DEBUG
243 	printf("ecattach %d: addr=",ui->ui_unit);
244 	ether_addr(es->es_addr);
245 #endif
246 	ifp->if_init = ecinit;
247 	ifp->if_ioctl = ecioctl;
248 	ifp->if_output = ecoutput;
249 	ifp->if_reset = ecreset;
250 	ifp->if_flags = IFF_BROADCAST;
251 	for (i=0; i<16; i++)
252 		es->es_buf[i]
253 		    = (u_char *)&umem[ui->ui_ubanum][ui->ui_flags + 2048*i];
254 	if_attach(ifp);
255 }
256 
257 /*
258  * Reset of interface after UNIBUS reset.
259  * If interface is on specified uba, reset its state.
260  */
261 ecreset(unit, uban)
262 	int unit, uban;
263 {
264 	register struct uba_device *ui;
265 
266 	if (unit >= NEC || (ui = ecinfo[unit]) == 0 || ui->ui_alive == 0 ||
267 	    ui->ui_ubanum != uban)
268 		return;
269 	printf(" ec%d", unit);
270 	ec_softc[unit].es_if.if_flags &= ~IFF_RUNNING;
271 	ecinit(unit);
272 }
273 
274 /*
275  * Initialization of interface; clear recorded pending
276  * operations, and reinitialize UNIBUS usage.
277  */
278 ecinit(unit)
279 	int unit;
280 {
281 	struct ec_softc *es = &ec_softc[unit];
282 	struct ecdevice *addr;
283 	register struct ifnet *ifp = &es->es_if;
284 	int i, s;
285 
286 	/* not yet, if address still unknown */
287 	if (ifp->if_addrlist == (struct ifaddr *)0)
288 		return;
289 
290 	/*
291 	 * Hang receive buffers and start any pending writes.
292 	 * Writing into the rcr also makes sure the memory
293 	 * is turned on.
294 	 */
295 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
296 		addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
297 		s = splimp();
298 		/*
299 		 * write our ethernet address into the address recognition ROM
300 		 * so we can always use the same EC_READ bits (referencing ROM),
301 		 * in case we change the address sometime.
302 		 * Note that this is safe here as the reciever is NOT armed.
303 		 */
304 		ec_setaddr(es->es_addr, unit);
305 		/*
306 		 * Arm the reciever
307 		 */
308 		for (i = ECRHBF; i >= ECRLBF; i--)
309 			addr->ec_rcr = EC_READ | i;
310 		es->es_oactive = 0;
311 		es->es_mask = ~0;
312 		es->es_if.if_flags |= IFF_RUNNING;
313 		if (es->es_if.if_snd.ifq_head)
314 			ecstart(unit);
315 		splx(s);
316 	}
317 }
318 
319 /*
320  * Start or restart output on interface.
321  * If interface is already active, then this is a retransmit
322  * after a collision, and just restuff registers.
323  * If interface is not already active, get another datagram
324  * to send off of the interface queue, and map it to the interface
325  * before starting the output.
326  */
327 ecstart(unit)
328 {
329 	struct ec_softc *es = &ec_softc[unit];
330 	struct ecdevice *addr;
331 	struct mbuf *m;
332 
333 	if (es->es_oactive)
334 		goto restart;
335 
336 	IF_DEQUEUE(&es->es_if.if_snd, m);
337 	if (m == 0) {
338 		es->es_oactive = 0;
339 		return;
340 	}
341 	ecput(es->es_buf[ECTBF], m);
342 
343 restart:
344 	addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
345 	addr->ec_xcr = EC_WRITE|ECTBF;
346 	es->es_oactive = 1;
347 }
348 
349 /*
350  * Ethernet interface transmitter interrupt.
351  * Start another output if more data to send.
352  */
353 ecxint(unit)
354 	int unit;
355 {
356 	register struct ec_softc *es = &ec_softc[unit];
357 	register struct ecdevice *addr =
358 		(struct ecdevice *)ecinfo[unit]->ui_addr;
359 
360 	if (es->es_oactive == 0)
361 		return;
362 	if ((addr->ec_xcr&EC_XDONE) == 0 || (addr->ec_xcr&EC_XBN) != ECTBF) {
363 		printf("ec%d: stray xmit interrupt, xcr=%b\n", unit,
364 			addr->ec_xcr, EC_XBITS);
365 		es->es_oactive = 0;
366 		addr->ec_xcr = EC_XCLR;
367 		return;
368 	}
369 	es->es_if.if_opackets++;
370 	es->es_oactive = 0;
371 	es->es_mask = ~0;
372 	addr->ec_xcr = EC_XCLR;
373 	if (es->es_if.if_snd.ifq_head)
374 		ecstart(unit);
375 }
376 
377 /*
378  * Collision on ethernet interface.  Do exponential
379  * backoff, and retransmit.  If have backed off all
380  * the way print warning diagnostic, and drop packet.
381  */
382 eccollide(unit)
383 	int unit;
384 {
385 	struct ec_softc *es = &ec_softc[unit];
386 
387 	es->es_if.if_collisions++;
388 	if (es->es_oactive)
389 		ecdocoll(unit);
390 }
391 
392 ecdocoll(unit)
393 	int unit;
394 {
395 	register struct ec_softc *es = &ec_softc[unit];
396 	register struct ecdevice *addr =
397 	    (struct ecdevice *)ecinfo[unit]->ui_addr;
398 	register i;
399 	int delay;
400 
401 	/*
402 	 * Es_mask is a 16 bit number with n low zero bits, with
403 	 * n the number of backoffs.  When es_mask is 0 we have
404 	 * backed off 16 times, and give up.
405 	 */
406 	if (es->es_mask == 0) {
407 		es->es_if.if_oerrors++;
408 		printf("ec%d: send error\n", unit);
409 		/*
410 		 * Reset interface, then requeue rcv buffers.
411 		 * Some incoming packets may be lost, but that
412 		 * can't be helped.
413 		 */
414 		addr->ec_xcr = EC_UECLR;
415 		for (i=ECRHBF; i>=ECRLBF; i--)
416 			addr->ec_rcr = EC_READ|i;
417 		/*
418 		 * Reset and transmit next packet (if any).
419 		 */
420 		es->es_oactive = 0;
421 		es->es_mask = ~0;
422 		if (es->es_if.if_snd.ifq_head)
423 			ecstart(unit);
424 		return;
425 	}
426 	/*
427 	 * Do exponential backoff.  Compute delay based on low bits
428 	 * of the interval timer.  Then delay for that number of
429 	 * slot times.  A slot time is 51.2 microseconds (rounded to 51).
430 	 * This does not take into account the time already used to
431 	 * process the interrupt.
432 	 */
433 	es->es_mask <<= 1;
434 	delay = mfpr(ICR) &~ es->es_mask;
435 	DELAY(delay * 51);
436 	/*
437 	 * Clear the controller's collision flag, thus enabling retransmit.
438 	 */
439 	addr->ec_xcr = EC_CLEAR;
440 }
441 
442 /*
443  * Ethernet interface receiver interrupt.
444  * If input error just drop packet.
445  * Otherwise examine
446  * packet to determine type.  If can't determine length
447  * from type, then have to drop packet.  Othewise decapsulate
448  * packet based on type and pass to type specific higher-level
449  * input routine.
450  */
451 ecrint(unit)
452 	int unit;
453 {
454 	struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
455 
456 	while (addr->ec_rcr & EC_RDONE)
457 		ecread(unit);
458 }
459 
460 ecread(unit)
461 	int unit;
462 {
463 	register struct ec_softc *es = &ec_softc[unit];
464 	struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
465 	register struct ether_header *ec;
466     	struct mbuf *m;
467 	int len, off, resid, ecoff, rbuf;
468 	register struct ifqueue *inq;
469 	u_char *ecbuf;
470 
471 	es->es_if.if_ipackets++;
472 	rbuf = addr->ec_rcr & EC_RBN;
473 	if (rbuf < ECRLBF || rbuf > ECRHBF)
474 		panic("ecrint");
475 	ecbuf = es->es_buf[rbuf];
476 	ecoff = *(short *)ecbuf;
477 	if (ecoff <= ECRDOFF || ecoff > 2046) {
478 		es->es_if.if_ierrors++;
479 #ifdef notdef
480 		if (es->es_if.if_ierrors % 100 == 0)
481 			printf("ec%d: += 100 input errors\n", unit);
482 #endif
483 		goto setup;
484 	}
485 
486 	/*
487 	 * Get input data length.
488 	 * Get pointer to ethernet header (in input buffer).
489 	 * Deal with trailer protocol: if type is trailer type
490 	 * get true type from first 16-bit word past data.
491 	 * Remember that type was trailer by setting off.
492 	 */
493 	len = ecoff - ECRDOFF - sizeof (struct ether_header);
494 	ec = (struct ether_header *)(ecbuf + ECRDOFF);
495 	ec->ether_type = ntohs((u_short)ec->ether_type);
496 #define	ecdataaddr(ec, off, type)	((type)(((caddr_t)((ec)+1)+(off))))
497 	if (ec->ether_type >= ETHERTYPE_TRAIL &&
498 	    ec->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
499 		off = (ec->ether_type - ETHERTYPE_TRAIL) * 512;
500 		if (off >= ETHERMTU)
501 			goto setup;		/* sanity */
502 		ec->ether_type = ntohs(*ecdataaddr(ec, off, u_short *));
503 		resid = ntohs(*(ecdataaddr(ec, off+2, u_short *)));
504 		if (off + resid > len)
505 			goto setup;		/* sanity */
506 		len = off + resid;
507 	} else
508 		off = 0;
509 	if (len == 0)
510 		goto setup;
511 
512 	/*
513 	 * Pull packet off interface.  Off is nonzero if packet
514 	 * has trailing header; ecget will then force this header
515 	 * information to be at the front, but we still have to drop
516 	 * the type and length which are at the front of any trailer data.
517 	 */
518 	m = ecget(ecbuf, len, off, &es->es_if);
519 	if (m == 0)
520 		goto setup;
521 	if (off) {
522 		struct ifnet *ifp;
523 
524 		ifp = *(mtod(m, struct ifnet **));
525 		m->m_off += 2 * sizeof (u_short);
526 		m->m_len -= 2 * sizeof (u_short);
527 		*(mtod(m, struct ifnet **)) = ifp;
528 	}
529 	switch (ec->ether_type) {
530 
531 #ifdef INET
532 	case ETHERTYPE_IP:
533 		schednetisr(NETISR_IP);
534 		inq = &ipintrq;
535 		break;
536 
537 	case ETHERTYPE_ARP:
538 		arpinput(&es->es_ac, m);
539 		goto setup;
540 #endif
541 #ifdef NS
542 	case ETHERTYPE_NS:
543 		schednetisr(NETISR_NS);
544 		inq = &nsintrq;
545 		break;
546 
547 #endif
548 	default:
549 		m_freem(m);
550 		goto setup;
551 	}
552 
553 	if (IF_QFULL(inq)) {
554 		IF_DROP(inq);
555 		m_freem(m);
556 		goto setup;
557 	}
558 	IF_ENQUEUE(inq, m);
559 
560 setup:
561 	/*
562 	 * Reset for next packet.
563 	 */
564 	addr->ec_rcr = EC_READ|EC_RCLR|rbuf;
565 }
566 
567 /*
568  * Ethernet output routine.
569  * Encapsulate a packet of type family for the local net.
570  * Use trailer local net encapsulation if enough data in first
571  * packet leaves a multiple of 512 bytes of data in remainder.
572  * If destination is this address or broadcast, send packet to
573  * loop device to kludge around the fact that 3com interfaces can't
574  * talk to themselves.
575  */
576 ecoutput(ifp, m0, dst)
577 	struct ifnet *ifp;
578 	struct mbuf *m0;
579 	struct sockaddr *dst;
580 {
581 	int type, s, error;
582  	u_char edst[6];
583 	struct in_addr idst;
584 	register struct ec_softc *es = &ec_softc[ifp->if_unit];
585 	register struct mbuf *m = m0;
586 	register struct ether_header *ec;
587 	register int off;
588 	struct mbuf *mcopy = (struct mbuf *)0;
589 
590 	switch (dst->sa_family) {
591 
592 #ifdef INET
593 	case AF_INET:
594 		idst = ((struct sockaddr_in *)dst)->sin_addr;
595 		if (!arpresolve(&es->es_ac, m, &idst, edst))
596 			return (0);	/* if not yet resolved */
597 		if (!bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr,
598 		    sizeof(edst)))
599 			mcopy = m_copy(m, 0, (int)M_COPYALL);
600 		off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
601 		/* need per host negotiation */
602 		if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
603 		if (off > 0 && (off & 0x1ff) == 0 &&
604 		    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
605 			type = ETHERTYPE_TRAIL + (off>>9);
606 			m->m_off -= 2 * sizeof (u_short);
607 			m->m_len += 2 * sizeof (u_short);
608 			*mtod(m, u_short *) = ntohs((u_short)ETHERTYPE_IP);
609 			*(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
610 			goto gottrailertype;
611 		}
612 		type = ETHERTYPE_IP;
613 		off = 0;
614 		goto gottype;
615 #endif
616 #ifdef NS
617 	case AF_NS:
618  		bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
619 		    (caddr_t)edst, sizeof (edst));
620 
621 		if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost,
622 			sizeof(edst))) {
623 
624 				mcopy = m_copy(m, 0, (int)M_COPYALL);
625 		} else if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost,
626 			sizeof(edst))) {
627 
628 				return(looutput(&loif, m, dst));
629 		}
630 		type = ETHERTYPE_NS;
631 		off = 0;
632 		goto gottype;
633 #endif
634 
635 	case AF_UNSPEC:
636 		ec = (struct ether_header *)dst->sa_data;
637  		bcopy((caddr_t)ec->ether_dhost, (caddr_t)edst, sizeof (edst));
638 		type = ec->ether_type;
639 		goto gottype;
640 
641 	default:
642 		printf("ec%d: can't handle af%d\n", ifp->if_unit,
643 			dst->sa_family);
644 		error = EAFNOSUPPORT;
645 		goto bad;
646 	}
647 
648 gottrailertype:
649 	/*
650 	 * Packet to be sent as trailer: move first packet
651 	 * (control information) to end of chain.
652 	 */
653 	while (m->m_next)
654 		m = m->m_next;
655 	m->m_next = m0;
656 	m = m0->m_next;
657 	m0->m_next = 0;
658 	m0 = m;
659 
660 gottype:
661 	/*
662 	 * Add local net header.  If no space in first mbuf,
663 	 * allocate another.
664 	 */
665 	if (m->m_off > MMAXOFF ||
666 	    MMINOFF + sizeof (struct ether_header) > m->m_off) {
667 		m = m_get(M_DONTWAIT, MT_HEADER);
668 		if (m == 0) {
669 			error = ENOBUFS;
670 			goto bad;
671 		}
672 		m->m_next = m0;
673 		m->m_off = MMINOFF;
674 		m->m_len = sizeof (struct ether_header);
675 	} else {
676 		m->m_off -= sizeof (struct ether_header);
677 		m->m_len += sizeof (struct ether_header);
678 	}
679 	ec = mtod(m, struct ether_header *);
680  	bcopy((caddr_t)edst, (caddr_t)ec->ether_dhost, sizeof (edst));
681 	bcopy((caddr_t)es->es_addr, (caddr_t)ec->ether_shost,
682 	    sizeof(ec->ether_shost));
683 	ec->ether_type = htons((u_short)type);
684 
685 	/*
686 	 * Queue message on interface, and start output if interface
687 	 * not yet active.
688 	 */
689 	s = splimp();
690 	if (IF_QFULL(&ifp->if_snd)) {
691 		IF_DROP(&ifp->if_snd);
692 		error = ENOBUFS;
693 		goto qfull;
694 	}
695 	IF_ENQUEUE(&ifp->if_snd, m);
696 	if (es->es_oactive == 0)
697 		ecstart(ifp->if_unit);
698 	splx(s);
699 	return (mcopy ? looutput(&loif, mcopy, dst) : 0);
700 
701 qfull:
702 	m0 = m;
703 	splx(s);
704 bad:
705 	m_freem(m0);
706 	if (mcopy)
707 		m_freem(mcopy);
708 	return (error);
709 }
710 
711 /*
712  * Routine to copy from mbuf chain to transmit
713  * buffer in UNIBUS memory.
714  * If packet size is less than the minimum legal size,
715  * the buffer is expanded.  We probably should zero out the extra
716  * bytes for security, but that would slow things down.
717  */
718 ecput(ecbuf, m)
719 	u_char *ecbuf;
720 	struct mbuf *m;
721 {
722 	register struct mbuf *mp;
723 	register int off;
724 	u_char *bp;
725 
726 	for (off = 2048, mp = m; mp; mp = mp->m_next)
727 		off -= mp->m_len;
728 	if (2048 - off < ETHERMIN + sizeof (struct ether_header))
729 		off = 2048 - ETHERMIN - sizeof (struct ether_header);
730 	*(u_short *)ecbuf = off;
731 	bp = (u_char *)(ecbuf + off);
732 	for (mp = m; mp; mp = mp->m_next) {
733 		register unsigned len = mp->m_len;
734 		u_char *mcp;
735 
736 		if (len == 0)
737 			continue;
738 		mcp = mtod(mp, u_char *);
739 		if ((unsigned)bp & 01) {
740 			*bp++ = *mcp++;
741 			len--;
742 		}
743 		if (off = (len >> 1)) {
744 			register u_short *to, *from;
745 
746 			to = (u_short *)bp;
747 			from = (u_short *)mcp;
748 			do
749 				*to++ = *from++;
750 			while (--off > 0);
751 			bp = (u_char *)to,
752 			mcp = (u_char *)from;
753 		}
754 		if (len & 01)
755 			*bp++ = *mcp++;
756 	}
757 	m_freem(m);
758 }
759 
760 /*
761  * Routine to copy from UNIBUS memory into mbufs.
762  * Similar in spirit to if_rubaget.
763  *
764  * Warning: This makes the fairly safe assumption that
765  * mbufs have even lengths.
766  */
767 struct mbuf *
768 ecget(ecbuf, totlen, off0, ifp)
769 	u_char *ecbuf;
770 	int totlen, off0;
771 	struct ifnet *ifp;
772 {
773 	register struct mbuf *m;
774 	struct mbuf *top = 0, **mp = &top;
775 	register int off = off0, len;
776 	u_char *cp;
777 
778 	cp = ecbuf + ECRDOFF + sizeof (struct ether_header);
779 	while (totlen > 0) {
780 		register int words;
781 		u_char *mcp;
782 
783 		MGET(m, M_DONTWAIT, MT_DATA);
784 		if (m == 0)
785 			goto bad;
786 		if (off) {
787 			len = totlen - off;
788 			cp = ecbuf + ECRDOFF +
789 				sizeof (struct ether_header) + off;
790 		} else
791 			len = totlen;
792 		if (ifp)
793 			len += sizeof(ifp);
794 		if (len >= NBPG) {
795 			struct mbuf *p;
796 
797 			MCLGET(p, 1);
798 			if (p != 0) {
799 				m->m_len = len = MIN(len, CLBYTES);
800 				m->m_off = (int)p - (int)m;
801 			} else {
802 				m->m_len = len = MIN(MLEN, len);
803 				m->m_off = MMINOFF;
804 			}
805 		} else {
806 			m->m_len = len = MIN(MLEN, len);
807 			m->m_off = MMINOFF;
808 		}
809 		mcp = mtod(m, u_char *);
810 		if (ifp) {
811 			/*
812 			 * Prepend interface pointer to first mbuf.
813 			 */
814 			*(mtod(m, struct ifnet **)) = ifp;
815 			mcp += sizeof(ifp);
816 			len -= sizeof(ifp);
817 			ifp = (struct ifnet *)0;
818 		}
819 		if (words = (len >> 1)) {
820 			register u_short *to, *from;
821 
822 			to = (u_short *)mcp;
823 			from = (u_short *)cp;
824 			do
825 				*to++ = *from++;
826 			while (--words > 0);
827 			mcp = (u_char *)to;
828 			cp = (u_char *)from;
829 		}
830 		if (len & 01)
831 			*mcp++ = *cp++;
832 		*mp = m;
833 		mp = &m->m_next;
834 		if (off == 0) {
835 			totlen -= len;
836 			continue;
837 		}
838 		off += len;
839 		if (off == totlen) {
840 			cp = ecbuf + ECRDOFF + sizeof (struct ether_header);
841 			off = 0;
842 			totlen = off0;
843 		}
844 	}
845 	return (top);
846 bad:
847 	m_freem(top);
848 	return (0);
849 }
850 
851 /*
852  * Process an ioctl request.
853  */
854 ecioctl(ifp, cmd, data)
855 	register struct ifnet *ifp;
856 	int cmd;
857 	caddr_t data;
858 {
859 	register struct ifaddr *ifa = (struct ifaddr *)data;
860 	int s = splimp(), error = 0;
861 
862 	switch (cmd) {
863 
864 	case SIOCSIFADDR:
865 		ifp->if_flags |= IFF_UP;
866 
867 		switch (ifa->ifa_addr.sa_family) {
868 #ifdef INET
869 		case AF_INET:
870 			ecinit(ifp->if_unit); /* before, so we can send the ARP packet */
871 			((struct arpcom *)ifp)->ac_ipaddr =
872 				IA_SIN(ifa)->sin_addr;
873 			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
874 			break;
875 #endif
876 #ifdef NS
877 		case AF_NS:
878 		    {
879 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
880 
881 			if (ns_nullhost(*ina)) {
882 				ina->x_host = * (union ns_host *)
883 				     (ec_softc[ifp->if_unit].es_addr);
884 			} else {
885 				/*
886 				 * The manual says we can't change the address
887 				 * while the reciever is armed so reset everything
888 				 */
889 				struct ec_softc *es = &ec_softc[ifp->if_unit];
890 				struct uba_device *ui = ecinfo[ifp->if_unit];
891 				struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
892 
893 				es->es_if.if_flags &= ~IFF_RUNNING;
894 				bcopy(ina->x_host.c_host, es->es_addr, sizeof(es->es_addr));
895 			}
896 			ecinit(ifp->if_unit); /* does ec_setaddr() */
897 			break;
898 		    }
899 #endif
900 		}
901 		break;
902 
903 	default:
904 		error = EINVAL;
905 	}
906 	splx(s);
907 	return (error);
908 }
909 
910 ec_setaddr(physaddr,unit)
911 u_char *physaddr;
912 int unit;
913 {
914 	struct ec_softc *es = &ec_softc[unit];
915 	struct uba_device *ui = ecinfo[unit];
916 	register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr;
917 	register char nibble;
918 	register int i, j;
919 
920 	/*
921 	 * Use the ethernet address supplied
922 	 * NOte that we do a UECLR here, so the recieve buffers
923 	 * must be requeued.
924 	 */
925 
926 #ifdef DEBUG
927 	printf("ec_setaddr: setting address for unit %d = ",
928 		unit);
929 	ether_addr(physaddr);
930 #endif
931 	addr->ec_xcr = EC_UECLR;
932 	addr->ec_rcr = 0;
933 	/* load requested address */
934 	for (i = 0; i < 6; i++) { /* 6 bytes of address */
935 	    es->es_addr[i] = physaddr[i];
936 	    nibble = physaddr[i] & 0xf; /* lower nibble */
937 	    addr->ec_rcr = (nibble << 8);
938 	    addr->ec_rcr = (nibble << 8) + EC_AWCLK; /* latch nibble */
939 	    addr->ec_rcr = (nibble << 8);
940 	    for (j=0; j < 4; j++) {
941 		addr->ec_rcr = 0;
942 		addr->ec_rcr = EC_ASTEP; /* step counter */
943 		addr->ec_rcr = 0;
944 	    }
945 	    nibble = (physaddr[i] >> 4) & 0xf; /* upper nibble */
946 	    addr->ec_rcr = (nibble << 8);
947 	    addr->ec_rcr = (nibble << 8) + EC_AWCLK; /* latch nibble */
948 	    addr->ec_rcr = (nibble << 8);
949 	    for (j=0; j < 4; j++) {
950 		addr->ec_rcr = 0;
951 		addr->ec_rcr = EC_ASTEP; /* step counter */
952 		addr->ec_rcr = 0;
953 	    }
954 	}
955 #ifdef DEBUG
956 	/*
957 	 * Read the ethernet address off the board, one nibble at a time.
958 	 */
959 	addr->ec_xcr = EC_UECLR;
960 	addr->ec_rcr = 0; /* read RAM */
961 	cp = es->es_addr;
962 #undef NEXTBIT
963 #define	NEXTBIT	addr->ec_rcr = EC_ASTEP; addr->ec_rcr = 0
964 	for (i=0; i < sizeof (es->es_addr); i++) {
965 		*cp = 0;
966 		for (j=0; j<=4; j+=4) {
967 			*cp |= ((addr->ec_rcr >> 8) & 0xf) << j;
968 			NEXTBIT; NEXTBIT; NEXTBIT; NEXTBIT;
969 		}
970 		cp++;
971 	}
972 	printf("ec_setaddr %d: ROM addr=",ui->ui_unit);
973 	ether_addr(es->es_addr);
974 #endif
975 }
976 #endif
977