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