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