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