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