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