|
|
1.1 ! root 1: /* @(#)if_qe.c 7.1 (Berkeley) 6/5/86 */ ! 2: ! 3: /* from @(#)if_qe.c 1.15 (ULTRIX) 4/16/86 */ ! 4: ! 5: ! 6: /**************************************************************** ! 7: * * ! 8: * Licensed from Digital Equipment Corporation * ! 9: * Copyright (c) * ! 10: * Digital Equipment Corporation * ! 11: * Maynard, Massachusetts * ! 12: * 1985, 1986 * ! 13: * All rights reserved. * ! 14: * * ! 15: * The Information in this software is subject to change * ! 16: * without notice and should not be construed as a commitment * ! 17: * by Digital Equipment Corporation. Digital makes no * ! 18: * representations about the suitability of this software for * ! 19: * any purpose. It is supplied "As Is" without expressed or * ! 20: * implied warranty. * ! 21: * * ! 22: * If the Regents of the University of California or its * ! 23: * licensees modify the software in a manner creating * ! 24: * derivative copyright rights, appropriate copyright * ! 25: * legends may be placed on the derivative work in addition * ! 26: * to that set forth above. * ! 27: * * ! 28: ****************************************************************/ ! 29: /* --------------------------------------------------------------------- ! 30: * Modification History ! 31: * ! 32: * 15-Apr-86 -- afd ! 33: * Rename "unused_multi" to "qunused_multi" for extending Generic ! 34: * kernel to MicroVAXen. ! 35: * ! 36: * 18-mar-86 -- jaw br/cvec changed to NOT use registers. ! 37: * ! 38: * 12 March 86 -- Jeff Chase ! 39: * Modified to handle the new MCLGET macro ! 40: * Changed if_qe_data.c to use more receive buffers ! 41: * Added a flag to poke with adb to log qe_restarts on console ! 42: * ! 43: * 19 Oct 85 -- rjl ! 44: * Changed the watch dog timer from 30 seconds to 3. VMS is using ! 45: * less than 1 second in their's. Also turned the printf into an ! 46: * mprintf. ! 47: * ! 48: * 09/16/85 -- Larry Cohen ! 49: * Add 43bsd alpha tape changes for subnet routing ! 50: * ! 51: * 1 Aug 85 -- rjl ! 52: * Panic on a non-existent memory interrupt and the case where a packet ! 53: * was chained. The first should never happen because non-existant ! 54: * memory interrupts cause a bus reset. The second should never happen ! 55: * because we hang 2k input buffers on the device. ! 56: * ! 57: * 1 Aug 85 -- rich ! 58: * Fixed the broadcast loopback code to handle Clusters without ! 59: * wedging the system. ! 60: * ! 61: * 27 Feb. 85 -- ejf ! 62: * Return default hardware address on ioctl request. ! 63: * ! 64: * 12 Feb. 85 -- ejf ! 65: * Added internal extended loopback capability. ! 66: * ! 67: * 27 Dec. 84 -- rjl ! 68: * Fixed bug that caused every other transmit descriptor to be used ! 69: * instead of every descriptor. ! 70: * ! 71: * 21 Dec. 84 -- rjl ! 72: * Added watchdog timer to mask hardware bug that causes device lockup. ! 73: * ! 74: * 18 Dec. 84 -- rjl ! 75: * Reworked driver to use q-bus mapping routines. MicroVAX-I now does ! 76: * copying instead of m-buf shuffleing. ! 77: * A number of deficencies in the hardware/firmware were compensated ! 78: * for. See comments in qestart and qerint. ! 79: * ! 80: * 14 Nov. 84 -- jf ! 81: * Added usage counts for multicast addresses. ! 82: * Updated general protocol support to allow access to the Ethernet ! 83: * header. ! 84: * ! 85: * 04 Oct. 84 -- jf ! 86: * Added support for new ioctls to add and delete multicast addresses ! 87: * and set the physical address. ! 88: * Add support for general protocols. ! 89: * ! 90: * 14 Aug. 84 -- rjl ! 91: * Integrated Shannon changes. (allow arp above 1024 and ? ) ! 92: * ! 93: * 13 Feb. 84 -- rjl ! 94: * ! 95: * Initial version of driver. derived from IL driver. ! 96: * ! 97: * --------------------------------------------------------------------- ! 98: */ ! 99: ! 100: #include "qe.h" ! 101: #if NQE > 0 ! 102: /* ! 103: * Digital Q-BUS to NI Adapter ! 104: */ ! 105: #include "../machine/pte.h" ! 106: ! 107: #include "param.h" ! 108: #include "systm.h" ! 109: #include "mbuf.h" ! 110: #include "buf.h" ! 111: #include "protosw.h" ! 112: #include "socket.h" ! 113: #include "vmmac.h" ! 114: #include "ioctl.h" ! 115: #include "errno.h" ! 116: #include "syslog.h" ! 117: #include "time.h" ! 118: #include "kernel.h" ! 119: ! 120: #include "../net/if.h" ! 121: #include "../net/netisr.h" ! 122: #include "../net/route.h" ! 123: ! 124: #ifdef INET ! 125: #include "../netinet/in.h" ! 126: #include "../netinet/in_systm.h" ! 127: #include "../netinet/in_var.h" ! 128: #include "../netinet/ip.h" ! 129: #include "../netinet/if_ether.h" ! 130: #endif ! 131: ! 132: #ifdef NS ! 133: #include "../netns/ns.h" ! 134: #include "../netns/ns_if.h" ! 135: #endif ! 136: ! 137: #include "../vax/cpu.h" ! 138: #include "../vax/mtpr.h" ! 139: #include "if_qereg.h" ! 140: #include "if_uba.h" ! 141: #include "../vaxuba/ubareg.h" ! 142: #include "../vaxuba/ubavar.h" ! 143: ! 144: #define NRCV 25 /* Receive descriptors */ ! 145: #define NXMT 5 /* Transmit descriptors */ ! 146: #define NTOT (NXMT + NRCV) ! 147: ! 148: /* ! 149: * This constant should really be 60 because the qna adds 4 bytes of crc. ! 150: * However when set to 60 our packets are ignored by deuna's , 3coms are ! 151: * okay ?????????????????????????????????????????? ! 152: */ ! 153: #define MINDATA 64 ! 154: ! 155: /* ! 156: * Ethernet software status per interface. ! 157: * ! 158: * Each interface is referenced by a network interface structure, ! 159: * is_if, which the routing code uses to locate the interface. ! 160: * This structure contains the output queue for the interface, its address, ... ! 161: */ ! 162: struct qe_softc { ! 163: struct arpcom is_ac; /* Ethernet common part */ ! 164: #define is_if is_ac.ac_if /* network-visible interface */ ! 165: #define is_addr is_ac.ac_enaddr /* hardware Ethernet address */ ! 166: struct ifubinfo qe_uba; /* Q-bus resources */ ! 167: struct ifrw qe_ifr[NRCV]; /* for receive buffers; */ ! 168: struct ifxmt qe_ifw[NXMT]; /* for xmit buffers; */ ! 169: int qe_flags; /* software state */ ! 170: #define QEF_RUNNING 0x01 ! 171: #define QEF_SETADDR 0x02 ! 172: int setupaddr; /* mapping info for setup pkts */ ! 173: struct qe_ring *rringaddr; /* mapping info for rings */ ! 174: struct qe_ring *tringaddr; /* "" */ ! 175: struct qe_ring rring[NRCV+1]; /* Receive ring descriptors */ ! 176: struct qe_ring tring[NXMT+1]; /* Transmit ring descriptors */ ! 177: u_char setup_pkt[16][8]; /* Setup packet */ ! 178: int rindex; /* Receive index */ ! 179: int tindex; /* Transmit index */ ! 180: int otindex; /* Old transmit index */ ! 181: int qe_intvec; /* Interrupt vector */ ! 182: struct qedevice *addr; /* device addr */ ! 183: int setupqueued; /* setup packet queued */ ! 184: int nxmit; /* Transmits in progress */ ! 185: int timeout; /* watchdog */ ! 186: int qe_restarts; /* timeouts */ ! 187: } qe_softc[NQE]; ! 188: ! 189: struct uba_device *qeinfo[NQE]; ! 190: ! 191: extern struct timeval time; ! 192: extern timeout(); ! 193: ! 194: int qeprobe(), qeattach(), qeintr(), qewatch(); ! 195: int qeinit(),qeoutput(),qeioctl(),qereset(),qewatch(); ! 196: ! 197: u_short qestd[] = { 0 }; ! 198: struct uba_driver qedriver = ! 199: { qeprobe, 0, qeattach, 0, qestd, "qe", qeinfo }; ! 200: ! 201: #define QE_TIMEO (15) ! 202: #define QEUNIT(x) minor(x) ! 203: static int mask = 0x3ffff; /* address mask */ ! 204: int qewatchrun = 0; /* watchdog running */ ! 205: /* ! 206: * The deqna shouldn't receive more than ETHERMTU + sizeof(struct ether_header) ! 207: * but will actually take in up to 2048 bytes. To guard against the receiver ! 208: * chaining buffers (which we aren't prepared to handle) we allocate 2kb ! 209: * size buffers. ! 210: */ ! 211: #define MAXPACKETSIZE 2048 /* Should really be ETHERMTU */ ! 212: /* ! 213: * Probe the QNA to see if it's there ! 214: */ ! 215: qeprobe(reg) ! 216: caddr_t reg; ! 217: { ! 218: register int br, cvec; /* r11, r10 value-result */ ! 219: register struct qedevice *addr = (struct qedevice *)reg; ! 220: register struct qe_ring *rp; ! 221: register struct qe_ring *prp; /* physical rp */ ! 222: register int i, j; ! 223: static int next=0; /* softc index */ ! 224: register struct qe_softc *sc = &qe_softc[next++]; ! 225: ! 226: #ifdef lint ! 227: br = 0; cvec = br; br = cvec; ! 228: qeintr(0); ! 229: #endif ! 230: /* ! 231: * Set the address mask for the particular cpu ! 232: */ ! 233: mask = 0x3ffff; ! 234: ! 235: /* ! 236: * The QNA interrupts on i/o operations. To do an I/O operation ! 237: * we have to setup the interface by transmitting a setup packet. ! 238: */ ! 239: addr->qe_csr = QE_RESET; ! 240: addr->qe_vector = (uba_hd[numuba].uh_lastiv -= 4); ! 241: ! 242: /* ! 243: * Map the communications area and the setup packet. ! 244: */ ! 245: sc->setupaddr = ! 246: uballoc(0, (caddr_t)sc->setup_pkt, sizeof(sc->setup_pkt), 0); ! 247: sc->rringaddr = (struct qe_ring *) uballoc(0, (caddr_t)sc->rring, ! 248: sizeof(struct qe_ring) * (NTOT+2), 0); ! 249: prp = (struct qe_ring *)((int)sc->rringaddr & mask); ! 250: ! 251: /* ! 252: * The QNA will loop the setup packet back to the receive ring ! 253: * for verification, therefore we initialize the first ! 254: * receive & transmit ring descriptors and link the setup packet ! 255: * to them. ! 256: */ ! 257: qeinitdesc(sc->tring, (caddr_t)(sc->setupaddr & mask), ! 258: sizeof(sc->setup_pkt)); ! 259: qeinitdesc(sc->rring, (caddr_t)(sc->setupaddr & mask), ! 260: sizeof(sc->setup_pkt)); ! 261: ! 262: rp = (struct qe_ring *)sc->tring; ! 263: rp->qe_setup = 1; ! 264: rp->qe_eomsg = 1; ! 265: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 266: rp->qe_valid = 1; ! 267: ! 268: rp = (struct qe_ring *)sc->rring; ! 269: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 270: rp->qe_valid = 1; ! 271: ! 272: /* ! 273: * Get the addr off of the interface and place it into the setup ! 274: * packet. This code looks strange due to the fact that the address ! 275: * is placed in the setup packet in col. major order. ! 276: */ ! 277: for( i = 0 ; i < 6 ; i++ ) ! 278: sc->setup_pkt[i][1] = addr->qe_sta_addr[i]; ! 279: ! 280: qesetup( sc ); ! 281: /* ! 282: * Start the interface and wait for the packet. ! 283: */ ! 284: j = cvec; ! 285: addr->qe_csr = QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT; ! 286: addr->qe_rcvlist_lo = (short)prp; ! 287: addr->qe_rcvlist_hi = (short)((int)prp >> 16); ! 288: prp += NRCV+1; ! 289: addr->qe_xmtlist_lo = (short)prp; ! 290: addr->qe_xmtlist_hi = (short)((int)prp >> 16); ! 291: DELAY(10000); ! 292: /* ! 293: * All done with the bus resources. ! 294: */ ! 295: ubarelse(0, &sc->setupaddr); ! 296: ubarelse(0, (int *)&sc->rringaddr); ! 297: if( cvec == j ) ! 298: return 0; /* didn't interrupt */ ! 299: ! 300: return( sizeof(struct qedevice) ); ! 301: } ! 302: ! 303: /* ! 304: * Interface exists: make available by filling in network interface ! 305: * record. System will initialize the interface when it is ready ! 306: * to accept packets. ! 307: */ ! 308: qeattach(ui) ! 309: struct uba_device *ui; ! 310: { ! 311: register struct qe_softc *sc = &qe_softc[ui->ui_unit]; ! 312: register struct ifnet *ifp = &sc->is_if; ! 313: register struct qedevice *addr = (struct qedevice *)ui->ui_addr; ! 314: register int i; ! 315: ! 316: ifp->if_unit = ui->ui_unit; ! 317: ifp->if_name = "qe"; ! 318: ifp->if_mtu = ETHERMTU; ! 319: ifp->if_flags = IFF_BROADCAST; ! 320: ! 321: /* ! 322: * Read the address from the prom and save it. ! 323: */ ! 324: for( i=0 ; i<6 ; i++ ) ! 325: sc->setup_pkt[i][1] = sc->is_addr[i] = addr->qe_sta_addr[i] & 0xff; ! 326: ! 327: /* ! 328: * Save the vector for initialization at reset time. ! 329: */ ! 330: sc->qe_intvec = addr->qe_vector; ! 331: ! 332: ifp->if_init = qeinit; ! 333: ifp->if_output = qeoutput; ! 334: ifp->if_ioctl = qeioctl; ! 335: ifp->if_reset = qereset; ! 336: sc->qe_uba.iff_flags = UBA_CANTWAIT; ! 337: if_attach(ifp); ! 338: } ! 339: ! 340: /* ! 341: * Reset of interface after UNIBUS reset. ! 342: * If interface is on specified uba, reset its state. ! 343: */ ! 344: qereset(unit, uban) ! 345: int unit, uban; ! 346: { ! 347: register struct uba_device *ui; ! 348: ! 349: if (unit >= NQE || (ui = qeinfo[unit]) == 0 || ui->ui_alive == 0 || ! 350: ui->ui_ubanum != uban) ! 351: return; ! 352: printf(" qe%d", unit); ! 353: qe_softc[unit].is_if.if_flags &= ~IFF_RUNNING; ! 354: qeinit(unit); ! 355: } ! 356: ! 357: /* ! 358: * Initialization of interface. ! 359: */ ! 360: qeinit(unit) ! 361: int unit; ! 362: { ! 363: register struct qe_softc *sc = &qe_softc[unit]; ! 364: register struct uba_device *ui = qeinfo[unit]; ! 365: register struct qedevice *addr = (struct qedevice *)ui->ui_addr; ! 366: register struct ifnet *ifp = &sc->is_if; ! 367: register i; ! 368: int s; ! 369: ! 370: /* address not known */ ! 371: if (ifp->if_addrlist == (struct ifaddr *)0) ! 372: return; ! 373: if (sc->qe_flags & QEF_RUNNING) ! 374: return; ! 375: ! 376: if ((ifp->if_flags & IFF_RUNNING) == 0) { ! 377: /* ! 378: * map the communications area onto the device ! 379: */ ! 380: sc->rringaddr = (struct qe_ring *) ! 381: ((int) uballoc(0, (caddr_t)sc->rring, ! 382: sizeof(struct qe_ring) * (NTOT+2), 0) & mask); ! 383: sc->tringaddr = sc->rringaddr + NRCV + 1; ! 384: sc->setupaddr = uballoc(0, (caddr_t)sc->setup_pkt, ! 385: sizeof(sc->setup_pkt), 0) & mask; ! 386: /* ! 387: * init buffers and maps ! 388: */ ! 389: if (if_ubaminit(&sc->qe_uba, ui->ui_ubanum, ! 390: sizeof (struct ether_header), (int)btoc(MAXPACKETSIZE), ! 391: sc->qe_ifr, NRCV, sc->qe_ifw, NXMT) == 0) { ! 392: printf("qe%d: can't initialize\n", unit); ! 393: sc->is_if.if_flags &= ~IFF_UP; ! 394: return; ! 395: } ! 396: } ! 397: /* ! 398: * Init the buffer descriptors and indexes for each of the lists and ! 399: * loop them back to form a ring. ! 400: */ ! 401: for (i = 0; i < NRCV; i++) { ! 402: qeinitdesc( &sc->rring[i], ! 403: (caddr_t)(sc->qe_ifr[i].ifrw_info & mask), MAXPACKETSIZE); ! 404: sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET; ! 405: sc->rring[i].qe_valid = 1; ! 406: } ! 407: qeinitdesc(&sc->rring[i], (caddr_t)NULL, 0); ! 408: ! 409: sc->rring[i].qe_addr_lo = (short)sc->rringaddr; ! 410: sc->rring[i].qe_addr_hi = (short)((int)sc->rringaddr >> 16); ! 411: sc->rring[i].qe_chain = 1; ! 412: sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET; ! 413: sc->rring[i].qe_valid = 1; ! 414: ! 415: for( i = 0 ; i <= NXMT ; i++ ) ! 416: qeinitdesc(&sc->tring[i], (caddr_t)NULL, 0); ! 417: i--; ! 418: ! 419: sc->tring[i].qe_addr_lo = (short)sc->tringaddr; ! 420: sc->tring[i].qe_addr_hi = (short)((int)sc->tringaddr >> 16); ! 421: sc->tring[i].qe_chain = 1; ! 422: sc->tring[i].qe_flag = sc->tring[i].qe_status1 = QE_NOTYET; ! 423: sc->tring[i].qe_valid = 1; ! 424: ! 425: sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0; ! 426: ! 427: /* ! 428: * Take the interface out of reset, program the vector, ! 429: * enable interrupts, and tell the world we are up. ! 430: */ ! 431: s = splimp(); ! 432: addr->qe_vector = sc->qe_intvec; ! 433: sc->addr = addr; ! 434: addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | ! 435: QE_RCV_INT | QE_ILOOP; ! 436: addr->qe_rcvlist_lo = (short)sc->rringaddr; ! 437: addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16); ! 438: ifp->if_flags |= IFF_UP | IFF_RUNNING; ! 439: sc->qe_flags |= QEF_RUNNING; ! 440: qesetup( sc ); ! 441: qestart( unit ); ! 442: splx( s ); ! 443: ! 444: } ! 445: ! 446: /* ! 447: * Start output on interface. ! 448: * ! 449: */ ! 450: qestart(dev) ! 451: dev_t dev; ! 452: { ! 453: int unit = QEUNIT(dev); ! 454: struct uba_device *ui = qeinfo[unit]; ! 455: register struct qe_softc *sc = &qe_softc[unit]; ! 456: register struct qedevice *addr; ! 457: register struct qe_ring *rp; ! 458: register index; ! 459: struct mbuf *m; ! 460: int buf_addr, len, s; ! 461: ! 462: ! 463: s = splimp(); ! 464: addr = (struct qedevice *)ui->ui_addr; ! 465: /* ! 466: * The deqna doesn't look at anything but the valid bit ! 467: * to determine if it should transmit this packet. If you have ! 468: * a ring and fill it the device will loop indefinately on the ! 469: * packet and continue to flood the net with packets until you ! 470: * break the ring. For this reason we never queue more than n-1 ! 471: * packets in the transmit ring. ! 472: * ! 473: * The microcoders should have obeyed their own defination of the ! 474: * flag and status words, but instead we have to compensate. ! 475: */ ! 476: for( index = sc->tindex; ! 477: sc->tring[index].qe_valid == 0 && sc->nxmit < (NXMT-1) ; ! 478: sc->tindex = index = ++index % NXMT){ ! 479: rp = &sc->tring[index]; ! 480: if( sc->setupqueued ) { ! 481: buf_addr = sc->setupaddr; ! 482: len = 128; ! 483: rp->qe_setup = 1; ! 484: sc->setupqueued = 0; ! 485: } else { ! 486: IF_DEQUEUE(&sc->is_if.if_snd, m); ! 487: if( m == 0 ){ ! 488: splx(s); ! 489: return; ! 490: } ! 491: buf_addr = sc->qe_ifw[index].ifw_info; ! 492: len = if_ubaput(&sc->qe_uba, &sc->qe_ifw[index], m); ! 493: } ! 494: /* ! 495: * Does buffer end on odd byte ? ! 496: */ ! 497: if( len & 1 ) { ! 498: len++; ! 499: rp->qe_odd_end = 1; ! 500: } ! 501: if( len < MINDATA ) ! 502: len = MINDATA; ! 503: rp->qe_buf_len = -(len/2); ! 504: buf_addr &= mask; ! 505: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 506: rp->qe_addr_lo = (short)buf_addr; ! 507: rp->qe_addr_hi = (short)(buf_addr >> 16); ! 508: rp->qe_eomsg = 1; ! 509: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 510: rp->qe_valid = 1; ! 511: sc->nxmit++; ! 512: /* ! 513: * If the watchdog time isn't running kick it. ! 514: */ ! 515: sc->timeout=1; ! 516: if (qewatchrun == 0) { ! 517: qewatchrun++; ! 518: timeout(qewatch, (caddr_t)0, QE_TIMEO); ! 519: } ! 520: ! 521: /* ! 522: * See if the xmit list is invalid. ! 523: */ ! 524: if( addr->qe_csr & QE_XL_INVALID ) { ! 525: buf_addr = (int)(sc->tringaddr+index); ! 526: addr->qe_xmtlist_lo = (short)buf_addr; ! 527: addr->qe_xmtlist_hi = (short)(buf_addr >> 16); ! 528: } ! 529: } ! 530: splx( s ); ! 531: } ! 532: ! 533: /* ! 534: * Ethernet interface interrupt processor ! 535: */ ! 536: qeintr(unit) ! 537: int unit; ! 538: { ! 539: register struct qe_softc *sc = &qe_softc[unit]; ! 540: struct qedevice *addr = (struct qedevice *)qeinfo[unit]->ui_addr; ! 541: int s, buf_addr, csr; ! 542: ! 543: s = splimp(); ! 544: csr = addr->qe_csr; ! 545: addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT | QE_ILOOP; ! 546: if( csr & QE_RCV_INT ) ! 547: qerint( unit ); ! 548: if( csr & QE_XMIT_INT ) ! 549: qetint( unit ); ! 550: if( csr & QE_NEX_MEM_INT ) ! 551: panic("qe: Non existant memory interrupt"); ! 552: ! 553: if( addr->qe_csr & QE_RL_INVALID && sc->rring[sc->rindex].qe_status1 == QE_NOTYET ) { ! 554: buf_addr = (int)&sc->rringaddr[sc->rindex]; ! 555: addr->qe_rcvlist_lo = (short)buf_addr; ! 556: addr->qe_rcvlist_hi = (short)(buf_addr >> 16); ! 557: } ! 558: splx( s ); ! 559: } ! 560: ! 561: /* ! 562: * Ethernet interface transmit interrupt. ! 563: */ ! 564: ! 565: qetint(unit) ! 566: int unit; ! 567: { ! 568: register struct qe_softc *sc = &qe_softc[unit]; ! 569: register struct qe_ring *rp; ! 570: register struct ifxmt *ifxp; ! 571: int status1, setupflag; ! 572: short len; ! 573: ! 574: ! 575: while( sc->otindex != sc->tindex && sc->tring[sc->otindex].qe_status1 != QE_NOTYET && sc->nxmit > 0 ) { ! 576: /* ! 577: * Save the status words from the descriptor so that it can ! 578: * be released. ! 579: */ ! 580: rp = &sc->tring[sc->otindex]; ! 581: status1 = rp->qe_status1; ! 582: setupflag = rp->qe_setup; ! 583: len = (-rp->qe_buf_len) * 2; ! 584: if( rp->qe_odd_end ) ! 585: len++; ! 586: /* ! 587: * Init the buffer descriptor ! 588: */ ! 589: bzero((caddr_t)rp, sizeof(struct qe_ring)); ! 590: if( --sc->nxmit == 0 ) ! 591: sc->timeout = 0; ! 592: if( !setupflag ) { ! 593: /* ! 594: * Do some statistics. ! 595: */ ! 596: sc->is_if.if_opackets++; ! 597: sc->is_if.if_collisions += ( status1 & QE_CCNT ) >> 4; ! 598: if (status1 & QE_ERROR) ! 599: sc->is_if.if_oerrors++; ! 600: /* ! 601: * If this was a broadcast packet loop it ! 602: * back because the hardware can't hear its own ! 603: * transmits. ! 604: */ ! 605: ifxp = &sc->qe_ifw[sc->otindex]; ! 606: if (bcmp((caddr_t)ifxp->ifw_addr, ! 607: (caddr_t)etherbroadcastaddr, ! 608: sizeof(etherbroadcastaddr)) == 0) ! 609: qeread(sc, &ifxp->ifrw, len); ! 610: if (ifxp->ifw_xtofree) { ! 611: m_freem(ifxp->ifw_xtofree); ! 612: ifxp->ifw_xtofree = 0; ! 613: } ! 614: } ! 615: sc->otindex = ++sc->otindex % NXMT; ! 616: } ! 617: qestart( unit ); ! 618: } ! 619: ! 620: /* ! 621: * Ethernet interface receiver interrupt. ! 622: * If can't determine length from type, then have to drop packet. ! 623: * Othewise decapsulate packet based on type and pass to type specific ! 624: * higher-level input routine. ! 625: */ ! 626: qerint(unit) ! 627: int unit; ! 628: { ! 629: register struct qe_softc *sc = &qe_softc[unit]; ! 630: register struct qe_ring *rp; ! 631: int len, status1, status2; ! 632: int bufaddr; ! 633: ! 634: /* ! 635: * Traverse the receive ring looking for packets to pass back. ! 636: * The search is complete when we find a descriptor not in use. ! 637: * ! 638: * As in the transmit case the deqna doesn't honor it's own protocols ! 639: * so there exists the possibility that the device can beat us around ! 640: * the ring. The proper way to guard against this is to insure that ! 641: * there is always at least one invalid descriptor. We chose instead ! 642: * to make the ring large enough to minimize the problem. With a ring ! 643: * size of 4 we haven't been able to see the problem. To be safe we ! 644: * doubled that to 8. ! 645: * ! 646: */ ! 647: for( ; sc->rring[sc->rindex].qe_status1 != QE_NOTYET ; sc->rindex = ++sc->rindex % NRCV ){ ! 648: rp = &sc->rring[sc->rindex]; ! 649: status1 = rp->qe_status1; ! 650: status2 = rp->qe_status2; ! 651: bzero((caddr_t)rp, sizeof(struct qe_ring)); ! 652: if( (status1 & QE_MASK) == QE_MASK ) ! 653: panic("qe: chained packet"); ! 654: len = ((status1 & QE_RBL_HI) | (status2 & QE_RBL_LO)) + 60; ! 655: sc->is_if.if_ipackets++; ! 656: ! 657: if (status1 & QE_ERROR) ! 658: sc->is_if.if_ierrors++; ! 659: else { ! 660: /* ! 661: * We don't process setup packets. ! 662: */ ! 663: if( !(status1 & QE_ESETUP) ) ! 664: qeread(sc, &sc->qe_ifr[sc->rindex], ! 665: len - sizeof(struct ether_header)); ! 666: } ! 667: /* ! 668: * Return the buffer to the ring ! 669: */ ! 670: bufaddr = (int)sc->qe_ifr[sc->rindex].ifrw_info & mask; ! 671: rp->qe_buf_len = -((MAXPACKETSIZE)/2); ! 672: rp->qe_addr_lo = (short)bufaddr; ! 673: rp->qe_addr_hi = (short)((int)bufaddr >> 16); ! 674: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 675: rp->qe_valid = 1; ! 676: } ! 677: } ! 678: /* ! 679: * Ethernet output routine. ! 680: * Encapsulate a packet of type family for the local net. ! 681: * Use trailer local net encapsulation if enough data in first ! 682: * packet leaves a multiple of 512 bytes of data in remainder. ! 683: */ ! 684: qeoutput(ifp, m0, dst) ! 685: struct ifnet *ifp; ! 686: struct mbuf *m0; ! 687: struct sockaddr *dst; ! 688: { ! 689: int type, s, error; ! 690: u_char edst[6]; ! 691: struct in_addr idst; ! 692: register struct qe_softc *is = &qe_softc[ifp->if_unit]; ! 693: register struct mbuf *m = m0; ! 694: register struct ether_header *eh; ! 695: register int off; ! 696: int usetrailers; ! 697: ! 698: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { ! 699: error = ENETDOWN; ! 700: goto bad; ! 701: } ! 702: ! 703: switch (dst->sa_family) { ! 704: ! 705: #ifdef INET ! 706: case AF_INET: ! 707: idst = ((struct sockaddr_in *)dst)->sin_addr; ! 708: if (!arpresolve(&is->is_ac, m, &idst, edst, &usetrailers)) ! 709: return (0); /* if not yet resolved */ ! 710: off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; ! 711: if (usetrailers && off > 0 && (off & 0x1ff) == 0 && ! 712: m->m_off >= MMINOFF + 2 * sizeof (u_short)) { ! 713: type = ETHERTYPE_TRAIL + (off>>9); ! 714: m->m_off -= 2 * sizeof (u_short); ! 715: m->m_len += 2 * sizeof (u_short); ! 716: *mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP); ! 717: *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len); ! 718: goto gottrailertype; ! 719: } ! 720: type = ETHERTYPE_IP; ! 721: off = 0; ! 722: goto gottype; ! 723: #endif ! 724: #ifdef NS ! 725: case AF_NS: ! 726: type = ETHERTYPE_NS; ! 727: bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), ! 728: (caddr_t)edst, sizeof (edst)); ! 729: off = 0; ! 730: goto gottype; ! 731: #endif ! 732: ! 733: ! 734: case AF_UNSPEC: ! 735: eh = (struct ether_header *)dst->sa_data; ! 736: bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); ! 737: type = eh->ether_type; ! 738: goto gottype; ! 739: ! 740: default: ! 741: printf("qe%d: can't handle af%d\n", ifp->if_unit, ! 742: dst->sa_family); ! 743: error = EAFNOSUPPORT; ! 744: goto bad; ! 745: } ! 746: ! 747: gottrailertype: ! 748: /* ! 749: * Packet to be sent as trailer: move first packet ! 750: * (control information) to end of chain. ! 751: */ ! 752: while (m->m_next) ! 753: m = m->m_next; ! 754: m->m_next = m0; ! 755: m = m0->m_next; ! 756: m0->m_next = 0; ! 757: m0 = m; ! 758: ! 759: gottype: ! 760: /* ! 761: * Add local net header. If no space in first mbuf, ! 762: * allocate another. ! 763: */ ! 764: if (m->m_off > MMAXOFF || ! 765: MMINOFF + sizeof (struct ether_header) > m->m_off) { ! 766: m = m_get(M_DONTWAIT, MT_HEADER); ! 767: if (m == 0) { ! 768: error = ENOBUFS; ! 769: goto bad; ! 770: } ! 771: m->m_next = m0; ! 772: m->m_off = MMINOFF; ! 773: m->m_len = sizeof (struct ether_header); ! 774: } else { ! 775: m->m_off -= sizeof (struct ether_header); ! 776: m->m_len += sizeof (struct ether_header); ! 777: } ! 778: eh = mtod(m, struct ether_header *); ! 779: eh->ether_type = htons((u_short)type); ! 780: bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); ! 781: bcopy((caddr_t)is->is_addr, (caddr_t)eh->ether_shost, sizeof (is->is_addr)); ! 782: ! 783: /* ! 784: * Queue message on interface, and start output if interface ! 785: * not yet active. ! 786: */ ! 787: s = splimp(); ! 788: if (IF_QFULL(&ifp->if_snd)) { ! 789: IF_DROP(&ifp->if_snd); ! 790: splx(s); ! 791: m_freem(m); ! 792: return (ENOBUFS); ! 793: } ! 794: IF_ENQUEUE(&ifp->if_snd, m); ! 795: qestart(ifp->if_unit); ! 796: splx(s); ! 797: return (0); ! 798: ! 799: bad: ! 800: m_freem(m0); ! 801: return (error); ! 802: } ! 803: ! 804: ! 805: /* ! 806: * Process an ioctl request. ! 807: */ ! 808: qeioctl(ifp, cmd, data) ! 809: register struct ifnet *ifp; ! 810: int cmd; ! 811: caddr_t data; ! 812: { ! 813: struct qe_softc *sc = &qe_softc[ifp->if_unit]; ! 814: struct ifaddr *ifa = (struct ifaddr *)data; ! 815: int s = splimp(), error = 0; ! 816: ! 817: switch (cmd) { ! 818: ! 819: case SIOCSIFADDR: ! 820: ifp->if_flags |= IFF_UP; ! 821: qeinit(ifp->if_unit); ! 822: switch(ifa->ifa_addr.sa_family) { ! 823: #ifdef INET ! 824: case AF_INET: ! 825: ((struct arpcom *)ifp)->ac_ipaddr = ! 826: IA_SIN(ifa)->sin_addr; ! 827: arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); ! 828: break; ! 829: #endif ! 830: #ifdef NS ! 831: case AF_NS: ! 832: { ! 833: register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); ! 834: ! 835: if (ns_nullhost(*ina)) ! 836: ina->x_host = *(union ns_host *)(sc->is_addr); ! 837: else ! 838: qe_setaddr(ina->x_host.c_host, ifp->if_unit); ! 839: break; ! 840: } ! 841: #endif ! 842: } ! 843: break; ! 844: ! 845: case SIOCSIFFLAGS: ! 846: if ((ifp->if_flags & IFF_UP) == 0 && ! 847: sc->qe_flags & QEF_RUNNING) { ! 848: ((struct qedevice *) ! 849: (qeinfo[ifp->if_unit]->ui_addr))->qe_csr = QE_RESET; ! 850: sc->qe_flags &= ~QEF_RUNNING; ! 851: } else if (ifp->if_flags & IFF_UP && ! 852: (sc->qe_flags & QEF_RUNNING) == 0) ! 853: qerestart(sc); ! 854: break; ! 855: ! 856: default: ! 857: error = EINVAL; ! 858: ! 859: } ! 860: splx(s); ! 861: return (error); ! 862: } ! 863: ! 864: /* ! 865: * set ethernet address for unit ! 866: */ ! 867: qe_setaddr(physaddr, unit) ! 868: u_char *physaddr; ! 869: int unit; ! 870: { ! 871: register struct qe_softc *sc = &qe_softc[unit]; ! 872: register int i; ! 873: ! 874: for (i = 0; i < 6; i++) ! 875: sc->setup_pkt[i][1] = sc->is_addr[i] = physaddr[i]; ! 876: sc->qe_flags |= QEF_SETADDR; ! 877: if (sc->is_if.if_flags & IFF_RUNNING) ! 878: qesetup(sc); ! 879: qeinit(unit); ! 880: } ! 881: ! 882: ! 883: /* ! 884: * Initialize a ring descriptor with mbuf allocation side effects ! 885: */ ! 886: qeinitdesc(rp, addr, len) ! 887: register struct qe_ring *rp; ! 888: caddr_t addr; /* mapped address */ ! 889: int len; ! 890: { ! 891: /* ! 892: * clear the entire descriptor ! 893: */ ! 894: bzero((caddr_t)rp, sizeof(struct qe_ring)); ! 895: ! 896: if( len ) { ! 897: rp->qe_buf_len = -(len/2); ! 898: rp->qe_addr_lo = (short)addr; ! 899: rp->qe_addr_hi = (short)((int)addr >> 16); ! 900: } ! 901: } ! 902: /* ! 903: * Build a setup packet - the physical address will already be present ! 904: * in first column. ! 905: */ ! 906: qesetup( sc ) ! 907: struct qe_softc *sc; ! 908: { ! 909: register i, j; ! 910: ! 911: /* ! 912: * Copy the target address to the rest of the entries in this row. ! 913: */ ! 914: for ( j = 0; j < 6 ; j++ ) ! 915: for ( i = 2 ; i < 8 ; i++ ) ! 916: sc->setup_pkt[j][i] = sc->setup_pkt[j][1]; ! 917: /* ! 918: * Duplicate the first half. ! 919: */ ! 920: bcopy((caddr_t)sc->setup_pkt[0], (caddr_t)sc->setup_pkt[8], 64); ! 921: /* ! 922: * Fill in the broadcast address. ! 923: */ ! 924: for ( i = 0; i < 6 ; i++ ) ! 925: sc->setup_pkt[i][2] = 0xff; ! 926: sc->setupqueued++; ! 927: } ! 928: ! 929: /* ! 930: * Pass a packet to the higher levels. ! 931: * We deal with the trailer protocol here. ! 932: */ ! 933: qeread(sc, ifrw, len) ! 934: register struct qe_softc *sc; ! 935: struct ifrw *ifrw; ! 936: int len; ! 937: { ! 938: struct ether_header *eh; ! 939: struct mbuf *m; ! 940: int off, resid; ! 941: struct ifqueue *inq; ! 942: ! 943: /* ! 944: * Deal with trailer protocol: if type is INET trailer ! 945: * get true type from first 16-bit word past data. ! 946: * Remember that type was trailer by setting off. ! 947: */ ! 948: ! 949: eh = (struct ether_header *)ifrw->ifrw_addr; ! 950: eh->ether_type = ntohs((u_short)eh->ether_type); ! 951: #define qedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) ! 952: if (eh->ether_type >= ETHERTYPE_TRAIL && ! 953: eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { ! 954: off = (eh->ether_type - ETHERTYPE_TRAIL) * 512; ! 955: if (off >= ETHERMTU) ! 956: return; /* sanity */ ! 957: eh->ether_type = ntohs(*qedataaddr(eh,off, u_short *)); ! 958: resid = ntohs(*(qedataaddr(eh, off+2, u_short *))); ! 959: if (off + resid > len) ! 960: return; /* sanity */ ! 961: len = off + resid; ! 962: } else ! 963: off = 0; ! 964: if (len == 0) ! 965: return; ! 966: ! 967: /* ! 968: * Pull packet off interface. Off is nonzero if packet ! 969: * has trailing header; qeget will then force this header ! 970: * information to be at the front, but we still have to drop ! 971: * the type and length which are at the front of any trailer data. ! 972: */ ! 973: m = if_ubaget(&sc->qe_uba, ifrw, len, off, &sc->is_if); ! 974: ! 975: if (m == 0) ! 976: return; ! 977: ! 978: if (off) { ! 979: struct ifnet *ifp; ! 980: ! 981: ifp = *(mtod(m, struct ifnet **)); ! 982: m->m_off += 2 * sizeof (u_short); ! 983: m->m_len -= 2 * sizeof (u_short); ! 984: *(mtod(m, struct ifnet **)) = ifp; ! 985: } ! 986: switch (eh->ether_type) { ! 987: ! 988: #ifdef INET ! 989: case ETHERTYPE_IP: ! 990: schednetisr(NETISR_IP); ! 991: inq = &ipintrq; ! 992: break; ! 993: ! 994: case ETHERTYPE_ARP: ! 995: arpinput(&sc->is_ac, m); ! 996: return; ! 997: #endif ! 998: #ifdef NS ! 999: case ETHERTYPE_NS: ! 1000: schednetisr(NETISR_NS); ! 1001: inq = &nsintrq; ! 1002: break; ! 1003: ! 1004: #endif ! 1005: ! 1006: default: ! 1007: m_freem(m); ! 1008: return; ! 1009: } ! 1010: ! 1011: if (IF_QFULL(inq)) { ! 1012: IF_DROP(inq); ! 1013: m_freem(m); ! 1014: return; ! 1015: } ! 1016: IF_ENQUEUE(inq, m); ! 1017: } ! 1018: ! 1019: /* ! 1020: * Watchdog timer routine. There is a condition in the hardware that ! 1021: * causes the board to lock up under heavy load. This routine detects ! 1022: * the hang up and restarts the device. ! 1023: */ ! 1024: qewatch() ! 1025: { ! 1026: register struct qe_softc *sc; ! 1027: register int i; ! 1028: int inprogress=0; ! 1029: ! 1030: for (i = 0; i < NQE; i++) { ! 1031: sc = &qe_softc[i]; ! 1032: if (sc->timeout) ! 1033: if (++sc->timeout > 3 ) { ! 1034: log(LOG_ERR, ! 1035: "qerestart: restarted qe%d %d\n", ! 1036: i, ++sc->qe_restarts); ! 1037: qerestart(sc); ! 1038: } else ! 1039: inprogress++; ! 1040: } ! 1041: if (inprogress) { ! 1042: timeout(qewatch, (caddr_t)0, QE_TIMEO); ! 1043: qewatchrun++; ! 1044: } else ! 1045: qewatchrun=0; ! 1046: } ! 1047: /* ! 1048: * Restart for board lockup problem. ! 1049: */ ! 1050: qerestart(sc) ! 1051: register struct qe_softc *sc; ! 1052: { ! 1053: register struct ifnet *ifp = &sc->is_if; ! 1054: register struct qedevice *addr = sc->addr; ! 1055: register struct qe_ring *rp; ! 1056: register i; ! 1057: ! 1058: addr->qe_csr = QE_RESET; ! 1059: sc->timeout = 0; ! 1060: qesetup( sc ); ! 1061: for (i = 0, rp = sc->tring; i < NXMT; rp++, i++) { ! 1062: rp->qe_flag = rp->qe_status1 = QE_NOTYET; ! 1063: rp->qe_valid = 0; ! 1064: } ! 1065: sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0; ! 1066: addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | ! 1067: QE_RCV_INT | QE_ILOOP; ! 1068: addr->qe_rcvlist_lo = (short)sc->rringaddr; ! 1069: addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16); ! 1070: sc->qe_flags |= QEF_RUNNING; ! 1071: qestart(ifp->if_unit); ! 1072: } ! 1073: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.