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