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