Annotation of 43BSD/sys/vaxif/if_qe.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.