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