[BACK]Return to if_le.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / stand / common

Annotation of sys/arch/hp300/stand/common/if_le.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_le.c,v 1.5 2006/08/17 06:31:10 miod Exp $  */;
                      2: /*     $NetBSD: if_le.c,v 1.9 1997/01/30 10:32:54 thorpej Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1993 Adam Glass
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by Adam Glass.
                     19:  * 4. The name of the Author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/types.h>
                     37:
                     38: #include <netinet/in.h>
                     39: #include <netinet/in_systm.h>
                     40:
                     41: #include <lib/libsa/stand.h>
                     42: #include <lib/libsa/netif.h>
                     43:
                     44: #include "samachdep.h"
                     45: #include "device.h"
                     46: #include "if_lereg.h"
                     47:
                     48: #ifndef NLE
                     49: #define NLE 1
                     50: #endif
                     51:
                     52: #ifdef LE_DEBUG
                     53: int le_debug = 0;
                     54: #endif
                     55:
                     56: #define        ETHER_MIN_LEN   64
                     57: #define        ETHER_MAX_LEN   1518
                     58: #define        ETHER_ADDR_LEN  6
                     59:
                     60: int    le_probe(struct netif *, void *);
                     61: int    le_match(struct netif *, void *);
                     62: void   le_init(struct iodesc *, void *);
                     63: int    le_get(struct iodesc *, void *, size_t, time_t);
                     64: int    le_put(struct iodesc *, void *, size_t);
                     65: void   le_end(struct netif *);
                     66:
                     67: struct le_sel {
                     68:         int    le_id;
                     69:         int    le_regs;
                     70:         int    le_mem;
                     71:         int    le_nvram;
                     72:         int    le_heat;
                     73:         int    le_bonus;
                     74: } le0conf[] = {
                     75: /* offsets for:           ID   REGS     MEM   NVRAM    le_heat le_bonus*/
                     76: {                  0,  0x4000, 0x8000, 0xC008, 1,      10   }
                     77: };
                     78:
                     79: extern struct netif_stats      le_stats[];
                     80:
                     81: struct netif_dif le_ifs[] = {
                     82: /*     dif_unit        dif_nsel        dif_stats       dif_private     */
                     83: {      0,              NENTS(le0conf), &le_stats[0],   le0conf,        },
                     84: };
                     85:
                     86: struct netif_stats le_stats[NENTS(le_ifs)];
                     87:
                     88: struct netif_driver le_driver = {
                     89:        "le",                   /* netif_bname */
                     90:        le_match,               /* netif_match */
                     91:        le_probe,               /* netif_probe */
                     92:        le_init,                /* netif_init */
                     93:        le_get,                 /* netif_get */
                     94:        le_put,                 /* netif_put */
                     95:        le_end,                 /* netif_end */
                     96:        le_ifs,                 /* netif_ifs */
                     97:        NENTS(le_ifs)           /* netif_nifs */
                     98: };
                     99:
                    100: struct le_softc {
                    101:        struct  lereg0 *sc_r0;  /* DIO registers */
                    102:        struct  lereg1 *sc_r1;  /* LANCE registers */
                    103:        void    *sc_mem;
                    104:        struct  init_block *sc_init;
                    105:        struct  mds *sc_rd, *sc_td;
                    106:        u_char  *sc_rbuf, *sc_tbuf;
                    107:        int     sc_next_rd, sc_next_td;
                    108:        u_char  sc_addr[ETHER_ADDR_LEN];
                    109: } le_softc[NLE];
                    110:
                    111: static inline void
                    112: lewrcsr(struct le_softc *sc, u_short port, u_short val)
                    113: {
                    114:        struct lereg0 *ler0 = sc->sc_r0;
                    115:        struct lereg1 *ler1 = sc->sc_r1;
                    116:
                    117:        do {
                    118:                ler1->ler1_rap = port;
                    119:        } while ((ler0->ler0_status & LE_ACK) == 0);
                    120:        do {
                    121:                ler1->ler1_rdp = val;
                    122:        } while ((ler0->ler0_status & LE_ACK) == 0);
                    123: }
                    124:
                    125: static inline u_short
                    126: lerdcsr(struct le_softc *sc, u_short port)
                    127: {
                    128:        struct lereg0 *ler0 = sc->sc_r0;
                    129:        struct lereg1 *ler1 = sc->sc_r1;
                    130:        u_short val;
                    131:
                    132:        do {
                    133:                ler1->ler1_rap = port;
                    134:        } while ((ler0->ler0_status & LE_ACK) == 0);
                    135:        do {
                    136:                val = ler1->ler1_rdp;
                    137:        } while ((ler0->ler0_status & LE_ACK) == 0);
                    138:        return (val);
                    139: }
                    140:
                    141: void   leinit(void);
                    142: void   lememinit(struct le_softc *);
                    143: void   le_error(int, char *, u_short);
                    144: int    le_poll(struct iodesc *, void *, int);
                    145: void   le_reset(int, u_char *);
                    146:
                    147: void
                    148: leinit()
                    149: {
                    150:        extern struct hp_hw sc_table[];
                    151:        struct hp_hw *hw;
                    152:        struct le_softc *sc;
                    153:        struct le_sel *sels;
                    154:        int i, n;
                    155:        char *cp;
                    156:
                    157:        i = 0;
                    158:
                    159:        for (hw = sc_table; i < NLE && hw < &sc_table[MAXCTLRS]; hw++) {
                    160: #ifdef LE_DEBUG
                    161:                if (le_debug)
                    162:                        printf("found type %x\n", hw->hw_type);
                    163: #endif
                    164:
                    165: #if 0
                    166:                if (!HW_ISDEV(hw, D_LAN))
                    167:                        continue;
                    168: #endif
                    169:
                    170:                 sels = (struct le_sel *)le_ifs[i].dif_private;
                    171:
                    172:                sc = &le_softc[i];
                    173:                 sc->sc_r0 = (struct lereg0 *)(sels->le_id + (int)hw->hw_kva);
                    174:
                    175:                 if (sc->sc_r0->ler0_id != LEID)
                    176:                         continue;
                    177:
                    178:                 sc->sc_r1 = (struct lereg1 *)(sels->le_regs + (int)hw->hw_kva);
                    179:                 sc->sc_mem = (struct lereg2 *)(sels->le_mem + (int)hw->hw_kva);
                    180:
                    181: #ifdef LE_DEBUG
                    182:                if (le_debug)
                    183:                        printf("le%d: DIO=%x regs=%x mem=%x\n",
                    184:                                i, sc->sc_r0, sc->sc_r1, sc->sc_mem);
                    185: #endif
                    186:
                    187:                /*
                    188:                 * Read the ethernet address off the board, one nibble at a time.
                    189:                 */
                    190:                cp = (char *)(sels->le_nvram + (int)hw->hw_kva);
                    191:                for (n = 0; n < sizeof(sc->sc_addr); n++) {
                    192:                    sc->sc_addr[n] = (*++cp & 0xF) << 4;
                    193:                    cp++;
                    194:                    sc->sc_addr[n] |= *++cp & 0xF;
                    195:                    cp++;
                    196:                }
                    197: #ifdef LE_DEBUG
                    198:                if (le_debug)
                    199:                        printf("le%d at sc%d physical address %s\n",
                    200:                                i, hw->hw_sc, ether_sprintf(sc->sc_addr));
                    201: #endif
                    202:                hw->hw_pa = (caddr_t) i;        /* XXX for autoconfig */
                    203:                i++;
                    204:        }
                    205: }
                    206:
                    207: int
                    208: le_match(struct netif *nif, void *machdep_hint)
                    209: {
                    210:        struct le_sel *sels;
                    211:        char *name = machdep_hint;
                    212:        int rv = 0;
                    213:
                    214:        if (nif->nif_sel < le_ifs[nif->nif_unit].dif_nsel) {
                    215:                sels = (struct le_sel *)le_ifs[nif->nif_unit].dif_private;
                    216:                rv = sels[nif->nif_sel].le_heat;
                    217:                if (name && !strncmp(le_driver.netif_bname, name, 2))
                    218:                        rv += sels[nif->nif_sel].le_bonus;
                    219:        }
                    220: #ifdef LE_DEBUG
                    221:        if (le_debug)
                    222:                printf("le%d: sel %d --> %d\n", nif->nif_unit, nif->nif_sel,
                    223:                    rv);
                    224: #endif
                    225:        return rv;
                    226: }
                    227:
                    228: int
                    229: le_probe(struct netif *nif, void *machdep_hint)
                    230: {
                    231:
                    232:        /* the set unit is the current unit */
                    233: #ifdef LE_DEBUG
                    234:        if (le_debug)
                    235:                printf("le%d.%d: le_probe called\n", nif->nif_unit, nif->nif_sel);
                    236: #endif
                    237:        /* XXX reset controller */
                    238:        return 0;
                    239: }
                    240:
                    241: void
                    242: le_error(int unit, char *str, u_short stat)
                    243: {
                    244:
                    245:        if (stat & LE_BABL)
                    246:                panic("le%d: been babbling, found by '%s'", unit, str);
                    247:        if (stat & LE_CERR)
                    248:                le_stats[unit].collision_error++;
                    249:        if (stat & LE_MISS)
                    250:                le_stats[unit].missed++;
                    251:        if (stat & LE_MERR) {
                    252:                panic("le%d: memory error in '%s'\n", unit, str);
                    253:        }
                    254: }
                    255:
                    256: #define        LANCE_ADDR(sc, a) \
                    257:        ((u_long)(a) - (u_long)sc->sc_mem)
                    258:
                    259: /* LANCE initialization block set up. */
                    260: void
                    261: lememinit(struct le_softc *sc)
                    262: {
                    263:        int i;
                    264:        void *mem;
                    265:        u_long a;
                    266:
                    267:        /*
                    268:         * At this point we assume that the memory allocated to the Lance is
                    269:         * quadword aligned.  If it isn't then the initialisation is going
                    270:         * fail later on.
                    271:         */
                    272:        mem = sc->sc_mem;
                    273:
                    274:        sc->sc_init = mem;
                    275:        sc->sc_init->mode = LE_NORMAL;
                    276:        for (i = 0; i < ETHER_ADDR_LEN; i++)
                    277:                sc->sc_init->padr[i] = sc->sc_addr[i^1];
                    278:        sc->sc_init->ladrf[0] = sc->sc_init->ladrf[1] = 0;
                    279:        mem += sizeof(struct init_block);
                    280:
                    281:        sc->sc_rd = mem;
                    282:        a = LANCE_ADDR(sc, mem);
                    283:        sc->sc_init->rdra = a;
                    284:        sc->sc_init->rlen = ((a >> 16) & 0xff) | (RLEN << 13);
                    285:        mem += NRBUF * sizeof(struct mds);
                    286:
                    287:        sc->sc_td = mem;
                    288:        a = LANCE_ADDR(sc, mem);
                    289:        sc->sc_init->tdra = a;
                    290:        sc->sc_init->tlen = ((a >> 16) & 0xff) | (TLEN << 13);
                    291:        mem += NTBUF * sizeof(struct mds);
                    292:
                    293:        /*
                    294:         * Set up receive ring descriptors.
                    295:         */
                    296:        sc->sc_rbuf = mem;
                    297:        for (i = 0; i < NRBUF; i++) {
                    298:                a = LANCE_ADDR(sc, mem);
                    299:                sc->sc_rd[i].addr = a;
                    300:                sc->sc_rd[i].flags = ((a >> 16) & 0xff) | LE_OWN;
                    301:                sc->sc_rd[i].bcnt = -BUFSIZE;
                    302:                sc->sc_rd[i].mcnt = 0;
                    303:                mem += BUFSIZE;
                    304:        }
                    305:
                    306:        /*
                    307:         * Set up transmit ring descriptors.
                    308:         */
                    309:        sc->sc_tbuf = mem;
                    310:        for (i = 0; i < NTBUF; i++) {
                    311:                a = LANCE_ADDR(sc, mem);
                    312:                sc->sc_td[i].addr = a;
                    313:                sc->sc_td[i].flags = ((a >> 16) & 0xff);
                    314:                sc->sc_td[i].bcnt = 0xf000;
                    315:                sc->sc_td[i].mcnt = 0;
                    316:                mem += BUFSIZE;
                    317:        }
                    318: }
                    319:
                    320: void
                    321: le_reset(int unit, u_char *myea)
                    322: {
                    323:        struct le_softc *sc = &le_softc[unit];
                    324:        u_long a;
                    325:        int timo = 100000;
                    326:
                    327: #ifdef LE_DEBUG
                    328:        if (le_debug) {
                    329:                printf("le%d: le_reset called\n", unit);
                    330:                printf("     r0=%x, r1=%x, mem=%x, addr=%x:%x:%x:%x:%x:%x\n",
                    331:                       sc->sc_r0, sc->sc_r1, sc->sc_mem,
                    332:                       sc->sc_addr[0], sc->sc_addr[1], sc->sc_addr[2],
                    333:                       sc->sc_addr[3], sc->sc_addr[4], sc->sc_addr[5]);
                    334:        }
                    335: #endif
                    336:        lewrcsr(sc, 0, LE_STOP);
                    337:        for (timo = 1000; timo; timo--);
                    338:
                    339:        sc->sc_next_rd = sc->sc_next_td = 0;
                    340:
                    341:        /* Set up LANCE init block. */
                    342:        lememinit(sc);
                    343:
                    344:        if (myea)
                    345:                bcopy(sc->sc_addr, myea, ETHER_ADDR_LEN);
                    346:
                    347:        /* Turn on byte swapping. */
                    348:        lewrcsr(sc, 3, LE_BSWP);
                    349:
                    350:        /* Give LANCE the physical address of its init block. */
                    351:        a = LANCE_ADDR(sc, sc->sc_init);
                    352:        lewrcsr(sc, 1, a);
                    353:        lewrcsr(sc, 2, (a >> 16) & 0xff);
                    354:
                    355: #ifdef LE_DEBUG
                    356:        if (le_debug)
                    357:                printf("le%d: before init\n", unit);
                    358: #endif
                    359:
                    360:        /* Try to initialize the LANCE. */
                    361:        lewrcsr(sc, 0, LE_INIT);
                    362:
                    363:        /* Wait for initialization to finish. */
                    364:        for (timo = 100000; timo; timo--)
                    365:                if (lerdcsr(sc, 0) & LE_IDON)
                    366:                        break;
                    367:
                    368:        if (lerdcsr(sc, 0) & LE_IDON) {
                    369:                /* Start the LANCE. */
                    370:                lewrcsr(sc, 0, LE_INEA | LE_STRT | LE_IDON);
                    371:        } else
                    372:                printf("le%d: card failed to initialize\n", unit);
                    373:
                    374: #ifdef LE_DEBUG
                    375:        if (le_debug)
                    376:                printf("le%d: after init\n", unit);
                    377: #endif
                    378: }
                    379:
                    380: int
                    381: le_poll(struct iodesc *desc, void *pkt, int len)
                    382: {
                    383: #if 0
                    384:        struct netif *nif = desc->io_netif;
                    385:        int unit = nif->nif_unit;
                    386: #else
                    387:        int unit = 0;
                    388: #endif
                    389:        struct le_softc *sc = &le_softc[unit];
                    390:        int length;
                    391:        volatile struct mds *cdm;
                    392:        int stat;
                    393:
                    394: #ifdef LE_DEBUG
                    395:        if (/*le_debug*/0)
                    396:                printf("le%d: le_poll called. next_rd=%d\n", unit, sc->sc_next_rd);
                    397: #endif
                    398:        stat = lerdcsr(sc, 0);
                    399:        lewrcsr(sc, 0, stat & (LE_BABL | LE_MISS | LE_MERR | LE_RINT));
                    400:        cdm = &sc->sc_rd[sc->sc_next_rd];
                    401:        if (cdm->flags & LE_OWN)
                    402:                return 0;
                    403: #ifdef LE_DEBUG
                    404:        if (le_debug) {
                    405:                printf("next_rd %d\n", sc->sc_next_rd);
                    406:                printf("cdm->flags %x\n", cdm->flags);
                    407:                printf("cdm->bcnt %x, cdm->mcnt %x\n", cdm->bcnt, cdm->mcnt);
                    408:                printf("cdm->rbuf msg %d buf %d\n", cdm->mcnt, -cdm->bcnt );
                    409:        }
                    410: #endif
                    411:        if (stat & (LE_BABL | LE_CERR | LE_MISS | LE_MERR))
                    412:                le_error(unit, "le_poll", stat);
                    413:        if (cdm->flags & (LE_FRAM | LE_OFLO | LE_CRC | LE_RBUFF)) {
                    414:                printf("le%d_poll: rmd status 0x%x\n", unit, cdm->flags);
                    415:                length = 0;
                    416:                goto cleanup;
                    417:        }
                    418:        if ((cdm->flags & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP))
                    419:                panic("le_poll: chained packet");
                    420:
                    421:        length = cdm->mcnt;
                    422: #ifdef LE_DEBUG
                    423:        if (le_debug)
                    424:                printf("le_poll: length %d\n", length);
                    425: #endif
                    426:        if (length >= BUFSIZE) {
                    427:                length = 0;
                    428:                panic("csr0 when bad things happen: %x", stat);
                    429:                goto cleanup;
                    430:        }
                    431:        if (!length)
                    432:                goto cleanup;
                    433:        length -= 4;
                    434:
                    435:        if (length > 0) {
                    436:                /*
                    437:                 * If the length of the packet is greater than the size of the
                    438:                 * buffer, we have to truncate it, to avoid Bad Things.
                    439:                 * XXX Is this the right thing to do?
                    440:                 */
                    441:                if (length > len)
                    442:                        length = len;
                    443:
                    444:                bcopy(sc->sc_rbuf + (BUFSIZE * sc->sc_next_rd), pkt, length);
                    445:        }
                    446:
                    447: cleanup:
                    448:        cdm->mcnt = 0;
                    449:        cdm->flags |= LE_OWN;
                    450:        if (++sc->sc_next_rd >= NRBUF)
                    451:                sc->sc_next_rd = 0;
                    452: #ifdef LE_DEBUG
                    453:        if (le_debug)
                    454:                printf("new next_rd %d\n", sc->sc_next_rd);
                    455: #endif
                    456:
                    457:        return length;
                    458: }
                    459:
                    460: int
                    461: le_put(struct iodesc *desc, void *pkt, size_t len)
                    462: {
                    463: #if 0
                    464:        struct netif *nif = desc->io_netif;
                    465:        int unit = nif->nif_unit;
                    466: #else
                    467:        int unit = 0;
                    468: #endif
                    469:        struct le_softc *sc = &le_softc[unit];
                    470:        volatile struct mds *cdm;
                    471:        int timo, i, stat;
                    472:
                    473:  le_put_loop:
                    474:        timo = 100000;
                    475:
                    476: #ifdef LE_DEBUG
                    477:        if (le_debug)
                    478:                printf("le%d: le_put called. next_td=%d\n", unit, sc->sc_next_td);
                    479: #endif
                    480:        stat = lerdcsr(sc, 0);
                    481:        lewrcsr(sc, 0, stat & (LE_BABL | LE_MISS | LE_MERR | LE_TINT));
                    482:        if (stat & (LE_BABL | LE_CERR | LE_MISS | LE_MERR))
                    483:                le_error(unit, "le_put(way before xmit)", stat);
                    484:        cdm = &sc->sc_td[sc->sc_next_td];
                    485:         i = 0;
                    486: #if 0
                    487:        while (cdm->flags & LE_OWN) {
                    488:                if ((i % 100) == 0)
                    489:                        printf("le%d: output buffer busy - flags=%x\n",
                    490:                                unit, cdm->flags);
                    491:                if (i++ > 500) break;
                    492:        }
                    493:        if (cdm->flags & LE_OWN)
                    494:                getchar();
                    495: #else
                    496:        while (cdm->flags & LE_OWN);
                    497: #endif
                    498:        bcopy(pkt, sc->sc_tbuf + (BUFSIZE * sc->sc_next_td), len);
                    499:        if (len < ETHER_MIN_LEN)
                    500:                cdm->bcnt = -ETHER_MIN_LEN;
                    501:        else
                    502:                cdm->bcnt = -len;
                    503:        cdm->mcnt = 0;
                    504:        cdm->flags |= LE_OWN | LE_STP | LE_ENP;
                    505:        stat = lerdcsr(sc, 0);
                    506:        if (stat & (LE_BABL | LE_CERR | LE_MISS | LE_MERR))
                    507:                le_error(unit, "le_put(before xmit)", stat);
                    508:        lewrcsr(sc, 0, LE_TDMD);
                    509:        stat = lerdcsr(sc, 0);
                    510:        if (stat & (LE_BABL | LE_CERR | LE_MISS | LE_MERR))
                    511:                le_error(unit, "le_put(after xmit)", stat);
                    512:        do {
                    513:                if (--timo == 0) {
                    514:                        printf("le%d: transmit timeout, stat = 0x%x\n",
                    515:                                unit, stat);
                    516:                        if (stat & LE_SERR)
                    517:                                le_error(unit, "le_put(timeout)", stat);
                    518:                        if (stat & LE_INIT) {
                    519:                                printf("le%d: reset and retry packet\n", unit);
                    520:                                lewrcsr(sc, 0, LE_TINT);        /* sanity */
                    521:                                le_init(desc, NULL);
                    522:                                goto le_put_loop;
                    523:                        }
                    524:                        break;
                    525:                }
                    526:                stat = lerdcsr(sc, 0);
                    527:        } while ((stat & LE_TINT) == 0);
                    528:        lewrcsr(sc, 0, LE_TINT);
                    529:        if (stat & (LE_BABL |/* LE_CERR |*/ LE_MISS | LE_MERR)) {
                    530:                printf("le_put: xmit error, buf %d\n", sc->sc_next_td);
                    531:                le_error(unit, "le_put(xmit error)", stat);
                    532:        }
                    533:        if (++sc->sc_next_td >= NTBUF)
                    534:                sc->sc_next_td = 0;
                    535:        if (cdm->flags & LE_DEF)
                    536:                le_stats[unit].deferred++;
                    537:        if (cdm->flags & LE_ONE)
                    538:                le_stats[unit].collisions++;
                    539:        if (cdm->flags & LE_MORE)
                    540:                le_stats[unit].collisions+=2;
                    541:        if (cdm->flags & LE_ERR) {
                    542:                printf("le%d: transmit error, error = 0x%x\n", unit,
                    543:                        cdm->mcnt);
                    544:                return -1;
                    545:        }
                    546: #ifdef LE_DEBUG
                    547:        if (le_debug) {
                    548:                printf("le%d: le_put() successful: sent %d\n", unit, len);
                    549:                printf("le%d: le_put(): flags: %x mcnt: %x\n", unit,
                    550:                        (unsigned int) cdm->flags,
                    551:                        (unsigned int) cdm->mcnt);
                    552:        }
                    553: #endif
                    554:        return len;
                    555: }
                    556:
                    557:
                    558: int
                    559: le_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
                    560: {
                    561:        time_t t;
                    562:        int cc;
                    563:
                    564:        t = getsecs();
                    565:        cc = 0;
                    566:        while (((getsecs() - t) < timeout) && !cc) {
                    567:                cc = le_poll(desc, pkt, len);
                    568:        }
                    569:        return cc;
                    570: }
                    571:
                    572: void
                    573: le_init(struct iodesc *desc, void *machdep_hint)
                    574: {
                    575:        struct netif *nif = desc->io_netif;
                    576:        int unit = nif->nif_unit;
                    577:
                    578:        /* Get machine's common ethernet interface. This is done in leinit() */
                    579:        /* machdep_common_ether(myea); */
                    580:        leinit();
                    581:
                    582: #ifdef LE_DEBUG
                    583:        if (le_debug)
                    584:                printf("le%d: le_init called\n", unit);
                    585: #endif
                    586:        unit = 0;
                    587:        le_reset(unit, desc->myea);
                    588: }
                    589:
                    590: void
                    591: le_end(struct netif *nif)
                    592: {
                    593:        int unit = nif->nif_unit;
                    594:
                    595: #ifdef LE_DEBUG
                    596:        if (le_debug)
                    597:                printf("le%d: le_end called\n", unit);
                    598: #endif
                    599:
                    600:        lewrcsr(&le_softc[unit], 0, LE_STOP);
                    601: }

CVSweb