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