[BACK]Return to sgec.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / if

Annotation of sys/arch/vax/if/sgec.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: sgec.c,v 1.15 2006/08/31 22:10:57 miod Exp $  */
                      2: /*      $NetBSD: sgec.c,v 1.5 2000/06/04 02:14:14 matt Exp $ */
                      3: /*
                      4:  * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *      This product includes software developed at Ludd, University of
                     17:  *      Lule}, Sweden and its contributors.
                     18:  * 4. The name of the author may not be used to endorse or promote products
                     19:  *    derived from this software without specific prior written permission
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
                     34:  * Driver for the SGEC (Second Generation Ethernet Controller), sitting
                     35:  * on for example the VAX 4000/300 (KA670).
                     36:  *
                     37:  * The SGEC looks like a mixture of the DEQNA and the TULIP. Fun toy.
                     38:  *
                     39:  * Even though the chip is capable to use virtual addresses (read the
                     40:  * System Page Table directly) this driver doesn't do so, and there
                     41:  * is no benefit in doing it either in NetBSD of today.
                     42:  *
                     43:  * Things that is still to do:
                     44:  *     Collect statistics.
                     45:  *     Use imperfect filtering when many multicast addresses.
                     46:  */
                     47:
                     48: #include "bpfilter.h"
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/mbuf.h>
                     52: #include <sys/socket.h>
                     53: #include <sys/device.h>
                     54: #include <sys/systm.h>
                     55: #include <sys/sockio.h>
                     56:
                     57: #include <net/if.h>
                     58: #include <net/if_dl.h>
                     59:
                     60: #include <netinet/in.h>
                     61: #include <netinet/if_ether.h>
                     62:
                     63: #if NBPFILTER > 0
                     64: #include <net/bpf.h>
                     65: #include <net/bpfdesc.h>
                     66: #endif
                     67:
                     68: #include <machine/bus.h>
                     69:
                     70: #include <vax/if/sgecreg.h>
                     71: #include <vax/if/sgecvar.h>
                     72:
                     73: void   sgec_rxintr(struct ze_softc *);
                     74: void   sgec_txintr(struct ze_softc *);
                     75: void   zeinit(struct ze_softc *);
                     76: int    zeioctl(struct ifnet *, u_long, caddr_t);
                     77: void   zekick(struct ze_softc *);
                     78: int    zereset(struct ze_softc *);
                     79: void   zestart(struct ifnet *);
                     80: void   zetimeout(struct ifnet *);
                     81: int    ze_add_rxbuf(struct ze_softc *, int);
                     82: void   ze_setup(struct ze_softc *);
                     83:
                     84: struct cfdriver ze_cd = {
                     85:        NULL, "ze", DV_IFNET
                     86: };
                     87:
                     88: #define        ZE_WCSR(csr, val) \
                     89:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, csr, val)
                     90: #define        ZE_RCSR(csr) \
                     91:        bus_space_read_4(sc->sc_iot, sc->sc_ioh, csr)
                     92:
                     93: /*
                     94:  * Interface exists: make available by filling in network interface
                     95:  * record.  System will initialize the interface when it is ready
                     96:  * to accept packets.
                     97:  */
                     98: void
                     99: sgec_attach(sc)
                    100:        struct ze_softc *sc;
                    101: {
                    102:        struct  ifnet *ifp = (struct ifnet *)&sc->sc_if;
                    103:        struct  ze_tdes *tp;
                    104:        struct  ze_rdes *rp;
                    105:        bus_dma_segment_t seg;
                    106:        int i, s, rseg, error;
                    107:
                    108:         /*
                    109:          * Allocate DMA safe memory for descriptors and setup memory.
                    110:          */
                    111:        if ((error = bus_dmamem_alloc(sc->sc_dmat,
                    112:            sizeof(struct ze_cdata), NBPG, 0, &seg, 1, &rseg,
                    113:            BUS_DMA_NOWAIT)) != 0) {
                    114:                printf(": unable to allocate control data, error = %d\n",
                    115:                    error);
                    116:                goto fail_0;
                    117:        }
                    118:
                    119:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
                    120:            sizeof(struct ze_cdata), (caddr_t *)&sc->sc_zedata,
                    121:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
                    122:                printf(": unable to map control data, error = %d\n", error);
                    123:                goto fail_1;
                    124:        }
                    125:
                    126:        if ((error = bus_dmamap_create(sc->sc_dmat,
                    127:            sizeof(struct ze_cdata), 1,
                    128:            sizeof(struct ze_cdata), 0, BUS_DMA_NOWAIT,
                    129:            &sc->sc_cmap)) != 0) {
                    130:                printf(": unable to create control data DMA map, error = %d\n",
                    131:                    error);
                    132:                goto fail_2;
                    133:        }
                    134:
                    135:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
                    136:            sc->sc_zedata, sizeof(struct ze_cdata), NULL,
                    137:            BUS_DMA_NOWAIT)) != 0) {
                    138:                printf(": unable to load control data DMA map, error = %d\n",
                    139:                    error);
                    140:                goto fail_3;
                    141:        }
                    142:
                    143:        /*
                    144:         * Zero the newly allocated memory.
                    145:         */
                    146:        bzero(sc->sc_zedata, sizeof(struct ze_cdata));
                    147:        /*
                    148:         * Create the transmit descriptor DMA maps.
                    149:         */
                    150:        for (i = 0; i < TXDESCS; i++) {
                    151:                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                    152:                    1, MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
                    153:                    &sc->sc_xmtmap[i]))) {
                    154:                        printf(": unable to create tx DMA map %d, error = %d\n",
                    155:                            i, error);
                    156:                        goto fail_4;
                    157:                }
                    158:        }
                    159:
                    160:        /*
                    161:         * Create receive buffer DMA maps.
                    162:         */
                    163:        for (i = 0; i < RXDESCS; i++) {
                    164:                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
                    165:                    MCLBYTES, 0, BUS_DMA_NOWAIT,
                    166:                    &sc->sc_rcvmap[i]))) {
                    167:                        printf(": unable to create rx DMA map %d, error = %d\n",
                    168:                            i, error);
                    169:                        goto fail_5;
                    170:                }
                    171:        }
                    172:        /*
                    173:         * Pre-allocate the receive buffers.
                    174:         */
                    175:        s = splnet();
                    176:        for (i = 0; i < RXDESCS; i++) {
                    177:                if ((error = ze_add_rxbuf(sc, i)) != 0) {
                    178:                        printf(": unable to allocate or map rx buffer %d\n,"
                    179:                            " error = %d\n", i, error);
                    180:                        goto fail_6;
                    181:                }
                    182:        }
                    183:        splx(s);
                    184:
                    185:        /*
                    186:         * Create ring loops of the buffer chains.
                    187:         * This is only done once.
                    188:         */
                    189:        sc->sc_pzedata = (struct ze_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
                    190:
                    191:        rp = sc->sc_zedata->zc_recv;
                    192:        rp[RXDESCS].ze_framelen = ZE_FRAMELEN_OW;
                    193:        rp[RXDESCS].ze_rdes1 = ZE_RDES1_CA;
                    194:        rp[RXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_recv;
                    195:
                    196:        tp = sc->sc_zedata->zc_xmit;
                    197:        tp[TXDESCS].ze_tdr = ZE_TDR_OW;
                    198:        tp[TXDESCS].ze_tdes1 = ZE_TDES1_CA;
                    199:        tp[TXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_xmit;
                    200:
                    201:        if (zereset(sc))
                    202:                return;
                    203:
                    204:        strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
                    205:        ifp->if_softc = sc;
                    206:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    207:        ifp->if_start = zestart;
                    208:        ifp->if_ioctl = zeioctl;
                    209:        ifp->if_watchdog = zetimeout;
                    210:
                    211:        /*
                    212:         * Attach the interface.
                    213:         */
                    214:        if_attach(ifp);
                    215:        ether_ifattach(ifp);
                    216:
                    217:        printf(": address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
                    218:        return;
                    219:
                    220:        /*
                    221:         * Free any resources we've allocated during the failed attach
                    222:         * attempt.  Do this in reverse order and fall through.
                    223:         */
                    224:  fail_6:
                    225:        for (i = 0; i < RXDESCS; i++) {
                    226:                if (sc->sc_rxmbuf[i] != NULL) {
                    227:                        bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
                    228:                        m_freem(sc->sc_rxmbuf[i]);
                    229:                }
                    230:        }
                    231:  fail_5:
                    232:        for (i = 0; i < RXDESCS; i++) {
                    233:                if (sc->sc_xmtmap[i] != NULL)
                    234:                        bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
                    235:        }
                    236:  fail_4:
                    237:        for (i = 0; i < TXDESCS; i++) {
                    238:                if (sc->sc_rcvmap[i] != NULL)
                    239:                        bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
                    240:        }
                    241:        bus_dmamap_unload(sc->sc_dmat, sc->sc_cmap);
                    242:  fail_3:
                    243:        bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
                    244:  fail_2:
                    245:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_zedata,
                    246:            sizeof(struct ze_cdata));
                    247:  fail_1:
                    248:        bus_dmamem_free(sc->sc_dmat, &seg, rseg);
                    249:  fail_0:
                    250:        return;
                    251: }
                    252:
                    253: /*
                    254:  * Initialization of interface.
                    255:  */
                    256: void
                    257: zeinit(sc)
                    258:        struct ze_softc *sc;
                    259: {
                    260:        struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
                    261:        struct ze_cdata *zc = sc->sc_zedata;
                    262:        int i;
                    263:
                    264:        /*
                    265:         * Reset the interface.
                    266:         */
                    267:        if (zereset(sc))
                    268:                return;
                    269:
                    270:        sc->sc_nexttx = sc->sc_inq = sc->sc_lastack = 0;
                    271:        /*
                    272:         * Release and init transmit descriptors.
                    273:         */
                    274:        for (i = 0; i < TXDESCS; i++) {
                    275:                if (sc->sc_txmbuf[i]) {
                    276:                        bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
                    277:                        m_freem(sc->sc_txmbuf[i]);
                    278:                        sc->sc_txmbuf[i] = 0;
                    279:                }
                    280:                zc->zc_xmit[i].ze_tdr = 0; /* Clear valid bit */
                    281:        }
                    282:
                    283:
                    284:        /*
                    285:         * Init receive descriptors.
                    286:         */
                    287:        for (i = 0; i < RXDESCS; i++)
                    288:                zc->zc_recv[i].ze_framelen = ZE_FRAMELEN_OW;
                    289:        sc->sc_nextrx = 0;
                    290:
                    291:        ZE_WCSR(ZE_CSR6, ZE_NICSR6_IE | ZE_NICSR6_BL_8 | ZE_NICSR6_ST |
                    292:            ZE_NICSR6_SR | ZE_NICSR6_DC);
                    293:
                    294:        ifp->if_flags |= IFF_RUNNING;
                    295:        ifp->if_flags &= ~IFF_OACTIVE;
                    296:
                    297:        /*
                    298:         * Send a setup frame.
                    299:         * This will start the transmit machinery as well.
                    300:         */
                    301:        ze_setup(sc);
                    302:
                    303: }
                    304:
                    305: /*
                    306:  * Kick off the transmit logic, if it is stopped.
                    307:  * On the VXT2000 we need to always reprogram CSR4,
                    308:  * so stop it unconditionnaly.
                    309:  */
                    310: void
                    311: zekick(struct ze_softc *sc)
                    312: {
                    313:        u_int csr5;
                    314:
                    315:        csr5 = ZE_RCSR(ZE_CSR5);
                    316:        if (ISSET(sc->sc_flags, SGECF_VXTQUIRKS)) {
                    317:                if ((csr5 & ZE_NICSR5_TS) == ZE_NICSR5_TS_RUN) {
                    318:                        ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) & ~ZE_NICSR6_ST);
                    319:                        while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) !=
                    320:                            ZE_NICSR5_TS_STOP)
                    321:                                DELAY(10);
                    322:                }
                    323:                ZE_WCSR(ZE_CSR4,
                    324:                    (vaddr_t)&sc->sc_pzedata->zc_xmit[sc->sc_nexttx]);
                    325:                ZE_WCSR(ZE_CSR1, ZE_NICSR1_TXPD);
                    326:                if ((csr5 & ZE_NICSR5_TS) == ZE_NICSR5_TS_RUN) {
                    327:                        ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) | ZE_NICSR6_ST);
                    328:                        while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) ==
                    329:                            ZE_NICSR5_TS_STOP)
                    330:                                DELAY(10);
                    331:                }
                    332:        } else {
                    333:                if ((csr5 & ZE_NICSR5_TS) != ZE_NICSR5_TS_RUN)
                    334:                        ZE_WCSR(ZE_CSR1, ZE_NICSR1_TXPD);
                    335:        }
                    336: }
                    337:
                    338: /*
                    339:  * Start output on interface.
                    340:  */
                    341: void
                    342: zestart(ifp)
                    343:        struct ifnet *ifp;
                    344: {
                    345:        struct ze_softc *sc = ifp->if_softc;
                    346:        struct ze_cdata *zc = sc->sc_zedata;
                    347:        paddr_t buffer;
                    348:        struct mbuf *m, *m0;
                    349:        int idx, len, s, i, totlen, error;
                    350:        int old_inq = sc->sc_inq;
                    351:        short orword;
                    352:
                    353:        s = splnet();
                    354:        while (sc->sc_inq < (TXDESCS - 1)) {
                    355:                if (ISSET(sc->sc_flags, SGECF_SETUP)) {
                    356:                        ze_setup(sc);
                    357:                        continue;
                    358:                }
                    359:                idx = sc->sc_nexttx;
                    360:                IF_DEQUEUE(&sc->sc_if.if_snd, m);
                    361:                if (m == 0)
                    362:                        goto out;
                    363:                /*
                    364:                 * Count number of mbufs in chain.
                    365:                 * Always do DMA directly from mbufs, therefore the transmit
                    366:                 * ring is really big.
                    367:                 */
                    368:                for (m0 = m, i = 0; m0; m0 = m0->m_next)
                    369:                        if (m0->m_len)
                    370:                                i++;
                    371:                if (i >= TXDESCS)
                    372:                        panic("zestart"); /* XXX */
                    373:
                    374:                if ((i + sc->sc_inq) >= (TXDESCS - 1)) {
                    375:                        IF_PREPEND(&sc->sc_if.if_snd, m);
                    376:                        ifp->if_flags |= IFF_OACTIVE;
                    377:                        goto out;
                    378:                }
                    379:
                    380: #if NBPFILTER > 0
                    381:                if (ifp->if_bpf)
                    382:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
                    383: #endif
                    384:                /*
                    385:                 * m now points to a mbuf chain that can be loaded.
                    386:                 * Loop around and set it.
                    387:                 */
                    388:                totlen = 0;
                    389:                for (m0 = m; m0; m0 = m0->m_next) {
                    390:                        error = bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[idx],
                    391:                            mtod(m0, void *), m0->m_len, 0, 0);
                    392:                        buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
                    393:                        len = m0->m_len;
                    394:                        if (len == 0)
                    395:                                continue;
                    396:
                    397:                        totlen += len;
                    398:                        /* Word alignment calc */
                    399:                        orword = 0;
                    400:                        if (totlen == len)
                    401:                                orword = ZE_TDES1_FS;
                    402:                        if (totlen == m->m_pkthdr.len) {
                    403:                                if (totlen < ETHER_ADDR_LEN)
                    404:                                        len += (ETHER_ADDR_LEN - totlen);
                    405:                                orword |= ZE_TDES1_LS;
                    406:                                sc->sc_txmbuf[idx] = m;
                    407:                        }
                    408:                        zc->zc_xmit[idx].ze_bufsize = len;
                    409:                        zc->zc_xmit[idx].ze_bufaddr = (char *)buffer;
                    410:                        zc->zc_xmit[idx].ze_tdes1 = orword | ZE_TDES1_IC;
                    411:                        zc->zc_xmit[idx].ze_tdr = ZE_TDR_OW;
                    412:
                    413:                        if (++idx == TXDESCS)
                    414:                                idx = 0;
                    415:                        sc->sc_inq++;
                    416:                }
                    417: #ifdef DIAGNOSTIC
                    418:                if (totlen != m->m_pkthdr.len)
                    419:                        panic("zestart: len fault");
                    420: #endif
                    421:
                    422:                /*
                    423:                 * Kick off the transmit logic, if it is stopped.
                    424:                 */
                    425:                zekick(sc);
                    426:                sc->sc_nexttx = idx;
                    427:        }
                    428:        if (sc->sc_inq == (TXDESCS - 1))
                    429:                ifp->if_flags |= IFF_OACTIVE;
                    430:
                    431: out:   if (old_inq < sc->sc_inq)
                    432:                ifp->if_timer = 5; /* If transmit logic dies */
                    433:        splx(s);
                    434: }
                    435:
                    436: void
                    437: sgec_rxintr(struct ze_softc *sc)
                    438: {
                    439:        struct ze_cdata *zc = sc->sc_zedata;
                    440:        struct ifnet *ifp = &sc->sc_if;
                    441:        struct ether_header *eh;
                    442:        struct mbuf *m;
                    443:        u_short rdes0;
                    444:        int len;
                    445:
                    446:        while ((zc->zc_recv[sc->sc_nextrx].ze_framelen &
                    447:            ZE_FRAMELEN_OW) == 0) {
                    448:                rdes0 = zc->zc_recv[sc->sc_nextrx].ze_rdes0;
                    449:                if (rdes0 & ZE_RDES0_ES) {
                    450:                        rdes0 &= ~ZE_RDES0_TL;  /* not really an error */
                    451:                        if ((rdes0 & (ZE_RDES0_OF | ZE_RDES0_CE | ZE_RDES0_CS |
                    452:                            ZE_RDES0_LE | ZE_RDES0_RF)) == 0)
                    453:                                rdes0 &= ~ZE_RDES0_ES;
                    454:                }
                    455:                if (rdes0 & ZE_RDES0_ES) {
                    456:                        ifp->if_ierrors++;
                    457:                        if (rdes0 & ZE_RDES0_CS)
                    458:                                ifp->if_collisions++;
                    459:                        m = NULL;
                    460:                } else {
                    461:                        ifp->if_ipackets++;
                    462:                        m = sc->sc_rxmbuf[sc->sc_nextrx];
                    463:                        len = zc->zc_recv[sc->sc_nextrx].ze_framelen;
                    464:                }
                    465:                ze_add_rxbuf(sc, sc->sc_nextrx);
                    466:                if (m != NULL) {
                    467:                        m->m_pkthdr.rcvif = ifp;
                    468:                        m->m_pkthdr.len = m->m_len = len;
                    469:                        eh = mtod(m, struct ether_header *);
                    470: #if NBPFILTER > 0
                    471:                        if (ifp->if_bpf) {
                    472:                                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                    473:                                if ((ifp->if_flags & IFF_PROMISC) != 0 &&
                    474:                                    ((eh->ether_dhost[0] & 1) == 0) &&
                    475:                                    bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
                    476:                                    ETHER_ADDR_LEN) != 0) {
                    477:                                        m_freem(m);
                    478:                                        continue;
                    479:                                }
                    480:                        }
                    481: #endif
                    482:                        /*
                    483:                         * ALLMULTI means PROMISC in this driver.
                    484:                         */
                    485:                        if ((ifp->if_flags & IFF_ALLMULTI) &&
                    486:                            ((eh->ether_dhost[0] & 1) == 0) &&
                    487:                            bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
                    488:                            ETHER_ADDR_LEN)) {
                    489:                                m_freem(m);
                    490:                                continue;
                    491:                        }
                    492:                        ether_input_mbuf(ifp, m);
                    493:                }
                    494:                if (++sc->sc_nextrx == RXDESCS)
                    495:                        sc->sc_nextrx = 0;
                    496:        }
                    497: }
                    498:
                    499: void
                    500: sgec_txintr(struct ze_softc *sc)
                    501: {
                    502:        struct ze_cdata *zc = sc->sc_zedata;
                    503:        struct ifnet *ifp = &sc->sc_if;
                    504:        u_short tdes0;
                    505:
                    506:        while ((zc->zc_xmit[sc->sc_lastack].ze_tdr & ZE_TDR_OW) == 0) {
                    507:                int idx = sc->sc_lastack;
                    508:
                    509:                if (sc->sc_lastack == sc->sc_nexttx)
                    510:                        break;
                    511:                sc->sc_inq--;
                    512:                if (++sc->sc_lastack == TXDESCS)
                    513:                        sc->sc_lastack = 0;
                    514:
                    515:                if ((zc->zc_xmit[idx].ze_tdes1 & ZE_TDES1_DT) ==
                    516:                    ZE_TDES1_DT_SETUP) {
                    517:                        continue;
                    518:                }
                    519:
                    520:                tdes0 = zc->zc_xmit[idx].ze_tdes0;
                    521:                if (tdes0 & ZE_TDES0_ES) {
                    522:                        if (tdes0 & ZE_TDES0_TO)
                    523:                                printf("%s: transmit watchdog timeout\n",
                    524:                                    sc->sc_dev.dv_xname);
                    525:                        if (tdes0 & (ZE_TDES0_LO | ZE_TDES0_NC))
                    526:                                printf("%s: no carrier\n",
                    527:                                    sc->sc_dev.dv_xname);
                    528:                        if (tdes0 & ZE_TDES0_EC) {
                    529:                                printf("%s: excessive collisions, tdr %d\n",
                    530:                                    sc->sc_dev.dv_xname,
                    531:                                    zc->zc_xmit[idx].ze_tdr & ~ZE_TDR_OW);
                    532:                                ifp->if_collisions += 16;
                    533:                        } else if (tdes0 & ZE_TDES0_LC)
                    534:                                ifp->if_collisions +=
                    535:                                    (tdes0 & ZE_TDES0_CC) >> 3;
                    536:                        if (tdes0 & ZE_TDES0_UF)
                    537:                                printf("%s: underflow\n", sc->sc_dev.dv_xname);
                    538:                        ifp->if_oerrors++;
                    539:                        if (tdes0 & (ZE_TDES0_TO | ZE_TDES0_UF))
                    540:                                zeinit(sc);
                    541:                } else {
                    542:                        if (zc->zc_xmit[idx].ze_tdes1 & ZE_TDES1_LS)
                    543:                                ifp->if_opackets++;
                    544:                        bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[idx]);
                    545:                        if (sc->sc_txmbuf[idx]) {
                    546:                                m_freem(sc->sc_txmbuf[idx]);
                    547:                                sc->sc_txmbuf[idx] = 0;
                    548:                        }
                    549:                }
                    550:        }
                    551:        if (sc->sc_inq == 0)
                    552:                ifp->if_timer = 0;
                    553:        ifp->if_flags &= ~IFF_OACTIVE;
                    554:        zestart(ifp); /* Put in more in queue */
                    555: }
                    556:
                    557: int
                    558: sgec_intr(sc)
                    559:        struct ze_softc *sc;
                    560: {
                    561:        int s, csr;
                    562:
                    563:        csr = ZE_RCSR(ZE_CSR5);
                    564:        if ((csr & ZE_NICSR5_IS) == 0) /* Wasn't we */
                    565:                return 0;
                    566:
                    567:        /*
                    568:         * On some systems, interrupts are handled at spl4, this can end up
                    569:         * in pool corruption.
                    570:         */
                    571:        s = splnet();
                    572:
                    573:        ZE_WCSR(ZE_CSR5, csr);
                    574:
                    575:        if (csr & ZE_NICSR5_ME) {
                    576:                printf("%s: memory error, resetting\n", sc->sc_dev.dv_xname);
                    577:                zeinit(sc);
                    578:                return (1);
                    579:        }
                    580:
                    581:        if (csr & ZE_NICSR5_RI)
                    582:                sgec_rxintr(sc);
                    583:
                    584:        if (csr & ZE_NICSR5_TI)
                    585:                sgec_txintr(sc);
                    586:
                    587:        splx(s);
                    588:
                    589:        return 1;
                    590: }
                    591:
                    592: /*
                    593:  * Process an ioctl request.
                    594:  */
                    595: int
                    596: zeioctl(ifp, cmd, data)
                    597:        struct ifnet *ifp;
                    598:        u_long cmd;
                    599:        caddr_t data;
                    600: {
                    601:        struct ze_softc *sc = ifp->if_softc;
                    602:        struct ifreq *ifr = (struct ifreq *)data;
                    603:        struct ifaddr *ifa = (struct ifaddr *)data;
                    604:        int s = splnet(), error = 0;
                    605:
                    606:        switch (cmd) {
                    607:
                    608:        case SIOCSIFADDR:
                    609:                ifp->if_flags |= IFF_UP;
                    610:                switch(ifa->ifa_addr->sa_family) {
                    611: #ifdef INET
                    612:                case AF_INET:
                    613:                        zeinit(sc);
                    614:                        arp_ifinit(&sc->sc_ac, ifa);
                    615:                        break;
                    616: #endif
                    617:                }
                    618:                break;
                    619:
                    620:        case SIOCSIFFLAGS:
                    621:                if ((ifp->if_flags & IFF_UP) == 0 &&
                    622:                    (ifp->if_flags & IFF_RUNNING) != 0) {
                    623:                        /*
                    624:                         * If interface is marked down and it is running,
                    625:                         * stop it. (by disabling receive mechanism).
                    626:                         */
                    627:                        ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) &
                    628:                            ~(ZE_NICSR6_ST|ZE_NICSR6_SR));
                    629:                        ifp->if_flags &= ~IFF_RUNNING;
                    630:                } else if ((ifp->if_flags & IFF_UP) != 0 &&
                    631:                           (ifp->if_flags & IFF_RUNNING) == 0) {
                    632:                        /*
                    633:                         * If interface it marked up and it is stopped, then
                    634:                         * start it.
                    635:                         */
                    636:                        zeinit(sc);
                    637:                } else if ((ifp->if_flags & IFF_UP) != 0) {
                    638:                        /*
                    639:                         * Send a new setup packet to match any new changes.
                    640:                         * (Like IFF_PROMISC etc)
                    641:                         */
                    642:                        ze_setup(sc);
                    643:                }
                    644:                break;
                    645:
                    646:        case SIOCADDMULTI:
                    647:        case SIOCDELMULTI:
                    648:                /*
                    649:                 * Update our multicast list.
                    650:                 */
                    651:                error = (cmd == SIOCADDMULTI) ?
                    652:                        ether_addmulti(ifr, &sc->sc_ac):
                    653:                        ether_delmulti(ifr, &sc->sc_ac);
                    654:
                    655:                if (error == ENETRESET) {
                    656:                        /*
                    657:                         * Multicast list has changed; set the hardware filter
                    658:                         * accordingly.
                    659:                         */
                    660:                        if (ifp->if_flags & IFF_RUNNING)
                    661:                                ze_setup(sc);
                    662:                        error = 0;
                    663:                }
                    664:                break;
                    665:
                    666:        default:
                    667:                error = EINVAL;
                    668:
                    669:        }
                    670:        splx(s);
                    671:        return (error);
                    672: }
                    673:
                    674: /*
                    675:  * Add a receive buffer to the indicated descriptor.
                    676:  */
                    677: int
                    678: ze_add_rxbuf(sc, i)
                    679:        struct ze_softc *sc;
                    680:        int i;
                    681: {
                    682:        struct mbuf *m;
                    683:        struct ze_rdes *rp;
                    684:        int error;
                    685:
                    686:        splassert(IPL_NET);
                    687:
                    688:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    689:        if (m == NULL)
                    690:                return (ENOBUFS);
                    691:
                    692:        MCLGET(m, M_DONTWAIT);
                    693:        if ((m->m_flags & M_EXT) == 0) {
                    694:                m_freem(m);
                    695:                return (ENOBUFS);
                    696:        }
                    697:
                    698:        if (sc->sc_rxmbuf[i] != NULL)
                    699:                bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
                    700:
                    701:        error = bus_dmamap_load(sc->sc_dmat, sc->sc_rcvmap[i],
                    702:            m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
                    703:        if (error)
                    704:                panic("%s: can't load rx DMA map %d, error = %d",
                    705:                    sc->sc_dev.dv_xname, i, error);
                    706:        sc->sc_rxmbuf[i] = m;
                    707:
                    708:        bus_dmamap_sync(sc->sc_dmat, sc->sc_rcvmap[i], 0,
                    709:            sc->sc_rcvmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD);
                    710:
                    711:        /*
                    712:         * We know that the mbuf cluster is page aligned. Also, be sure
                    713:         * that the IP header will be longword aligned.
                    714:         */
                    715:        m->m_data += 2;
                    716:        rp = &sc->sc_zedata->zc_recv[i];
                    717:        rp->ze_bufsize = (m->m_ext.ext_size - 2);
                    718:        rp->ze_bufaddr = (char *)sc->sc_rcvmap[i]->dm_segs[0].ds_addr + 2;
                    719:        rp->ze_framelen = ZE_FRAMELEN_OW;
                    720:
                    721:        return (0);
                    722: }
                    723:
                    724: /*
                    725:  * Create a setup packet and put in queue for sending.
                    726:  */
                    727: void
                    728: ze_setup(sc)
                    729:        struct ze_softc *sc;
                    730: {
                    731:        struct ether_multi *enm;
                    732:        struct ether_multistep step;
                    733:        struct ze_cdata *zc = sc->sc_zedata;
                    734:        struct ifnet *ifp = &sc->sc_if;
                    735:        u_int8_t *enaddr = sc->sc_ac.ac_enaddr;
                    736:        int j, idx, s, reg;
                    737:
                    738:        s = splnet();
                    739:        if (sc->sc_inq == (TXDESCS - 1)) {
                    740:                SET(sc->sc_flags, SGECF_SETUP);
                    741:                splx(s);
                    742:                return;
                    743:        }
                    744:        CLR(sc->sc_flags, SGECF_SETUP);
                    745:
                    746:        /*
                    747:         * Init the setup packet with valid info.
                    748:         */
                    749:        memset(zc->zc_setup, 0xff, sizeof(zc->zc_setup)); /* Broadcast */
                    750:        bcopy(enaddr, zc->zc_setup, ETHER_ADDR_LEN);
                    751:
                    752:        /*
                    753:         * Multicast handling. The SGEC can handle up to 16 direct
                    754:         * ethernet addresses.
                    755:         */
                    756:        j = 16;
                    757:        ifp->if_flags &= ~IFF_ALLMULTI;
                    758:        ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
                    759:        while (enm != NULL) {
                    760:                if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
                    761:                        ifp->if_flags |= IFF_ALLMULTI;
                    762:                        break;
                    763:                }
                    764:                bcopy(enm->enm_addrlo, &zc->zc_setup[j], ETHER_ADDR_LEN);
                    765:                j += 8;
                    766:                ETHER_NEXT_MULTI(step, enm);
                    767:                if ((enm != NULL)&& (j == 128)) {
                    768:                        ifp->if_flags |= IFF_ALLMULTI;
                    769:                        break;
                    770:                }
                    771:        }
                    772:
                    773:        /*
                    774:         * Fiddle with the receive logic.
                    775:         */
                    776:        reg = ZE_RCSR(ZE_CSR6);
                    777:        DELAY(10);
                    778:        ZE_WCSR(ZE_CSR6, reg & ~ZE_NICSR6_SR); /* Stop rx */
                    779:        while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_RS) != ZE_NICSR5_RS_STOP)
                    780:                DELAY(10);
                    781:        reg &= ~ZE_NICSR6_AF;
                    782:        if (ifp->if_flags & IFF_PROMISC)
                    783:                reg |= ZE_NICSR6_AF_PROM;
                    784:        else if (ifp->if_flags & IFF_ALLMULTI)
                    785:                reg |= ZE_NICSR6_AF_ALLM;
                    786:        DELAY(10);
                    787:        ZE_WCSR(ZE_CSR6, reg);
                    788:        while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_RS) == ZE_NICSR5_RS_STOP)
                    789:                DELAY(10);
                    790:        /*
                    791:         * Only send a setup packet if needed.
                    792:         */
                    793:        if ((ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) == 0) {
                    794:                idx = sc->sc_nexttx;
                    795:                zc->zc_xmit[idx].ze_tdes1 = ZE_TDES1_DT_SETUP;
                    796:                zc->zc_xmit[idx].ze_bufsize = 128;
                    797:                zc->zc_xmit[idx].ze_bufaddr = sc->sc_pzedata->zc_setup;
                    798:                zc->zc_xmit[idx].ze_tdr = ZE_TDR_OW;
                    799:
                    800:                zekick(sc);
                    801:
                    802:                sc->sc_inq++;
                    803:                if (++sc->sc_nexttx == TXDESCS)
                    804:                        sc->sc_nexttx = 0;
                    805:        }
                    806:        splx(s);
                    807: }
                    808:
                    809: /*
                    810:  * Check for dead transmit logic.
                    811:  */
                    812: void
                    813: zetimeout(ifp)
                    814:        struct ifnet *ifp;
                    815: {
                    816:        struct ze_softc *sc = ifp->if_softc;
                    817:
                    818:        if (sc->sc_inq == 0)
                    819:                return;
                    820:
                    821:        printf("%s: xmit logic died, resetting...\n", sc->sc_dev.dv_xname);
                    822:        /*
                    823:         * Do a reset of interface, to get it going again.
                    824:         * Will it work by just restart the transmit logic?
                    825:         */
                    826:        zeinit(sc);
                    827: }
                    828:
                    829: /*
                    830:  * Reset chip:
                    831:  * Set/reset the reset flag.
                    832:  *  Write interrupt vector.
                    833:  *  Write ring buffer addresses.
                    834:  *  Write SBR.
                    835:  */
                    836: int
                    837: zereset(sc)
                    838:        struct ze_softc *sc;
                    839: {
                    840:        int reg, i, s;
                    841:
                    842:        ZE_WCSR(ZE_CSR6, ZE_NICSR6_RE);
                    843:        DELAY(50000);
                    844:        if (ZE_RCSR(ZE_CSR5) & ZE_NICSR5_SF) {
                    845:                printf("%s: selftest failed\n", sc->sc_dev.dv_xname);
                    846:                return 1;
                    847:        }
                    848:
                    849:        /*
                    850:         * Get the vector that were set at match time, and remember it.
                    851:         * WHICH VECTOR TO USE? Take one unused. XXX
                    852:         * Funny way to set vector described in the programmers manual.
                    853:         */
                    854:        reg = ZE_NICSR0_IPL14 | sc->sc_intvec | ZE_NICSR0_MBO; /* SYNC/ASYNC??? */
                    855:        i = 10;
                    856:        s = splnet();
                    857:        do {
                    858:                if (i-- == 0) {
                    859:                        printf("Failing SGEC CSR0 init\n");
                    860:                        splx(s);
                    861:                        return 1;
                    862:                }
                    863:                ZE_WCSR(ZE_CSR0, reg);
                    864:        } while (ZE_RCSR(ZE_CSR0) != reg);
                    865:        splx(s);
                    866:
                    867:        ZE_WCSR(ZE_CSR3, (vaddr_t)sc->sc_pzedata->zc_recv);
                    868:        ZE_WCSR(ZE_CSR4, (vaddr_t)sc->sc_pzedata->zc_xmit);
                    869:        return 0;
                    870: }

CVSweb