[BACK]Return to if_txp.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/if_txp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_txp.c,v 1.84 2007/04/11 14:41:15 claudio Exp $     */
                      2:
                      3: /*
                      4:  * Copyright (c) 2001
                      5:  *     Jason L. Wright <jason@thought.net>, Theo de Raadt, and
                      6:  *     Aaron Campbell <aaron@monkey.org>.  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:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
                     18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     19:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR THE VOICES IN THEIR HEADS
                     21:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     22:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     23:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     24:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     25:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     26:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     27:  * THE POSSIBILITY OF SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * Driver for 3c990 (Typhoon) Ethernet ASIC
                     32:  */
                     33:
                     34: #include "bpfilter.h"
                     35: #include "vlan.h"
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/sockio.h>
                     40: #include <sys/mbuf.h>
                     41: #include <sys/malloc.h>
                     42: #include <sys/kernel.h>
                     43: #include <sys/socket.h>
                     44: #include <sys/device.h>
                     45: #include <sys/timeout.h>
                     46:
                     47: #include <net/if.h>
                     48: #include <net/if_dl.h>
                     49: #include <net/if_types.h>
                     50:
                     51: #ifdef INET
                     52: #include <netinet/in.h>
                     53: #include <netinet/in_systm.h>
                     54: #include <netinet/in_var.h>
                     55: #include <netinet/ip.h>
                     56: #include <netinet/if_ether.h>
                     57: #endif
                     58:
                     59: #include <net/if_media.h>
                     60:
                     61: #if NBPFILTER > 0
                     62: #include <net/bpf.h>
                     63: #endif
                     64:
                     65: #if NVLAN > 0
                     66: #include <net/if_types.h>
                     67: #include <net/if_vlan_var.h>
                     68: #endif
                     69:
                     70: #include <machine/bus.h>
                     71:
                     72: #include <dev/mii/mii.h>
                     73: #include <dev/mii/miivar.h>
                     74: #include <dev/pci/pcireg.h>
                     75: #include <dev/pci/pcivar.h>
                     76: #include <dev/pci/pcidevs.h>
                     77:
                     78: #include <dev/pci/if_txpreg.h>
                     79:
                     80: /*
                     81:  * These currently break the 3c990 firmware, hopefully will be resolved
                     82:  * at some point.
                     83:  */
                     84: #undef TRY_TX_UDP_CSUM
                     85: #undef TRY_TX_TCP_CSUM
                     86:
                     87: int txp_probe(struct device *, void *, void *);
                     88: void txp_attach(struct device *, struct device *, void *);
                     89: void txp_attachhook(void *vsc);
                     90: int txp_intr(void *);
                     91: void txp_tick(void *);
                     92: void txp_shutdown(void *);
                     93: int txp_ioctl(struct ifnet *, u_long, caddr_t);
                     94: void txp_start(struct ifnet *);
                     95: void txp_stop(struct txp_softc *);
                     96: void txp_init(struct txp_softc *);
                     97: void txp_watchdog(struct ifnet *);
                     98:
                     99: int txp_chip_init(struct txp_softc *);
                    100: int txp_reset_adapter(struct txp_softc *);
                    101: int txp_download_fw(struct txp_softc *);
                    102: int txp_download_fw_wait(struct txp_softc *);
                    103: int txp_download_fw_section(struct txp_softc *,
                    104:     struct txp_fw_section_header *, int, u_char *, size_t);
                    105: int txp_alloc_rings(struct txp_softc *);
                    106: void txp_dma_free(struct txp_softc *, struct txp_dma_alloc *);
                    107: int txp_dma_malloc(struct txp_softc *, bus_size_t, struct txp_dma_alloc *, int);
                    108: void txp_set_filter(struct txp_softc *);
                    109:
                    110: int txp_cmd_desc_numfree(struct txp_softc *);
                    111: int txp_command(struct txp_softc *, u_int16_t, u_int16_t, u_int32_t,
                    112:     u_int32_t, u_int16_t *, u_int32_t *, u_int32_t *, int);
                    113: int txp_command2(struct txp_softc *, u_int16_t, u_int16_t,
                    114:     u_int32_t, u_int32_t, struct txp_ext_desc *, u_int8_t,
                    115:     struct txp_rsp_desc **, int);
                    116: int txp_response(struct txp_softc *, u_int32_t, u_int16_t, u_int16_t,
                    117:     struct txp_rsp_desc **);
                    118: void txp_rsp_fixup(struct txp_softc *, struct txp_rsp_desc *,
                    119:     struct txp_rsp_desc *);
                    120: void txp_capabilities(struct txp_softc *);
                    121:
                    122: void txp_ifmedia_sts(struct ifnet *, struct ifmediareq *);
                    123: int txp_ifmedia_upd(struct ifnet *);
                    124: void txp_show_descriptor(void *);
                    125: void txp_tx_reclaim(struct txp_softc *, struct txp_tx_ring *,
                    126:     struct txp_dma_alloc *);
                    127: void txp_rxbuf_reclaim(struct txp_softc *);
                    128: void txp_rx_reclaim(struct txp_softc *, struct txp_rx_ring *,
                    129:     struct txp_dma_alloc *);
                    130:
                    131: struct cfattach txp_ca = {
                    132:        sizeof(struct txp_softc), txp_probe, txp_attach,
                    133: };
                    134:
                    135: struct cfdriver txp_cd = {
                    136:        0, "txp", DV_IFNET
                    137: };
                    138:
                    139: const struct pci_matchid txp_devices[] = {
                    140:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990 },
                    141:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990TX },
                    142:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990TX95 },
                    143:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990TX97 },
                    144:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990SVR95 },
                    145:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990SVR97 },
                    146:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C990BTXM },
                    147:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C990BSVR },
                    148:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CR990FX },
                    149: };
                    150:
                    151: int
                    152: txp_probe(parent, match, aux)
                    153:        struct device *parent;
                    154:        void *match, *aux;
                    155: {
                    156:        return (pci_matchbyid((struct pci_attach_args *)aux, txp_devices,
                    157:            sizeof(txp_devices)/sizeof(txp_devices[0])));
                    158: }
                    159:
                    160: void
                    161: txp_attachhook(void *vsc)
                    162: {
                    163:        struct txp_softc *sc = vsc;
                    164:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    165:        u_int16_t p1;
                    166:        u_int32_t p2;
                    167:        int s;
                    168:
                    169:        s = splnet();
                    170:        printf("%s: ", sc->sc_dev.dv_xname);
                    171:
                    172:        if (txp_chip_init(sc)) {
                    173:                printf("failed chip init\n");
                    174:                splx(s);
                    175:                return;
                    176:        }
                    177:
                    178:        if (txp_download_fw(sc)) {
                    179:                splx(s);
                    180:                return;
                    181:        }
                    182:
                    183:        if (txp_alloc_rings(sc)) {
                    184:                splx(s);
                    185:                return;
                    186:        }
                    187:
                    188:        if (txp_command(sc, TXP_CMD_MAX_PKT_SIZE_WRITE, TXP_MAX_PKTLEN, 0, 0,
                    189:            NULL, NULL, NULL, 1)) {
                    190:                splx(s);
                    191:                return;
                    192:        }
                    193:
                    194:        if (txp_command(sc, TXP_CMD_STATION_ADDRESS_READ, 0, 0, 0,
                    195:            &p1, &p2, NULL, 1)) {
                    196:                splx(s);
                    197:                return;
                    198:        }
                    199:
                    200:        txp_set_filter(sc);
                    201:
                    202:        p1 = htole16(p1);
                    203:        sc->sc_arpcom.ac_enaddr[0] = ((u_int8_t *)&p1)[1];
                    204:        sc->sc_arpcom.ac_enaddr[1] = ((u_int8_t *)&p1)[0];
                    205:        p2 = htole32(p2);
                    206:        sc->sc_arpcom.ac_enaddr[2] = ((u_int8_t *)&p2)[3];
                    207:        sc->sc_arpcom.ac_enaddr[3] = ((u_int8_t *)&p2)[2];
                    208:        sc->sc_arpcom.ac_enaddr[4] = ((u_int8_t *)&p2)[1];
                    209:        sc->sc_arpcom.ac_enaddr[5] = ((u_int8_t *)&p2)[0];
                    210:
                    211:        printf("address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
                    212:        sc->sc_cold = 0;
                    213:
                    214:        ifmedia_init(&sc->sc_ifmedia, 0, txp_ifmedia_upd, txp_ifmedia_sts);
                    215:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
                    216:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
                    217:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
                    218:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
                    219:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
                    220:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
                    221:        ifmedia_add(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
                    222:
                    223:        sc->sc_xcvr = TXP_XCVR_AUTO;
                    224:        txp_command(sc, TXP_CMD_XCVR_SELECT, TXP_XCVR_AUTO, 0, 0,
                    225:            NULL, NULL, NULL, 0);
                    226:        ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO);
                    227:
                    228:        ifp->if_softc = sc;
                    229:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    230:        ifp->if_ioctl = txp_ioctl;
                    231:        ifp->if_start = txp_start;
                    232:        ifp->if_watchdog = txp_watchdog;
                    233:        ifp->if_baudrate = 10000000;
                    234:        IFQ_SET_MAXLEN(&ifp->if_snd, TX_ENTRIES);
                    235:        IFQ_SET_READY(&ifp->if_snd);
                    236:        ifp->if_capabilities = 0;
                    237:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                    238:
                    239:        txp_capabilities(sc);
                    240:
                    241:        timeout_set(&sc->sc_tick, txp_tick, sc);
                    242:
                    243:        /*
                    244:         * Attach us everywhere
                    245:         */
                    246:        if_attach(ifp);
                    247:        ether_ifattach(ifp);
                    248:
                    249:        shutdownhook_establish(txp_shutdown, sc);
                    250:        splx(s);
                    251: }
                    252:
                    253: void
                    254: txp_attach(parent, self, aux)
                    255:        struct device *parent, *self;
                    256:        void *aux;
                    257: {
                    258:        struct txp_softc *sc = (struct txp_softc *)self;
                    259:        struct pci_attach_args *pa = aux;
                    260:        pci_chipset_tag_t pc = pa->pa_pc;
                    261:        pci_intr_handle_t ih;
                    262:        const char *intrstr = NULL;
                    263:        bus_size_t iosize;
                    264:
                    265:        sc->sc_cold = 1;
                    266:
                    267:        if (pci_mapreg_map(pa, TXP_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
                    268:            &sc->sc_bt, &sc->sc_bh, NULL, &iosize, 0)) {
                    269:                printf(": can't map mem space %d\n", 0);
                    270:                return;
                    271:        }
                    272:
                    273:        sc->sc_dmat = pa->pa_dmat;
                    274:
                    275:        /*
                    276:         * Allocate our interrupt.
                    277:         */
                    278:        if (pci_intr_map(pa, &ih)) {
                    279:                printf(": couldn't map interrupt\n");
                    280:                return;
                    281:        }
                    282:
                    283:        intrstr = pci_intr_string(pc, ih);
                    284:        sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, txp_intr, sc,
                    285:            self->dv_xname);
                    286:        if (sc->sc_ih == NULL) {
                    287:                printf(": couldn't establish interrupt");
                    288:                if (intrstr != NULL)
                    289:                        printf(" at %s", intrstr);
                    290:                printf("\n");
                    291:                return;
                    292:        }
                    293:        printf(": %s\n", intrstr);
                    294:
                    295:        if (rootvp == NULL)
                    296:                mountroothook_establish(txp_attachhook, sc);
                    297:        else
                    298:                txp_attachhook(sc);
                    299:
                    300: }
                    301:
                    302: int
                    303: txp_chip_init(sc)
                    304:        struct txp_softc *sc;
                    305: {
                    306:        /* disable interrupts */
                    307:        WRITE_REG(sc, TXP_IER, 0);
                    308:        WRITE_REG(sc, TXP_IMR,
                    309:            TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
                    310:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    311:            TXP_INT_LATCH);
                    312:
                    313:        /* ack all interrupts */
                    314:        WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH |
                    315:            TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
                    316:            TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
                    317:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    318:            TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0);
                    319:
                    320:        if (txp_reset_adapter(sc))
                    321:                return (-1);
                    322:
                    323:        /* disable interrupts */
                    324:        WRITE_REG(sc, TXP_IER, 0);
                    325:        WRITE_REG(sc, TXP_IMR,
                    326:            TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
                    327:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    328:            TXP_INT_LATCH);
                    329:
                    330:        /* ack all interrupts */
                    331:        WRITE_REG(sc, TXP_ISR, TXP_INT_RESERVED | TXP_INT_LATCH |
                    332:            TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
                    333:            TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
                    334:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    335:            TXP_INT_A2H_3 | TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0);
                    336:
                    337:        return (0);
                    338: }
                    339:
                    340: int
                    341: txp_reset_adapter(sc)
                    342:        struct txp_softc *sc;
                    343: {
                    344:        u_int32_t r;
                    345:        int i;
                    346:
                    347:        WRITE_REG(sc, TXP_SRR, TXP_SRR_ALL);
                    348:        DELAY(1000);
                    349:        WRITE_REG(sc, TXP_SRR, 0);
                    350:
                    351:        /* Should wait max 6 seconds */
                    352:        for (i = 0; i < 6000; i++) {
                    353:                r = READ_REG(sc, TXP_A2H_0);
                    354:                if (r == STAT_WAITING_FOR_HOST_REQUEST)
                    355:                        break;
                    356:                DELAY(1000);
                    357:        }
                    358:
                    359:        if (r != STAT_WAITING_FOR_HOST_REQUEST) {
                    360:                printf("%s: reset hung\n", TXP_DEVNAME(sc));
                    361:                return (-1);
                    362:        }
                    363:
                    364:        return (0);
                    365: }
                    366:
                    367: int
                    368: txp_download_fw(sc)
                    369:        struct txp_softc *sc;
                    370: {
                    371:        struct txp_fw_file_header *fileheader;
                    372:        struct txp_fw_section_header *secthead;
                    373:        u_int32_t r, i, ier, imr;
                    374:        size_t buflen;
                    375:        int sect, err;
                    376:        u_char *buf;
                    377:
                    378:        ier = READ_REG(sc, TXP_IER);
                    379:        WRITE_REG(sc, TXP_IER, ier | TXP_INT_A2H_0);
                    380:
                    381:        imr = READ_REG(sc, TXP_IMR);
                    382:        WRITE_REG(sc, TXP_IMR, imr | TXP_INT_A2H_0);
                    383:
                    384:        for (i = 0; i < 10000; i++) {
                    385:                r = READ_REG(sc, TXP_A2H_0);
                    386:                if (r == STAT_WAITING_FOR_HOST_REQUEST)
                    387:                        break;
                    388:                DELAY(50);
                    389:        }
                    390:        if (r != STAT_WAITING_FOR_HOST_REQUEST) {
                    391:                printf("not waiting for host request\n");
                    392:                return (-1);
                    393:        }
                    394:
                    395:        /* Ack the status */
                    396:        WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0);
                    397:
                    398:        err = loadfirmware("3c990", &buf, &buflen);
                    399:        if (err) {
                    400:                printf("failed loadfirmware of file 3c990: errno %d\n",
                    401:                    err);
                    402:                return (err);
                    403:        }
                    404:
                    405:        fileheader = (struct txp_fw_file_header *)buf;
                    406:        if (bcmp("TYPHOON", fileheader->magicid, sizeof(fileheader->magicid))) {
                    407:                printf("firmware invalid magic\n");
                    408:                goto fail;
                    409:        }
                    410:
                    411:        /* Tell boot firmware to get ready for image */
                    412:        WRITE_REG(sc, TXP_H2A_1, letoh32(fileheader->addr));
                    413:        WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_RUNTIME_IMAGE);
                    414:
                    415:        if (txp_download_fw_wait(sc)) {
                    416:                printf("fw wait failed, initial\n");
                    417:                goto fail;
                    418:        }
                    419:
                    420:        secthead = (struct txp_fw_section_header *)(buf +
                    421:            sizeof(struct txp_fw_file_header));
                    422:
                    423:        for (sect = 0; sect < letoh32(fileheader->nsections); sect++) {
                    424:                if (txp_download_fw_section(sc, secthead, sect, buf, buflen))
                    425:                        goto fail;
                    426:                secthead = (struct txp_fw_section_header *)
                    427:                    (((u_int8_t *)secthead) + letoh32(secthead->nbytes) +
                    428:                        sizeof(*secthead));
                    429:        }
                    430:
                    431:        WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_DOWNLOAD_COMPLETE);
                    432:
                    433:        for (i = 0; i < 10000; i++) {
                    434:                r = READ_REG(sc, TXP_A2H_0);
                    435:                if (r == STAT_WAITING_FOR_BOOT)
                    436:                        break;
                    437:                DELAY(50);
                    438:        }
                    439:        if (r != STAT_WAITING_FOR_BOOT) {
                    440:                printf("not waiting for boot\n");
                    441:                goto fail;
                    442:        }
                    443:
                    444:        WRITE_REG(sc, TXP_IER, ier);
                    445:        WRITE_REG(sc, TXP_IMR, imr);
                    446:
                    447:        free(buf, M_DEVBUF);
                    448:        printf("loaded firmware, ");
                    449:        return (0);
                    450: fail:
                    451:        free(buf, M_DEVBUF);
                    452:        return (-1);
                    453: }
                    454:
                    455: int
                    456: txp_download_fw_wait(sc)
                    457:        struct txp_softc *sc;
                    458: {
                    459:        u_int32_t i, r;
                    460:
                    461:        for (i = 0; i < 10000; i++) {
                    462:                r = READ_REG(sc, TXP_ISR);
                    463:                if (r & TXP_INT_A2H_0)
                    464:                        break;
                    465:                DELAY(50);
                    466:        }
                    467:
                    468:        if (!(r & TXP_INT_A2H_0)) {
                    469:                printf("fw wait failed comm0\n");
                    470:                return (-1);
                    471:        }
                    472:
                    473:        WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0);
                    474:
                    475:        r = READ_REG(sc, TXP_A2H_0);
                    476:        if (r != STAT_WAITING_FOR_SEGMENT) {
                    477:                printf("fw not waiting for segment\n");
                    478:                return (-1);
                    479:        }
                    480:        return (0);
                    481: }
                    482:
                    483: int
                    484: txp_download_fw_section(sc, sect, sectnum, buf, buflen)
                    485:        struct txp_softc *sc;
                    486:        struct txp_fw_section_header *sect;
                    487:        int sectnum;
                    488:        u_char *buf;
                    489:        size_t buflen;
                    490: {
                    491:        struct txp_dma_alloc dma;
                    492:        int rseg, err = 0;
                    493:        struct mbuf m;
                    494:        u_int16_t csum;
                    495:
                    496:        /* Skip zero length sections */
                    497:        if (sect->nbytes == 0)
                    498:                return (0);
                    499:
                    500:        /* Make sure we aren't past the end of the image */
                    501:        rseg = ((u_int8_t *)sect) - ((u_int8_t *)buf);
                    502:        if (rseg >= buflen) {
                    503:                printf("fw invalid section address, section %d\n", sectnum);
                    504:                return (-1);
                    505:        }
                    506:
                    507:        /* Make sure this section doesn't go past the end */
                    508:        rseg += letoh32(sect->nbytes);
                    509:        if (rseg >= buflen) {
                    510:                printf("fw truncated section %d\n", sectnum);
                    511:                return (-1);
                    512:        }
                    513:
                    514:        /* map a buffer, copy segment to it, get physaddr */
                    515:        if (txp_dma_malloc(sc, letoh32(sect->nbytes), &dma, 0)) {
                    516:                printf("fw dma malloc failed, section %d\n", sectnum);
                    517:                return (-1);
                    518:        }
                    519:
                    520:        bcopy(((u_int8_t *)sect) + sizeof(*sect), dma.dma_vaddr,
                    521:            letoh32(sect->nbytes));
                    522:
                    523:        /*
                    524:         * dummy up mbuf and verify section checksum
                    525:         */
                    526:        m.m_type = MT_DATA;
                    527:        m.m_next = m.m_nextpkt = NULL;
                    528:        m.m_len = letoh32(sect->nbytes);
                    529:        m.m_data = dma.dma_vaddr;
                    530:        m.m_flags = 0;
                    531:        csum = in_cksum(&m, letoh32(sect->nbytes));
                    532:        if (csum != sect->cksum) {
                    533:                printf("fw section %d, bad cksum (expected 0x%x got 0x%x)\n",
                    534:                    sectnum, sect->cksum, csum);
                    535:                err = -1;
                    536:                goto bail;
                    537:        }
                    538:
                    539:        bus_dmamap_sync(sc->sc_dmat, dma.dma_map, 0,
                    540:            dma.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
                    541:
                    542:        WRITE_REG(sc, TXP_H2A_1, letoh32(sect->nbytes));
                    543:        WRITE_REG(sc, TXP_H2A_2, letoh16(sect->cksum));
                    544:        WRITE_REG(sc, TXP_H2A_3, letoh32(sect->addr));
                    545:        WRITE_REG(sc, TXP_H2A_4, dma.dma_paddr >> 32);
                    546:        WRITE_REG(sc, TXP_H2A_5, dma.dma_paddr & 0xffffffff);
                    547:        WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_SEGMENT_AVAILABLE);
                    548:
                    549:        if (txp_download_fw_wait(sc)) {
                    550:                printf("%s: fw wait failed, section %d\n",
                    551:                    sc->sc_dev.dv_xname, sectnum);
                    552:                err = -1;
                    553:        }
                    554:
                    555:        bus_dmamap_sync(sc->sc_dmat, dma.dma_map, 0,
                    556:            dma.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    557:
                    558: bail:
                    559:        txp_dma_free(sc, &dma);
                    560:
                    561:        return (err);
                    562: }
                    563:
                    564: int
                    565: txp_intr(vsc)
                    566:        void *vsc;
                    567: {
                    568:        struct txp_softc *sc = vsc;
                    569:        struct txp_hostvar *hv = sc->sc_hostvar;
                    570:        u_int32_t isr;
                    571:        int claimed = 0;
                    572:
                    573:        /* mask all interrupts */
                    574:        WRITE_REG(sc, TXP_IMR, TXP_INT_RESERVED | TXP_INT_SELF |
                    575:            TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
                    576:            TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 |
                    577:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    578:            TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |  TXP_INT_LATCH);
                    579:
                    580:        bus_dmamap_sync(sc->sc_dmat, sc->sc_host_dma.dma_map, 0,
                    581:            sizeof(struct txp_hostvar), BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
                    582:
                    583:        isr = READ_REG(sc, TXP_ISR);
                    584:        while (isr) {
                    585:                claimed = 1;
                    586:                WRITE_REG(sc, TXP_ISR, isr);
                    587:
                    588:                if ((*sc->sc_rxhir.r_roff) != (*sc->sc_rxhir.r_woff))
                    589:                        txp_rx_reclaim(sc, &sc->sc_rxhir, &sc->sc_rxhiring_dma);
                    590:                if ((*sc->sc_rxlor.r_roff) != (*sc->sc_rxlor.r_woff))
                    591:                        txp_rx_reclaim(sc, &sc->sc_rxlor, &sc->sc_rxloring_dma);
                    592:
                    593:                if (hv->hv_rx_buf_write_idx == hv->hv_rx_buf_read_idx)
                    594:                        txp_rxbuf_reclaim(sc);
                    595:
                    596:                if (sc->sc_txhir.r_cnt && (sc->sc_txhir.r_cons !=
                    597:                    TXP_OFFSET2IDX(letoh32(*(sc->sc_txhir.r_off)))))
                    598:                        txp_tx_reclaim(sc, &sc->sc_txhir, &sc->sc_txhiring_dma);
                    599:
                    600:                if (sc->sc_txlor.r_cnt && (sc->sc_txlor.r_cons !=
                    601:                    TXP_OFFSET2IDX(letoh32(*(sc->sc_txlor.r_off)))))
                    602:                        txp_tx_reclaim(sc, &sc->sc_txlor, &sc->sc_txloring_dma);
                    603:
                    604:                isr = READ_REG(sc, TXP_ISR);
                    605:        }
                    606:
                    607:        bus_dmamap_sync(sc->sc_dmat, sc->sc_host_dma.dma_map, 0,
                    608:            sizeof(struct txp_hostvar), BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
                    609:
                    610:        /* unmask all interrupts */
                    611:        WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3);
                    612:
                    613:        txp_start(&sc->sc_arpcom.ac_if);
                    614:
                    615:        return (claimed);
                    616: }
                    617:
                    618: void
                    619: txp_rx_reclaim(sc, r, dma)
                    620:        struct txp_softc *sc;
                    621:        struct txp_rx_ring *r;
                    622:        struct txp_dma_alloc *dma;
                    623: {
                    624:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    625:        struct txp_rx_desc *rxd;
                    626:        struct mbuf *m;
                    627:        struct txp_swdesc *sd;
                    628:        u_int32_t roff, woff;
                    629:        int sumflags = 0, idx;
                    630:
                    631:        roff = letoh32(*r->r_roff);
                    632:        woff = letoh32(*r->r_woff);
                    633:        idx = roff / sizeof(struct txp_rx_desc);
                    634:        rxd = r->r_desc + idx;
                    635:
                    636:        while (roff != woff) {
                    637:
                    638:                bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
                    639:                    idx * sizeof(struct txp_rx_desc), sizeof(struct txp_rx_desc),
                    640:                    BUS_DMASYNC_POSTREAD);
                    641:
                    642:                if (rxd->rx_flags & RX_FLAGS_ERROR) {
                    643:                        printf("%s: error 0x%x\n", sc->sc_dev.dv_xname,
                    644:                            letoh32(rxd->rx_stat));
                    645:                        ifp->if_ierrors++;
                    646:                        goto next;
                    647:                }
                    648:
                    649:                /* retrieve stashed pointer */
                    650:                bcopy((u_long *)&rxd->rx_vaddrlo, &sd, sizeof(sd));
                    651:
                    652:                bus_dmamap_sync(sc->sc_dmat, sd->sd_map, 0,
                    653:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                    654:                bus_dmamap_unload(sc->sc_dmat, sd->sd_map);
                    655:                bus_dmamap_destroy(sc->sc_dmat, sd->sd_map);
                    656:                m = sd->sd_mbuf;
                    657:                free(sd, M_DEVBUF);
                    658:                m->m_pkthdr.len = m->m_len = letoh16(rxd->rx_len);
                    659:
                    660: #if NVLAN > 0
                    661:                /*
                    662:                 * XXX Another firmware bug: the vlan encapsulation
                    663:                 * is always removed, even when we tell the card not
                    664:                 * to do that.  Restore the vlan encapsulation below.
                    665:                 */
                    666:                if (rxd->rx_stat & htole32(RX_STAT_VLAN)) {
                    667:                        struct ether_vlan_header vh;
                    668:
                    669:                        if (m->m_pkthdr.len < ETHER_HDR_LEN) {
                    670:                                m_freem(m);
                    671:                                goto next;
                    672:                        }
                    673:                        m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&vh);
                    674:                        vh.evl_proto = vh.evl_encap_proto;
                    675:                        vh.evl_tag = rxd->rx_vlan >> 16;
                    676:                        vh.evl_encap_proto = htons(ETHERTYPE_VLAN);
                    677:                        m_adj(m, ETHER_HDR_LEN);
                    678:                        M_PREPEND(m, sizeof(vh), M_DONTWAIT);
                    679:                        if (m == NULL)
                    680:                                goto next;
                    681:                        m_copyback(m, 0, sizeof(vh), &vh);
                    682:                }
                    683: #endif
                    684:
                    685: #ifdef __STRICT_ALIGNMENT
                    686:                {
                    687:                        /*
                    688:                         * XXX Nice chip, except it won't accept "off by 2"
                    689:                         * buffers, so we're force to copy.  Supposedly
                    690:                         * this will be fixed in a newer firmware rev
                    691:                         * and this will be temporary.
                    692:                         */
                    693:                        struct mbuf *mnew;
                    694:
                    695:                        MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                    696:                        if (mnew == NULL) {
                    697:                                m_freem(m);
                    698:                                goto next;
                    699:                        }
                    700:                        if (m->m_len > (MHLEN - 2)) {
                    701:                                MCLGET(mnew, M_DONTWAIT);
                    702:                                if (!(mnew->m_flags & M_EXT)) {
                    703:                                        m_freem(mnew);
                    704:                                        m_freem(m);
                    705:                                        goto next;
                    706:                                }
                    707:                        }
                    708:                        mnew->m_pkthdr.rcvif = ifp;
                    709:                        mnew->m_pkthdr.len = mnew->m_len = m->m_len;
                    710:                        mnew->m_data += 2;
                    711:                        bcopy(m->m_data, mnew->m_data, m->m_len);
                    712:                        m_freem(m);
                    713:                        m = mnew;
                    714:                }
                    715: #endif
                    716:
                    717: #if NBPFILTER > 0
                    718:                /*
                    719:                 * Handle BPF listeners. Let the BPF user see the packet.
                    720:                 */
                    721:                if (ifp->if_bpf)
                    722:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                    723: #endif
                    724:
                    725:                if (rxd->rx_stat & htole32(RX_STAT_IPCKSUMBAD))
                    726:                        sumflags |= M_IPV4_CSUM_IN_BAD;
                    727:                else if (rxd->rx_stat & htole32(RX_STAT_IPCKSUMGOOD))
                    728:                        sumflags |= M_IPV4_CSUM_IN_OK;
                    729:
                    730:                if (rxd->rx_stat & htole32(RX_STAT_TCPCKSUMBAD))
                    731:                        sumflags |= M_TCP_CSUM_IN_BAD;
                    732:                else if (rxd->rx_stat & htole32(RX_STAT_TCPCKSUMGOOD))
                    733:                        sumflags |= M_TCP_CSUM_IN_OK;
                    734:
                    735:                if (rxd->rx_stat & htole32(RX_STAT_UDPCKSUMBAD))
                    736:                        sumflags |= M_UDP_CSUM_IN_BAD;
                    737:                else if (rxd->rx_stat & htole32(RX_STAT_UDPCKSUMGOOD))
                    738:                        sumflags |= M_UDP_CSUM_IN_OK;
                    739:
                    740:                m->m_pkthdr.csum_flags = sumflags;
                    741:
                    742:                ether_input_mbuf(ifp, m);
                    743:
                    744: next:
                    745:                bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
                    746:                    idx * sizeof(struct txp_rx_desc), sizeof(struct txp_rx_desc),
                    747:                    BUS_DMASYNC_PREREAD);
                    748:
                    749:                roff += sizeof(struct txp_rx_desc);
                    750:                if (roff == (RX_ENTRIES * sizeof(struct txp_rx_desc))) {
                    751:                        idx = 0;
                    752:                        roff = 0;
                    753:                        rxd = r->r_desc;
                    754:                } else {
                    755:                        idx++;
                    756:                        rxd++;
                    757:                }
                    758:                woff = letoh32(*r->r_woff);
                    759:        }
                    760:
                    761:        *r->r_roff = htole32(woff);
                    762: }
                    763:
                    764: void
                    765: txp_rxbuf_reclaim(sc)
                    766:        struct txp_softc *sc;
                    767: {
                    768:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    769:        struct txp_hostvar *hv = sc->sc_hostvar;
                    770:        struct txp_rxbuf_desc *rbd;
                    771:        struct txp_swdesc *sd;
                    772:        u_int32_t i, end;
                    773:
                    774:        end = TXP_OFFSET2IDX(letoh32(hv->hv_rx_buf_read_idx));
                    775:        i = TXP_OFFSET2IDX(letoh32(hv->hv_rx_buf_write_idx));
                    776:
                    777:        if (++i == RXBUF_ENTRIES)
                    778:                i = 0;
                    779:
                    780:        rbd = sc->sc_rxbufs + i;
                    781:
                    782:        while (i != end) {
                    783:                sd = (struct txp_swdesc *)malloc(sizeof(struct txp_swdesc),
                    784:                    M_DEVBUF, M_NOWAIT);
                    785:                if (sd == NULL)
                    786:                        break;
                    787:
                    788:                MGETHDR(sd->sd_mbuf, M_DONTWAIT, MT_DATA);
                    789:                if (sd->sd_mbuf == NULL)
                    790:                        goto err_sd;
                    791:
                    792:                MCLGET(sd->sd_mbuf, M_DONTWAIT);
                    793:                if ((sd->sd_mbuf->m_flags & M_EXT) == 0)
                    794:                        goto err_mbuf;
                    795:                /* reserve some space for a possible VLAN header */
                    796:                sd->sd_mbuf->m_data += 8;
                    797:                sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES - 8;
                    798:                sd->sd_mbuf->m_pkthdr.rcvif = ifp;
                    799:                if (bus_dmamap_create(sc->sc_dmat, TXP_MAX_PKTLEN, 1,
                    800:                    TXP_MAX_PKTLEN, 0, BUS_DMA_NOWAIT, &sd->sd_map))
                    801:                        goto err_mbuf;
                    802:                if (bus_dmamap_load_mbuf(sc->sc_dmat, sd->sd_map, sd->sd_mbuf,
                    803:                    BUS_DMA_NOWAIT)) {
                    804:                        bus_dmamap_destroy(sc->sc_dmat, sd->sd_map);
                    805:                        goto err_mbuf;
                    806:                }
                    807:
                    808:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rxbufring_dma.dma_map,
                    809:                    i * sizeof(struct txp_rxbuf_desc),
                    810:                    sizeof(struct txp_rxbuf_desc), BUS_DMASYNC_POSTWRITE);
                    811:
                    812:                /* stash away pointer */
                    813:                bcopy(&sd, (u_long *)&rbd->rb_vaddrlo, sizeof(sd));
                    814:
                    815:                rbd->rb_paddrlo = ((u_int64_t)sd->sd_map->dm_segs[0].ds_addr)
                    816:                    & 0xffffffff;
                    817:                rbd->rb_paddrhi = ((u_int64_t)sd->sd_map->dm_segs[0].ds_addr)
                    818:                    >> 32;
                    819:
                    820:                bus_dmamap_sync(sc->sc_dmat, sd->sd_map, 0,
                    821:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
                    822:
                    823:                bus_dmamap_sync(sc->sc_dmat, sc->sc_rxbufring_dma.dma_map,
                    824:                    i * sizeof(struct txp_rxbuf_desc),
                    825:                    sizeof(struct txp_rxbuf_desc), BUS_DMASYNC_PREWRITE);
                    826:
                    827:                hv->hv_rx_buf_write_idx = htole32(TXP_IDX2OFFSET(i));
                    828:
                    829:                if (++i == RXBUF_ENTRIES) {
                    830:                        i = 0;
                    831:                        rbd = sc->sc_rxbufs;
                    832:                } else
                    833:                        rbd++;
                    834:        }
                    835:        return;
                    836:
                    837: err_mbuf:
                    838:        m_freem(sd->sd_mbuf);
                    839: err_sd:
                    840:        free(sd, M_DEVBUF);
                    841: }
                    842:
                    843: /*
                    844:  * Reclaim mbufs and entries from a transmit ring.
                    845:  */
                    846: void
                    847: txp_tx_reclaim(sc, r, dma)
                    848:        struct txp_softc *sc;
                    849:        struct txp_tx_ring *r;
                    850:        struct txp_dma_alloc *dma;
                    851: {
                    852:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    853:        u_int32_t idx = TXP_OFFSET2IDX(letoh32(*(r->r_off)));
                    854:        u_int32_t cons = r->r_cons, cnt = r->r_cnt;
                    855:        struct txp_tx_desc *txd = r->r_desc + cons;
                    856:        struct txp_swdesc *sd = sc->sc_txd + cons;
                    857:        struct mbuf *m;
                    858:
                    859:        while (cons != idx) {
                    860:                if (cnt == 0)
                    861:                        break;
                    862:
                    863:                bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
                    864:                    cons * sizeof(struct txp_tx_desc),
                    865:                    sizeof(struct txp_tx_desc),
                    866:                    BUS_DMASYNC_POSTWRITE);
                    867:
                    868:                if ((txd->tx_flags & TX_FLAGS_TYPE_M) ==
                    869:                    TX_FLAGS_TYPE_DATA) {
                    870:                        bus_dmamap_sync(sc->sc_dmat, sd->sd_map, 0,
                    871:                            sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    872:                        bus_dmamap_unload(sc->sc_dmat, sd->sd_map);
                    873:                        m = sd->sd_mbuf;
                    874:                        if (m != NULL) {
                    875:                                m_freem(m);
                    876:                                txd->tx_addrlo = 0;
                    877:                                txd->tx_addrhi = 0;
                    878:                                ifp->if_opackets++;
                    879:                        }
                    880:                }
                    881:                ifp->if_flags &= ~IFF_OACTIVE;
                    882:
                    883:                if (++cons == TX_ENTRIES) {
                    884:                        txd = r->r_desc;
                    885:                        cons = 0;
                    886:                        sd = sc->sc_txd;
                    887:                } else {
                    888:                        txd++;
                    889:                        sd++;
                    890:                }
                    891:
                    892:                cnt--;
                    893:        }
                    894:
                    895:        r->r_cons = cons;
                    896:        r->r_cnt = cnt;
                    897:        if (cnt == 0)
                    898:                ifp->if_timer = 0;
                    899: }
                    900:
                    901: void
                    902: txp_shutdown(vsc)
                    903:        void *vsc;
                    904: {
                    905:        struct txp_softc *sc = (struct txp_softc *)vsc;
                    906:
                    907:        /* mask all interrupts */
                    908:        WRITE_REG(sc, TXP_IMR,
                    909:            TXP_INT_SELF | TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |
                    910:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                    911:            TXP_INT_LATCH);
                    912:
                    913:        txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0);
                    914:        txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 0);
                    915:        txp_command(sc, TXP_CMD_HALT, 0, 0, 0, NULL, NULL, NULL, 0);
                    916: }
                    917:
                    918: int
                    919: txp_alloc_rings(sc)
                    920:        struct txp_softc *sc;
                    921: {
                    922:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    923:        struct txp_boot_record *boot;
                    924:        struct txp_swdesc *sd;
                    925:        u_int32_t r;
                    926:        int i, j;
                    927:
                    928:        /* boot record */
                    929:        if (txp_dma_malloc(sc, sizeof(struct txp_boot_record), &sc->sc_boot_dma,
                    930:            BUS_DMA_COHERENT)) {
                    931:                printf("can't allocate boot record\n");
                    932:                return (-1);
                    933:        }
                    934:        boot = (struct txp_boot_record *)sc->sc_boot_dma.dma_vaddr;
                    935:        bzero(boot, sizeof(*boot));
                    936:        sc->sc_boot = boot;
                    937:
                    938:        /* host variables */
                    939:        if (txp_dma_malloc(sc, sizeof(struct txp_hostvar), &sc->sc_host_dma,
                    940:            BUS_DMA_COHERENT)) {
                    941:                printf("can't allocate host ring\n");
                    942:                goto bail_boot;
                    943:        }
                    944:        bzero(sc->sc_host_dma.dma_vaddr, sizeof(struct txp_hostvar));
                    945:        boot->br_hostvar_lo = htole32(sc->sc_host_dma.dma_paddr & 0xffffffff);
                    946:        boot->br_hostvar_hi = htole32(sc->sc_host_dma.dma_paddr >> 32);
                    947:        sc->sc_hostvar = (struct txp_hostvar *)sc->sc_host_dma.dma_vaddr;
                    948:
                    949:        /* high priority tx ring */
                    950:        if (txp_dma_malloc(sc, sizeof(struct txp_tx_desc) * TX_ENTRIES,
                    951:            &sc->sc_txhiring_dma, BUS_DMA_COHERENT)) {
                    952:                printf("can't allocate high tx ring\n");
                    953:                goto bail_host;
                    954:        }
                    955:        bzero(sc->sc_txhiring_dma.dma_vaddr, sizeof(struct txp_tx_desc) * TX_ENTRIES);
                    956:        boot->br_txhipri_lo = htole32(sc->sc_txhiring_dma.dma_paddr & 0xffffffff);
                    957:        boot->br_txhipri_hi = htole32(sc->sc_txhiring_dma.dma_paddr >> 32);
                    958:        boot->br_txhipri_siz = htole32(TX_ENTRIES * sizeof(struct txp_tx_desc));
                    959:        sc->sc_txhir.r_reg = TXP_H2A_1;
                    960:        sc->sc_txhir.r_desc = (struct txp_tx_desc *)sc->sc_txhiring_dma.dma_vaddr;
                    961:        sc->sc_txhir.r_cons = sc->sc_txhir.r_prod = sc->sc_txhir.r_cnt = 0;
                    962:        sc->sc_txhir.r_off = &sc->sc_hostvar->hv_tx_hi_desc_read_idx;
                    963:        for (i = 0; i < TX_ENTRIES; i++) {
                    964:                if (bus_dmamap_create(sc->sc_dmat, TXP_MAX_PKTLEN,
                    965:                    TX_ENTRIES - 4, TXP_MAX_SEGLEN, 0,
                    966:                    BUS_DMA_NOWAIT, &sc->sc_txd[i].sd_map) != 0) {
                    967:                        for (j = 0; j < i; j++) {
                    968:                                bus_dmamap_destroy(sc->sc_dmat,
                    969:                                    sc->sc_txd[j].sd_map);
                    970:                                sc->sc_txd[j].sd_map = NULL;
                    971:                        }
                    972:                        goto bail_txhiring;
                    973:                }
                    974:        }
                    975:
                    976:        /* low priority tx ring */
                    977:        if (txp_dma_malloc(sc, sizeof(struct txp_tx_desc) * TX_ENTRIES,
                    978:            &sc->sc_txloring_dma, BUS_DMA_COHERENT)) {
                    979:                printf("can't allocate low tx ring\n");
                    980:                goto bail_txhiring;
                    981:        }
                    982:        bzero(sc->sc_txloring_dma.dma_vaddr, sizeof(struct txp_tx_desc) * TX_ENTRIES);
                    983:        boot->br_txlopri_lo = htole32(sc->sc_txloring_dma.dma_paddr & 0xffffffff);
                    984:        boot->br_txlopri_hi = htole32(sc->sc_txloring_dma.dma_paddr >> 32);
                    985:        boot->br_txlopri_siz = htole32(TX_ENTRIES * sizeof(struct txp_tx_desc));
                    986:        sc->sc_txlor.r_reg = TXP_H2A_3;
                    987:        sc->sc_txlor.r_desc = (struct txp_tx_desc *)sc->sc_txloring_dma.dma_vaddr;
                    988:        sc->sc_txlor.r_cons = sc->sc_txlor.r_prod = sc->sc_txlor.r_cnt = 0;
                    989:        sc->sc_txlor.r_off = &sc->sc_hostvar->hv_tx_lo_desc_read_idx;
                    990:
                    991:        /* high priority rx ring */
                    992:        if (txp_dma_malloc(sc, sizeof(struct txp_rx_desc) * RX_ENTRIES,
                    993:            &sc->sc_rxhiring_dma, BUS_DMA_COHERENT)) {
                    994:                printf("can't allocate high rx ring\n");
                    995:                goto bail_txloring;
                    996:        }
                    997:        bzero(sc->sc_rxhiring_dma.dma_vaddr, sizeof(struct txp_rx_desc) * RX_ENTRIES);
                    998:        boot->br_rxhipri_lo = htole32(sc->sc_rxhiring_dma.dma_paddr & 0xffffffff);
                    999:        boot->br_rxhipri_hi = htole32(sc->sc_rxhiring_dma.dma_paddr >> 32);
                   1000:        boot->br_rxhipri_siz = htole32(RX_ENTRIES * sizeof(struct txp_rx_desc));
                   1001:        sc->sc_rxhir.r_desc =
                   1002:            (struct txp_rx_desc *)sc->sc_rxhiring_dma.dma_vaddr;
                   1003:        sc->sc_rxhir.r_roff = &sc->sc_hostvar->hv_rx_hi_read_idx;
                   1004:        sc->sc_rxhir.r_woff = &sc->sc_hostvar->hv_rx_hi_write_idx;
                   1005:        bus_dmamap_sync(sc->sc_dmat, sc->sc_rxhiring_dma.dma_map,
                   1006:            0, sc->sc_rxhiring_dma.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1007:
                   1008:        /* low priority ring */
                   1009:        if (txp_dma_malloc(sc, sizeof(struct txp_rx_desc) * RX_ENTRIES,
                   1010:            &sc->sc_rxloring_dma, BUS_DMA_COHERENT)) {
                   1011:                printf("can't allocate low rx ring\n");
                   1012:                goto bail_rxhiring;
                   1013:        }
                   1014:        bzero(sc->sc_rxloring_dma.dma_vaddr, sizeof(struct txp_rx_desc) * RX_ENTRIES);
                   1015:        boot->br_rxlopri_lo = htole32(sc->sc_rxloring_dma.dma_paddr & 0xffffffff);
                   1016:        boot->br_rxlopri_hi = htole32(sc->sc_rxloring_dma.dma_paddr >> 32);
                   1017:        boot->br_rxlopri_siz = htole32(RX_ENTRIES * sizeof(struct txp_rx_desc));
                   1018:        sc->sc_rxlor.r_desc =
                   1019:            (struct txp_rx_desc *)sc->sc_rxloring_dma.dma_vaddr;
                   1020:        sc->sc_rxlor.r_roff = &sc->sc_hostvar->hv_rx_lo_read_idx;
                   1021:        sc->sc_rxlor.r_woff = &sc->sc_hostvar->hv_rx_lo_write_idx;
                   1022:        bus_dmamap_sync(sc->sc_dmat, sc->sc_rxloring_dma.dma_map,
                   1023:            0, sc->sc_rxloring_dma.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1024:
                   1025:        /* command ring */
                   1026:        if (txp_dma_malloc(sc, sizeof(struct txp_cmd_desc) * CMD_ENTRIES,
                   1027:            &sc->sc_cmdring_dma, BUS_DMA_COHERENT)) {
                   1028:                printf("can't allocate command ring\n");
                   1029:                goto bail_rxloring;
                   1030:        }
                   1031:        bzero(sc->sc_cmdring_dma.dma_vaddr, sizeof(struct txp_cmd_desc) * CMD_ENTRIES);
                   1032:        boot->br_cmd_lo = htole32(sc->sc_cmdring_dma.dma_paddr & 0xffffffff);
                   1033:        boot->br_cmd_hi = htole32(sc->sc_cmdring_dma.dma_paddr >> 32);
                   1034:        boot->br_cmd_siz = htole32(CMD_ENTRIES * sizeof(struct txp_cmd_desc));
                   1035:        sc->sc_cmdring.base = (struct txp_cmd_desc *)sc->sc_cmdring_dma.dma_vaddr;
                   1036:        sc->sc_cmdring.size = CMD_ENTRIES * sizeof(struct txp_cmd_desc);
                   1037:        sc->sc_cmdring.lastwrite = 0;
                   1038:
                   1039:        /* response ring */
                   1040:        if (txp_dma_malloc(sc, sizeof(struct txp_rsp_desc) * RSP_ENTRIES,
                   1041:            &sc->sc_rspring_dma, BUS_DMA_COHERENT)) {
                   1042:                printf("can't allocate response ring\n");
                   1043:                goto bail_cmdring;
                   1044:        }
                   1045:        bzero(sc->sc_rspring_dma.dma_vaddr, sizeof(struct txp_rsp_desc) * RSP_ENTRIES);
                   1046:        boot->br_resp_lo = htole32(sc->sc_rspring_dma.dma_paddr & 0xffffffff);
                   1047:        boot->br_resp_hi = htole32(sc->sc_rspring_dma.dma_paddr >> 32);
                   1048:        boot->br_resp_siz = htole32(CMD_ENTRIES * sizeof(struct txp_rsp_desc));
                   1049:        sc->sc_rspring.base = (struct txp_rsp_desc *)sc->sc_rspring_dma.dma_vaddr;
                   1050:        sc->sc_rspring.size = RSP_ENTRIES * sizeof(struct txp_rsp_desc);
                   1051:        sc->sc_rspring.lastwrite = 0;
                   1052:
                   1053:        /* receive buffer ring */
                   1054:        if (txp_dma_malloc(sc, sizeof(struct txp_rxbuf_desc) * RXBUF_ENTRIES,
                   1055:            &sc->sc_rxbufring_dma, BUS_DMA_COHERENT)) {
                   1056:                printf("can't allocate rx buffer ring\n");
                   1057:                goto bail_rspring;
                   1058:        }
                   1059:        bzero(sc->sc_rxbufring_dma.dma_vaddr, sizeof(struct txp_rxbuf_desc) * RXBUF_ENTRIES);
                   1060:        boot->br_rxbuf_lo = htole32(sc->sc_rxbufring_dma.dma_paddr & 0xffffffff);
                   1061:        boot->br_rxbuf_hi = htole32(sc->sc_rxbufring_dma.dma_paddr >> 32);
                   1062:        boot->br_rxbuf_siz = htole32(RXBUF_ENTRIES * sizeof(struct txp_rxbuf_desc));
                   1063:        sc->sc_rxbufs = (struct txp_rxbuf_desc *)sc->sc_rxbufring_dma.dma_vaddr;
                   1064:        for (i = 0; i < RXBUF_ENTRIES; i++) {
                   1065:                sd = (struct txp_swdesc *)malloc(sizeof(struct txp_swdesc),
                   1066:                    M_DEVBUF, M_NOWAIT);
                   1067:
                   1068:                /* stash away pointer */
                   1069:                bcopy(&sd, (u_long *)&sc->sc_rxbufs[i].rb_vaddrlo, sizeof(sd));
                   1070:
                   1071:                if (sd == NULL)
                   1072:                        break;
                   1073:
                   1074:                MGETHDR(sd->sd_mbuf, M_DONTWAIT, MT_DATA);
                   1075:                if (sd->sd_mbuf == NULL) {
                   1076:                        goto bail_rxbufring;
                   1077:                }
                   1078:
                   1079:                MCLGET(sd->sd_mbuf, M_DONTWAIT);
                   1080:                if ((sd->sd_mbuf->m_flags & M_EXT) == 0) {
                   1081:                        goto bail_rxbufring;
                   1082:                }
                   1083:                /* reserve some space for a possible VLAN header */
                   1084:                sd->sd_mbuf->m_data += 8;
                   1085:                sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES - 8;
                   1086:                sd->sd_mbuf->m_pkthdr.rcvif = ifp;
                   1087:                if (bus_dmamap_create(sc->sc_dmat, TXP_MAX_PKTLEN, 1,
                   1088:                    TXP_MAX_PKTLEN, 0, BUS_DMA_NOWAIT, &sd->sd_map)) {
                   1089:                        goto bail_rxbufring;
                   1090:                }
                   1091:                if (bus_dmamap_load_mbuf(sc->sc_dmat, sd->sd_map, sd->sd_mbuf,
                   1092:                    BUS_DMA_NOWAIT)) {
                   1093:                        bus_dmamap_destroy(sc->sc_dmat, sd->sd_map);
                   1094:                        goto bail_rxbufring;
                   1095:                }
                   1096:                bus_dmamap_sync(sc->sc_dmat, sd->sd_map, 0,
                   1097:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1098:
                   1099:                sc->sc_rxbufs[i].rb_paddrlo =
                   1100:                    ((u_int64_t)sd->sd_map->dm_segs[0].ds_addr) & 0xffffffff;
                   1101:                sc->sc_rxbufs[i].rb_paddrhi =
                   1102:                    ((u_int64_t)sd->sd_map->dm_segs[0].ds_addr) >> 32;
                   1103:        }
                   1104:        bus_dmamap_sync(sc->sc_dmat, sc->sc_rxbufring_dma.dma_map,
                   1105:            0, sc->sc_rxbufring_dma.dma_map->dm_mapsize,
                   1106:            BUS_DMASYNC_PREWRITE);
                   1107:        sc->sc_hostvar->hv_rx_buf_write_idx = htole32((RXBUF_ENTRIES - 1) *
                   1108:            sizeof(struct txp_rxbuf_desc));
                   1109:
                   1110:        /* zero dma */
                   1111:        if (txp_dma_malloc(sc, sizeof(u_int32_t), &sc->sc_zero_dma,
                   1112:            BUS_DMA_COHERENT)) {
                   1113:                printf("can't allocate response ring\n");
                   1114:                goto bail_rxbufring;
                   1115:        }
                   1116:        bzero(sc->sc_zero_dma.dma_vaddr, sizeof(u_int32_t));
                   1117:        boot->br_zero_lo = htole32(sc->sc_zero_dma.dma_paddr & 0xffffffff);
                   1118:        boot->br_zero_hi = htole32(sc->sc_zero_dma.dma_paddr >> 32);
                   1119:
                   1120:        /* See if it's waiting for boot, and try to boot it */
                   1121:        for (i = 0; i < 10000; i++) {
                   1122:                r = READ_REG(sc, TXP_A2H_0);
                   1123:                if (r == STAT_WAITING_FOR_BOOT)
                   1124:                        break;
                   1125:                DELAY(50);
                   1126:        }
                   1127:        if (r != STAT_WAITING_FOR_BOOT) {
                   1128:                printf("not waiting for boot\n");
                   1129:                goto bail;
                   1130:        }
                   1131:        WRITE_REG(sc, TXP_H2A_2, sc->sc_boot_dma.dma_paddr >> 32);
                   1132:        WRITE_REG(sc, TXP_H2A_1, sc->sc_boot_dma.dma_paddr & 0xffffffff);
                   1133:        WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_REGISTER_BOOT_RECORD);
                   1134:
                   1135:        /* See if it booted */
                   1136:        for (i = 0; i < 10000; i++) {
                   1137:                r = READ_REG(sc, TXP_A2H_0);
                   1138:                if (r == STAT_RUNNING)
                   1139:                        break;
                   1140:                DELAY(50);
                   1141:        }
                   1142:        if (r != STAT_RUNNING) {
                   1143:                printf("fw not running\n");
                   1144:                goto bail;
                   1145:        }
                   1146:
                   1147:        /* Clear TX and CMD ring write registers */
                   1148:        WRITE_REG(sc, TXP_H2A_1, TXP_BOOTCMD_NULL);
                   1149:        WRITE_REG(sc, TXP_H2A_2, TXP_BOOTCMD_NULL);
                   1150:        WRITE_REG(sc, TXP_H2A_3, TXP_BOOTCMD_NULL);
                   1151:        WRITE_REG(sc, TXP_H2A_0, TXP_BOOTCMD_NULL);
                   1152:
                   1153:        return (0);
                   1154:
                   1155: bail:
                   1156:        txp_dma_free(sc, &sc->sc_zero_dma);
                   1157: bail_rxbufring:
                   1158:        for (i = 0; i < RXBUF_ENTRIES; i++) {
                   1159:                bcopy((u_long *)&sc->sc_rxbufs[i].rb_vaddrlo, &sd, sizeof(sd));
                   1160:                if (sd)
                   1161:                        free(sd, M_DEVBUF);
                   1162:        }
                   1163:        txp_dma_free(sc, &sc->sc_rxbufring_dma);
                   1164: bail_rspring:
                   1165:        txp_dma_free(sc, &sc->sc_rspring_dma);
                   1166: bail_cmdring:
                   1167:        txp_dma_free(sc, &sc->sc_cmdring_dma);
                   1168: bail_rxloring:
                   1169:        txp_dma_free(sc, &sc->sc_rxloring_dma);
                   1170: bail_rxhiring:
                   1171:        txp_dma_free(sc, &sc->sc_rxhiring_dma);
                   1172: bail_txloring:
                   1173:        txp_dma_free(sc, &sc->sc_txloring_dma);
                   1174: bail_txhiring:
                   1175:        txp_dma_free(sc, &sc->sc_txhiring_dma);
                   1176: bail_host:
                   1177:        txp_dma_free(sc, &sc->sc_host_dma);
                   1178: bail_boot:
                   1179:        txp_dma_free(sc, &sc->sc_boot_dma);
                   1180:        return (-1);
                   1181: }
                   1182:
                   1183: int
                   1184: txp_dma_malloc(sc, size, dma, mapflags)
                   1185:        struct txp_softc *sc;
                   1186:        bus_size_t size;
                   1187:        struct txp_dma_alloc *dma;
                   1188:        int mapflags;
                   1189: {
                   1190:        int r;
                   1191:
                   1192:        if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
                   1193:            &dma->dma_seg, 1, &dma->dma_nseg, 0)) != 0)
                   1194:                goto fail_0;
                   1195:
                   1196:        if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg,
                   1197:            size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0)
                   1198:                goto fail_1;
                   1199:
                   1200:        if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
                   1201:            BUS_DMA_NOWAIT, &dma->dma_map)) != 0)
                   1202:                goto fail_2;
                   1203:
                   1204:        if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr,
                   1205:            size, NULL, BUS_DMA_NOWAIT)) != 0)
                   1206:                goto fail_3;
                   1207:
                   1208:        dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr;
                   1209:        return (0);
                   1210:
                   1211: fail_3:
                   1212:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                   1213: fail_2:
                   1214:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size);
                   1215: fail_1:
                   1216:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg);
                   1217: fail_0:
                   1218:        return (r);
                   1219: }
                   1220:
                   1221: void
                   1222: txp_dma_free(sc, dma)
                   1223:        struct txp_softc *sc;
                   1224:        struct txp_dma_alloc *dma;
                   1225: {
                   1226:        bus_dmamap_unload(sc->sc_dmat, dma->dma_map);
                   1227:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_map->dm_mapsize);
                   1228:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg);
                   1229:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                   1230: }
                   1231:
                   1232: int
                   1233: txp_ioctl(ifp, command, data)
                   1234:        struct ifnet *ifp;
                   1235:        u_long command;
                   1236:        caddr_t data;
                   1237: {
                   1238:        struct txp_softc *sc = ifp->if_softc;
                   1239:        struct ifreq *ifr = (struct ifreq *)data;
                   1240:        struct ifaddr *ifa = (struct ifaddr *)data;
                   1241:        int s, error = 0;
                   1242:
                   1243:        s = splnet();
                   1244:
                   1245:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command, data)) > 0) {
                   1246:                splx(s);
                   1247:                return error;
                   1248:        }
                   1249:
                   1250:        switch(command) {
                   1251:        case SIOCSIFADDR:
                   1252:                ifp->if_flags |= IFF_UP;
                   1253:                switch (ifa->ifa_addr->sa_family) {
                   1254: #ifdef INET
                   1255:                case AF_INET:
                   1256:                        txp_init(sc);
                   1257:                        arp_ifinit(&sc->sc_arpcom, ifa);
                   1258:                        break;
                   1259: #endif /* INET */
                   1260:                default:
                   1261:                        txp_init(sc);
                   1262:                        break;
                   1263:                }
                   1264:                break;
                   1265:        case SIOCSIFFLAGS:
                   1266:                if (ifp->if_flags & IFF_UP) {
                   1267:                        txp_init(sc);
                   1268:                } else {
                   1269:                        if (ifp->if_flags & IFF_RUNNING)
                   1270:                                txp_stop(sc);
                   1271:                }
                   1272:                break;
                   1273:        case SIOCADDMULTI:
                   1274:        case SIOCDELMULTI:
                   1275:                error = (command == SIOCADDMULTI) ?
                   1276:                    ether_addmulti(ifr, &sc->sc_arpcom) :
                   1277:                    ether_delmulti(ifr, &sc->sc_arpcom);
                   1278:
                   1279:                if (error == ENETRESET) {
                   1280:                        /*
                   1281:                         * Multicast list has changed; set the hardware
                   1282:                         * filter accordingly.
                   1283:                         */
                   1284:                        if (ifp->if_flags & IFF_RUNNING)
                   1285:                                txp_set_filter(sc);
                   1286:                        error = 0;
                   1287:                }
                   1288:                break;
                   1289:        case SIOCGIFMEDIA:
                   1290:        case SIOCSIFMEDIA:
                   1291:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, command);
                   1292:                break;
                   1293:        default:
                   1294:                error = ENOTTY;
                   1295:                break;
                   1296:        }
                   1297:
                   1298:        splx(s);
                   1299:
                   1300:        return(error);
                   1301: }
                   1302:
                   1303: void
                   1304: txp_init(sc)
                   1305:        struct txp_softc *sc;
                   1306: {
                   1307:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1308:        int s;
                   1309:
                   1310:        txp_stop(sc);
                   1311:
                   1312:        s = splnet();
                   1313:
                   1314:        txp_set_filter(sc);
                   1315:
                   1316:        txp_command(sc, TXP_CMD_TX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
                   1317:        txp_command(sc, TXP_CMD_RX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
                   1318:
                   1319:        WRITE_REG(sc, TXP_IER, TXP_INT_RESERVED | TXP_INT_SELF |
                   1320:            TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
                   1321:            TXP_INT_A2H_2 | TXP_INT_A2H_1 | TXP_INT_A2H_0 |
                   1322:            TXP_INT_DMA3 | TXP_INT_DMA2 | TXP_INT_DMA1 | TXP_INT_DMA0 |
                   1323:            TXP_INT_PCI_TABORT | TXP_INT_PCI_MABORT |  TXP_INT_LATCH);
                   1324:        WRITE_REG(sc, TXP_IMR, TXP_INT_A2H_3);
                   1325:
                   1326:        ifp->if_flags |= IFF_RUNNING;
                   1327:        ifp->if_flags &= ~IFF_OACTIVE;
                   1328:        ifp->if_timer = 0;
                   1329:
                   1330:        if (!timeout_pending(&sc->sc_tick))
                   1331:                timeout_add(&sc->sc_tick, hz);
                   1332:
                   1333:        splx(s);
                   1334: }
                   1335:
                   1336: void
                   1337: txp_tick(vsc)
                   1338:        void *vsc;
                   1339: {
                   1340:        struct txp_softc *sc = vsc;
                   1341:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1342:        struct txp_rsp_desc *rsp = NULL;
                   1343:        struct txp_ext_desc *ext;
                   1344:        int s;
                   1345:
                   1346:        s = splnet();
                   1347:        txp_rxbuf_reclaim(sc);
                   1348:
                   1349:        if (txp_command2(sc, TXP_CMD_READ_STATISTICS, 0, 0, 0, NULL, 0,
                   1350:            &rsp, 1))
                   1351:                goto out;
                   1352:        if (rsp->rsp_numdesc != 6)
                   1353:                goto out;
                   1354:        if (txp_command(sc, TXP_CMD_CLEAR_STATISTICS, 0, 0, 0,
                   1355:            NULL, NULL, NULL, 1))
                   1356:                goto out;
                   1357:        ext = (struct txp_ext_desc *)(rsp + 1);
                   1358:
                   1359:        ifp->if_ierrors += ext[3].ext_2 + ext[3].ext_3 + ext[3].ext_4 +
                   1360:            ext[4].ext_1 + ext[4].ext_4;
                   1361:        ifp->if_oerrors += ext[0].ext_1 + ext[1].ext_1 + ext[1].ext_4 +
                   1362:            ext[2].ext_1;
                   1363:        ifp->if_collisions += ext[0].ext_2 + ext[0].ext_3 + ext[1].ext_2 +
                   1364:            ext[1].ext_3;
                   1365:        ifp->if_opackets += rsp->rsp_par2;
                   1366:        ifp->if_ipackets += ext[2].ext_3;
                   1367:
                   1368: out:
                   1369:        if (rsp != NULL)
                   1370:                free(rsp, M_DEVBUF);
                   1371:
                   1372:        splx(s);
                   1373:        timeout_add(&sc->sc_tick, hz);
                   1374: }
                   1375:
                   1376: void
                   1377: txp_start(ifp)
                   1378:        struct ifnet *ifp;
                   1379: {
                   1380:        struct txp_softc *sc = ifp->if_softc;
                   1381:        struct txp_tx_ring *r = &sc->sc_txhir;
                   1382:        struct txp_tx_desc *txd;
                   1383:        int txdidx;
                   1384:        struct txp_frag_desc *fxd;
                   1385:        struct mbuf *m, *mnew;
                   1386:        struct txp_swdesc *sd;
                   1387:        u_int32_t firstprod, firstcnt, prod, cnt, i;
                   1388: #if NVLAN > 0
                   1389:        struct ifvlan           *ifv;
                   1390: #endif
                   1391:
                   1392:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   1393:                return;
                   1394:
                   1395:        prod = r->r_prod;
                   1396:        cnt = r->r_cnt;
                   1397:
                   1398:        while (1) {
                   1399:                IFQ_POLL(&ifp->if_snd, m);
                   1400:                if (m == NULL)
                   1401:                        break;
                   1402:                mnew = NULL;
                   1403:
                   1404:                firstprod = prod;
                   1405:                firstcnt = cnt;
                   1406:
                   1407:                sd = sc->sc_txd + prod;
                   1408:                sd->sd_mbuf = m;
                   1409:
                   1410:                if (bus_dmamap_load_mbuf(sc->sc_dmat, sd->sd_map, m,
                   1411:                    BUS_DMA_NOWAIT)) {
                   1412:                        MGETHDR(mnew, M_DONTWAIT, MT_DATA);
                   1413:                        if (mnew == NULL)
                   1414:                                goto oactive1;
                   1415:                        if (m->m_pkthdr.len > MHLEN) {
                   1416:                                MCLGET(mnew, M_DONTWAIT);
                   1417:                                if ((mnew->m_flags & M_EXT) == 0) {
                   1418:                                        m_freem(mnew);
                   1419:                                        goto oactive1;
                   1420:                                }
                   1421:                        }
                   1422:                        m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t));
                   1423:                        mnew->m_pkthdr.len = mnew->m_len = m->m_pkthdr.len;
                   1424:                        IFQ_DEQUEUE(&ifp->if_snd, m);
                   1425:                        m_freem(m);
                   1426:                        m = mnew;
                   1427:                        if (bus_dmamap_load_mbuf(sc->sc_dmat, sd->sd_map, m,
                   1428:                            BUS_DMA_NOWAIT))
                   1429:                                goto oactive1;
                   1430:                }
                   1431:
                   1432:                if ((TX_ENTRIES - cnt) < 4)
                   1433:                        goto oactive;
                   1434:
                   1435:                txd = r->r_desc + prod;
                   1436:                txdidx = prod;
                   1437:                txd->tx_flags = TX_FLAGS_TYPE_DATA;
                   1438:                txd->tx_numdesc = 0;
                   1439:                txd->tx_addrlo = 0;
                   1440:                txd->tx_addrhi = 0;
                   1441:                txd->tx_totlen = m->m_pkthdr.len;
                   1442:                txd->tx_pflags = 0;
                   1443:                txd->tx_numdesc = sd->sd_map->dm_nsegs;
                   1444:
                   1445:                if (++prod == TX_ENTRIES)
                   1446:                        prod = 0;
                   1447:
                   1448:                if (++cnt >= (TX_ENTRIES - 4))
                   1449:                        goto oactive;
                   1450:
                   1451: #if NVLAN > 0
                   1452:                if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
                   1453:                    m->m_pkthdr.rcvif != NULL) {
                   1454:                        ifv = m->m_pkthdr.rcvif->if_softc;
                   1455:                        txd->tx_pflags = TX_PFLAGS_VLAN |
                   1456:                            (htons(ifv->ifv_tag) << TX_PFLAGS_VLANTAG_S);
                   1457:                }
                   1458: #endif
                   1459:
                   1460:                if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
                   1461:                        txd->tx_pflags |= TX_PFLAGS_IPCKSUM;
                   1462: #ifdef TRY_TX_TCP_CSUM
                   1463:                if (m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
                   1464:                        txd->tx_pflags |= TX_PFLAGS_TCPCKSUM;
                   1465: #endif
                   1466: #ifdef TRY_TX_UDP_CSUM
                   1467:                if (m->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
                   1468:                        txd->tx_pflags |= TX_PFLAGS_UDPCKSUM;
                   1469: #endif
                   1470:
                   1471:                bus_dmamap_sync(sc->sc_dmat, sd->sd_map, 0,
                   1472:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
                   1473:
                   1474:                fxd = (struct txp_frag_desc *)(r->r_desc + prod);
                   1475:                for (i = 0; i < sd->sd_map->dm_nsegs; i++) {
                   1476:                        if (++cnt >= (TX_ENTRIES - 4)) {
                   1477:                                bus_dmamap_sync(sc->sc_dmat, sd->sd_map,
                   1478:                                    0, sd->sd_map->dm_mapsize,
                   1479:                                    BUS_DMASYNC_POSTWRITE);
                   1480:                                goto oactive;
                   1481:                        }
                   1482:
                   1483:                        fxd->frag_flags = FRAG_FLAGS_TYPE_FRAG |
                   1484:                            FRAG_FLAGS_VALID;
                   1485:                        fxd->frag_rsvd1 = 0;
                   1486:                        fxd->frag_len = sd->sd_map->dm_segs[i].ds_len;
                   1487:                        fxd->frag_addrlo =
                   1488:                            ((u_int64_t)sd->sd_map->dm_segs[i].ds_addr) &
                   1489:                            0xffffffff;
                   1490:                        fxd->frag_addrhi =
                   1491:                            ((u_int64_t)sd->sd_map->dm_segs[i].ds_addr) >>
                   1492:                            32;
                   1493:                        fxd->frag_rsvd2 = 0;
                   1494:
                   1495:                        bus_dmamap_sync(sc->sc_dmat,
                   1496:                            sc->sc_txhiring_dma.dma_map,
                   1497:                            prod * sizeof(struct txp_frag_desc),
                   1498:                            sizeof(struct txp_frag_desc), BUS_DMASYNC_PREWRITE);
                   1499:
                   1500:                        if (++prod == TX_ENTRIES) {
                   1501:                                fxd = (struct txp_frag_desc *)r->r_desc;
                   1502:                                prod = 0;
                   1503:                        } else
                   1504:                                fxd++;
                   1505:
                   1506:                }
                   1507:
                   1508:                /*
                   1509:                 * if mnew isn't NULL, we already dequeued and copied
                   1510:                 * the packet.
                   1511:                 */
                   1512:                if (mnew == NULL)
                   1513:                        IFQ_DEQUEUE(&ifp->if_snd, m);
                   1514:
                   1515:                ifp->if_timer = 5;
                   1516:
                   1517: #if NBPFILTER > 0
                   1518:                if (ifp->if_bpf)
                   1519:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
                   1520: #endif
                   1521:
                   1522:                txd->tx_flags |= TX_FLAGS_VALID;
                   1523:                bus_dmamap_sync(sc->sc_dmat, sc->sc_txhiring_dma.dma_map,
                   1524:                    txdidx * sizeof(struct txp_tx_desc),
                   1525:                    sizeof(struct txp_tx_desc), BUS_DMASYNC_PREWRITE);
                   1526:
                   1527: #if 0
                   1528:                {
                   1529:                        struct mbuf *mx;
                   1530:                        int i;
                   1531:
                   1532:                        printf("txd: flags 0x%x ndesc %d totlen %d pflags 0x%x\n",
                   1533:                            txd->tx_flags, txd->tx_numdesc, txd->tx_totlen,
                   1534:                            txd->tx_pflags);
                   1535:                        for (mx = m; mx != NULL; mx = mx->m_next) {
                   1536:                                for (i = 0; i < mx->m_len; i++) {
                   1537:                                        printf(":%02x",
                   1538:                                            (u_int8_t)m->m_data[i]);
                   1539:                                }
                   1540:                        }
                   1541:                        printf("\n");
                   1542:                }
                   1543: #endif
                   1544:
                   1545:                WRITE_REG(sc, r->r_reg, TXP_IDX2OFFSET(prod));
                   1546:        }
                   1547:
                   1548:        r->r_prod = prod;
                   1549:        r->r_cnt = cnt;
                   1550:        return;
                   1551:
                   1552: oactive:
                   1553:        bus_dmamap_unload(sc->sc_dmat, sd->sd_map);
                   1554: oactive1:
                   1555:        ifp->if_flags |= IFF_OACTIVE;
                   1556:        r->r_prod = firstprod;
                   1557:        r->r_cnt = firstcnt;
                   1558: }
                   1559:
                   1560: /*
                   1561:  * Handle simple commands sent to the typhoon
                   1562:  */
                   1563: int
                   1564: txp_command(sc, id, in1, in2, in3, out1, out2, out3, wait)
                   1565:        struct txp_softc *sc;
                   1566:        u_int16_t id, in1, *out1;
                   1567:        u_int32_t in2, in3, *out2, *out3;
                   1568:        int wait;
                   1569: {
                   1570:        struct txp_rsp_desc *rsp = NULL;
                   1571:
                   1572:        if (txp_command2(sc, id, in1, in2, in3, NULL, 0, &rsp, wait))
                   1573:                return (-1);
                   1574:
                   1575:        if (!wait)
                   1576:                return (0);
                   1577:
                   1578:        if (out1 != NULL)
                   1579:                *out1 = letoh16(rsp->rsp_par1);
                   1580:        if (out2 != NULL)
                   1581:                *out2 = letoh32(rsp->rsp_par2);
                   1582:        if (out3 != NULL)
                   1583:                *out3 = letoh32(rsp->rsp_par3);
                   1584:        free(rsp, M_DEVBUF);
                   1585:        return (0);
                   1586: }
                   1587:
                   1588: int
                   1589: txp_command2(sc, id, in1, in2, in3, in_extp, in_extn, rspp, wait)
                   1590:        struct txp_softc *sc;
                   1591:        u_int16_t id, in1;
                   1592:        u_int32_t in2, in3;
                   1593:        struct txp_ext_desc *in_extp;
                   1594:        u_int8_t in_extn;
                   1595:        struct txp_rsp_desc **rspp;
                   1596:        int wait;
                   1597: {
                   1598:        struct txp_hostvar *hv = sc->sc_hostvar;
                   1599:        struct txp_cmd_desc *cmd;
                   1600:        struct txp_ext_desc *ext;
                   1601:        u_int32_t idx, i;
                   1602:        u_int16_t seq;
                   1603:
                   1604:        if (txp_cmd_desc_numfree(sc) < (in_extn + 1)) {
                   1605:                printf("%s: no free cmd descriptors\n", TXP_DEVNAME(sc));
                   1606:                return (-1);
                   1607:        }
                   1608:
                   1609:        idx = sc->sc_cmdring.lastwrite;
                   1610:        cmd = (struct txp_cmd_desc *)(((u_int8_t *)sc->sc_cmdring.base) + idx);
                   1611:        bzero(cmd, sizeof(*cmd));
                   1612:
                   1613:        cmd->cmd_numdesc = in_extn;
                   1614:        seq = sc->sc_seq++;
                   1615:        cmd->cmd_seq = htole16(seq);
                   1616:        cmd->cmd_id = htole16(id);
                   1617:        cmd->cmd_par1 = htole16(in1);
                   1618:        cmd->cmd_par2 = htole32(in2);
                   1619:        cmd->cmd_par3 = htole32(in3);
                   1620:        cmd->cmd_flags = CMD_FLAGS_TYPE_CMD |
                   1621:            (wait ? CMD_FLAGS_RESP : 0) | CMD_FLAGS_VALID;
                   1622:
                   1623:        idx += sizeof(struct txp_cmd_desc);
                   1624:        if (idx == sc->sc_cmdring.size)
                   1625:                idx = 0;
                   1626:
                   1627:        for (i = 0; i < in_extn; i++) {
                   1628:                ext = (struct txp_ext_desc *)(((u_int8_t *)sc->sc_cmdring.base) + idx);
                   1629:                bcopy(in_extp, ext, sizeof(struct txp_ext_desc));
                   1630:                in_extp++;
                   1631:                idx += sizeof(struct txp_cmd_desc);
                   1632:                if (idx == sc->sc_cmdring.size)
                   1633:                        idx = 0;
                   1634:        }
                   1635:
                   1636:        sc->sc_cmdring.lastwrite = idx;
                   1637:
                   1638:        WRITE_REG(sc, TXP_H2A_2, sc->sc_cmdring.lastwrite);
                   1639:        bus_dmamap_sync(sc->sc_dmat, sc->sc_host_dma.dma_map, 0,
                   1640:            sizeof(struct txp_hostvar), BUS_DMASYNC_PREREAD);
                   1641:
                   1642:        if (!wait)
                   1643:                return (0);
                   1644:
                   1645:        for (i = 0; i < 10000; i++) {
                   1646:                bus_dmamap_sync(sc->sc_dmat, sc->sc_host_dma.dma_map, 0,
                   1647:                    sizeof(struct txp_hostvar), BUS_DMASYNC_POSTREAD);
                   1648:                idx = letoh32(hv->hv_resp_read_idx);
                   1649:                if (idx != letoh32(hv->hv_resp_write_idx)) {
                   1650:                        *rspp = NULL;
                   1651:                        if (txp_response(sc, idx, id, seq, rspp))
                   1652:                                return (-1);
                   1653:                        if (*rspp != NULL)
                   1654:                                break;
                   1655:                }
                   1656:                bus_dmamap_sync(sc->sc_dmat, sc->sc_host_dma.dma_map, 0,
                   1657:                    sizeof(struct txp_hostvar), BUS_DMASYNC_PREREAD);
                   1658:                DELAY(50);
                   1659:        }
                   1660:        if (i == 1000 || (*rspp) == NULL) {
                   1661:                printf("%s: 0x%x command failed\n", TXP_DEVNAME(sc), id);
                   1662:                return (-1);
                   1663:        }
                   1664:
                   1665:        return (0);
                   1666: }
                   1667:
                   1668: int
                   1669: txp_response(sc, ridx, id, seq, rspp)
                   1670:        struct txp_softc *sc;
                   1671:        u_int32_t ridx;
                   1672:        u_int16_t id;
                   1673:        u_int16_t seq;
                   1674:        struct txp_rsp_desc **rspp;
                   1675: {
                   1676:        struct txp_hostvar *hv = sc->sc_hostvar;
                   1677:        struct txp_rsp_desc *rsp;
                   1678:
                   1679:        while (ridx != letoh32(hv->hv_resp_write_idx)) {
                   1680:                rsp = (struct txp_rsp_desc *)(((u_int8_t *)sc->sc_rspring.base) + ridx);
                   1681:
                   1682:                if (id == letoh16(rsp->rsp_id) && letoh16(rsp->rsp_seq) == seq) {
                   1683:                        *rspp = (struct txp_rsp_desc *)malloc(
                   1684:                            sizeof(struct txp_rsp_desc) * (rsp->rsp_numdesc + 1),
                   1685:                            M_DEVBUF, M_NOWAIT);
                   1686:                        if ((*rspp) == NULL)
                   1687:                                return (-1);
                   1688:                        txp_rsp_fixup(sc, rsp, *rspp);
                   1689:                        return (0);
                   1690:                }
                   1691:
                   1692:                if (rsp->rsp_flags & RSP_FLAGS_ERROR) {
                   1693:                        printf("%s: response error: id 0x%x\n",
                   1694:                            TXP_DEVNAME(sc), letoh16(rsp->rsp_id));
                   1695:                        txp_rsp_fixup(sc, rsp, NULL);
                   1696:                        ridx = letoh32(hv->hv_resp_read_idx);
                   1697:                        continue;
                   1698:                }
                   1699:
                   1700:                switch (letoh16(rsp->rsp_id)) {
                   1701:                case TXP_CMD_CYCLE_STATISTICS:
                   1702:                case TXP_CMD_MEDIA_STATUS_READ:
                   1703:                        break;
                   1704:                case TXP_CMD_HELLO_RESPONSE:
                   1705:                        printf("%s: hello\n", TXP_DEVNAME(sc));
                   1706:                        break;
                   1707:                default:
                   1708:                        printf("%s: unknown id(0x%x)\n", TXP_DEVNAME(sc),
                   1709:                            letoh16(rsp->rsp_id));
                   1710:                }
                   1711:
                   1712:                txp_rsp_fixup(sc, rsp, NULL);
                   1713:                ridx = letoh32(hv->hv_resp_read_idx);
                   1714:                hv->hv_resp_read_idx = letoh32(ridx);
                   1715:        }
                   1716:
                   1717:        return (0);
                   1718: }
                   1719:
                   1720: void
                   1721: txp_rsp_fixup(sc, rsp, dst)
                   1722:        struct txp_softc *sc;
                   1723:        struct txp_rsp_desc *rsp, *dst;
                   1724: {
                   1725:        struct txp_rsp_desc *src = rsp;
                   1726:        struct txp_hostvar *hv = sc->sc_hostvar;
                   1727:        u_int32_t i, ridx;
                   1728:
                   1729:        ridx = letoh32(hv->hv_resp_read_idx);
                   1730:
                   1731:        for (i = 0; i < rsp->rsp_numdesc + 1; i++) {
                   1732:                if (dst != NULL)
                   1733:                        bcopy(src, dst++, sizeof(struct txp_rsp_desc));
                   1734:                ridx += sizeof(struct txp_rsp_desc);
                   1735:                if (ridx == sc->sc_rspring.size) {
                   1736:                        src = sc->sc_rspring.base;
                   1737:                        ridx = 0;
                   1738:                } else
                   1739:                        src++;
                   1740:                sc->sc_rspring.lastwrite = ridx;
                   1741:                hv->hv_resp_read_idx = htole32(ridx);
                   1742:        }
                   1743:
                   1744:        hv->hv_resp_read_idx = htole32(ridx);
                   1745: }
                   1746:
                   1747: int
                   1748: txp_cmd_desc_numfree(sc)
                   1749:        struct txp_softc *sc;
                   1750: {
                   1751:        struct txp_hostvar *hv = sc->sc_hostvar;
                   1752:        struct txp_boot_record *br = sc->sc_boot;
                   1753:        u_int32_t widx, ridx, nfree;
                   1754:
                   1755:        widx = sc->sc_cmdring.lastwrite;
                   1756:        ridx = letoh32(hv->hv_cmd_read_idx);
                   1757:
                   1758:        if (widx == ridx) {
                   1759:                /* Ring is completely free */
                   1760:                nfree = letoh32(br->br_cmd_siz) - sizeof(struct txp_cmd_desc);
                   1761:        } else {
                   1762:                if (widx > ridx)
                   1763:                        nfree = letoh32(br->br_cmd_siz) -
                   1764:                            (widx - ridx + sizeof(struct txp_cmd_desc));
                   1765:                else
                   1766:                        nfree = ridx - widx - sizeof(struct txp_cmd_desc);
                   1767:        }
                   1768:
                   1769:        return (nfree / sizeof(struct txp_cmd_desc));
                   1770: }
                   1771:
                   1772: void
                   1773: txp_stop(sc)
                   1774:        struct txp_softc *sc;
                   1775: {
                   1776:        txp_command(sc, TXP_CMD_TX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1);
                   1777:        txp_command(sc, TXP_CMD_RX_DISABLE, 0, 0, 0, NULL, NULL, NULL, 1);
                   1778:
                   1779:        if (timeout_pending(&sc->sc_tick))
                   1780:                timeout_del(&sc->sc_tick);
                   1781: }
                   1782:
                   1783: void
                   1784: txp_watchdog(ifp)
                   1785:        struct ifnet *ifp;
                   1786: {
                   1787: }
                   1788:
                   1789: int
                   1790: txp_ifmedia_upd(ifp)
                   1791:        struct ifnet *ifp;
                   1792: {
                   1793:        struct txp_softc *sc = ifp->if_softc;
                   1794:        struct ifmedia *ifm = &sc->sc_ifmedia;
                   1795:        u_int16_t new_xcvr;
                   1796:
                   1797:        if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
                   1798:                return (EINVAL);
                   1799:
                   1800:        if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) {
                   1801:                if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
                   1802:                        new_xcvr = TXP_XCVR_10_FDX;
                   1803:                else
                   1804:                        new_xcvr = TXP_XCVR_10_HDX;
                   1805:        } else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
                   1806:                if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
                   1807:                        new_xcvr = TXP_XCVR_100_FDX;
                   1808:                else
                   1809:                        new_xcvr = TXP_XCVR_100_HDX;
                   1810:        } else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
                   1811:                new_xcvr = TXP_XCVR_AUTO;
                   1812:        } else
                   1813:                return (EINVAL);
                   1814:
                   1815:        /* nothing to do */
                   1816:        if (sc->sc_xcvr == new_xcvr)
                   1817:                return (0);
                   1818:
                   1819:        txp_command(sc, TXP_CMD_XCVR_SELECT, new_xcvr, 0, 0,
                   1820:            NULL, NULL, NULL, 0);
                   1821:        sc->sc_xcvr = new_xcvr;
                   1822:
                   1823:        return (0);
                   1824: }
                   1825:
                   1826: void
                   1827: txp_ifmedia_sts(ifp, ifmr)
                   1828:        struct ifnet *ifp;
                   1829:        struct ifmediareq *ifmr;
                   1830: {
                   1831:        struct txp_softc *sc = ifp->if_softc;
                   1832:        struct ifmedia *ifm = &sc->sc_ifmedia;
                   1833:        u_int16_t bmsr, bmcr, anlpar;
                   1834:
                   1835:        ifmr->ifm_status = IFM_AVALID;
                   1836:        ifmr->ifm_active = IFM_ETHER;
                   1837:
                   1838:        if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0,
                   1839:            &bmsr, NULL, NULL, 1))
                   1840:                goto bail;
                   1841:        if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMSR, 0,
                   1842:            &bmsr, NULL, NULL, 1))
                   1843:                goto bail;
                   1844:
                   1845:        if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_BMCR, 0,
                   1846:            &bmcr, NULL, NULL, 1))
                   1847:                goto bail;
                   1848:
                   1849:        if (txp_command(sc, TXP_CMD_PHY_MGMT_READ, 0, MII_ANLPAR, 0,
                   1850:            &anlpar, NULL, NULL, 1))
                   1851:                goto bail;
                   1852:
                   1853:        if (bmsr & BMSR_LINK)
                   1854:                ifmr->ifm_status |= IFM_ACTIVE;
                   1855:
                   1856:        if (bmcr & BMCR_ISO) {
                   1857:                ifmr->ifm_active |= IFM_NONE;
                   1858:                ifmr->ifm_status = 0;
                   1859:                return;
                   1860:        }
                   1861:
                   1862:        if (bmcr & BMCR_LOOP)
                   1863:                ifmr->ifm_active |= IFM_LOOP;
                   1864:
                   1865:        if (bmcr & BMCR_AUTOEN) {
                   1866:                if ((bmsr & BMSR_ACOMP) == 0) {
                   1867:                        ifmr->ifm_active |= IFM_NONE;
                   1868:                        return;
                   1869:                }
                   1870:
                   1871:                if (anlpar & ANLPAR_T4)
                   1872:                        ifmr->ifm_active |= IFM_100_T4;
                   1873:                else if (anlpar & ANLPAR_TX_FD)
                   1874:                        ifmr->ifm_active |= IFM_100_TX|IFM_FDX;
                   1875:                else if (anlpar & ANLPAR_TX)
                   1876:                        ifmr->ifm_active |= IFM_100_TX;
                   1877:                else if (anlpar & ANLPAR_10_FD)
                   1878:                        ifmr->ifm_active |= IFM_10_T|IFM_FDX;
                   1879:                else if (anlpar & ANLPAR_10)
                   1880:                        ifmr->ifm_active |= IFM_10_T;
                   1881:                else
                   1882:                        ifmr->ifm_active |= IFM_NONE;
                   1883:        } else
                   1884:                ifmr->ifm_active = ifm->ifm_cur->ifm_media;
                   1885:        return;
                   1886:
                   1887: bail:
                   1888:        ifmr->ifm_active |= IFM_NONE;
                   1889:        ifmr->ifm_status &= ~IFM_AVALID;
                   1890: }
                   1891:
                   1892: void
                   1893: txp_show_descriptor(d)
                   1894:        void *d;
                   1895: {
                   1896:        struct txp_cmd_desc *cmd = d;
                   1897:        struct txp_rsp_desc *rsp = d;
                   1898:        struct txp_tx_desc *txd = d;
                   1899:        struct txp_frag_desc *frgd = d;
                   1900:
                   1901:        switch (cmd->cmd_flags & CMD_FLAGS_TYPE_M) {
                   1902:        case CMD_FLAGS_TYPE_CMD:
                   1903:                /* command descriptor */
                   1904:                printf("[cmd flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
                   1905:                    cmd->cmd_flags, cmd->cmd_numdesc, letoh16(cmd->cmd_id),
                   1906:                    letoh16(cmd->cmd_seq), letoh16(cmd->cmd_par1),
                   1907:                    letoh32(cmd->cmd_par2), letoh32(cmd->cmd_par3));
                   1908:                break;
                   1909:        case CMD_FLAGS_TYPE_RESP:
                   1910:                /* response descriptor */
                   1911:                printf("[rsp flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
                   1912:                    rsp->rsp_flags, rsp->rsp_numdesc, letoh16(rsp->rsp_id),
                   1913:                    letoh16(rsp->rsp_seq), letoh16(rsp->rsp_par1),
                   1914:                    letoh32(rsp->rsp_par2), letoh32(rsp->rsp_par3));
                   1915:                break;
                   1916:        case CMD_FLAGS_TYPE_DATA:
                   1917:                /* data header (assuming tx for now) */
                   1918:                printf("[data flags 0x%x num %d totlen %d addr 0x%x/0x%x pflags 0x%x]",
                   1919:                    txd->tx_flags, txd->tx_numdesc, txd->tx_totlen,
                   1920:                    txd->tx_addrlo, txd->tx_addrhi, txd->tx_pflags);
                   1921:                break;
                   1922:        case CMD_FLAGS_TYPE_FRAG:
                   1923:                /* fragment descriptor */
                   1924:                printf("[frag flags 0x%x rsvd1 0x%x len %d addr 0x%x/0x%x rsvd2 0x%x]",
                   1925:                    frgd->frag_flags, frgd->frag_rsvd1, frgd->frag_len,
                   1926:                    frgd->frag_addrlo, frgd->frag_addrhi, frgd->frag_rsvd2);
                   1927:                break;
                   1928:        default:
                   1929:                printf("[unknown(%x) flags 0x%x num %d id %d seq %d par1 0x%x par2 0x%x par3 0x%x]\n",
                   1930:                    cmd->cmd_flags & CMD_FLAGS_TYPE_M,
                   1931:                    cmd->cmd_flags, cmd->cmd_numdesc, letoh16(cmd->cmd_id),
                   1932:                    letoh16(cmd->cmd_seq), letoh16(cmd->cmd_par1),
                   1933:                    letoh32(cmd->cmd_par2), letoh32(cmd->cmd_par3));
                   1934:                break;
                   1935:        }
                   1936: }
                   1937:
                   1938: void
                   1939: txp_set_filter(sc)
                   1940:        struct txp_softc *sc;
                   1941: {
                   1942:        struct arpcom *ac = &sc->sc_arpcom;
                   1943:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1944:        u_int32_t hashbit, hash[2];
                   1945:        u_int16_t filter;
                   1946:        int mcnt = 0;
                   1947:        struct ether_multi *enm;
                   1948:        struct ether_multistep step;
                   1949:
                   1950:        if (ifp->if_flags & IFF_PROMISC) {
                   1951:                filter = TXP_RXFILT_PROMISC;
                   1952:                goto setit;
                   1953:        }
                   1954:
                   1955: again:
                   1956:        filter = TXP_RXFILT_DIRECT;
                   1957:
                   1958:        if (ifp->if_flags & IFF_BROADCAST)
                   1959:                filter |= TXP_RXFILT_BROADCAST;
                   1960:
                   1961:        if (ifp->if_flags & IFF_ALLMULTI)
                   1962:                filter |= TXP_RXFILT_ALLMULTI;
                   1963:        else {
                   1964:                hash[0] = hash[1] = 0;
                   1965:
                   1966:                ETHER_FIRST_MULTI(step, ac, enm);
                   1967:                while (enm != NULL) {
                   1968:                        if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
                   1969:                                /*
                   1970:                                 * We must listen to a range of multicast
                   1971:                                 * addresses.  For now, just accept all
                   1972:                                 * multicasts, rather than trying to set only
                   1973:                                 * those filter bits needed to match the range.
                   1974:                                 * (At this time, the only use of address
                   1975:                                 * ranges is for IP multicast routing, for
                   1976:                                 * which the range is big enough to require
                   1977:                                 * all bits set.)
                   1978:                                 */
                   1979:                                ifp->if_flags |= IFF_ALLMULTI;
                   1980:                                goto again;
                   1981:                        }
                   1982:
                   1983:                        mcnt++;
                   1984:                        hashbit = (u_int16_t)(ether_crc32_be(enm->enm_addrlo,
                   1985:                            ETHER_ADDR_LEN) & (64 - 1));
                   1986:                        hash[hashbit / 32] |= (1 << hashbit % 32);
                   1987:                        ETHER_NEXT_MULTI(step, enm);
                   1988:                }
                   1989:
                   1990:                if (mcnt > 0) {
                   1991:                        filter |= TXP_RXFILT_HASHMULTI;
                   1992:                        txp_command(sc, TXP_CMD_MCAST_HASH_MASK_WRITE,
                   1993:                            2, hash[0], hash[1], NULL, NULL, NULL, 0);
                   1994:                }
                   1995:        }
                   1996:
                   1997: setit:
                   1998:        txp_command(sc, TXP_CMD_RX_FILTER_WRITE, filter, 0, 0,
                   1999:            NULL, NULL, NULL, 1);
                   2000: }
                   2001:
                   2002: void
                   2003: txp_capabilities(sc)
                   2004:        struct txp_softc *sc;
                   2005: {
                   2006:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   2007:        struct txp_rsp_desc *rsp = NULL;
                   2008:        struct txp_ext_desc *ext;
                   2009:
                   2010:        if (txp_command2(sc, TXP_CMD_OFFLOAD_READ, 0, 0, 0, NULL, 0, &rsp, 1))
                   2011:                goto out;
                   2012:
                   2013:        if (rsp->rsp_numdesc != 1)
                   2014:                goto out;
                   2015:        ext = (struct txp_ext_desc *)(rsp + 1);
                   2016:
                   2017:        sc->sc_tx_capability = ext->ext_1 & OFFLOAD_MASK;
                   2018:        sc->sc_rx_capability = ext->ext_2 & OFFLOAD_MASK;
                   2019:
                   2020:        ifp->if_capabilities |= IFCAP_VLAN_MTU;
                   2021:
                   2022: #if NVLAN > 0
                   2023:        if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_VLAN) {
                   2024:                sc->sc_tx_capability |= OFFLOAD_VLAN;
                   2025:                ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
                   2026:        }
                   2027: #endif
                   2028:
                   2029: #if 0
                   2030:        /* not ready yet */
                   2031:        if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPSEC) {
                   2032:                sc->sc_tx_capability |= OFFLOAD_IPSEC;
                   2033:                sc->sc_rx_capability |= OFFLOAD_IPSEC;
                   2034:                ifp->if_capabilities |= IFCAP_IPSEC;
                   2035:        }
                   2036: #endif
                   2037:
                   2038:        if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_IPCKSUM) {
                   2039:                sc->sc_tx_capability |= OFFLOAD_IPCKSUM;
                   2040:                sc->sc_rx_capability |= OFFLOAD_IPCKSUM;
                   2041:                ifp->if_capabilities |= IFCAP_CSUM_IPv4;
                   2042:        }
                   2043:
                   2044:        if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_TCPCKSUM) {
                   2045:                sc->sc_rx_capability |= OFFLOAD_TCPCKSUM;
                   2046: #ifdef TRY_TX_TCP_CSUM
                   2047:                sc->sc_tx_capability |= OFFLOAD_TCPCKSUM;
                   2048:                ifp->if_capabilities |= IFCAP_CSUM_TCPv4;
                   2049: #endif
                   2050:        }
                   2051:
                   2052:        if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_UDPCKSUM) {
                   2053:                sc->sc_rx_capability |= OFFLOAD_UDPCKSUM;
                   2054: #ifdef TRY_TX_UDP_CSUM
                   2055:                sc->sc_tx_capability |= OFFLOAD_UDPCKSUM;
                   2056:                ifp->if_capabilities |= IFCAP_CSUM_UDPv4;
                   2057: #endif
                   2058:        }
                   2059:
                   2060:        if (txp_command(sc, TXP_CMD_OFFLOAD_WRITE, 0,
                   2061:            sc->sc_tx_capability, sc->sc_rx_capability, NULL, NULL, NULL, 1))
                   2062:                goto out;
                   2063:
                   2064: out:
                   2065:        if (rsp != NULL)
                   2066:                free(rsp, M_DEVBUF);
                   2067: }

CVSweb