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