Annotation of researchv9/sys/sundev/le.c, revision 1.1.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.