Annotation of researchv9/sys/sundev/le.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             3:  */
        !             4: #include "le.h"
        !             5: 
        !             6: /*
        !             7:  * AMD Am7990 LANCE Ethernet Controller driver
        !             8:  */
        !             9: #include "../h/param.h"
        !            10: #include "../h/systm.h"
        !            11: #include "../machine/pte.h"
        !            12: #include "../h/map.h"
        !            13: #include "../h/buf.h"
        !            14: #include "../h/vmmac.h"
        !            15: #include "../h/conf.h"
        !            16: #include "../h/ttyio.h"
        !            17: #include "../h/enio.h"
        !            18: #include "../h/ttyld.h"
        !            19: #include "../h/stream.h"
        !            20: #include "../h/ethernet.h"
        !            21: 
        !            22: #include "../sundev/mbvar.h"
        !            23: #include "../sundev/lereg.h"
        !            24: 
        !            25: #define ETHERMAXP      (1500 + sizeof(struct etherpup))
        !            26: 
        !            27: /* corresponds to minor device numbers (# of servers) */
        !            28: #define        CHANS_PER_UNIT  8
        !            29: 
        !            30: int    leprobe(), leattach(), leintr();
        !            31: struct mb_device *leinfo[NLE];
        !            32: struct mb_driver ledriver = {
        !            33:        leprobe, 0, leattach, 0, 0, leintr,
        !            34:        sizeof (struct le_device), "le", leinfo, 0, 0, 0,
        !            35: };
        !            36: 
        !            37: /*
        !            38:  * Transmit and receive buffer layout.
        !            39: *      The buffer size is chosen to give room for the maximum ether
        !            40:  *     transmission unit, an overrun consisting of the entire fifo
        !            41:  *     contents, and slop that experience indicates is necessary.
        !            42:  *     (The exact amount of slop required is still unknown.)
        !            43:  */
        !            44: struct lebuf {
        !            45:        char            buffer[MAXBUF]; /* Packet's data */
        !            46: };
        !            47: 
        !            48: struct leu {
        !            49:        struct  le_device *dev;         /* hardware pointer */
        !            50:        struct  le_init_block *ib;      /* Initialization block */
        !            51:        struct  le_md *rdrp;            /* Receive Descriptor Ring Ptr */
        !            52:        struct  le_md *tdrp;            /* Transmit Descriptor Ring Ptr */
        !            53:        struct  le_md *rdrend;          /* Receive Descriptor Ring End */
        !            54:        struct  le_md *his_rmd;         /* Next descriptor in ring */
        !            55:        int     nrmdp2;                 /* log(2) Num. Rcv. Msg. Descs. */
        !            56:        int     ntmdp2;                 /* log(2) Num. Tran. Msg. Descs. */
        !            57:        int     nrmds;                  /* Num. Rcv. Msg. Descs. */
        !            58:        int     ntmds;                  /* Num. Xmit. Msg. Descs. */
        !            59:        struct  lebuf *rbufs;           /* Receive Buffers */
        !            60:        struct  lebuf *tbufs;           /* Transmit Buffers */
        !            61:        /* Error counters */
        !            62:        int     frame;                  /* Receive Framing Errors (dribble) */
        !            63:        int     crc;                    /* Receive CRC Errors */
        !            64:        int     oflo;                   /* Receive overruns */
        !            65:        int     uflo;                   /* Transmit underruns */
        !            66:        int     retries;                /* Transmit retries */
        !            67:        int     missed;                 /* Number of missed packets */
        !            68:        int     noheartbeat;            /* Number of nonexistent heartbeats */
        !            69:        int     ierrors, oerrors;
        !            70:        int     ipackets, opackets;
        !            71:        char    myetheradr[6];
        !            72:        char    attached;
        !            73:        char    active;
        !            74: } leu[NLE];
        !            75: 
        !            76: #define        NLECHAN (CHANS_PER_UNIT * NLE)
        !            77: struct lechan {
        !            78:        struct  leu *leu;
        !            79:        int     packets;
        !            80:        struct  queue *q;
        !            81:        int     type;
        !            82: } lechan[NLECHAN];
        !            83: 
        !            84: int    nodev(), leopen(), leclose(), leput();
        !            85: static struct qinit lerinit = { nodev, NULL, leopen, leclose, 0, 0 };
        !            86: static struct qinit lewinit = { leput, NULL, leopen, leclose, 1514, 0 };
        !            87:        /* 1514 bytes is minimum highwater mark to send 1514 byte packets */
        !            88: struct streamtab lesinfo = { &lerinit, &lewinit };
        !            89: 
        !            90: /*
        !            91:  * Resource amounts.
        !            92:  */
        !            93: /* Numbers of ring descriptors */
        !            94: int le_ntmdp2 = 0;             /* 2 ^ 0 = 1 */
        !            95: int le_nrmdp2 = 4;             /* 2 ^ 4 = 16 */
        !            96: 
        !            97: /*
        !            98:  * Return the address of an adjacent descriptor in the given ring.
        !            99:  */
        !           100: #define next_rmd(lu,rmdp)      ((rmdp) == (lu)->rdrend         \
        !           101:                                        ? (lu)->rdrp : ((rmdp) + 1))
        !           102: 
        !           103: /*
        !           104:  * Probe for device.
        !           105:  */
        !           106: leprobe(reg)
        !           107:        caddr_t reg;
        !           108: {
        !           109:        register struct le_device *le = (struct le_device *)reg;
        !           110: 
        !           111:        if (pokec((char *)&le->le_rdp, 0))
        !           112:                return (0);
        !           113:        return (sizeof (struct le_device));
        !           114: }
        !           115: 
        !           116: /*
        !           117:  * Interface exists: make available by filling in network interface
        !           118:  * record.  System will initialize the interface when it is ready
        !           119:  * to accept packets.
        !           120:  */
        !           121: leattach(md)
        !           122:        struct mb_device *md;
        !           123: {
        !           124:        struct leu *lu = &leu[md->md_unit];
        !           125: 
        !           126:        /* Reset the chip. */
        !           127:        lu->dev = (struct le_device *)md->md_addr;
        !           128:        lu->dev->le_rap = LE_CSR0;
        !           129:        lu->dev->le_csr = LE_STOP;
        !           130:        localetheraddr(NULL, lu->myetheradr);
        !           131:        le_alloc_buffers(lu);
        !           132:        lu->attached = 1;
        !           133: }
        !           134: 
        !           135: /* ARGSUSED */
        !           136: leopen(q, dev)
        !           137: register struct queue *q;
        !           138: register dev_t dev;
        !           139: {
        !           140:        register struct lechan *led;
        !           141:        register struct leu *lu;
        !           142:        register unit;
        !           143: 
        !           144:        dev = minor(dev);
        !           145:        unit = dev / CHANS_PER_UNIT;
        !           146: 
        !           147:        if (dev >= NLECHAN)
        !           148:                return(0);
        !           149:        if (unit >= NLE)
        !           150:                return(0);
        !           151: 
        !           152:        lu = &leu[unit];
        !           153:        if(!lu->attached)
        !           154:                return(0);
        !           155:        led = &lechan[dev];
        !           156:        if (led->q)
        !           157:                return(0);
        !           158:        led->leu = lu;
        !           159:        led->q = q;
        !           160:        q->ptr = (caddr_t)led;
        !           161:        q->flag |= QBIGB | QDELIM;
        !           162:        WR(q)->ptr = (caddr_t)led;
        !           163:        WR(q)->flag |= QBIGB|QDELIM;
        !           164:        return(1);
        !           165: }
        !           166: 
        !           167: leclose(q)
        !           168: register struct queue *q;
        !           169: {
        !           170:        register struct lechan *led;
        !           171: 
        !           172:        led = (struct lechan *)q->ptr;
        !           173:        flushq(WR(q), 1);
        !           174:        lechan->q = NULL;
        !           175: }
        !           176: 
        !           177: leput(q, bp)
        !           178: register struct queue *q;
        !           179: register struct block *bp;
        !           180: {
        !           181:        register struct lechan *led;
        !           182:        register struct leu *lu;
        !           183:        register s;
        !           184: 
        !           185:        led = (struct lechan *)q->ptr;
        !           186:        lu = led->leu;
        !           187: 
        !           188:        switch(bp->type) {
        !           189:        
        !           190:                case M_IOCTL:
        !           191:                        leioctl(q, bp);
        !           192:                        return;
        !           193: 
        !           194:                case M_DATA:
        !           195:                        putq(q, bp);
        !           196:                        return;
        !           197:                
        !           198:                case M_DELIM:
        !           199:                        break;
        !           200: 
        !           201:                default:
        !           202:                        freeb(bp);
        !           203:                        return;
        !           204:        }
        !           205: 
        !           206:        putq(q, bp);
        !           207:        s = splimp();
        !           208:        led->packets++;
        !           209:        if (lu->active == 0)
        !           210:                lestart(lu);
        !           211:        splx(s);
        !           212: }
        !           213: 
        !           214: /*
        !           215:  * Grab memory for message descriptors and buffers and set fields
        !           216:  * in the interfaces's software status structure accordingly.
        !           217:  */
        !           218: le_alloc_buffers(lu)
        !           219: register struct leu *lu;
        !           220: {
        !           221:        int size;
        !           222:        int memall();
        !           223:        caddr_t wmemall(), v;
        !           224: 
        !           225:        /* Set numbers of message descriptors. */
        !           226:        lu->nrmdp2 = le_nrmdp2;
        !           227:        lu->ntmdp2 = le_ntmdp2;
        !           228:        lu->nrmds = 1 << lu->nrmdp2;
        !           229:        lu->ntmds = 1 << lu->ntmdp2;
        !           230: 
        !           231:        size = sizeof(struct le_md) * (lu->nrmds + lu->ntmds) +
        !           232:                sizeof(struct lebuf) * (lu->nrmds + lu->ntmds) +
        !           233:                sizeof(struct le_init_block);
        !           234:        v = wmemall(memall, size);
        !           235: 
        !           236: #define        valloc(name, type, num) \
        !           237:            (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
        !           238: 
        !           239:        valloc(lu->rdrp, struct le_md , lu->nrmds);
        !           240:        valloc(lu->tdrp, struct le_md , lu->ntmds);
        !           241:        valloc(lu->ib, struct le_init_block , 1);
        !           242:        valloc(lu->rbufs, struct lebuf , lu->nrmds);
        !           243:        valloc(lu->tbufs, struct lebuf , lu->ntmds);
        !           244: 
        !           245:        /*
        !           246:         * Remember address of last descriptor in the ring for
        !           247:         * ease of bumping pointers around the ring.
        !           248:         */
        !           249:        lu->rdrend = &((lu->rdrp)[lu->nrmds-1]);
        !           250:        leinit(lu);
        !           251: }
        !           252: 
        !           253: /*
        !           254:  * Initialization of interface; clear recorded pending
        !           255:  * operations.
        !           256:  */
        !           257: leinit(lu)
        !           258: register struct leu *lu;
        !           259: {
        !           260:        register struct le_device *le;
        !           261:        register struct le_init_block *ib;
        !           262:        register int s;
        !           263:        register struct lebuf   *bp;
        !           264:        register struct le_md *md;
        !           265:        int i;
        !           266: 
        !           267:        s = splimp();
        !           268: 
        !           269:        le = lu->dev;
        !           270:        le->le_csr = LE_STOP;           /* reset the chip */
        !           271: 
        !           272:        /*
        !           273:         * Reset message descriptors.
        !           274:         */
        !           275:        lu->his_rmd = lu->rdrp;
        !           276: 
        !           277:        /* Construct the initialization block */
        !           278:        ib = lu->ib;
        !           279:        bzero((caddr_t)ib, sizeof (struct le_init_block));
        !           280: 
        !           281:        ib->ib_padr[0] = lu->myetheradr[1];
        !           282:        ib->ib_padr[1] = lu->myetheradr[0];
        !           283:        ib->ib_padr[2] = lu->myetheradr[3];
        !           284:        ib->ib_padr[3] = lu->myetheradr[2];
        !           285:        ib->ib_padr[4] = lu->myetheradr[5];
        !           286:        ib->ib_padr[5] = lu->myetheradr[4];
        !           287:                                                
        !           288:        /* No multicast filter yet, FIXME MULTICAST, leave zeros. */
        !           289: 
        !           290:        ib->ib_rdrp.drp_laddr = (long)lu->rdrp;
        !           291:        ib->ib_rdrp.drp_haddr = (long)lu->rdrp >> 16;
        !           292:        ib->ib_rdrp.drp_len   = (long)lu->nrmdp2;
        !           293:        ib->ib_tdrp.drp_laddr = (long)lu->tdrp;
        !           294:        ib->ib_tdrp.drp_haddr = (long)lu->tdrp >> 16;
        !           295:        ib->ib_tdrp.drp_len   = (long)lu->ntmdp2;
        !           296: 
        !           297:        /* Clear all the descriptors */
        !           298:        bzero((caddr_t)lu->rdrp, lu->nrmds * sizeof (struct le_md));
        !           299:        bzero((caddr_t)lu->tdrp, lu->ntmds * sizeof (struct le_md));
        !           300: 
        !           301:        /* Hang out the receive buffers. */
        !           302:        for(i = 0; i < lu->nrmds; i++) {
        !           303:                bp = &lu->rbufs[i];
        !           304:                md = &lu->rdrp[i];
        !           305:                md->lmd_ladr = (u_short) bp;
        !           306:                md->lmd_hadr = (long)bp >> 16;
        !           307:                md->lmd_bcnt = -MAXBUF;
        !           308:                md->lmd_mcnt = 0;
        !           309:                md->lmd_flags = LMD_OWN;
        !           310:        }
        !           311:        lu->his_rmd == lu->rdrp;
        !           312: 
        !           313:        /* Transmit md intialization */
        !           314:        for(i = 0; i < lu->ntmds; i++) {
        !           315:                bp = &lu->tbufs[i];
        !           316:                md = &lu->tdrp[i];
        !           317:                md->lmd_ladr = (u_short) bp;
        !           318:                md->lmd_hadr = (long)bp >> 16;
        !           319:        }
        !           320: 
        !           321:        /* Give the init block to the chip */
        !           322:        le->le_rap = LE_CSR1;   /* select the low address register */
        !           323:        le->le_rdp = (long)ib & 0xffff;
        !           324: 
        !           325:        le->le_rap = LE_CSR2;   /* select the high address register */
        !           326:        le->le_rdp = ((long)ib >> 16) & 0xff;
        !           327: 
        !           328:        le->le_rap = LE_CSR3;   /* Bus Master control register */
        !           329:        le->le_rdp = LE_BSWP;
        !           330: 
        !           331:        le->le_rap = LE_CSR0;   /* main control/status register */
        !           332:        le->le_csr = LE_INIT;
        !           333: 
        !           334:        for (i = 10000; ! (le->le_csr & LE_IDON); i-- )
        !           335:                if (i <= 0)
        !           336:                        panic("le: chip didn't initialize");
        !           337:        le->le_csr = LE_IDON;           /* Now reset the interrupt */
        !           338:        lu->active = 0;
        !           339:        /* (Re)start the chip. */
        !           340:        le->le_csr = LE_STRT | LE_INEA;
        !           341:        (void) splx(s);
        !           342: }
        !           343: 
        !           344: /*
        !           345:  * Start or restart output on interface.
        !           346:  * If interface is already active, then this is a nop.
        !           347:  * If interface is not already active, get another packet
        !           348:  * to send from the interface queue, and map it to the
        !           349:  * interface before starting the output.
        !           350:  */
        !           351: lestart(lu)
        !           352: register struct leu *lu;
        !           353: {
        !           354:        register char *to;
        !           355:        register struct lechan *led;
        !           356:        register struct queue *q;
        !           357:        register struct block *bp;
        !           358:        register count, i;
        !           359:        struct le_device *le;
        !           360:        register struct le_md *t;
        !           361: 
        !           362:        led = &lechan[(lu - leu) * CHANS_PER_UNIT];
        !           363:        for(i = 0; i < CHANS_PER_UNIT; i++, led++)
        !           364:                if (led->q && led->packets > 0)
        !           365:                        break;
        !           366:        if (i >= CHANS_PER_UNIT)
        !           367:                return;
        !           368: 
        !           369:        led->packets--;
        !           370:        q = WR(led->q);
        !           371: 
        !           372:        le = (struct le_device *)lu->dev;
        !           373:        to = lu->tbufs->buffer;
        !           374:        count = 0;
        !           375:        while (bp = getq(q)) {
        !           376:                if (bp->type == M_DELIM) {
        !           377:                        freeb(bp);
        !           378:                        break;
        !           379:                }
        !           380:                i = bp->wptr - bp->rptr;
        !           381:                /*
        !           382:                 * If larger than maximum packet, throw out extra
        !           383:                 */
        !           384:                if (count + i > ETHERMAXP) {
        !           385:                        i = ETHERMAXP - count;
        !           386:                        bcopy(bp->rptr, to, i);
        !           387:                        count += i;
        !           388:                        freeb(bp);
        !           389:                        while (bp = getq(q)) {
        !           390:                                if (bp->type == M_DELIM) {
        !           391:                                        freeb(bp);
        !           392:                                        break;
        !           393:                                }
        !           394:                                freeb(bp);
        !           395:                        }
        !           396:                        break;
        !           397:                }
        !           398:                bcopy(bp->rptr, to, i);
        !           399:                to += i;
        !           400:                count += i;
        !           401:                freeb(bp);
        !           402:        }
        !           403: 
        !           404:        /* if there is no ethernet header in packet, throw it out */
        !           405:        if (count < sizeof(struct etherpup))
        !           406:                return;
        !           407:        if (count < 60)
        !           408:                count = 60;
        !           409: 
        !           410:        to = lu->tbufs->buffer + 6;
        !           411:        bcopy(lu->myetheradr, to, 6);
        !           412:        t = lu->tdrp;
        !           413:        if (t->lmd_flags & LMD_OWN)
        !           414:                panic("lestart: tmd ownership conflict");
        !           415:        t->lmd_bcnt = -count;
        !           416:        t->lmd_flags3 = 0; 
        !           417:        t->lmd_flags = 0;
        !           418:        t->lmd_flags = LMD_STP|LMD_ENP;
        !           419:        t->lmd_flags |= LMD_OWN;
        !           420:        lu->active = 1;
        !           421:        le->le_csr = LE_TDMD | LE_INEA;
        !           422: 
        !           423: }
        !           424: 
        !           425: /*
        !           426:  * interrupt routine
        !           427:  */
        !           428: leintr()
        !           429: {
        !           430:        register struct leu *lu;
        !           431:        register struct le_device *le;
        !           432:        register struct le_md *lmd;
        !           433:        register struct mb_device *md;
        !           434:        int serviced = 0;
        !           435: 
        !           436:        lu = leu;
        !           437:        for (lu = leu; lu < &leu[NLE]; lu++) {
        !           438:                if (!lu->attached)
        !           439:                        continue;
        !           440:                le = lu->dev;
        !           441:                if (!(le->le_csr & LE_INTR))
        !           442:                        continue;
        !           443: 
        !           444:                /* Keep statistics for lack of heartbeat */
        !           445:                if (le->le_csr & LE_CERR) {
        !           446:                        le->le_csr = LE_CERR | LE_INEA;
        !           447:                        lu->noheartbeat++;
        !           448:                }
        !           449: 
        !           450:                /* Check for receive activity */
        !           451:                if ( (le->le_csr & LE_RINT) && (le->le_csr & LE_RXON) ) {
        !           452:                        /* Pull packets off interface */
        !           453:                        for (lmd = lu->his_rmd;
        !           454:                             !(lmd->lmd_flags & LMD_OWN);
        !           455:                             lu->his_rmd = lmd = next_rmd(lu, lmd)) {
        !           456:                                serviced = 1;
        !           457:                                le->le_csr = LE_RINT | LE_INEA;
        !           458:                                leread(lu, lmd);
        !           459:                                lmd->lmd_mcnt = 0;
        !           460:                                lmd->lmd_flags = LMD_OWN;
        !           461:                        }
        !           462:                        if (!serviced)
        !           463:                                panic("RINT with buffer owned by chip");
        !           464:                }
        !           465: 
        !           466:                /* Check for transmit activity */
        !           467:                if ((le->le_csr & LE_TINT) && (le->le_csr & LE_TXON)) {
        !           468:                        lmd = lu->tdrp;
        !           469:                        if (lmd->lmd_flags & (TMD_MORE | TMD_ONE))
        !           470:                                lu->retries++;
        !           471:                        if (lmd->lmd_flags3 &
        !           472:                            (TMD_BUFF|TMD_UFLO|TMD_LCOL|TMD_LCAR|TMD_RTRY))
        !           473:                                le_xmit_error(lu, lmd->lmd_flags3, le);
        !           474:                        le->le_csr = LE_TINT | LE_INEA;
        !           475:                        lu->active = 0;
        !           476:                        lu->opackets++;
        !           477:                        lestart(lu);
        !           478:                        serviced = 1;
        !           479:                }
        !           480: 
        !           481:                /*
        !           482:                 * Check for errors not specifically related
        !           483:                 * to transmission or reception.
        !           484:                 */
        !           485:                if ( (le->le_csr & (LE_BABL|LE_MERR|LE_MISS|LE_TXON|LE_RXON))
        !           486:                     != (LE_RXON|LE_TXON) ) {
        !           487:                        serviced = 1;
        !           488:                        le_chip_error(lu, le);
        !           489:                }
        !           490:        }
        !           491:        return (serviced);
        !           492: }
        !           493: 
        !           494: /*
        !           495:  * Move info from driver toward protocol interface
        !           496:  */
        !           497: leread(lu, rmd)
        !           498: register struct leu *lu;
        !           499: register struct le_md *rmd;
        !           500: {
        !           501:        register struct lechan *led;
        !           502:        register struct queue *q;
        !           503:        register struct block *bp;
        !           504:        register short type;
        !           505:        register caddr_t from;
        !           506:        register len, i;
        !           507: 
        !           508:        /* Check for packet errors. */
        !           509:        if ((rmd->lmd_flags & ~RMD_OFLO) != (LMD_STP|LMD_ENP)) {
        !           510:                le_rcv_error(lu, rmd->lmd_flags);
        !           511:                lu->ierrors++;
        !           512:                return;
        !           513:        }
        !           514: 
        !           515:        /*
        !           516:         * Get input data length (minus crc)
        !           517:         */
        !           518:        len = rmd->lmd_mcnt - 4;        /* subtract off trailing crc */
        !           519:        if (len == 0) {
        !           520:                printf("runt packet\n");
        !           521:                lu->ierrors++;
        !           522:                return;
        !           523:        }
        !           524: 
        !           525:        from = (caddr_t)lu->rbufs[rmd - lu->rdrp].buffer;
        !           526:        type = ((struct etherpup *)from)->type;
        !           527:        led = &lechan[(lu - leu) * CHANS_PER_UNIT];
        !           528:        for (i = 0; i < CHANS_PER_UNIT; i++, led++)
        !           529:                if (led->q && led->type == type)
        !           530:                        break;
        !           531:        if (i >= CHANS_PER_UNIT)
        !           532:                return;
        !           533:        q = led->q;
        !           534:        if (q->next->flag & QFULL) {
        !           535:                lu->ierrors++;
        !           536:                return;
        !           537:        }
        !           538:        while (len > 0) {
        !           539:                bp = allocb(len);
        !           540:                i = MIN((bp->lim - bp->base), len);
        !           541:                len -= i;
        !           542:                bcopy(from, bp->wptr, i);
        !           543:                bp->wptr += i;
        !           544:                from += i;
        !           545:                (*q->next->qinfo->putp)(q->next, bp);
        !           546:        }
        !           547:        if (putctl(q->next, M_DELIM))
        !           548:                lu->ipackets++;
        !           549:        else 
        !           550:                printf("leread no DELIM bp\n");
        !           551: }
        !           552: 
        !           553: /*
        !           554:  * Process an ioctl request.
        !           555:  */
        !           556: leioctl(q, bp)
        !           557: register struct queue *q;
        !           558: register struct block *bp;
        !           559: {
        !           560:        register struct lechan *led;
        !           561:        register struct leu *lu;
        !           562:        register u_char *msg;
        !           563:        int cmd;
        !           564:        
        !           565:        led = (struct lechan *)q->ptr;
        !           566:        lu = led->leu;
        !           567:        cmd = ((union stmsg *)(bp->rptr))->ioc1.com;
        !           568:        msg = (u_char *)&((union stmsg *)(bp->rptr))->ioc1.sb;
        !           569: 
        !           570:        bp->type = M_IOCACK;
        !           571:        switch (cmd) {
        !           572:                case ENIOADDR:          /* get my Ethernet address */
        !           573:                        bcopy(lu->myetheradr, (int *)msg, 6);
        !           574:                        break;
        !           575: 
        !           576:                case ENIOTYPE:
        !           577:                        led->type = *(int *)msg;
        !           578:                        break;
        !           579:                        
        !           580:                default:
        !           581:                        bp->type = M_IOCNAK;
        !           582:                        break;
        !           583:        }
        !           584:        qreply(q, bp);
        !           585: }
        !           586: 
        !           587: le_rcv_error(lu, flags)
        !           588:        struct leu *lu;
        !           589:        u_char flags;
        !           590: {
        !           591:        if (flags & RMD_FRAM)
        !           592:                lu->frame++;
        !           593:        if (flags & RMD_CRC )
        !           594:                lu->crc++;
        !           595:        if (flags & RMD_OFLO)
        !           596:                lu->oflo++;
        !           597:        if (flags & RMD_BUFF)
        !           598:                printf("Receive buffer error - BUFF bit set in rmd\n");
        !           599:        if (!(flags & LMD_STP))
        !           600:                printf("Received packet with STP bit in rmd cleared\n");
        !           601:        if (!(flags & LMD_ENP))
        !           602:                printf("Received packet with ENP bit in rmd cleared\n");
        !           603: }
        !           604: 
        !           605: le_xmit_error(lu, flags, le)
        !           606:        struct leu *lu;
        !           607:        u_short flags;
        !           608:        struct le_device *le;
        !           609: {
        !           610:        /*
        !           611:         * The BUFF bit isn't valid if the RTRY bit is set.
        !           612:         */
        !           613:        if ((flags & (TMD_BUFF | TMD_RTRY)) == TMD_BUFF)
        !           614:                printf("Transmit buffer error - BUFF bit set in tmd\n");
        !           615:        if (flags & TMD_UFLO) {
        !           616:                printf("Transmit underflow error\n");
        !           617:                lu->uflo++;
        !           618:        }
        !           619:        if (flags & TMD_LCOL)
        !           620:                printf("Transmit late collision - net problem?\n");
        !           621:        if (flags & TMD_LCAR)
        !           622:                printf("No carrier - transceiver cable problem?\n");
        !           623:        if (flags & TMD_RTRY)
        !           624:                printf("Transmit retried more than 16 times - net jammed\n");
        !           625: }
        !           626: 
        !           627: /* Handles errors that are reported in the chip's status register */
        !           628: /* ARGSUSED */
        !           629: le_chip_error(lu, le)
        !           630:        struct leu *lu;
        !           631:        struct le_device *le;
        !           632: {
        !           633:        register u_short        csr = le->le_csr;
        !           634:        int restart = 0;
        !           635: 
        !           636:        if (csr & LE_MISS) {
        !           637:                lu->missed++;
        !           638:                le->le_csr = LE_MISS | LE_INEA;
        !           639:        }
        !           640: 
        !           641:        if (csr & LE_BABL) {
        !           642:            printf("Babble error - sent a packet longer than the maximum length\n");
        !           643:            le->le_csr = LE_BABL | LE_INEA;
        !           644:        }
        !           645:        /*
        !           646:         * If a memory error has occurred, both the transmitter
        !           647:         * and the receiver will have shut down.
        !           648:         */
        !           649:        if (csr & LE_MERR) {
        !           650:            printf("Memory Error!  Ethernet chip memory access timed out\n");
        !           651:            le->le_csr = LE_MERR | LE_INEA;
        !           652:        }
        !           653:        if ( !(csr & LE_RXON) ) {
        !           654:            printf("Reception stopped\n");
        !           655:            restart++;
        !           656:        }
        !           657:        if ( !(csr & LE_TXON) ) {
        !           658:            printf("Transmission stopped\n");
        !           659:            restart++;
        !           660:        }
        !           661:        if (restart) {
        !           662:            le_print_csr(csr);
        !           663:            leinit(lu);
        !           664:        }
        !           665: }
        !           666: 
        !           667: /*
        !           668:  * Print out a csr value in a nicely formatted way.
        !           669:  */
        !           670: le_print_csr (csr)
        !           671:        register u_short        csr;
        !           672: {
        !           673:        printf("csr: %b\n", csr,
        !           674: "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\7INEA\6RXON\5TXON\4TDMD\3STOP\2STRT\1INIT\n");
        !           675: }

unix.superglobalmegacorp.com

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