xref: /csrg-svn/sys/vax/if/if_dmc.c (revision 27266)
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_dmc.c	6.12 (Berkeley) 04/23/86
7  */
8 
9 #include "dmc.h"
10 #if NDMC > 0
11 
12 /*
13  * DMC11 device driver, internet version
14  *
15  *	Bill Nesheim
16  *	Cornell University
17  *
18  *	Lou Salkind
19  *	New York University
20  */
21 
22 /* #define DEBUG	/* for base table dump on fatal error */
23 
24 #include "../machine/pte.h"
25 
26 #include "param.h"
27 #include "systm.h"
28 #include "mbuf.h"
29 #include "buf.h"
30 #include "ioctl.h"		/* must precede tty.h */
31 #include "tty.h"
32 #include "protosw.h"
33 #include "socket.h"
34 #include "syslog.h"
35 #include "vmmac.h"
36 #include "errno.h"
37 
38 #include "../net/if.h"
39 #include "../net/netisr.h"
40 #include "../net/route.h"
41 
42 #ifdef	INET
43 #include "../netinet/in.h"
44 #include "../netinet/in_systm.h"
45 #include "../netinet/ip.h"
46 #endif
47 
48 #include "../vax/cpu.h"
49 #include "../vax/mtpr.h"
50 #include "if_uba.h"
51 #include "if_dmc.h"
52 #include "../vaxuba/ubareg.h"
53 #include "../vaxuba/ubavar.h"
54 
55 #include "../h/time.h"
56 #include "../h/kernel.h"
57 
58 int	dmctimer;			/* timer started? */
59 int	dmc_timeout = 8;		/* timeout value */
60 int	dmcwatch();
61 
62 /*
63  * Driver information for auto-configuration stuff.
64  */
65 int	dmcprobe(), dmcattach(), dmcinit(), dmcioctl();
66 int	dmcoutput(), dmcreset();
67 struct	uba_device *dmcinfo[NDMC];
68 u_short	dmcstd[] = { 0 };
69 struct	uba_driver dmcdriver =
70 	{ dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
71 
72 #define NRCV 7
73 #define NXMT 3
74 #define NCMDS	(NRCV+NXMT+4)	/* size of command queue */
75 
76 #define printd if(dmcdebug)printf
77 int dmcdebug = 0;
78 
79 /* error reporting intervals */
80 #define DMC_RPNBFS	50
81 #define DMC_RPDSC	1
82 #define DMC_RPTMO	10
83 #define DMC_RPDCK	10
84 
85 struct  dmc_command {
86 	char	qp_cmd;		/* command */
87 	short	qp_ubaddr;	/* buffer address */
88 	short	qp_cc;		/* character count || XMEM */
89 	struct	dmc_command *qp_next;	/* next command on queue */
90 };
91 
92 struct dmcbufs {
93 	int	ubinfo;		/* from uballoc */
94 	short	cc;		/* buffer size */
95 	short	flags;		/* access control */
96 };
97 #define	DBUF_OURS	0	/* buffer is available */
98 #define	DBUF_DMCS	1	/* buffer claimed by somebody */
99 #define	DBUF_XMIT	4	/* transmit buffer */
100 #define	DBUF_RCV	8	/* receive buffer */
101 
102 
103 /*
104  * DMC software status per interface.
105  *
106  * Each interface is referenced by a network interface structure,
107  * sc_if, which the routing code uses to locate the interface.
108  * This structure contains the output queue for the interface, its address, ...
109  * We also have, for each interface, a  set of 7 UBA interface structures
110  * for each, which
111  * contain information about the UNIBUS resources held by the interface:
112  * map registers, buffered data paths, etc.  Information is cached in this
113  * structure for use by the if_uba.c routines in running the interface
114  * efficiently.
115  */
116 struct dmc_softc {
117 	struct	ifnet sc_if;		/* network-visible interface */
118 	struct	dmcbufs sc_rbufs[NRCV];	/* receive buffer info */
119 	struct	dmcbufs sc_xbufs[NXMT];	/* transmit buffer info */
120 	struct	ifubinfo sc_ifuba;	/* UNIBUS resources */
121 	struct	ifrw sc_ifr[NRCV];	/* UNIBUS receive buffer maps */
122 	struct	ifxmt sc_ifw[NXMT];	/* UNIBUS receive buffer maps */
123 	short	sc_oused;		/* output buffers currently in use */
124 	short	sc_iused;		/* input buffers given to DMC */
125 	short	sc_flag;		/* flags */
126 	int	sc_nticks;		/* seconds since last interrupt */
127 	int	sc_ubinfo;		/* UBA mapping info for base table */
128 	int	sc_errors[4];		/* non-fatal error counters */
129 #define sc_datck sc_errors[0]
130 #define sc_timeo sc_errors[1]
131 #define sc_nobuf sc_errors[2]
132 #define sc_disc  sc_errors[3]
133 	/* command queue stuff */
134 	struct	dmc_command sc_cmdbuf[NCMDS];
135 	struct	dmc_command *sc_qhead;	/* head of command queue */
136 	struct	dmc_command *sc_qtail;	/* tail of command queue */
137 	struct	dmc_command *sc_qactive;	/* command in progress */
138 	struct	dmc_command *sc_qfreeh;	/* head of list of free cmd buffers */
139 	struct	dmc_command *sc_qfreet;	/* tail of list of free cmd buffers */
140 	/* end command queue stuff */
141 } dmc_softc[NDMC];
142 
143 /* flags */
144 #define DMC_ALLOC	0x01		/* unibus resources allocated */
145 #define DMC_BMAPPED	0x02		/* base table mapped */
146 #define DMC_RESTART	0x04		/* software restart in progress */
147 #define DMC_ACTIVE	0x08		/* device active */
148 #define DMC_RUNNING	0x20		/* device initialized */
149 
150 struct dmc_base {
151 	short	d_base[128];		/* DMC base table */
152 } dmc_base[NDMC];
153 
154 /* queue manipulation macros */
155 #define	QUEUE_AT_HEAD(qp, head, tail) \
156 	(qp)->qp_next = (head); \
157 	(head) = (qp); \
158 	if ((tail) == (struct dmc_command *) 0) \
159 		(tail) = (head)
160 
161 #define QUEUE_AT_TAIL(qp, head, tail) \
162 	if ((tail)) \
163 		(tail)->qp_next = (qp); \
164 	else \
165 		(head) = (qp); \
166 	(qp)->qp_next = (struct dmc_command *) 0; \
167 	(tail) = (qp)
168 
169 #define DEQUEUE(head, tail) \
170 	(head) = (head)->qp_next;\
171 	if ((head) == (struct dmc_command *) 0)\
172 		(tail) = (head)
173 
174 dmcprobe(reg)
175 	caddr_t reg;
176 {
177 	register int br, cvec;
178 	register struct dmcdevice *addr = (struct dmcdevice *)reg;
179 	register int i;
180 
181 #ifdef lint
182 	br = 0; cvec = br; br = cvec;
183 	dmcrint(0); dmcxint(0);
184 #endif
185 	addr->bsel1 = DMC_MCLR;
186 	for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
187 		;
188 	if ((addr->bsel1 & DMC_RUN) == 0) {
189 		printf("dmcprobe: can't start device\n" );
190 		return (0);
191 	}
192 	addr->bsel0 = DMC_RQI|DMC_IEI;
193 	/* let's be paranoid */
194 	addr->bsel0 |= DMC_RQI|DMC_IEI;
195 	DELAY(1000000);
196 	addr->bsel1 = DMC_MCLR;
197 	for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
198 		;
199 	return (1);
200 }
201 
202 /*
203  * Interface exists: make available by filling in network interface
204  * record.  System will initialize the interface when it is ready
205  * to accept packets.
206  */
207 dmcattach(ui)
208 	register struct uba_device *ui;
209 {
210 	register struct dmc_softc *sc = &dmc_softc[ui->ui_unit];
211 
212 	sc->sc_if.if_unit = ui->ui_unit;
213 	sc->sc_if.if_name = "dmc";
214 	sc->sc_if.if_mtu = DMCMTU;
215 	sc->sc_if.if_init = dmcinit;
216 	sc->sc_if.if_output = dmcoutput;
217 	sc->sc_if.if_ioctl = dmcioctl;
218 	sc->sc_if.if_reset = dmcreset;
219 	sc->sc_if.if_flags = IFF_POINTOPOINT;
220 	sc->sc_ifuba.iff_flags = UBA_CANTWAIT;
221 
222 	if (dmctimer == 0) {
223 		dmctimer = 1;
224 		timeout(dmcwatch, (caddr_t) 0, hz);
225 	}
226 	if_attach(&sc->sc_if);
227 }
228 
229 /*
230  * Reset of interface after UNIBUS reset.
231  * If interface is on specified UBA, reset its state.
232  */
233 dmcreset(unit, uban)
234 	int unit, uban;
235 {
236 	register struct uba_device *ui;
237 	register struct dmc_softc *sc = &dmc_softc[unit];
238 
239 	if (unit >= NDMC || (ui = dmcinfo[unit]) == 0 || ui->ui_alive == 0 ||
240 	    ui->ui_ubanum != uban)
241 		return;
242 	printf(" dmc%d", unit);
243 	sc->sc_flag = 0;
244 	sc->sc_if.if_flags &= ~IFF_RUNNING;
245 	dmcinit(unit);
246 }
247 
248 /*
249  * Initialization of interface; reinitialize UNIBUS usage.
250  */
251 dmcinit(unit)
252 	int unit;
253 {
254 	register struct dmc_softc *sc = &dmc_softc[unit];
255 	register struct uba_device *ui = dmcinfo[unit];
256 	register struct dmcdevice *addr;
257 	register struct ifnet *ifp = &sc->sc_if;
258 	register struct ifrw *ifrw;
259 	register struct ifxmt *ifxp;
260 	register struct dmcbufs *rp;
261 	register struct dmc_command *qp;
262 	struct ifaddr *ifa;
263 	int base;
264 	int s;
265 
266 	addr = (struct dmcdevice *)ui->ui_addr;
267 
268 	/*
269 	 * Check to see that an address has been set
270 	 * (both local and destination for an address family).
271 	 */
272 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
273 		if (ifa->ifa_addr.sa_family && ifa->ifa_dstaddr.sa_family)
274 			break;
275 	if (ifa == (struct ifaddr *) 0)
276 		return;
277 
278 	if ((addr->bsel1&DMC_RUN) == 0) {
279 		printf("dmcinit: DMC not running\n");
280 		ifp->if_flags &= ~IFF_UP;
281 		return;
282 	}
283 	/* map base table */
284 	if ((sc->sc_flag & DMC_BMAPPED) == 0) {
285 		sc->sc_ubinfo = uballoc(ui->ui_ubanum,
286 			(caddr_t)&dmc_base[unit], sizeof (struct dmc_base), 0);
287 		sc->sc_flag |= DMC_BMAPPED;
288 	}
289 	/* initialize UNIBUS resources */
290 	sc->sc_iused = sc->sc_oused = 0;
291 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
292 		if (if_ubaminit(&sc->sc_ifuba, ui->ui_ubanum,
293 		    sizeof(struct dmc_header), (int)btoc(DMCMTU),
294 		    sc->sc_ifr, NRCV, sc->sc_ifw, NXMT) == 0) {
295 			printf("dmc%d: can't allocate uba resources\n", unit);
296 			ifp->if_flags &= ~IFF_UP;
297 			return;
298 		}
299 		ifp->if_flags |= IFF_RUNNING;
300 	}
301 	sc->sc_flag |= DMC_RUNNING;
302 
303 	/* initialize buffer pool */
304 	/* receives */
305 	ifrw = &sc->sc_ifr[0];
306 	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
307 		rp->ubinfo = ifrw->ifrw_info & 0x3ffff;
308 		rp->cc = DMCMTU + sizeof (struct dmc_header);
309 		rp->flags = DBUF_OURS|DBUF_RCV;
310 		ifrw++;
311 	}
312 	/* transmits */
313 	ifxp = &sc->sc_ifw[0];
314 	for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++) {
315 		rp->ubinfo = ifxp->ifw_info & 0x3ffff;
316 		rp->cc = 0;
317 		rp->flags = DBUF_OURS|DBUF_XMIT;
318 		ifxp++;
319 	}
320 
321 	/* set up command queues */
322 	sc->sc_qfreeh = sc->sc_qfreet
323 		 = sc->sc_qhead = sc->sc_qtail = sc->sc_qactive =
324 		(struct dmc_command *)0;
325 	/* set up free command buffer list */
326 	for (qp = &sc->sc_cmdbuf[0]; qp < &sc->sc_cmdbuf[NCMDS]; qp++) {
327 		QUEUE_AT_HEAD(qp, sc->sc_qfreeh, sc->sc_qfreet);
328 	}
329 
330 	/* base in */
331 	base = sc->sc_ubinfo & 0x3ffff;
332 	dmcload(sc, DMC_BASEI, base, (base>>2) & DMC_XMEM);
333 	/* specify half duplex operation, flags tell if primary */
334 	/* or secondary station */
335 	if (ui->ui_flags == 0)
336 		/* use DDCMP mode in full duplex */
337 		dmcload(sc, DMC_CNTLI, 0, 0);
338 	else if (ui->ui_flags == 1)
339 		/* use MAINTENENCE mode */
340 		dmcload(sc, DMC_CNTLI, 0, DMC_MAINT );
341 	else if (ui->ui_flags == 2)
342 		/* use DDCMP half duplex as primary station */
343 		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX);
344 	else if (ui->ui_flags == 3)
345 		/* use DDCMP half duplex as secondary station */
346 		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);
347 
348 	/* enable operation done interrupts */
349 	sc->sc_flag &= ~DMC_ACTIVE;
350 	while ((addr->bsel2 & DMC_IEO) == 0)
351 		addr->bsel2 |= DMC_IEO;
352 	s = spl5();
353 	/* queue first NRCV buffers for DMC to fill */
354 	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
355 		rp->flags |= DBUF_DMCS;
356 		dmcload(sc, DMC_READ, rp->ubinfo,
357 			(((rp->ubinfo>>2)&DMC_XMEM) | rp->cc));
358 		sc->sc_iused++;
359 	}
360 	splx(s);
361 }
362 
363 /*
364  * Start output on interface.  Get another datagram
365  * to send from the interface queue and map it to
366  * the interface before starting output.
367  *
368  * Must be called at spl 5
369  */
370 dmcstart(dev)
371 	dev_t dev;
372 {
373 	int unit = minor(dev);
374 	register struct dmc_softc *sc = &dmc_softc[unit];
375 	struct mbuf *m;
376 	register struct dmcbufs *rp;
377 	register int n;
378 
379 	/*
380 	 * Dequeue up to NXMT requests and map them to the UNIBUS.
381 	 * If no more requests, or no dmc buffers available, just return.
382 	 */
383 	n = 0;
384 	for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++ ) {
385 		/* find an available buffer */
386 		if ((rp->flags & DBUF_DMCS) == 0) {
387 			IF_DEQUEUE(&sc->sc_if.if_snd, m);
388 			if (m == 0)
389 				return;
390 			/* mark it dmcs */
391 			rp->flags |= (DBUF_DMCS);
392 			/*
393 			 * Have request mapped to UNIBUS for transmission
394 			 * and start the output.
395 			 */
396 			rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m);
397 			rp->cc &= DMC_CCOUNT;
398 			sc->sc_oused++;
399 			dmcload(sc, DMC_WRITE, rp->ubinfo,
400 				rp->cc | ((rp->ubinfo>>2)&DMC_XMEM));
401 		}
402 		n++;
403 	}
404 }
405 
406 /*
407  * Utility routine to load the DMC device registers.
408  */
409 dmcload(sc, type, w0, w1)
410 	register struct dmc_softc *sc;
411 	int type, w0, w1;
412 {
413 	register struct dmcdevice *addr;
414 	register int unit, sps;
415 	register struct dmc_command *qp;
416 
417 	unit = sc - dmc_softc;
418 	addr = (struct dmcdevice *)dmcinfo[unit]->ui_addr;
419 	sps = spl5();
420 
421 	/* grab a command buffer from the free list */
422 	if ((qp = sc->sc_qfreeh) == (struct dmc_command *)0)
423 		panic("dmc command queue overflow");
424 	DEQUEUE(sc->sc_qfreeh, sc->sc_qfreet);
425 
426 	/* fill in requested info */
427 	qp->qp_cmd = (type | DMC_RQI);
428 	qp->qp_ubaddr = w0;
429 	qp->qp_cc = w1;
430 
431 	if (sc->sc_qactive) {	/* command in progress */
432 		if (type == DMC_READ) {
433 			QUEUE_AT_HEAD(qp, sc->sc_qhead, sc->sc_qtail);
434 		} else {
435 			QUEUE_AT_TAIL(qp, sc->sc_qhead, sc->sc_qtail);
436 		}
437 	} else {	/* command port free */
438 		sc->sc_qactive = qp;
439 		addr->bsel0 = qp->qp_cmd;
440 		dmcrint(unit);
441 	}
442 	splx(sps);
443 }
444 
445 /*
446  * DMC interface receiver interrupt.
447  * Ready to accept another command,
448  * pull one off the command queue.
449  */
450 dmcrint(unit)
451 	int unit;
452 {
453 	register struct dmc_softc *sc;
454 	register struct dmcdevice *addr;
455 	register struct dmc_command *qp;
456 	register int n;
457 
458 	addr = (struct dmcdevice *)dmcinfo[unit]->ui_addr;
459 	sc = &dmc_softc[unit];
460 	if ((qp = sc->sc_qactive) == (struct dmc_command *) 0) {
461 		printf("dmc%d: dmcrint no command\n", unit);
462 		return;
463 	}
464 	while (addr->bsel0&DMC_RDYI) {
465 		addr->sel4 = qp->qp_ubaddr;
466 		addr->sel6 = qp->qp_cc;
467 		addr->bsel0 &= ~(DMC_IEI|DMC_RQI);
468 		/* free command buffer */
469 		QUEUE_AT_HEAD(qp, sc->sc_qfreeh, sc->sc_qfreet);
470 		while (addr->bsel0 & DMC_RDYI) {
471 			/*
472 			 * Can't check for RDYO here 'cause
473 			 * this routine isn't reentrant!
474 			 */
475 			DELAY(5);
476 		}
477 		/* move on to next command */
478 		if ((sc->sc_qactive = sc->sc_qhead) == (struct dmc_command *)0)
479 			break;		/* all done */
480 		/* more commands to do, start the next one */
481 		qp = sc->sc_qactive;
482 		DEQUEUE(sc->sc_qhead, sc->sc_qtail);
483 		addr->bsel0 = qp->qp_cmd;
484 		n = RDYSCAN;
485 		while (n-- > 0)
486 			if ((addr->bsel0&DMC_RDYI) || (addr->bsel2&DMC_RDYO))
487 				break;
488 	}
489 	if (sc->sc_qactive) {
490 		addr->bsel0 |= DMC_IEI|DMC_RQI;
491 		/* VMS does it twice !*$%@# */
492 		addr->bsel0 |= DMC_IEI|DMC_RQI;
493 	}
494 
495 }
496 
497 /*
498  * DMC interface transmitter interrupt.
499  * A transfer may have completed, check for errors.
500  * If it was a read, notify appropriate protocol.
501  * If it was a write, pull the next one off the queue.
502  */
503 dmcxint(unit)
504 	int unit;
505 {
506 	register struct dmc_softc *sc;
507 	register struct ifnet *ifp;
508 	struct uba_device *ui = dmcinfo[unit];
509 	struct dmcdevice *addr;
510 	struct mbuf *m;
511 	struct ifqueue *inq;
512 	int arg, pkaddr, cmd, len, s;
513 	register struct ifrw *ifrw;
514 	register struct dmcbufs *rp;
515 	register struct ifxmt *ifxp;
516 	struct dmc_header *dh;
517 	int off, resid;
518 
519 	addr = (struct dmcdevice *)ui->ui_addr;
520 	sc = &dmc_softc[unit];
521 	ifp = &sc->sc_if;
522 
523 	while (addr->bsel2 & DMC_RDYO) {
524 
525 		cmd = addr->bsel2 & 0xff;
526 		arg = addr->sel6 & 0xffff;
527 		/* reconstruct UNIBUS address of buffer returned to us */
528 		pkaddr = ((arg&DMC_XMEM)<<2) | (addr->sel4 & 0xffff);
529 		/* release port */
530 		addr->bsel2 &= ~DMC_RDYO;
531 		switch (cmd & 07) {
532 
533 		case DMC_OUR:
534 			/*
535 			 * A read has completed.
536 			 * Pass packet to type specific
537 			 * higher-level input routine.
538 			 */
539 			ifp->if_ipackets++;
540 			/* find location in dmcuba struct */
541 			ifrw= &sc->sc_ifr[0];
542 			for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
543 				if(rp->ubinfo == pkaddr)
544 					break;
545 				ifrw++;
546 			}
547 			if (rp >= &sc->sc_rbufs[NRCV])
548 				panic("dmc rcv");
549 			if ((rp->flags & DBUF_DMCS) == 0)
550 				printf("dmc%d: done unalloc rbuf\n", unit);
551 
552 			len = (arg & DMC_CCOUNT) - sizeof (struct dmc_header);
553 			if (len < 0 || len > DMCMTU) {
554 				ifp->if_ierrors++;
555 				printd("dmc%d: bad rcv pkt addr 0x%x len 0x%x\n",
556 				    unit, pkaddr, len);
557 				goto setup;
558 			}
559 			/*
560 			 * Deal with trailer protocol: if type is trailer
561 			 * get true type from first 16-bit word past data.
562 			 * Remember that type was trailer by setting off.
563 			 */
564 			dh = (struct dmc_header *)ifrw->ifrw_addr;
565 			dh->dmc_type = ntohs((u_short)dh->dmc_type);
566 #define dmcdataaddr(dh, off, type)	((type)(((caddr_t)((dh)+1)+(off))))
567 			if (dh->dmc_type >= DMC_TRAILER &&
568 			    dh->dmc_type < DMC_TRAILER+DMC_NTRAILER) {
569 				off = (dh->dmc_type - DMC_TRAILER) * 512;
570 				if (off >= DMCMTU)
571 					goto setup;		/* sanity */
572 				dh->dmc_type = ntohs(*dmcdataaddr(dh, off, u_short *));
573 				resid = ntohs(*(dmcdataaddr(dh, off+2, u_short *)));
574 				if (off + resid > len)
575 					goto setup;		/* sanity */
576 				len = off + resid;
577 			} else
578 				off = 0;
579 			if (len == 0)
580 				goto setup;
581 
582 			/*
583 			 * Pull packet off interface.  Off is nonzero if
584 			 * packet has trailing header; dmc_get will then
585 			 * force this header information to be at the front,
586 			 * but we still have to drop the type and length
587 			 * which are at the front of any trailer data.
588 			 */
589 			m = if_ubaget(&sc->sc_ifuba, ifrw, len, off, ifp);
590 			if (m == 0)
591 				goto setup;
592 			if (off) {
593 				ifp = *(mtod(m, struct ifnet **));
594 				m->m_off += 2 * sizeof (u_short);
595 				m->m_len -= 2 * sizeof (u_short);
596 				*(mtod(m, struct ifnet **)) = ifp;
597 			}
598 			switch (dh->dmc_type) {
599 
600 #ifdef INET
601 			case DMC_IPTYPE:
602 				schednetisr(NETISR_IP);
603 				inq = &ipintrq;
604 				break;
605 #endif
606 			default:
607 				m_freem(m);
608 				goto setup;
609 			}
610 
611 			s = splimp();
612 			if (IF_QFULL(inq)) {
613 				IF_DROP(inq);
614 				m_freem(m);
615 			} else
616 				IF_ENQUEUE(inq, m);
617 			splx(s);
618 
619 	setup:
620 			/* is this needed? */
621 			rp->ubinfo = ifrw->ifrw_info & 0x3ffff;
622 
623 			dmcload(sc, DMC_READ, rp->ubinfo,
624 			    ((rp->ubinfo >> 2) & DMC_XMEM) | rp->cc);
625 			break;
626 
627 		case DMC_OUX:
628 			/*
629 			 * A write has completed, start another
630 			 * transfer if there is more data to send.
631 			 */
632 			ifp->if_opackets++;
633 			/* find associated dmcbuf structure */
634 			ifxp = &sc->sc_ifw[0];
635 			for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++) {
636 				if(rp->ubinfo == pkaddr)
637 					break;
638 				ifxp++;
639 			}
640 			if (rp >= &sc->sc_xbufs[NXMT]) {
641 				printf("dmc%d: bad packet address 0x%x\n",
642 				    unit, pkaddr);
643 				break;
644 			}
645 			if ((rp->flags & DBUF_DMCS) == 0)
646 				printf("dmc%d: unallocated packet 0x%x\n",
647 				    unit, pkaddr);
648 			/* mark buffer free */
649 			if (ifxp->ifw_xtofree) {
650 				(void)m_freem(ifxp->ifw_xtofree);
651 				ifxp->ifw_xtofree = 0;
652 			}
653 			rp->flags &= ~DBUF_DMCS;
654 			sc->sc_oused--;
655 			sc->sc_nticks = 0;
656 			sc->sc_flag |= DMC_ACTIVE;
657 			break;
658 
659 		case DMC_CNTLO:
660 			arg &= DMC_CNTMASK;
661 			if (arg & DMC_FATAL) {
662 				log(LOG_ERR, "dmc%d: fatal error, flags=%b\n",
663 				    unit, arg, CNTLO_BITS);
664 				dmcrestart(unit);
665 				break;
666 			}
667 			/* ACCUMULATE STATISTICS */
668 			switch(arg) {
669 			case DMC_NOBUFS:
670 				ifp->if_ierrors++;
671 				if ((sc->sc_nobuf++ % DMC_RPNBFS) == 0)
672 					goto report;
673 				break;
674 			case DMC_DISCONN:
675 				if ((sc->sc_disc++ % DMC_RPDSC) == 0)
676 					goto report;
677 				break;
678 			case DMC_TIMEOUT:
679 				if ((sc->sc_timeo++ % DMC_RPTMO) == 0)
680 					goto report;
681 				break;
682 			case DMC_DATACK:
683 				ifp->if_oerrors++;
684 				if ((sc->sc_datck++ % DMC_RPDCK) == 0)
685 					goto report;
686 				break;
687 			default:
688 				goto report;
689 			}
690 			break;
691 		report:
692 			printd("dmc%d: soft error, flags=%b\n", unit,
693 			    arg, CNTLO_BITS);
694 			if ((sc->sc_flag & DMC_RESTART) == 0) {
695 				/*
696 				 * kill off the dmc to get things
697 				 * going again by generating a
698 				 * procedure error
699 				 */
700 				sc->sc_flag |= DMC_RESTART;
701 				arg = sc->sc_ubinfo & 0x3ffff;
702 				dmcload(sc, DMC_BASEI, arg, (arg>>2)&DMC_XMEM);
703 			}
704 			break;
705 
706 		default:
707 			printf("dmc%d: bad control %o\n", unit, cmd);
708 			break;
709 		}
710 	}
711 	dmcstart(unit);
712 	return;
713 }
714 
715 /*
716  * DMC output routine.
717  * Encapsulate a packet of type family for the dmc.
718  * Use trailer local net encapsulation if enough data in first
719  * packet leaves a multiple of 512 bytes of data in remainder.
720  */
721 dmcoutput(ifp, m0, dst)
722 	register struct ifnet *ifp;
723 	register struct mbuf *m0;
724 	struct sockaddr *dst;
725 {
726 	int type, error, s;
727 	register struct mbuf *m = m0;
728 	register struct dmc_header *dh;
729 	register int off;
730 
731 	switch (dst->sa_family) {
732 #ifdef	INET
733 	case AF_INET:
734 		off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
735 		if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
736 		if (off > 0 && (off & 0x1ff) == 0 &&
737 		    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
738 			type = DMC_TRAILER + (off>>9);
739 			m->m_off -= 2 * sizeof (u_short);
740 			m->m_len += 2 * sizeof (u_short);
741 			*mtod(m, u_short *) = htons((u_short)DMC_IPTYPE);
742 			*(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
743 			goto gottrailertype;
744 		}
745 		type = DMC_IPTYPE;
746 		off = 0;
747 		goto gottype;
748 #endif
749 
750 	case AF_UNSPEC:
751 		dh = (struct dmc_header *)dst->sa_data;
752 		type = dh->dmc_type;
753 		goto gottype;
754 
755 	default:
756 		printf("dmc%d: can't handle af%d\n", ifp->if_unit,
757 			dst->sa_family);
758 		error = EAFNOSUPPORT;
759 		goto bad;
760 	}
761 
762 gottrailertype:
763 	/*
764 	 * Packet to be sent as a trailer; move first packet
765 	 * (control information) to end of chain.
766 	 */
767 	while (m->m_next)
768 		m = m->m_next;
769 	m->m_next = m0;
770 	m = m0->m_next;
771 	m0->m_next = 0;
772 	m0 = m;
773 
774 gottype:
775 	/*
776 	 * Add local network header
777 	 * (there is space for a uba on a vax to step on)
778 	 */
779 	if (m->m_off > MMAXOFF ||
780 	    MMINOFF + sizeof(struct dmc_header) > m->m_off) {
781 		m = m_get(M_DONTWAIT, MT_HEADER);
782 		if (m == 0) {
783 			error = ENOBUFS;
784 			goto bad;
785 		}
786 		m->m_next = m0;
787 		m->m_off = MMINOFF;
788 		m->m_len = sizeof (struct dmc_header);
789 	} else {
790 		m->m_off -= sizeof (struct dmc_header);
791 		m->m_len += sizeof (struct dmc_header);
792 	}
793 	dh = mtod(m, struct dmc_header *);
794 	dh->dmc_type = htons((u_short)type);
795 
796 	/*
797 	 * Queue message on interface, and start output if interface
798 	 * not yet active.
799 	 */
800 	s = splimp();
801 	if (IF_QFULL(&ifp->if_snd)) {
802 		IF_DROP(&ifp->if_snd);
803 		m_freem(m);
804 		splx(s);
805 		return (ENOBUFS);
806 	}
807 	IF_ENQUEUE(&ifp->if_snd, m);
808 	dmcstart(ifp->if_unit);
809 	splx(s);
810 	return (0);
811 
812 bad:
813 	m_freem(m0);
814 	return (error);
815 }
816 
817 
818 /*
819  * Process an ioctl request.
820  */
821 /* ARGSUSED */
822 dmcioctl(ifp, cmd, data)
823 	register struct ifnet *ifp;
824 	int cmd;
825 	caddr_t data;
826 {
827 	int s = splimp(), error = 0;
828 	register struct dmc_softc *sc = &dmc_softc[ifp->if_unit];
829 
830 	switch (cmd) {
831 
832 	case SIOCSIFADDR:
833 		ifp->if_flags |= IFF_UP;
834 		if ((ifp->if_flags & IFF_RUNNING) == 0)
835 			dmcinit(ifp->if_unit);
836 		break;
837 
838 	case SIOCSIFDSTADDR:
839 		if ((ifp->if_flags & IFF_RUNNING) == 0)
840 			dmcinit(ifp->if_unit);
841 		break;
842 
843 	case SIOCSIFFLAGS:
844 		if ((ifp->if_flags & IFF_UP) == 0 &&
845 		    sc->sc_flag & DMC_RUNNING) {
846 			((struct dmcdevice *)
847 			   (dmcinfo[ifp->if_unit]->ui_addr))->bsel1 = DMC_MCLR;
848 			sc->sc_flag &= ~DMC_RUNNING;
849 		} else if (ifp->if_flags & IFF_UP &&
850 		    (sc->sc_flag & DMC_RUNNING) == 0)
851 			dmcrestart(ifp->if_unit);
852 		break;
853 
854 	default:
855 		error = EINVAL;
856 	}
857 	splx(s);
858 	return (error);
859 }
860 
861 /*
862  * Restart after a fatal error.
863  * Clear device and reinitialize.
864  */
865 dmcrestart(unit)
866 	int unit;
867 {
868 	register struct dmc_softc *sc = &dmc_softc[unit];
869 	register struct uba_device *ui = dmcinfo[unit];
870 	register struct dmcdevice *addr;
871 	register struct ifxmt *ifxp;
872 	register int i;
873 
874 	addr = (struct dmcdevice *)ui->ui_addr;
875 #ifdef DEBUG
876 	/* dump base table */
877 	printf("dmc%d base table:\n", unit);
878 	for (i = 0; i < sizeof (struct dmc_base); i++)
879 		printf("%o\n" ,dmc_base[unit].d_base[i]);
880 #endif
881 	/*
882 	 * Let the DMR finish the MCLR.	 At 1 Mbit, it should do so
883 	 * in about a max of 6.4 milliseconds with diagnostics enabled.
884 	 */
885 	addr->bsel1 = DMC_MCLR;
886 	for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
887 		;
888 	/* Did the timer expire or did the DMR finish? */
889 	if ((addr->bsel1 & DMC_RUN) == 0) {
890 		log(LOG_ERR, "dmc%d: M820 Test Failed\n", unit);
891 		return;
892 	}
893 
894 	for (ifxp = sc->sc_ifw; ifxp < &sc->sc_ifw[NXMT]; ifxp++) {
895 		if (ifxp->ifw_xtofree) {
896 			(void) m_freem(ifxp->ifw_xtofree);
897 			ifxp->ifw_xtofree = 0;
898 		}
899 	}
900 
901 	/* restart DMC */
902 	dmcinit(unit);
903 	sc->sc_flag &= ~DMC_RESTART;
904 	sc->sc_if.if_collisions++;	/* why not? */
905 }
906 
907 /*
908  * Check to see that transmitted packets don't
909  * lose interrupts.  The device has to be active.
910  */
911 dmcwatch()
912 {
913 	register struct uba_device *ui;
914 	register struct dmc_softc *sc;
915 	struct dmcdevice *addr;
916 	register int i;
917 
918 	for (i = 0; i < NDMC; i++) {
919 		sc = &dmc_softc[i];
920 		if ((sc->sc_flag & DMC_ACTIVE) == 0)
921 			continue;
922 		if ((ui = dmcinfo[i]) == 0 || ui->ui_alive == 0)
923 			continue;
924 		if (sc->sc_oused) {
925 			sc->sc_nticks++;
926 			if (sc->sc_nticks > dmc_timeout) {
927 				sc->sc_nticks = 0;
928 				addr = (struct dmcdevice *)ui->ui_addr;
929 				log(LOG_ERR, "dmc%d hung: bsel0=%b bsel2=%b\n",
930 				    i, addr->bsel0 & 0xff, DMC0BITS,
931 				    addr->bsel2 & 0xff, DMC2BITS);
932 				dmcrestart(i);
933 			}
934 		}
935 	}
936 	timeout(dmcwatch, (caddr_t) 0, hz);
937 }
938 #endif
939