1: /* @(#)if_qt.c 1.2 (2.11BSD) 2/20/93 2: * 3: * Modification History 4: * 23-Feb-92 -- sms 5: * Rewrite the buffer handling so that fewer than the maximum number of 6: * buffers may be used (32 receive and 12 transmit buffers consume 66+kb 7: * of main system memory in addition to the internal structures in the 8: * networking code). A freelist of available buffers is maintained now. 9: * When I/O operations complete the associated buffer is placed on the 10: * freelist (a single linked list for simplicity) and when an I/O is 11: * started a buffer is pulled off the list. 12: * 13: * 20-Feb-92 -- sms 14: * It works! Darned board couldn't handle "short" rings - those rings 15: * where only half the entries were made available to the board (the 16: * ring descriptors were the full size, merely half the entries were 17: * flagged as belonging always to the driver). Grrrr. Would have thought 18: * the board could skip over those entries reserved by the driver. 19: * Now to find a way not to have to allocated 32+12 times 1.5kb worth of 20: * buffers... 21: * 22: * 03-Feb-92 -- sms 23: * Released but still not working. The driver now responds to arp and 24: * ping requests. The board is apparently not returning ring descriptors 25: * to the driver so eventually we run out of buffers. Back to the 26: * drawing board. 27: * 28: * 28-Dec-92 -- sms 29: * Still not released. Hiatus in finding free time and thin-netting 30: * the systems (many thanks Terry!). 31: * Added logic to dynamically allocate a vector and initialize it. 32: * 33: * 23-Oct-92 -- sms 34: * The INIT block must (apparently) be quadword aligned [no thanks to 35: * the manual for not mentioning that fact]. The necessary alignment 36: * is achieved by allocating the INIT block from main memory ('malloc' 37: * guarantees click alignment) and mapping it as needed (which is _very_ 38: * infrequently). A check for quadword alignment of the ring descriptors 39: * was added - at present the descriptors are properly aligned, if this 40: * should change then something will have to be done (like do it "right"). 41: * Darned alignment restrictions! 42: * 43: * A couple of typos were corrected (missing parentheses, reversed 44: * arguments to printf calls, etc). 45: * 46: * 13-Oct-92 -- sms@wlv.iipo.gtegsc.com 47: * Created based on the DELQA-PLUS addendum to DELQA User's Guide. 48: * This driver ('qt') is selected at system configuration time. If the 49: * board * is not a DELQA-YM an error message will be printed and the 50: * interface will not be attached. 51: */ 52: 53: #include "qt.h" 54: #if NQT > 0 55: 56: #include "param.h" 57: #include "pdp/psl.h" 58: #include "pdp/seg.h" 59: #include "map.h" 60: #include "systm.h" 61: #include "mbuf.h" 62: #include "buf.h" 63: #include "protosw.h" 64: #include "socket.h" 65: #include "ioctl.h" 66: #include "errno.h" 67: #include "syslog.h" 68: #include "time.h" 69: #include "kernel.h" 70: 71: #include "../net/if.h" 72: #include "../net/netisr.h" 73: #include "../net/route.h" 74: 75: #ifdef INET 76: #include "domain.h" 77: #include "../netinet/in.h" 78: #include "../netinet/in_systm.h" 79: #include "../netinet/in_var.h" 80: #include "../netinet/ip.h" 81: #include "../netinet/if_ether.h" 82: #endif 83: 84: #ifdef NS 85: #include "../netns/ns.h" 86: #include "../netns/ns_if.h" 87: #endif 88: 89: #include "if_qtreg.h" 90: #include "if_uba.h" 91: #include "../pdpuba/ubavar.h" 92: 93: #define NRCV 16 /* Receive descriptors (must be <= 32) */ 94: #define NXMT 6 /* Transmit descriptors (must be <= 12) */ 95: #if NRCV > 32 || NXMT > 12 96: generate an error 97: #endif 98: 99: struct qt_uba 100: { 101: struct qt_uba *next; /* link to next buffer in list or 102: * NULL if the last buffer 103: */ 104: struct ifuba ubabuf; /* buffer descriptor */ 105: }; 106: 107: struct qt_softc { 108: struct arpcom is_ac; /* common part - must be first */ 109: #define is_if is_ac.ac_if /* network-visible interface */ 110: #define is_addr is_ac.ac_enaddr /* hardware Ethernet address */ 111: struct qt_uba *freelist; /* list of available buffers */ 112: struct qt_uba ifrw[NRCV + NXMT]; 113: u_short initclick; /* click addr of the INIT block */ 114: struct qt_rring *rring; /* Receive ring address */ 115: struct qt_tring *tring; /* Transmit ring address */ 116: char r_align[QT_MAX_RCV * sizeof (struct qt_rring) + 8]; 117: char t_align[QT_MAX_XMT * sizeof (struct qt_tring) + 8]; 118: short qt_flags; /* software state */ 119: #define QTF_RUNNING 0x1 120: #define QTF_STARTUP 0x2 /* Waiting for start interrupt */ 121: char rindex; /* Receive Completed Index */ 122: char nxtrcv; /* Next Receive Index */ 123: char nrcv; /* Number of Receives active */ 124: char tindex; /* Transmit index */ 125: char otindex; /* Old transmit index */ 126: char nxmit; /* # of xmits in progress */ 127: struct qtdevice *addr; /* device CSR addr */ 128: } qt_softc[NQT]; 129: 130: struct uba_device *qtinfo[NQT]; 131: 132: int qtattach(), qtintr(), qtinit(), qtoutput(), qtioctl(); 133: 134: extern struct ifnet loif; 135: 136: u_short qtstd[] = { 0 }; 137: 138: struct uba_driver qtdriver = 139: { 0, 0, qtattach, 0, qtstd, "qe", qtinfo }; 140: 141: /* 142: * Maximum packet size needs to include 4 bytes for the CRC 143: * on received packets. 144: */ 145: #define MAXPACKETSIZE (ETHERMTU + sizeof (struct ether_header) + 4) 146: #define MINPACKETSIZE 64 147: 148: /* 149: * The C compiler's propensity for prepending '_'s to names is the reason 150: * for the hack below. We need the "handler" address (the code which 151: * sets up the interrupt stack frame) in order to initialize the vector. 152: */ 153: 154: static int qtfoo() 155: { 156: asm("mov $qtintr, r0"); /* return value is in r0 */ 157: } 158: 159: /* 160: * Interface exists. More accurately, something exists at the CSR (see 161: * sys/sys_net.c) -- there's no guarantee it's a DELQA-YM. 162: * 163: * The ring descriptors are initialized, the buffers allocated using first the 164: * DMA region allocated at network load time and then later main memory. The 165: * INIT block is filled in and the device is poked/probed to see if it really 166: * is a DELQA-YM. If the device is not a -YM then a message is printed and 167: * the 'if_attach' call is skipped. For a -YM the START command is issued, 168: * but the device is not marked as running|up - that happens at interrupt level 169: * when the device interrupts to say it has started. 170: */ 171: 172: qtattach(ui) 173: struct uba_device *ui; 174: { 175: register struct qt_softc *sc = &qt_softc[ui->ui_unit]; 176: register struct ifnet *ifp = &sc->is_if; 177: register struct qt_init *iniblk = (struct qt_init *)SEG5; 178: segm seg5; 179: long bufaddr; 180: extern int nextiv(); 181: 182: ifp->if_unit = ui->ui_unit; 183: ifp->if_name = "qe"; 184: ifp->if_mtu = ETHERMTU; 185: ifp->if_flags = IFF_BROADCAST; 186: 187: /* 188: * Fill in most of the INIT block: vector, options (interrupt enable), ring 189: * locations. The physical address is copied from the ROMs as part of the 190: * -YM testing proceedure. The CSR is saved here rather than in qtinit() 191: * because the qtturbo() routine needs it. 192: * 193: * The INIT block must be quadword aligned. Using malloc() guarantees click 194: * (64 byte) alignment. Since the only time the INIT block is referenced is 195: * at 'startup' or 'reset' time there is really no time penalty (and a modest 196: * D space savings) involved. 197: */ 198: sc->addr = (struct qtdevice *)ui->ui_addr; 199: sc->initclick = MALLOC(coremap, btoc(sizeof (struct qt_init))); 200: saveseg5(seg5); 201: mapseg5(sc->initclick, 077406); 202: bzero(iniblk, sizeof (struct qt_init)); 203: sc->rring = (struct qt_rring *)(((int)sc->r_align + 7) & ~7); 204: sc->tring = (struct qt_tring *)(((int)sc->t_align + 7) & ~7); 205: 206: /* 207: * Fetch the next available interrupt vector. The routine is in the kernel 208: * (for several reasons) so use SKcall. Then initialize the vector with 209: * the address of our 'handler' and PSW of supervisor, priority 4 and unit 210: */ 211: iniblk->vector = SKcall(nextiv, 0); 212: mtkd(iniblk->vector, qtfoo()); 213: mtkd(iniblk->vector + 2, PSL_CURSUP | PSL_BR4 | ifp->if_unit); 214: 215: iniblk->options = INIT_OPTIONS_INT; 216: bufaddr = startnet + (long)sc->rring; 217: iniblk->rx_lo = loint(bufaddr); 218: iniblk->rx_hi = hiint(bufaddr); 219: bufaddr = startnet + (long)sc->tring; 220: iniblk->tx_lo = loint(bufaddr); 221: iniblk->tx_hi = hiint(bufaddr); 222: restorseg5(seg5); 223: 224: /* 225: * Now allocate the buffers and initialize the buffers. This should _never_ 226: * fail because main memory is allocated after the DMA pool is used up. 227: */ 228: 229: if (!qbaini(sc, NRCV + NXMT)) 230: return; /* XXX */ 231: 232: ifp->if_init = qtinit; 233: ifp->if_output = qtoutput; 234: ifp->if_ioctl = qtioctl; 235: ifp->if_reset = 0; 236: if (qtturbo(sc)) 237: if_attach(ifp); 238: } 239: 240: qtturbo(sc) 241: register struct qt_softc *sc; 242: { 243: register int i; 244: register struct qtdevice *addr = sc->addr; 245: struct qt_init *iniblk = (struct qt_init *)SEG5; 246: segm seg5; 247: 248: /* 249: * Issue the software reset. Delay 150us. The board should now be in 250: * DELQA-Normal mode. Set ITB and DEQTA select. If both bits do not 251: * stay turned on then the board is not a DELQA-YM. 252: */ 253: addr->arqr = ARQR_SR; 254: addr->arqr = 0; 255: delay(150L); 256: 257: addr->srr = 0x8001; /* MS | ITB */ 258: i = addr->srr; 259: addr->srr = 0x8000; /* Turn off ITB, set DELQA select */ 260: if (i != 0x8001) 261: { 262: printf("qt@%o !-YM\n", addr); 263: return(0); 264: } 265: /* 266: * Board is a DELQA-YM. Send the commands to enable Turbo mode. Delay 267: * 1 second, testing the SRR register every millisecond to see if the 268: * board has shifted to Turbo mode. 269: */ 270: addr->xcr0 = 0x0baf; 271: addr->xcr1 = 0xff00; 272: for (i = 0; i < 1000; i++) 273: { 274: if ((addr->srr & SRR_RESP) == 1) 275: break; 276: delay(1000L); 277: } 278: if (i >= 1000) 279: { 280: printf("qt@%o !Turbo\n", addr); 281: return(0); 282: } 283: /* 284: * Board has entered Turbo mode. Now copy the physical address from the 285: * ROMs to the INIT block. Fill in the address in the part of the structure 286: * "visible" to the rest of the system. 287: */ 288: saveseg5(seg5); 289: mapseg5(sc->initclick, 077406); 290: sc->is_addr[0] = addr->sarom[0]; 291: sc->is_addr[1] = addr->sarom[2]; 292: sc->is_addr[2] = addr->sarom[4]; 293: sc->is_addr[3] = addr->sarom[6]; 294: sc->is_addr[4] = addr->sarom[8]; 295: sc->is_addr[5] = addr->sarom[10]; 296: bcopy(sc->is_addr, iniblk->paddr, 6); 297: restorseg5(seg5); 298: return(1); 299: } 300: 301: qtinit(unit) 302: int unit; 303: { 304: int s; 305: register struct qt_softc *sc = &qt_softc[unit]; 306: struct qtdevice *addr = sc->addr; 307: struct ifnet *ifp = &sc->is_if; 308: struct qt_rring *rp; 309: struct qt_tring *tp; 310: register struct qt_uba *xp; 311: register int i; 312: long buf_adr; 313: 314: if (!ifp->if_addrlist) /* oops! */ 315: return; 316: /* 317: * Now initialize the receive ring descriptors. Because this routine can be 318: * called with outstanding I/O operations we check the ring descriptors for 319: * a non-zero 'rhost0' (or 'thost0') word and place those buffers back on 320: * the free list. 321: */ 322: for (i = 0, rp = sc->rring; i < QT_MAX_RCV; i++, rp++) 323: { 324: rp->rmd3 = RMD3_OWN; 325: if (xp = rp->rhost0) 326: { 327: rp->rhost0 = 0; 328: xp->next = sc->freelist; 329: sc->freelist = xp; 330: } 331: } 332: for (i = 0, tp = sc->tring ; i < QT_MAX_XMT; i++, tp++) 333: { 334: sc->tring[i].tmd3 = TMD3_OWN; 335: if (xp = tp->thost0) 336: { 337: tp->thost0 = 0; 338: xp->next = sc->freelist; 339: sc->freelist = xp; 340: } 341: } 342: 343: sc->nxmit = 0; 344: sc->otindex = 0; 345: sc->tindex = 0; 346: sc->rindex = 0; 347: sc->nxtrcv = 0; 348: sc->nrcv = 0; 349: 350: s = splimp(); 351: /* 352: * Now we tell the device the address of the INIT block. The device 353: * _must_ be in the Turbo mode at this time. The "START" command is 354: * then issued to the device. A 1 second timeout is then started. 355: * When the interrupt occurs the IFF_UP|IFF_RUNNING state is entered and 356: * full operations will proceed. If the timeout expires without an interrupt 357: * being received an error is printed, the flags cleared and the device left 358: * marked down. 359: */ 360: buf_adr = ctob((long)sc->initclick); 361: addr->ibal = loint(buf_adr); 362: addr->ibah = hiint(buf_adr); 363: addr->srqr = 2; 364: /* 365: * set internal state to 'startup' and start a one second timer. the interrupt 366: * service routine will be entered either 1) when the device posts the 'start' 367: * interrupt or 2) when the timer expires. The interrupt routine will fill 368: * the receive rings, etc. 369: */ 370: sc->qt_flags = QTF_STARTUP; 371: TIMEOUT(qtintr, unit, 60); 372: splx(s); 373: } 374: 375: /* 376: * Start output on interface. 377: */ 378: 379: qtstart(unit) 380: int unit; 381: { 382: int len, s; 383: register struct qt_softc *sc = &qt_softc[unit]; 384: register struct qt_tring *rp; 385: struct mbuf *m; 386: long buf_addr; 387: register struct qt_uba *xp; 388: 389: s = splimp(); 390: while (sc->nxmit < NXMT) 391: { 392: IF_DEQUEUE(&sc->is_if.if_snd, m); 393: if (m == 0) 394: break; 395: rp = &sc->tring[sc->tindex]; 396: #ifdef QTDEBUG 397: if ((rp->tmd3 & TMD3_OWN) == 0) 398: printf("qt xmit in progress\n"); 399: #endif 400: /* 401: * Now pull a buffer off of the freelist. Guaranteed to be a buffer 402: * because both the receive and transmit sides limit themselves to 403: * NRCV and NXMT buffers respectively. 404: */ 405: xp = sc->freelist; 406: sc->freelist = xp->next; 407: 408: buf_addr = xp->ubabuf.ifu_w.ifrw_info; 409: len = if_wubaput(&xp->ubabuf, m); 410: if (len < MINPACKETSIZE) 411: len = MINPACKETSIZE; 412: rp->tmd4 = loint(buf_addr); 413: rp->tmd5 = hiint(buf_addr) & TMD5_HADR; 414: rp->tmd3 = len & TMD3_BCT; /* set length,clear ownership */ 415: rp->thost0 = xp; /* set entry active */ 416: sc->addr->arqr = ARQR_TRQ; /* tell device it has buffer */ 417: sc->nxmit++; 418: if (++sc->tindex >= QT_MAX_XMT) 419: sc->tindex = 0; 420: } 421: splx(s); 422: } 423: 424: /* 425: * General interrupt service routine. Receive, transmit, device start 426: * interrupts and timeouts come here. Check for hard device errors and print a 427: * message if any errors are found. If we are waiting for the device to 428: * START then check if the device is now running. 429: */ 430: 431: qtintr(unit) 432: int unit; 433: { 434: register struct qt_softc *sc = &qt_softc[unit]; 435: register int status; 436: int s; 437: 438: status = sc->addr->srr; 439: if (status < 0) 440: /* should we reset the device after a bunch of these errs? */ 441: qtsrr(unit, status); 442: if (sc->qt_flags == QTF_STARTUP) 443: { 444: if ((status & SRR_RESP) == 2) 445: { 446: sc->qt_flags = QTF_RUNNING; 447: sc->is_if.if_flags |= (IFF_UP | IFF_RUNNING); 448: } 449: else 450: printf("qt%d !start\n", unit); 451: } 452: s = splimp(); 453: qtrint(unit); 454: if (sc->nxmit) 455: qttint(unit); 456: qtstart(unit); 457: splx(s); 458: } 459: 460: /* 461: * Transmit interrupt service. Only called if there are outstanding transmit 462: * requests which could have completed. The DELQA-YM doesn't provide the 463: * status bits telling the kind (receive, transmit) of interrupt. 464: */ 465: 466: #define BBLMIS (TMD2_BBL|TMD2_MIS) 467: 468: qttint(unit) 469: int unit; 470: { 471: register struct qt_softc *sc = &qt_softc[unit]; 472: register struct qt_tring *rp; 473: register struct qt_uba *xp; 474: 475: while (sc->nxmit > 0) 476: { 477: rp = &sc->tring[sc->otindex]; 478: if ((rp->tmd3 & TMD3_OWN) == 0) 479: break; 480: /* 481: * Now check the buffer address (the first word in the ring descriptor 482: * available for the host's use). If it is NULL then we have already seen 483: * and processed (or never presented to the board in the first place) this 484: * entry and the ring descriptor should not be counted. 485: */ 486: xp = rp->thost0; 487: if (xp == 0) 488: break; 489: /* 490: * Clear the buffer address from the ring descriptor and put the 491: * buffer back on the freelist for future use. 492: */ 493: rp->thost0 = 0; 494: xp->next = sc->freelist; 495: sc->freelist = xp; 496: 497: sc->nxmit--; 498: sc->is_if.if_opackets++; 499: /* 500: * Collisions don't count as output errors, but babbling and missing packets 501: * do count as output errors. 502: */ 503: if (rp->tmd2 & TMD2_CER) 504: sc->is_if.if_collisions++; 505: if ((rp->tmd0 & TMD0_ERR1) || 506: ((rp->tmd2 & TMD2_ERR2) && (rp->tmd2 & BBLMIS))) 507: { 508: #ifdef QTDEBUG 509: printf("qt%d tmd2 %b\n", unit, rp->tmd2, TMD2_BITS); 510: #endif 511: sc->is_if.if_oerrors++; 512: } 513: if (++sc->otindex >= QT_MAX_XMT) 514: sc->otindex = 0; 515: } 516: } 517: 518: /* 519: * Receive interrupt service. Pull packet off the interface and put into 520: * a mbuf chain for processing later. 521: */ 522: 523: qtrint(unit) 524: int unit; 525: { 526: register struct qt_softc *sc = &qt_softc[unit]; 527: register struct qt_rring *rp; 528: register struct qt_uba *xp; 529: int len; 530: long bufaddr; 531: 532: while (sc->rring[sc->rindex].rmd3 & RMD3_OWN) 533: { 534: rp = &sc->rring[sc->rindex]; 535: /* 536: * If the host word is 0 then this is a buffer either already seen or not 537: * presented to the device in the first place. 538: */ 539: xp = rp->rhost0; 540: if (xp == 0) 541: break; 542: 543: if ((rp->rmd0 & (RMD0_STP|RMD0_ENP)) != (RMD0_STP|RMD0_ENP)) 544: { 545: printf("qt%d chained packet\n", unit); 546: sc->is_if.if_ierrors++; 547: goto rnext; 548: } 549: len = (rp->rmd1 & RMD1_MCNT) - 4; /* -4 for CRC */ 550: sc->is_if.if_ipackets++; 551: 552: if ((rp->rmd0 & RMD0_ERR3) || (rp->rmd2 & RMD2_ERR4)) 553: { 554: sc->is_if.if_ierrors++; 555: #ifdef QTDEBUG 556: printf("qt%d rmd0 %b\n", unit, rp->rmd0, RMD0_BITS); 557: printf("qt%d rmd2 %b\n", unit, rp->rmd2, RMD2_BITS); 558: #endif 559: } 560: else 561: qtread(sc, &xp->ubabuf, 562: len - sizeof (struct ether_header)); 563: rnext: 564: --sc->nrcv; 565: if (++sc->rindex >= QT_MAX_RCV) 566: sc->rindex = 0; 567: /* 568: * put the buffer back on the free list and clear the first host word 569: * in the ring descriptor so we don't process this one again. 570: */ 571: xp->next = sc->freelist; 572: sc->freelist = xp; 573: rp->rhost0 = 0; 574: } 575: while (sc->nrcv < NRCV) 576: { 577: rp = &sc->rring[sc->nxtrcv]; 578: #ifdef QTDEBUG 579: if ((rp->rmd3 & RMD3_OWN) == 0) 580: printf("qtrint: !OWN\n"); 581: #endif 582: xp = sc->freelist; 583: sc->freelist = xp->next; 584: bufaddr = xp->ubabuf.ifu_r.ifrw_info; 585: rp->rmd1 = MAXPACKETSIZE; 586: rp->rmd4 = loint(bufaddr); 587: rp->rmd5 = hiint(bufaddr); 588: rp->rhost0 = xp; 589: rp->rmd3 = 0; /* clear RMD3_OWN */ 590: ++sc->nrcv; 591: sc->addr->arqr = ARQR_RRQ; /* tell device it has buffer */ 592: if (++sc->nxtrcv >= QT_MAX_RCV) 593: sc->nxtrcv = 0; 594: } 595: } 596: 597: /* 598: * Place data on the appropriate queue and call the start routine to 599: * send the data to the device. 600: */ 601: 602: qtoutput(ifp, m0, dst) 603: struct ifnet *ifp; 604: struct mbuf *m0; 605: struct sockaddr *dst; 606: { 607: int type, s, trail; 608: u_char edst[6]; 609: struct in_addr idst; 610: register struct ether_header *eh; 611: register struct qt_softc *is = &qt_softc[ifp->if_unit]; 612: register struct mbuf *m = m0; 613: struct mbuf *mcopy = (struct mbuf *)0; 614: 615: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 616: { 617: m_freem(m0); 618: return(ENETDOWN); 619: } 620: switch (dst->sa_family) 621: { 622: #ifdef INET 623: case AF_INET: 624: idst = ((struct sockaddr_in *)dst)->sin_addr; 625: if (!arpresolve(&is->is_ac, m, &idst, edst,&trail)) 626: return(0); /* wait for arp to finish */ 627: if (!bcmp(edst, etherbroadcastaddr,sizeof (edst))) 628: mcopy = m_copy(m, 0, (int)M_COPYALL); 629: type = ETHERTYPE_IP; 630: break; 631: #endif 632: #ifdef NS 633: case AF_NS: 634: type = ETHERTYPE_NS; 635: bcopy(&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 636: edst, sizeof (edst)); 637: if (!bcmp(edst, &ns_broadcast, sizeof (edst))) 638: return(looutput(&loif, m, dst)); 639: break; 640: #endif 641: case AF_UNSPEC: 642: eh = (struct ether_header *)dst->sa_data; 643: bcopy(eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 644: type = eh->ether_type; 645: break; 646: default: 647: printf("qt%d can't handle af%d\n", ifp->if_unit, 648: dst->sa_family); 649: m_freem(m); 650: return(EAFNOSUPPORT); 651: } 652: /* 653: * Add local net header. If no space in first mbuf, allocate another. 654: */ 655: if (m->m_off > MMAXOFF || 656: MMINOFF + sizeof (struct ether_header) > m->m_off) 657: { 658: m = m_get(M_DONTWAIT, MT_HEADER); 659: if (m == 0) 660: { 661: m_freem(m0); 662: nobufs: if (mcopy) 663: m_freem(mcopy); 664: return(ENOBUFS); 665: } 666: m->m_next = m0; 667: m->m_off = MMINOFF; 668: m->m_len = sizeof (struct ether_header); 669: } 670: else 671: { 672: m->m_off -= sizeof (struct ether_header); 673: m->m_len += sizeof (struct ether_header); 674: } 675: eh = mtod(m, struct ether_header *); 676: eh->ether_type = htons((u_short)type); 677: bcopy(edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 678: bcopy(is->is_addr, (caddr_t)eh->ether_shost, sizeof (is->is_addr)); 679: 680: s = splimp(); 681: if (IF_QFULL(&ifp->if_snd)) 682: { 683: IF_DROP(&ifp->if_snd); 684: m_freem(m); 685: splx(s); 686: goto nobufs; 687: } 688: IF_ENQUEUE(&ifp->if_snd, m); 689: qtstart(ifp->if_unit); 690: splx(s); 691: return(mcopy ? looutput(&loif, mcopy, dst) : 0); 692: } 693: 694: qtioctl(ifp, cmd, data) 695: register struct ifnet *ifp; 696: int cmd; 697: caddr_t data; 698: { 699: struct qt_softc *sc = &qt_softc[ifp->if_unit]; 700: struct ifaddr *ifa = (struct ifaddr *)data; 701: int s = splimp(), error = 0; 702: #ifdef NS 703: register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 704: #endif 705: 706: switch (cmd) 707: { 708: case SIOCSIFADDR: 709: /* 710: * Resetting the board is probably overkill, but then again this is only 711: * done when the system comes up or possibly when a reset is needed after a 712: * major network fault (open wire, etc). 713: */ 714: qtrestart(sc); 715: switch (ifa->ifa_addr.sa_family) 716: { 717: #ifdef INET 718: case AF_INET: 719: ((struct arpcom *)ifp)->ac_ipaddr = 720: IA_SIN(ifa)->sin_addr; 721: arpwhohas(ifp, &IA_SIN(ifa)->sin_addr); 722: break; 723: #endif 724: #ifdef NS 725: case AF_NS: 726: if (ns_nullhost(*ina)) 727: ina->x_host = 728: *(union ns_host *)(sc->is_addr); 729: else 730: { 731: qt_ns(ina->x_host.c_host); 732: qtrestart(sc); 733: } 734: break; 735: #endif 736: } 737: break; 738: case SIOCSIFFLAGS: 739: if ((ifp->if_flags & IFF_UP) == 0 && 740: sc->qt_flags & QTF_RUNNING) 741: { 742: /* 743: * We've been asked to stop the board and leave it that way. qtturbo() 744: * does this with the side effect of placing the device back in Turbo mode. 745: */ 746: qtturbo(sc); 747: sc->qt_flags &= ~QTF_RUNNING; 748: } 749: else if (ifp->if_flags & IFF_UP && 750: !(sc->qt_flags & QTF_RUNNING)) 751: qtrestart(sc); 752: break; 753: default: 754: error = EINVAL; 755: } 756: splx(s); 757: return(error); 758: } 759: 760: #ifdef NS 761: qt_ns(cp) 762: register char *cp; 763: { 764: segm seg5; 765: register struct qt_init *iniblk = (struct qt_init *)SEG5; 766: 767: saveseg5(seg5); 768: mapseg5(sc->initclick, 077406); 769: bcopy(cp, sc->is_addr, 6); 770: bcopy(cp, iniblk->paddr, 6); 771: restorseg5(seg5); 772: } 773: #endif 774: 775: /* 776: * Pull the data off of the board and pass back to the upper layers of 777: * the networking code. Trailers are counted as errors and the packet 778: * dropped. SEG5 is saved and restored (used to peek at the packet type). 779: */ 780: 781: qtread(sc, ifuba, len) 782: register struct qt_softc *sc; 783: struct ifuba *ifuba; 784: int len; 785: { 786: struct ether_header *eh; 787: register struct mbuf *m; 788: struct ifqueue *inq; 789: int type; 790: segm seg5; 791: 792: saveseg5(seg5); 793: mapseg5(ifuba->ifu_r.ifrw_click, 077406); 794: eh = (struct ether_header *)SEG5; 795: eh->ether_type = ntohs((u_short)eh->ether_type); 796: type = eh->ether_type; 797: restorseg5(seg5); 798: if (len == 0 || type >= ETHERTYPE_TRAIL && 799: type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) 800: { 801: sc->is_if.if_ierrors++; 802: return; 803: } 804: 805: m = if_rubaget(ifuba, len, 0, &sc->is_if); 806: if (m == 0) 807: return; 808: 809: switch (type) 810: { 811: #ifdef INET 812: case ETHERTYPE_IP: 813: schednetisr(NETISR_IP); 814: inq = &ipintrq; 815: break; 816: case ETHERTYPE_ARP: 817: arpinput(&sc->is_ac, m); 818: return; 819: #endif 820: #ifdef NS 821: case ETHERTYPE_NS: 822: schednetisr(NETISR_NS); 823: inq = &nsintrq; 824: break; 825: #endif 826: default: 827: m_freem(m); 828: return; 829: } 830: 831: if (IF_QFULL(inq)) 832: { 833: IF_DROP(inq); 834: m_freem(m); 835: return; 836: } 837: IF_ENQUEUE(inq, m); 838: } 839: 840: 841: qtsrr(unit, srrbits) 842: int unit, srrbits; 843: { 844: printf("qt%d srr=%b\n", unit, srrbits, SRR_BITS); 845: } 846: 847: /* 848: * Reset the device. This moves it from DELQA-T mode to DELQA-Normal mode. 849: * After the reset put the device back in -T mode. Then call qtinit() to 850: * reinitialize the ring structures and issue the 'timeout' for the "device 851: * started interrupt". 852: */ 853: 854: qtrestart(sc) 855: register struct qt_softc *sc; 856: { 857: 858: qtturbo(sc); 859: qtinit(sc - qt_softc); 860: } 861: 862: qbaini(sc, num) 863: struct qt_softc *sc; 864: int num; 865: { 866: register int i; 867: register memaddr click; 868: struct qt_uba *xp; 869: register struct ifuba *ifuba; 870: 871: for (i = 0; i < num; i++) 872: { 873: xp = &sc->ifrw[i]; 874: ifuba = &xp->ubabuf; 875: click = m_ioget(MAXPACKETSIZE); 876: if (click == 0) 877: { 878: click = MALLOC(coremap, btoc(MAXPACKETSIZE)); 879: if (click == 0) 880: return(0); /* _can't_ happen */ 881: } 882: ifuba->ifu_hlen = sizeof (struct ether_header); 883: ifuba->ifu_w.ifrw_click = ifuba->ifu_r.ifrw_click = click; 884: ifuba->ifu_w.ifrw_info = ifuba->ifu_r.ifrw_info = 885: ctob((long)click); 886: xp->next = sc->freelist; 887: sc->freelist = xp; 888: } 889: return(1); 890: } 891: #endif