Annotation of cci/sys/tahoeif/if_enp.c, revision 1.1.1.1

1.1       root        1: #include "enp.h"
                      2: #define ENPBPTE 128
                      3: #if NENP > 0
                      4: 
                      5: /*
                      6:  * Modified 3 Com Ethernet Controller interface
                      7:  * enp modifications added S. F. Holmgren
                      8:  */
                      9: 
                     10: #include "../h/param.h"
                     11: #include "../h/systm.h"
                     12: #include "../h/mbuf.h"
                     13: #include "../h/buf.h"
                     14: #include "../h/protosw.h"
                     15: #include "../h/socket.h"
                     16: #include "../h/vmmac.h"
                     17: #include "../h/errno.h"
                     18: #include "../h/time.h"
                     19: #include "../h/kernel.h"
                     20: #include "../h/uio.h"
                     21: #include "../net/if.h"
                     22: #include "../net/netisr.h"
                     23: #include "../net/route.h"
                     24: #include "../netinet/in.h"
                     25: #include "../h/ioctl.h"
                     26: 
                     27: #include "../netinet/in_systm.h"
                     28: #include "../netinet/ip.h"
                     29: #include "../netinet/ip_var.h"
                     30: #include "../netinet/if_ether.h"
                     31: #include "../netpup/pup.h"
                     32: #include "../vba/vbavar.h"
                     33: #include "../tahoeif/if_enp.h"
                     34: #include "../machine/mtpr.h"
                     35: #include "../tahoeif/if_debug.h"
                     36: 
                     37: #define ENP0_PHYSADDR  0xf40000        /* board # 0 physical base addr */
                     38: #define ENP1_PHYSADDR  0xf60000        /* board # 1 physical base addr */
                     39: #define ENPSTART       0xf02000        /* standard enp start addr      */
                     40: 
                     41: int    enpprobe(), enpattach(), enpintr();
                     42: extern nulldev();
                     43: caddr_t        vtoph();
                     44: struct  mbuf *m_tofree();
                     45: struct  vba_device *enpinfo[ NENP ];
                     46: 
                     47: /*     Maximun 2 controllers per system supported                      */
                     48: 
                     49: long  enpstd[] = { ENP0_PHYSADDR+0x1000,ENP1_PHYSADDR+0x1000, 0 };
                     50: extern char    enp0utl[], enp1utl[];   /* enp accessible ram map       */
                     51: char   *enpmap[]= { enp0utl, enp1utl };
                     52: extern long    ENP0map[], ENP1map[];
                     53: long   *ENPmap[] = {ENP0map, ENP1map};
                     54: long   ENPmapa[] = {0xfff41000, 0xfff61000};
                     55: long   enpismapped[NENP];
                     56: 
                     57: unsigned short intvec[4] = 
                     58:        { 0xc1, 0xc2, 0xc3, 0xc4 };     /* intrvec of upto 4 enps       */
                     59: 
                     60: struct  vba_driver enpdriver = 
                     61: {
                     62: /* use of prom based version 
                     63:        enpprobe, 0, enpattach, 0, 0,   enpintr,
                     64: */
                     65:        enpprobe, 0, nulldev, 0, 
                     66:        enpstd,   "enp", enpinfo, "ENP 20", 0
                     67: };
                     68: 
                     69: int     enpinit(),
                     70:        enpioctl(),
                     71:        enpoutput(),
                     72:        enpreset(),
                     73:        enpbroadcast(),
                     74:        enptimeout();
                     75: 
                     76: int    enpcopy();
                     77: 
                     78: struct  mbuf *enpget();
                     79: 
                     80: extern  struct ifnet loif;
                     81: 
                     82: /*
                     83:  * Ethernet software status per interface.
                     84:  *
                     85:  * Each interface is referenced by a network interface structure,
                     86:  * es_if, which the routing code uses to locate the interface.
                     87:  * This structure contains the output queue for the interface, its address, ...
                     88:  */
                     89: 
                     90: struct         enp_softc       enp_softc[NENP];
                     91: long   stat_addr[NENP];        /* enp statistic addr (for nstat use) */
                     92: long   ring_addr[NENP];        /* enp dev ring addresses (for nstat use) */
                     93: int    numenp = NENP;
                     94: int    enp_intr = 0,           /* no. of enp_to_host interrupts */
                     95:        host_intr = 0;          /* no. of host_to_enp interrupts */
                     96: short  enpram[NENP];           /* open/close flags for enp devices */
                     97: /*     Debugging tools, used to trace input packets */
                     98: extern         int     printerror;     /* error print flag, from if_ace.c */
                     99: int    save_enp_inpkt = 0;
                    100: #define        ENPTRACE(X)     if (save_enp_inpkt) X;
                    101: 
                    102: struct         inp_err         enperr[NENP];
                    103: 
                    104: /*
                    105:  * Probe for device.
                    106:  */
                    107: 
                    108: enpprobe(reg)
                    109: caddr_t reg;
                    110: {
                    111:        static  int     unit=0;
                    112:        register ENPDEVICE      *addr = (ENPDEVICE *)reg;
                    113: 
                    114:        if( (badaddr( addr, 2 ) ) || (badaddr( &addr->enp_ram[0], 2 ) ) )
                    115:                return( 0 );
                    116:        addr->enp_state = S_ENPRESET; /* controller is reset by vbus reset */
                    117:        /* save address of statistic area for nstat uses        */
                    118: 
                    119:        stat_addr[unit] = (long) &(addr->enp_stat); 
                    120:        ring_addr[unit++] = (long) &(addr->enp_toenp); 
                    121: 
                    122:        return( ENPSIZE );
                    123: }
                    124: 
                    125: /*
                    126:  * Interface exists: make available by filling in network interface
                    127:  * record.  System will initialize the interface when it is ready
                    128:  * to accept packets. 
                    129:  */
                    130: 
                    131: enpattach( md )
                    132: register struct vba_device *md;
                    133: {
                    134:        struct enp_softc        *es = &enp_softc[md->ui_unit];
                    135:        register struct ifnet   *ifp = &es->es_if;
                    136:        register ENPDEVICE      *addr = (ENPDEVICE *)md->ui_addr;
                    137:        struct sockaddr_in      *sin;
                    138: 
                    139:        enpgetaddr( md->ui_unit );
                    140: 
                    141:        ifp->if_unit = md->ui_unit;
                    142:        ifp->if_name = "enp";
                    143:        ifp->if_mtu = ETHERMTU;
                    144: 
                    145: /*     bcopy(&es->es_boardaddr, es->es_enaddr, sizeof(es->es_enaddr)); */
                    146: 
                    147:        sin = (struct sockaddr_in *)&es->es_if.if_addr;
                    148:        sin->sin_family = AF_INET;
                    149: 
                    150:        ifp->if_init = enpinit;
                    151:        ifp->if_ioctl = enpioctl;
                    152:        ifp->if_output = enpoutput;
                    153:        ifp->if_reset = enpreset;
                    154:        if_attach(ifp);
                    155: }
                    156: 
                    157: 
                    158: /*
                    159:  * Reset of interface after UNIBUS reset.
                    160:  */
                    161: enpreset(unit)
                    162: int unit;
                    163: {
                    164:        register struct vba_device *md;
                    165: 
                    166:        if (unit >= NENP || (md = enpinfo[unit]) == 0 || md->ui_alive == 0)
                    167:                return(ENODEV);
                    168: 
                    169:        enpinit(unit);
                    170: }
                    171: 
                    172: /*
                    173:  * Initialization of interface; clear recorded pending
                    174:  * operations.
                    175:  */
                    176: 
                    177: enpinit( unit )
                    178: int unit;
                    179: {
                    180:        struct enp_softc        *es = &enp_softc[unit];
                    181:        ENPDEVICE               *addr;
                    182:        int i, s;
                    183:        u_char *cp, *ap;
                    184:        register struct ifnet   *ifp = &es->es_if;
                    185:        register struct sockaddr_in *sin, *sinb;
                    186: 
                    187:        sin = (struct sockaddr_in *)&ifp->if_addr;
                    188: 
                    189:        if ( !enpismapped[unit] ) {
                    190:                ioaccess(ENPmap[unit],ENPmapa[unit],ENPBPTE);
                    191:                ++enpismapped[unit];
                    192:        }
                    193:        if ((addr = (ENPDEVICE *)enpinfo[unit]->ui_addr) == (ENPDEVICE *)0)
                    194:                return(ENODEV);
                    195:        s = splimp();
                    196:        RESET_ENP( addr );
                    197:        DELAY( 200000 );
                    198: 
                    199: #ifdef notdef
                    200: /* only needed if not downloading ( ie, ROM-resident ENP code) */
                    201:        addr->enp_intrvec = intvec[unit];
                    202:        ENP_GO( addr,ENPSTART );
                    203:        DELAY( 200000 );
                    204: /* end of ROM-resident */
                    205: #endif notdef
                    206: 
                    207:        es->es_if.if_flags |= IFF_UP|IFF_RUNNING; /* open for business*/
                    208:        splx(s);
                    209: 
                    210:        if_rtinit( &es->es_if,RTF_UP );
                    211:        arpwhohas(&es->es_ac, &sin->sin_addr);
                    212: }
                    213: 
                    214: 
                    215: /*
                    216:  * Ethernet interface interrupt.
                    217:  */
                    218: 
                    219: enpintr( unit )
                    220: {
                    221:        register ENPDEVICE              *addr;
                    222:        register BCB                    *bcbp;
                    223:        register struct vba_device       *md;
                    224: 
                    225:        enp_intr++;
                    226: 
                    227:        if (unit >= NENP || (md = enpinfo[unit]) == 0)
                    228:                return;
                    229: 
                    230:        addr = (ENPDEVICE *)md->ui_addr;
                    231: 
                    232:        if( IS_ENP_INTR(addr) == 0 )
                    233:                return;
                    234: 
                    235:        ACK_ENP_INTR( addr );
                    236: 
                    237:        while( (bcbp = (BCB *)ringget( &addr->enp_tohost )) != 0 )
                    238:        {
                    239:                enpread( &enp_softc[ unit ],bcbp, unit );
                    240:                ringput( &addr->enp_enpfree,bcbp ); 
                    241:        }
                    242:        return(0);
                    243: }
                    244: 
                    245: #define        MAXBLEN 1500
                    246: char   errpkt[MAXBLEN];
                    247: int    bufptr = 0;
                    248: int    maxl_tosave = 200;              /* save only the first 200 bytes */
                    249: 
                    250: saverrpkt(errbuf, errtype, len)
                    251: register u_char *errbuf;
                    252: int errtype, len;
                    253: {
                    254:        int remain, newptr;
                    255: 
                    256:        remain = MAXBLEN - bufptr;
                    257:        if (remain < 50)                /* if too small                 */
                    258:                return;                 /* no space avail               */
                    259:        len = (len > maxl_tosave || len <= 0) ? maxl_tosave : len;
                    260:        len = len > remain ? (remain - 2*sizeof(len)): len;
                    261:        newptr = bufptr + len + 2*sizeof(len);
                    262:        if (newptr <= MAXBLEN) {
                    263:                enpcopy((char *)&len, &errpkt[bufptr], sizeof(len));
                    264:                enpcopy((char *)&errtype, &errpkt[bufptr+sizeof(len)],
                    265:                        sizeof(errtype));
                    266:                enpcopy(errbuf, &errpkt[bufptr+(2*sizeof(len))], len);
                    267:        }
                    268:        bufptr = newptr;
                    269: }
                    270: 
                    271: /*
                    272:  * Read input packet, examine its packet type, and enqueue it.
                    273:  */
                    274: 
                    275: enpread( es, bcbp, unit )
                    276: struct enp_softc *es;
                    277: register BCB *bcbp;
                    278: int    unit;
                    279: {
                    280:        register struct ether_header *enp;
                    281:        struct mbuf *m;
                    282:        long int  s, v;
                    283:        register short *vp = (short *)&v,
                    284:                        *sp;
                    285:        int len, off, resid, enptype;
                    286:        register struct ifqueue *inq;
                    287: 
                    288:        es->es_if.if_ipackets++; 
                    289: 
                    290:        /*
                    291:         * Get input data length.
                    292:         * Get pointer to ethernet header (in input buffer).
                    293:         * Deal with trailer protocol: if type is PUP trailer
                    294:         * get true type from first 16-bit word past data.
                    295:         * Remember that type was trailer by setting off.
                    296:         */
                    297: 
                    298:        len = bcbp->b_msglen - SIZEOF_ETHEADER;
                    299: #ifdef TAHOE
                    300:        sp = (short *)&bcbp->b_addr;
                    301:        *vp = *sp; vp[1] = sp[1];
                    302:        enp = (struct ether_header *) v;
                    303: #else
                    304:        enp = (struct ether_header *)bcbp->b_addr;
                    305: #endif TAHOE
                    306: 
                    307: #define enpdataaddr(enp, off, type) ((type)(((caddr_t)(((char *)enp)+SIZEOF_ETHEADER)+(off))))
                    308: 
                    309:        enptype = enp->ether_type;
                    310:        if (enptype >= ETHERPUP_TRAIL && enptype < ETHERPUP_TRAIL+ETHERPUP_NTRAILER) 
                    311:        {
                    312:                off = (enptype - ETHERPUP_TRAIL) * 512;
                    313:                if (off >= ETHERMTU) {
                    314:                        enperr[unit].bad_offset++;
                    315:                        ENPTRACE(saverrpkt((char *)enp, B_OFFSET, bcbp->b_msglen)); 
                    316: 
                    317:                        goto badinput;
                    318:                }
                    319:                enptype = *enpdataaddr(enp, off, u_short *);
                    320:                resid = *(enpdataaddr(enp, off+2, u_short *));
                    321: 
                    322:                if (off + resid > len) {
                    323:                        enperr[unit].bad_length++;
                    324:                        ENPTRACE(saverrpkt((char *)enp, B_LENGTH, bcbp->b_msglen)); 
                    325:                        goto badinput;
                    326:                }
                    327:                len = off + resid;
                    328:        } 
                    329:        else
                    330:                off = 0;
                    331: 
                    332:        if( len == 0 ) {
                    333:                enperr[unit].bad_length++;
                    334:                ENPTRACE(saverrpkt((char *)enp, B_LENGTH, bcbp->b_msglen)); 
                    335:                goto badinput;
                    336:        }
                    337:        /*
                    338:         * Pull packet off interface.  Off is nonzero if packet
                    339:         * has trailing header; enpget will then force this header
                    340:         * information to be at the front, but we still have to drop
                    341:         * the type and length which are at the front of any trailer data.
                    342:         */
                    343: 
                    344:        m = enpget(bcbp, len, off);
                    345:        if( m == 0 )  {
                    346:                enperr[unit].h_nobuffer++; /* host runs out of buf */
                    347:                goto badinput;
                    348:        }
                    349:        if( off )
                    350:        {
                    351:                m->m_off += 2 * sizeof (u_short);
                    352:                m->m_len -= 2 * sizeof (u_short);
                    353:        }
                    354: 
                    355:        switch (enptype) 
                    356:        {
                    357: #ifdef INET
                    358:        case ETHERPUP_IPTYPE:
                    359: #ifdef notdef
                    360:                arpipin(enp, m);
                    361: #endif notdef
                    362:                schednetisr(NETISR_IP);
                    363:                inq = &ipintrq;
                    364:                break;
                    365: 
                    366:        case ETHERPUP_ARPTYPE:
                    367:                arpinput(&es->es_ac, m);
                    368:                return(0);
                    369: #endif
                    370:        default:        /* unrecognized ethernet header */
                    371:                enperr[unit].bad_packetype++;
                    372:                if (printerror) { 
                    373:                        printf("\nenp%d: Undefined packet type 0x%x ", unit,
                    374:                                enp->ether_type);
                    375:                        printf("from host: %x.%x.%x.%x.%x.%x\n", 
                    376:                                enp->ether_shost[0], enp->ether_shost[1], 
                    377:                                enp->ether_shost[2], enp->ether_shost[3],
                    378:                                enp->ether_shost[4], enp->ether_shost[5]);
                    379:                }       /* end debugging aid    */
                    380:                ENPTRACE(saverrpkt((char *)enp, B_PACKETYPE, bcbp->b_msglen)); 
                    381:                m_freem(m);
                    382:                goto badinput;
                    383:        }
                    384: 
                    385:        if (IF_QFULL(inq)) 
                    386:        {
                    387:                enperr[unit].inq_full++;
                    388:                IF_DROP(inq);
                    389:                m_freem(m);
                    390:                return(0);
                    391:        }
                    392:        s = splimp();
                    393:        IF_ENQUEUE(inq, m);
                    394:        splx(s);
                    395: badinput:
                    396:        return(0);         /* sanity */
                    397: }
                    398: 
                    399: /*
                    400:  * Ethernet output routine. (called by user)
                    401:  * Encapsulate a packet of type family for the local net.
                    402:  * Use trailer local net encapsulation if enough data in first
                    403:  * packet leaves a multiple of 512 bytes of data in remainder.
                    404:  * If destination is this address or broadcast, send packet to
                    405:  * loop device to kludge around the fact that 3com interfaces can't
                    406:  * talk to themselves.
                    407:  */
                    408: 
                    409: enpoutput(ifp, m0, dst)
                    410: struct ifnet *ifp;
                    411: struct mbuf *m0;
                    412: struct sockaddr *dst;
                    413: {
                    414:        int type, s, error;
                    415:        struct ether_addr edst;
                    416:        struct in_addr idst;
                    417: 
                    418:        register struct enp_softc *es = &enp_softc[ifp->if_unit];
                    419:        register struct mbuf *m = m0;
                    420:        register struct ether_header *enp;
                    421:        register int off, i;
                    422: 
                    423:        struct mbuf *mcopy = (struct mbuf *) 0;         /* Null */
                    424:        int unit = ifp->if_unit;
                    425: 
                    426:        switch( dst->sa_family )
                    427:        {
                    428: #ifdef INET
                    429:        case AF_INET:
                    430:                idst = ((struct sockaddr_in *)dst)->sin_addr;
                    431: 
                    432:                /* translate internet to ethernet address */
                    433: 
                    434:                switch(arpresolve(&es->es_ac, m, &idst, &edst)) {
                    435: 
                    436:                        case ARPRESOLVE_WILLSEND:
                    437:                                return (0);     /* if not yet resolved */
                    438:                        case ARPRESOLVE_BROADCAST:
                    439:                                mcopy = m_copy(m, 0, (int)M_COPYALL);
                    440:                                if (mcopy)
                    441:                                        looutput(&loif, mcopy, dst);
                    442: 
                    443:                                /* falls through ... */
                    444:                        case ARPRESOLVE_OK:
                    445:                                break;
                    446:                }
                    447:                off = ((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                    448:                if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
                    449:                        if (off > 0 && (off & 0x1ff) == 0 &&
                    450:                            m->m_off >= MMINOFF + 2 * sizeof (u_short)) 
                    451:                        {
                    452:                                type = ETHERPUP_TRAIL + (off>>9);
                    453:                                m->m_off -= 2 * sizeof (u_short);
                    454:                                m->m_len += 2 * sizeof (u_short);
                    455:                                *mtod(m, u_short *) = ETHERPUP_IPTYPE;
                    456:                                *(mtod(m, u_short *) + 1) = m->m_len;
                    457:                                goto gottrailertype;
                    458:                        }
                    459: 
                    460:                type = ETHERPUP_IPTYPE;
                    461:                off = 0;
                    462:                goto gottype;
                    463: #endif
                    464: 
                    465: #ifdef notdef
                    466:        case AF_RAW:
                    467:                enp = mtod(m, struct ether_header *);
                    468:                if (m->m_len < sizeof *enp) 
                    469:                {
                    470:                        error = EMSGSIZE;
                    471:                        goto bad;
                    472:                }
                    473:                goto gotheader;
                    474: #endif
                    475: 
                    476:        case AF_UNSPEC:
                    477:                enp = (struct ether_header *)dst->sa_data;
                    478:                bcopy( enp->ether_dhost, &edst, sizeof(edst));
                    479:                type = enp->ether_type;
                    480:                goto gottype;
                    481: 
                    482:        default:
                    483:                if (printerror)
                    484:                    printf("enp%d: can't handle af%d\n", unit,dst->sa_family);
                    485:                error = EAFNOSUPPORT;
                    486:                goto bad;
                    487:        }
                    488: 
                    489: gottrailertype:
                    490:        /*
                    491:         * Packet to be sent as trailer: move first packet
                    492:         * (control information) to end of chain.
                    493:         */
                    494:        while (m->m_next)
                    495:                m = m->m_next;
                    496:        m->m_next = m0;
                    497:        m = m0->m_next;
                    498:        m0->m_next = 0;
                    499:        m0 = m;
                    500: 
                    501: gottype:
                    502:        /*
                    503:          * Add local net header.  If no space in first mbuf,
                    504:          * allocate another.
                    505:          */
                    506:        if (m->m_off > MMAXOFF ||
                    507:            MMINOFF + SIZEOF_ETHEADER > m->m_off) 
                    508:        {
                    509:                m = m_get(M_DONTWAIT, MT_HEADER);
                    510:                if (m == 0) 
                    511:                {
                    512:                        enperr[unit].h_nobuffer++; /* host runs out of buf */
                    513:                        error = ENOBUFS;
                    514:                        goto bad;
                    515:                }
                    516:                m->m_next = m0;
                    517:                m->m_off = MMINOFF;
                    518:                m->m_len = SIZEOF_ETHEADER;
                    519:        } 
                    520:        else
                    521:        {
                    522:                m->m_off -= SIZEOF_ETHEADER;
                    523:                m->m_len += SIZEOF_ETHEADER;
                    524:        }
                    525:        enp = mtod(m, struct ether_header *);
                    526:        bcopy( &edst, enp->ether_dhost, sizeof(enp->ether_dhost) );
                    527:        enp->ether_type = type;
                    528: gotheader:
                    529:        bcopy( es->es_enaddr, enp->ether_shost, sizeof(enp->ether_shost));
                    530: 
                    531:        /*
                    532:         * Queue message on interface if possible 
                    533:         */
                    534: 
                    535:        s = splimp();   
                    536:        if( enpput( unit,m ) )
                    537:        {
                    538:                error = ENOBUFS;
                    539:                enperr[unit].c_nobuffer++; /* controller runs out of buf */
                    540:                goto qfull;
                    541:        }
                    542:        splx( s );      
                    543:        es->es_if.if_opackets++; 
                    544:        return(0);
                    545: qfull:
                    546:        splx( s );      
                    547:        m0 = m;
                    548: bad:
                    549:        m_freem(m0);
                    550:        return(error);
                    551: }
                    552: 
                    553: /*
                    554:  * Routine to copy from mbuf chain to transmitter
                    555:  * buffer in Multibus memory.
                    556:  */
                    557: 
                    558: enpput( unit,m )
                    559: int unit;
                    560: struct mbuf *m;
                    561: {
                    562:        register BCB *bcbp;
                    563:        register ENPDEVICE *addr;
                    564:        register struct mbuf *mp;
                    565:        register u_char *bp;
                    566:        int      ctr = 0;
                    567:        long int        v;
                    568:        register short *vp = (short *)&v,
                    569:                        *sp;
                    570: 
                    571:        addr = (ENPDEVICE *)enpinfo[ unit ]->ui_addr;
                    572: 
                    573:        if ( ringempty( &addr->enp_hostfree ) ) 
                    574:                        return( 1 );    
                    575: 
                    576:        bcbp = (BCB *)ringget( &addr->enp_hostfree );
                    577:        bcbp->b_len = 0;
                    578: #ifdef TAHOE
                    579:        sp = (short *)&bcbp->b_addr;
                    580:        *vp = *sp; vp[1] = sp[1];
                    581:        bp = (u_char *)v;
                    582: #else
                    583:        bp = (u_char *)bcbp->b_addr;
                    584: #endif TAHOE
                    585:        for (mp = m; mp; mp = mp->m_next) 
                    586:        {
                    587:                register unsigned len;
                    588:                u_char *mcp;
                    589: 
                    590:                len = mp->m_len;
                    591:                if( len == 0 )
                    592:                        continue;
                    593:                mcp = mtod( mp,u_char * );
                    594:                enpcopy( mcp,bp,len );
                    595:                bp += len;
                    596:                bcbp->b_len += len;
                    597:        }
                    598:        bcbp->b_len = max( MINPKTSIZE,bcbp->b_len );
                    599:        bcbp->b_reserved = 0;
                    600:        if ( ringput( &addr->enp_toenp,bcbp ) == 1 ) {
                    601:                host_intr++;
                    602:                INTR_ENP( addr );
                    603:        }
                    604:        m_freem(m);
                    605:        return( 0 );
                    606: }
                    607: 
                    608: /*
                    609:  * Routine to copy from Multibus memory into mbufs.
                    610:  *
                    611:  * Warning: This makes the fairly safe assumption that
                    612:  * mbufs have even lengths.
                    613:  */
                    614: struct mbuf *
                    615: enpget( bcbp, totlen, off0 )
                    616: register BCB *bcbp;
                    617: int totlen, off0;
                    618: {
                    619:        register struct mbuf *m;
                    620:        register int off = off0;
                    621:        register unsigned char *cp;
                    622:        long int        v;
                    623:        register short *vp = (short *)&v,
                    624:                        *sp;
                    625: 
                    626:        int len;
                    627:        struct mbuf *top = 0;
                    628:        struct mbuf **mp = &top;
                    629: 
                    630: #ifdef TAHOE
                    631:        sp = (short *)&bcbp->b_addr;
                    632:        *vp = *sp; vp[1] = sp[1];
                    633:        cp = (unsigned char *)v + SIZEOF_ETHEADER;
                    634: #else
                    635:        cp = (unsigned char *)bcbp->b_addr + SIZEOF_ETHEADER;
                    636: #endif TAHOE
                    637: 
                    638:        while( totlen > 0 )
                    639:        {
                    640:                u_char *mcp;
                    641: 
                    642:                MGET(m, M_DONTWAIT, MT_DATA);
                    643:                if (m == 0) 
                    644:                        goto bad;
                    645:                if( off )
                    646:                {
                    647:                        len = totlen - off;
                    648: #ifdef TAHOE
                    649:                        sp = (short *)&bcbp->b_addr;
                    650:                        *vp = *sp; vp[1] = sp[1];
                    651:                        cp = (unsigned char *)v + SIZEOF_ETHEADER
                    652:                                + off;
                    653: #else
                    654:                        cp = (unsigned char *)bcbp->b_addr + 
                    655:                                SIZEOF_ETHEADER + off;
                    656: #endif TAHOE
                    657:                } 
                    658:                else
                    659:                        len = totlen;
                    660: 
                    661: 
                    662:                if (len >= CLBYTES) {
                    663:                        struct mbuf *p;
                    664: 
                    665:                        MCLGET(p, 1);
                    666:                        if (p != 0) {
                    667:                                m->m_len = len = CLBYTES;
                    668:                                m->m_off = (int)p - (int)m;
                    669:                        } else  {
                    670:                                m->m_len = len = MIN(MLEN, len);
                    671:                                m->m_off = MMINOFF;
                    672:                                }
                    673:                } else  { 
                    674:                        m->m_len = len = MIN(MLEN, len);
                    675:                        m->m_off = MMINOFF;
                    676:                }
                    677: 
                    678:                mcp = mtod(m, u_char *);
                    679:                enpcopy(cp, mcp, len);
                    680:                cp += len;
                    681:                *mp = m;
                    682:                mp = &m->m_next;
                    683:                if (off == 0) 
                    684:                {
                    685:                        totlen -= len;
                    686:                        continue;
                    687:                }
                    688:                off += len;
                    689:                if (off == totlen) 
                    690:                {
                    691: #ifdef TAHOE
                    692:                        sp = (short *)&bcbp->b_addr;
                    693:                        *vp = *sp; vp[1] = sp[1];
                    694:                        cp = (unsigned char *)v + SIZEOF_ETHEADER;
                    695: #else
                    696:                        cp = (unsigned char *)bcbp->b_addr + SIZEOF_ETHEADER;
                    697: #endif TAHOE
                    698:                        off = 0;
                    699:                        totlen = off0;
                    700:                }
                    701:        }
                    702:        return (top);
                    703: bad:
                    704:        m_freem(top);
                    705:        return (0);
                    706: }
                    707: 
                    708: /*
                    709:  * Process an ioctl request.
                    710:  *    this can be called via the "socket" route for SIOCSIFADDR or
                    711:  *     by the cdev/inode route for SIOCSIFCCFWR/RD
                    712:  *
                    713:  */
                    714: 
                    715: enpioctl(ifp, cmd, data)
                    716: register struct ifnet *ifp;
                    717: int cmd;
                    718: caddr_t data;
                    719: {
                    720:        register int    unit = ifp->if_unit;
                    721:        register struct vba_device *md;
                    722:        int s, error = 0;
                    723:        struct sockaddr_in      *sin;
                    724:        struct sockaddr         *sa;
                    725:        struct enp_softc        *es = &enp_softc[ifp->if_unit];
                    726:        ENPDEVICE               *addr;
                    727:        struct config_entry     *cf;
                    728:        struct ifreq *ifr       = (struct ifreq *)data;
                    729:        struct sockaddr_in      *et_addr;
                    730:        int code, i;
                    731: 
                    732: 
                    733:        if (unit >= NENP || (md = enpinfo[unit]) == 0 || md->ui_alive == 0)
                    734:                return(ENODEV);
                    735: 
                    736:        switch (cmd) {
                    737: 
                    738:        case SIOCSIFADDR:
                    739:                s = splimp();
                    740:                sa = (struct sockaddr *)&ifr->ifr_addr;
                    741:                if (sa->sa_family == AF_UNSPEC ) {
                    742:                        if (sa->sa_data[0] & 1){ /*broad or multi-cast*/
                    743:                                splx( s );
                    744:                                return( EINVAL );
                    745:                        }
                    746:                        bcopy(sa->sa_data,es->es_enaddr,sizeof(es->es_enaddr));
                    747:                        enpinit( ifp->if_unit);
                    748:                        break;
                    749:                }
                    750:                sin = (struct sockaddr_in *)&ifr->ifr_addr;
                    751:                if (sin->sin_family != AF_INET){
                    752:                        splx( s );
                    753:                        return( EINVAL );
                    754:                }
                    755:                if (ifp->if_flags & IFF_RUNNING)
                    756:                        if_rtinit(ifp, -1);     /* delete previous route */
                    757:                enpsetaddr(ifp, sin);
                    758:                enpinit(ifp->if_unit);
                    759:                enpgetaddr( ifp->if_unit );
                    760:                splx(s);
                    761:                break;
                    762: 
                    763: 
                    764:        case SIOCSETETADDR:     /* Set Ethernet station address */
                    765:                s = splimp();
                    766:                ifp->if_flags &= (~IFF_RUNNING | IFF_UP);
                    767:                et_addr = (struct sockaddr_in *)&ifr->ifr_addr;
                    768:                addr = (ENPDEVICE *)enpinfo[ifp->if_unit]->ui_addr;
                    769: 
                    770:                /* Set station address and reset controller board */
                    771:                {
                    772:                u_char  *to = &addr->enp_addr.e_baseaddr.ea_addr[0];
                    773:                char    *from = &et_addr->sin_zero[2];
                    774:                int     i;
                    775: 
                    776:                for (i = 0 ; i < ETHADDR_SIZE; i++) 
                    777:                        *to++ = (u_char) (~(*from++ & 0xff));
                    778:                }
                    779:                enpcopy(&addr->enp_addr.e_listsize, &code, sizeof(code)); 
                    780:                code |= E_ADDR_SUPP;
                    781:                enpcopy(&code, &addr->enp_addr.e_listsize, sizeof(code)); 
                    782:                enpreset(ifp->if_unit);         /* Re-initialize */
                    783:                enpgetaddr(ifp->if_unit);
                    784:                splx(s);
                    785:                break;
                    786: 
                    787:        case SIOCGETETADDR:     /* Get Foreign Hosts' Ethernet addresses */
                    788:                arpwhohas(&es->es_ac, (struct in_addr *)ifr->ifr_data);
                    789:                break;
                    790: 
                    791:        default:
                    792:                error = EINVAL;
                    793:        }
                    794:        return(error);
                    795: }
                    796: 
                    797: enpsetaddr(ifp, sin)
                    798: register struct ifnet *ifp;
                    799: register struct sockaddr_in *sin;
                    800: {
                    801: 
                    802:        ifp->if_addr = *(struct sockaddr *)sin;
                    803:        ifp->if_net = in_netof(sin->sin_addr);
                    804:        ifp->if_host[0] = in_lnaof(sin->sin_addr);
                    805:        sin = (struct sockaddr_in *)&ifp->if_broadaddr;
                    806:        sin->sin_family = AF_INET;
                    807:        sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY);
                    808:        ifp->if_flags |= IFF_BROADCAST;
                    809: }
                    810: 
                    811: 
                    812: /*
                    813:  * Get the ethernet addr, store it and print it
                    814:  * Read the ethernet address off the board, one byte at a time.
                    815:  *     put it in enp_softc
                    816:  */
                    817: 
                    818: 
                    819: enpgetaddr( unit )
                    820: int unit;
                    821: {
                    822:        register struct enp_softc       *es = &enp_softc[unit];
                    823:        register ENPDEVICE *addr =(ENPDEVICE *)enpinfo[unit]->ui_addr;
                    824:        int i;
                    825:        
                    826: #ifdef TAHOE
                    827:        enpcopy(&addr->enp_addr.e_baseaddr, &es->es_boardaddr, sizeof(es->es_boardaddr));
                    828: #else
                    829:        es->es_boardaddr = addr->enp_addr.e_baseaddr;
                    830: #endif TAHOE
                    831:        bcopy(&es->es_boardaddr, es->es_enaddr, ETHADDR_SIZE);
                    832:        return( 1 );
                    833: }
                    834: 
                    835: /*
                    836:  * enpram device
                    837:  *
                    838:  */
                    839: 
                    840: enpr_open( dev )
                    841: {
                    842:        register int    unit = minor(dev);
                    843:        register struct vba_device *md;
                    844:        register ENPDEVICE      *addr;
                    845: 
                    846:        if (unit >= NENP || (md = enpinfo[unit]) == 0 || md->ui_alive == 0 ||
                    847:            (addr = (ENPDEVICE *)md->ui_addr) == (ENPDEVICE *)0)
                    848:                return(ENODEV);
                    849:        if (addr->enp_state != S_ENPRESET)
                    850:                return(EACCES);  /* enp is not in reset state, don't open  */
                    851:        if ( !enpismapped[unit] ) {
                    852:                ioaccess(ENPmap[unit],ENPmapa[unit],ENPBPTE);
                    853:                ++enpismapped[unit];
                    854:        }
                    855:        enpram[unit] = ENP_OPEN;
                    856:        return( 0 );
                    857: }
                    858: 
                    859: enpr_close(dev)
                    860: {
                    861:        enpram[minor(dev)] = ENP_CLOSE;
                    862:        return( 0 );
                    863: }
                    864: 
                    865: enpr_read( dev,uio )
                    866: int dev;
                    867: register struct uio *uio;
                    868: {
                    869:        register ENPDEVICE *addr;
                    870:        register struct iovec *iov;
                    871:        register r=0;
                    872: 
                    873:        if (enpram[minor(dev)] != ENP_OPEN)
                    874:                return(EACCES);
                    875:        if ( uio->uio_offset > RAM_SIZE )
                    876:                return( ENODEV );
                    877:        if ( uio->uio_offset + iov->iov_len > RAM_SIZE )
                    878:                iov->iov_len = RAM_SIZE - uio->uio_offset;
                    879:        addr = (ENPDEVICE *)enpinfo[ minor( dev ) ]->ui_addr;
                    880:        iov  = uio->uio_iov;
                    881: 
                    882:        if( r = enpcopyout( &addr->enp_ram[ uio->uio_offset ], iov->iov_base,
                    883:                         iov->iov_len ) )
                    884:                 return( r );
                    885: 
                    886:        uio->uio_resid -= iov->iov_len;
                    887:        iov->iov_len = 0;
                    888: 
                    889:        return( 0 );
                    890: }
                    891: 
                    892: enpr_write( dev,uio )
                    893: int dev;
                    894: register struct uio *uio;
                    895: {
                    896:        register ENPDEVICE *addr;
                    897:        register struct iovec *iov;
                    898:        register r=0;
                    899: 
                    900:        if (enpram[minor(dev)] != ENP_OPEN)
                    901:                return(EACCES);
                    902:        addr = (ENPDEVICE *)enpinfo[ minor( dev ) ]->ui_addr;
                    903:        iov  = uio->uio_iov;
                    904: 
                    905:        if ( uio->uio_offset > RAM_SIZE )
                    906:                return( ENODEV );
                    907:        if ( uio->uio_offset + iov->iov_len > RAM_SIZE )
                    908:                iov->iov_len = RAM_SIZE - uio->uio_offset;
                    909:        if( r = enpcopyin( iov->iov_base, &addr->enp_ram[ uio->uio_offset ],
                    910:                        iov->iov_len ) )
                    911:                return( r );
                    912: 
                    913:        uio->uio_resid -= iov->iov_len;
                    914:        iov->iov_len = 0;
                    915: 
                    916:        return( 0 );
                    917: }
                    918: 
                    919: enpr_ioctl( dev,cmd,arg,fflag )
                    920: dev_t dev;
                    921: caddr_t *arg;
                    922: {
                    923:        register ENPDEVICE *addr;
                    924:        long int        v;
                    925:        register short  *vp = (short *)&v, *sp;
                    926:        register unit = minor(dev);
                    927:        register struct vba_device *md;
                    928: 
                    929:        if (unit >= NENP || (md = enpinfo[unit]) == 0 || md->ui_alive == 0 ||
                    930:            (addr = (ENPDEVICE *)md->ui_addr) == (ENPDEVICE *)0)
                    931:                return(ENODEV);
                    932:        switch( cmd )
                    933:        {
                    934:                case ENPIOGO:
                    935: /* not needed if prom based version */
                    936: #ifdef TAHOE
                    937:                        sp = (short *)&addr->enp_base;
                    938:                        v = (int)addr;
                    939:                        *sp = *vp; sp[1] = vp[1];
                    940: #else
                    941:                        addr->enp_base = (int)addr;
                    942: #endif TAHOE
                    943:                        addr->enp_intrvec = intvec[ unit ];
                    944:                        ENP_GO( addr, ENPSTART );
                    945:                        DELAY( 200000 );
                    946:                        enpattach( enpinfo[ unit ] );
                    947:                        enpinit( unit );
                    948:                        addr->enp_state = S_ENPRUN;  /* it is running now */
                    949: /* end of not needed */
                    950: 
                    951:                        break;
                    952: 
                    953:                case ENPIORESET:
                    954:                        RESET_ENP( addr );
                    955:                        addr->enp_state = S_ENPRESET;  /* it is reset now */
                    956:                        DELAY( 100000 );
                    957:                        break;
                    958:        }
                    959:        return( 0 );
                    960: }
                    961: 
                    962: /* 
                    963:  * routines to synchronize enp and host 
                    964:  */
                    965: 
                    966: static
                    967: ringinit( rp,size )
                    968: register RING *rp;
                    969: {
                    970:        register int    i;
                    971:        register short *sp; 
                    972: 
                    973:        rp->r_rdidx = rp->r_wrtidx = 0;
                    974:        rp->r_size = size;
                    975: }
                    976: 
                    977: static
                    978: ringempty( rp )
                    979: register RING *rp;
                    980: {
                    981:        return( rp->r_rdidx == rp->r_wrtidx );
                    982: }
                    983: 
                    984: static
                    985: ringfull( rp )
                    986: register RING *rp;
                    987: {
                    988:        register short idx;
                    989: 
                    990:        idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
                    991:        return( idx == rp->r_rdidx );
                    992: }
                    993: 
                    994: static
                    995: ringput( rp,v )
                    996: register RING *rp;
                    997: {
                    998:        register int idx;
                    999:        register short *vp = (short *)&v,
                   1000:                       *sp;
                   1001: 
                   1002:        idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
                   1003:        if( idx != rp->r_rdidx )
                   1004:        {
                   1005: #ifdef TAHOE
                   1006:                sp = (short *)&rp->r_slot[ rp->r_wrtidx ];
                   1007:                *sp = *vp; sp[1] = vp[1];
                   1008: #else
                   1009:                rp->r_slot[ rp->r_wrtidx ] = v;
                   1010: #endif TAHOE
                   1011:                rp->r_wrtidx = idx;
                   1012:                if( (idx -= rp->r_rdidx) < 0 )
                   1013:                        idx += rp->r_size;
                   1014:                return( idx );                  /* num ring entries */
                   1015:        }
                   1016:        return( 0 );
                   1017: }
                   1018: 
                   1019: static
                   1020: ringget( rp )
                   1021: register RING *rp;
                   1022: {
                   1023:        register int i = 0;
                   1024:        long int v;
                   1025:        register short *vp = (short *)&v,
                   1026:                       *sp;
                   1027: 
                   1028:        if( rp->r_rdidx != rp->r_wrtidx )
                   1029:        {
                   1030: #ifdef TAHOE
                   1031:                sp = (short *)&rp->r_slot[ rp->r_rdidx ];
                   1032:                *vp = *sp; vp[1] = sp[1];
                   1033:                i = v;
                   1034: #else
                   1035:                i = rp->r_slot[ rp->r_rdidx ];
                   1036: #endif TAHOE
                   1037:                rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1);
                   1038:        }
                   1039:        return( i );
                   1040: }
                   1041: 
                   1042: #ifdef notdef
                   1043: struct mbuf *
                   1044: m_tofree( rp )
                   1045: register RING *rp;
                   1046: {
                   1047:        long int v = 0;
                   1048:        register short *vp = (short *)&v,
                   1049:                       *sp;
                   1050: 
                   1051:        if( rp->r_rdidx != rp->r_wrtidx )
                   1052:        {
                   1053: #ifdef TAHOE
                   1054:                sp = (short *)&rp->r_slot[ rp->r_rdidx ];
                   1055:                *vp = *sp; vp[1] = sp[1];
                   1056:                /* *sp = 0xffff; sp[1] = 0xffff; */
                   1057: #else
                   1058:                v = rp->r_slot[ rp->r_rdidx ];
                   1059: #endif TAHOE
                   1060:                rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1);
                   1061:        }
                   1062:        return( (struct mbuf *)v );
                   1063: }
                   1064: #endif
                   1065: static
                   1066: fir( rp )
                   1067: register RING *rp;
                   1068: {
                   1069:        long int v;
                   1070:        register short *vp = (short *)&v,
                   1071:                       *sp;
                   1072: 
                   1073:        if( rp->r_rdidx != rp->r_wrtidx )
                   1074: #ifdef TAHOE
                   1075:        {
                   1076:                sp = (short *)&rp->r_slot[ rp->r_rdidx ];
                   1077:                *vp = *sp; vp[1] = sp[1];
                   1078:                return( v );
                   1079:        }
                   1080: #else
                   1081:                return( rp->r_slot[ rp->r_rdidx ] );
                   1082: #endif TAHOE
                   1083:        else   
                   1084:                return( 0 );
                   1085: }
                   1086: 
                   1087: 
                   1088: static
                   1089: prtbytes( addr )
                   1090: register char *addr;
                   1091: {
                   1092:        register int i;
                   1093: 
                   1094:        for( i = 0; i < 12; i++ )
                   1095:        {
                   1096:                printf("%X ",*addr&0377);
                   1097:                addr++;
                   1098:        }
                   1099:        printf("\n");
                   1100: }
                   1101: 
                   1102: static
                   1103: enpcopy(from, to, cnt)
                   1104: register char *from, *to;
                   1105: register cnt;
                   1106: {
                   1107:        register c;
                   1108:        register short *f, *t;
                   1109: 
                   1110:        if (((int)from & 01) && ((int)to & 01)) {
                   1111:                                        /* source & dest at odd addresses */
                   1112:                *to++ = *from++;
                   1113:                --cnt;
                   1114:        }
                   1115:        if (cnt > 1 && (((int)to & 01)==0) && (((int)from & 01)==0)) {
                   1116:                t = (short *) to;
                   1117:                f = (short *) from;
                   1118:                for( c = cnt>>1; c; --c)        /* even address copy */
                   1119:                        *t++ = *f++;
                   1120:                cnt &= 1;
                   1121:                if ( cnt ) {                    /* odd len */
                   1122:                        from = (char *) f;
                   1123:                        to   = (char *) t;
                   1124:                        *to = *from;
                   1125:                }
                   1126:        }
                   1127:        while (cnt-- > 0)       /* one of the address(es) must be odd */
                   1128:                *to++ = *from++;
                   1129: 
                   1130: }
                   1131: 
                   1132: static
                   1133: enpcopyin(userv, kernv, cnt)
                   1134: {
                   1135: 
                   1136:        if (useracc(userv, cnt, 1)) {
                   1137:                enpcopy( userv, kernv, cnt );
                   1138:                return( 0 );
                   1139:        }
                   1140:        else    return( EFAULT );
                   1141: }
                   1142: 
                   1143: 
                   1144: static
                   1145: enpcopyout(kernv, userv, cnt)
                   1146: {
                   1147: 
                   1148:        if (useracc(userv, cnt, 0)) {
                   1149:                enpcopy( kernv, userv, cnt );
                   1150:                return( 0 );
                   1151:        }
                   1152:        else    return( EFAULT );
                   1153: }
                   1154: #endif

unix.superglobalmegacorp.com

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