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