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