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
dmcprobe(reg)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 */
dmcattach(ui)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 */
dmcreset(unit,uban)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 */
dmcinit(unit)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 */
dmcstart(unit)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 */
dmcload(sc,type,w0,w1)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 */
dmcrint(unit)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 */
dmcxint(unit)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 */
dmcoutput(ifp,m0,dst)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 */
dmcioctl(ifp,cmd,data)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 */
dmcrestart(unit)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 */
dmcdown(unit)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 */
dmctimeout(unit)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