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