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

Annotation of sys/dev/ic/fxp.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: fxp.c,v 1.87 2007/06/06 09:43:44 henning Exp $        */
        !             2: /*     $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $       */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995, David Greenman
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Modifications to support NetBSD:
        !             9:  * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice unmodified, this list of conditions, and the following
        !            16:  *    disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     Id: if_fxp.c,v 1.55 1998/08/04 08:53:12 dg Exp
        !            34:  */
        !            35:
        !            36: /*
        !            37:  * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
        !            38:  */
        !            39:
        !            40: #include "bpfilter.h"
        !            41:
        !            42: #include <sys/param.h>
        !            43: #include <sys/systm.h>
        !            44: #include <sys/mbuf.h>
        !            45: #include <sys/malloc.h>
        !            46: #include <sys/kernel.h>
        !            47: #include <sys/socket.h>
        !            48: #include <sys/syslog.h>
        !            49: #include <sys/timeout.h>
        !            50:
        !            51: #include <net/if.h>
        !            52: #include <net/if_dl.h>
        !            53: #include <net/if_media.h>
        !            54: #include <net/if_types.h>
        !            55:
        !            56: #ifdef INET
        !            57: #include <netinet/in.h>
        !            58: #include <netinet/in_systm.h>
        !            59: #include <netinet/in_var.h>
        !            60: #include <netinet/ip.h>
        !            61: #endif
        !            62:
        !            63: #if NBPFILTER > 0
        !            64: #include <net/bpf.h>
        !            65: #endif
        !            66:
        !            67: #include <sys/ioctl.h>
        !            68: #include <sys/errno.h>
        !            69: #include <sys/device.h>
        !            70:
        !            71: #include <netinet/if_ether.h>
        !            72:
        !            73: #include <machine/cpu.h>
        !            74: #include <machine/bus.h>
        !            75: #include <machine/intr.h>
        !            76:
        !            77: #include <dev/mii/miivar.h>
        !            78:
        !            79: #include <dev/ic/fxpreg.h>
        !            80: #include <dev/ic/fxpvar.h>
        !            81:
        !            82: /*
        !            83:  * NOTE!  On the Alpha, we have an alignment constraint.  The
        !            84:  * card DMAs the packet immediately following the RFA.  However,
        !            85:  * the first thing in the packet is a 14-byte Ethernet header.
        !            86:  * This means that the packet is misaligned.  To compensate,
        !            87:  * we actually offset the RFA 2 bytes into the cluster.  This
        !            88:  * aligns the packet after the Ethernet header at a 32-bit
        !            89:  * boundary.  HOWEVER!  This means that the RFA is misaligned!
        !            90:  */
        !            91: #define        RFA_ALIGNMENT_FUDGE     (2 + sizeof(bus_dmamap_t *))
        !            92:
        !            93: /*
        !            94:  * Inline function to copy a 16-bit aligned 32-bit quantity.
        !            95:  */
        !            96: static __inline void fxp_lwcopy(volatile u_int32_t *,
        !            97:        volatile u_int32_t *);
        !            98:
        !            99: static __inline void
        !           100: fxp_lwcopy(volatile u_int32_t *src, volatile u_int32_t *dst)
        !           101: {
        !           102:        volatile u_int16_t *a = (u_int16_t *)src;
        !           103:        volatile u_int16_t *b = (u_int16_t *)dst;
        !           104:
        !           105:        b[0] = a[0];
        !           106:        b[1] = a[1];
        !           107: }
        !           108:
        !           109: /*
        !           110:  * Template for default configuration parameters.
        !           111:  * See struct fxp_cb_config for the bit definitions.
        !           112:  * Note, cb_command is filled in later.
        !           113:  */
        !           114: static u_char fxp_cb_config_template[] = {
        !           115:        0x0, 0x0,               /* cb_status */
        !           116:        0x0, 0x0,               /* cb_command */
        !           117:        0xff, 0xff, 0xff, 0xff, /* link_addr */
        !           118:        0x16,   /*  0 Byte count. */
        !           119:        0x08,   /*  1 Fifo limit */
        !           120:        0x00,   /*  2 Adaptive ifs */
        !           121:        0x00,   /*  3 ctrl0 */
        !           122:        0x00,   /*  4 rx_dma_bytecount */
        !           123:        0x80,   /*  5 tx_dma_bytecount */
        !           124:        0xb2,   /*  6 ctrl 1*/
        !           125:        0x03,   /*  7 ctrl 2*/
        !           126:        0x01,   /*  8 mediatype */
        !           127:        0x00,   /*  9 void2 */
        !           128:        0x26,   /* 10 ctrl3 */
        !           129:        0x00,   /* 11 linear priority */
        !           130:        0x60,   /* 12 interfrm_spacing */
        !           131:        0x00,   /* 13 void31 */
        !           132:        0xf2,   /* 14 void32 */
        !           133:        0x48,   /* 15 promiscuous */
        !           134:        0x00,   /* 16 void41 */
        !           135:        0x40,   /* 17 void42 */
        !           136:        0xf3,   /* 18 stripping */
        !           137:        0x00,   /* 19 fdx_pin */
        !           138:        0x3f,   /* 20 multi_ia */
        !           139:        0x05    /* 21 mc_all */
        !           140: };
        !           141:
        !           142: void fxp_eeprom_shiftin(struct fxp_softc *, int, int);
        !           143: void fxp_eeprom_putword(struct fxp_softc *, int, u_int16_t);
        !           144: void fxp_write_eeprom(struct fxp_softc *, u_short *, int, int);
        !           145: int fxp_mediachange(struct ifnet *);
        !           146: void fxp_mediastatus(struct ifnet *, struct ifmediareq *);
        !           147: void fxp_scb_wait(struct fxp_softc *);
        !           148: void fxp_start(struct ifnet *);
        !           149: int fxp_ioctl(struct ifnet *, u_long, caddr_t);
        !           150: void fxp_init(void *);
        !           151: void fxp_load_ucode(struct fxp_softc *);
        !           152: void fxp_stop(struct fxp_softc *, int);
        !           153: void fxp_watchdog(struct ifnet *);
        !           154: int fxp_add_rfabuf(struct fxp_softc *, struct mbuf *);
        !           155: int fxp_mdi_read(struct device *, int, int);
        !           156: void fxp_mdi_write(struct device *, int, int, int);
        !           157: void fxp_autosize_eeprom(struct fxp_softc *);
        !           158: void fxp_statchg(struct device *);
        !           159: void fxp_read_eeprom(struct fxp_softc *, u_int16_t *,
        !           160:                                    int, int);
        !           161: void fxp_stats_update(void *);
        !           162: void fxp_mc_setup(struct fxp_softc *, int);
        !           163: void fxp_scb_cmd(struct fxp_softc *, u_int8_t);
        !           164:
        !           165: /*
        !           166:  * Set initial transmit threshold at 64 (512 bytes). This is
        !           167:  * increased by 64 (512 bytes) at a time, to maximum of 192
        !           168:  * (1536 bytes), if an underrun occurs.
        !           169:  */
        !           170: static int tx_threshold = 64;
        !           171:
        !           172: /*
        !           173:  * Interrupts coalescing code params
        !           174:  */
        !           175: int fxp_int_delay = FXP_INT_DELAY;
        !           176: int fxp_bundle_max = FXP_BUNDLE_MAX;
        !           177: int fxp_min_size_mask = FXP_MIN_SIZE_MASK;
        !           178:
        !           179: /*
        !           180:  * TxCB list index mask. This is used to do list wrap-around.
        !           181:  */
        !           182: #define FXP_TXCB_MASK  (FXP_NTXCB - 1)
        !           183:
        !           184: /*
        !           185:  * Maximum number of seconds that the receiver can be idle before we
        !           186:  * assume it's dead and attempt to reset it by reprogramming the
        !           187:  * multicast filter. This is part of a work-around for a bug in the
        !           188:  * NIC. See fxp_stats_update().
        !           189:  */
        !           190: #define FXP_MAX_RX_IDLE        15
        !           191:
        !           192: /*
        !           193:  * Wait for the previous command to be accepted (but not necessarily
        !           194:  * completed).
        !           195:  */
        !           196: void
        !           197: fxp_scb_wait(struct fxp_softc *sc)
        !           198: {
        !           199:        int i = 10000;
        !           200:
        !           201:        while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
        !           202:                DELAY(2);
        !           203:        if (i == 0)
        !           204:                printf("%s: warning: SCB timed out\n", sc->sc_dev.dv_xname);
        !           205: }
        !           206:
        !           207: void
        !           208: fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length)
        !           209: {
        !           210:        u_int16_t reg;
        !           211:        int x;
        !           212:
        !           213:        /*
        !           214:         * Shift in data.
        !           215:         */
        !           216:        for (x = 1 << (length - 1); x; x >>= 1) {
        !           217:                if (data & x)
        !           218:                        reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
        !           219:                else
        !           220:                        reg = FXP_EEPROM_EECS;
        !           221:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           222:                DELAY(1);
        !           223:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
        !           224:                DELAY(1);
        !           225:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           226:                DELAY(1);
        !           227:        }
        !           228: }
        !           229:
        !           230: void
        !           231: fxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data)
        !           232: {
        !           233:        int i;
        !           234:
        !           235:        /*
        !           236:         * Erase/write enable.
        !           237:         */
        !           238:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           239:        fxp_eeprom_shiftin(sc, 0x4, 3);
        !           240:        fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size);
        !           241:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           242:        DELAY(1);
        !           243:        /*
        !           244:         * Shift in write opcode, address, data.
        !           245:         */
        !           246:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           247:        fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
        !           248:        fxp_eeprom_shiftin(sc, offset, sc->eeprom_size);
        !           249:        fxp_eeprom_shiftin(sc, data, 16);
        !           250:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           251:        DELAY(1);
        !           252:        /*
        !           253:         * Wait for EEPROM to finish up.
        !           254:         */
        !           255:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           256:        DELAY(1);
        !           257:        for (i = 0; i < 1000; i++) {
        !           258:                if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
        !           259:                        break;
        !           260:                DELAY(50);
        !           261:        }
        !           262:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           263:        DELAY(1);
        !           264:        /*
        !           265:         * Erase/write disable.
        !           266:         */
        !           267:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           268:        fxp_eeprom_shiftin(sc, 0x4, 3);
        !           269:        fxp_eeprom_shiftin(sc, 0, sc->eeprom_size);
        !           270:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           271:        DELAY(1);
        !           272: }
        !           273:
        !           274: void
        !           275: fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
        !           276: {
        !           277:        int i;
        !           278:
        !           279:        for (i = 0; i < words; i++)
        !           280:                fxp_eeprom_putword(sc, offset + i, data[i]);
        !           281: }
        !           282:
        !           283: /*************************************************************
        !           284:  * Operating system-specific autoconfiguration glue
        !           285:  *************************************************************/
        !           286:
        !           287: void   fxp_shutdown(void *);
        !           288: void   fxp_power(int, void *);
        !           289:
        !           290: struct cfdriver fxp_cd = {
        !           291:        NULL, "fxp", DV_IFNET
        !           292: };
        !           293:
        !           294: /*
        !           295:  * Device shutdown routine. Called at system shutdown after sync. The
        !           296:  * main purpose of this routine is to shut off receiver DMA so that
        !           297:  * kernel memory doesn't get clobbered during warmboot.
        !           298:  */
        !           299: void
        !           300: fxp_shutdown(void *sc)
        !           301: {
        !           302:        fxp_stop((struct fxp_softc *) sc, 0);
        !           303: }
        !           304:
        !           305: /*
        !           306:  * Power handler routine. Called when the system is transitioning
        !           307:  * into/out of power save modes.  As with fxp_shutdown, the main
        !           308:  * purpose of this routine is to shut off receiver DMA so it doesn't
        !           309:  * clobber kernel memory at the wrong time.
        !           310:  */
        !           311: void
        !           312: fxp_power(int why, void *arg)
        !           313: {
        !           314:        struct fxp_softc *sc = arg;
        !           315:        struct ifnet *ifp;
        !           316:        int s;
        !           317:
        !           318:        s = splnet();
        !           319:        if (why != PWR_RESUME)
        !           320:                fxp_stop(sc, 0);
        !           321:        else {
        !           322:                ifp = &sc->sc_arpcom.ac_if;
        !           323:                if (ifp->if_flags & IFF_UP)
        !           324:                        fxp_init(sc);
        !           325:        }
        !           326:        splx(s);
        !           327: }
        !           328:
        !           329: /*************************************************************
        !           330:  * End of operating system-specific autoconfiguration glue
        !           331:  *************************************************************/
        !           332:
        !           333: /*
        !           334:  * Do generic parts of attach.
        !           335:  */
        !           336: int
        !           337: fxp_attach(struct fxp_softc *sc, const char *intrstr)
        !           338: {
        !           339:        struct ifnet *ifp;
        !           340:        struct mbuf *m;
        !           341:        bus_dmamap_t rxmap;
        !           342:        u_int16_t data;
        !           343:        u_int8_t enaddr[6];
        !           344:        int i, err;
        !           345:
        !           346:        /*
        !           347:         * Reset to a stable state.
        !           348:         */
        !           349:        CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
        !           350:        DELAY(10);
        !           351:
        !           352:        if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct fxp_ctrl),
        !           353:            PAGE_SIZE, 0, &sc->sc_cb_seg, 1, &sc->sc_cb_nseg, BUS_DMA_NOWAIT))
        !           354:                goto fail;
        !           355:        if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg,
        !           356:            sizeof(struct fxp_ctrl), (caddr_t *)&sc->sc_ctrl,
        !           357:            BUS_DMA_NOWAIT)) {
        !           358:                bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
        !           359:                goto fail;
        !           360:        }
        !           361:        if (bus_dmamap_create(sc->sc_dmat, sizeof(struct fxp_ctrl),
        !           362:            1, sizeof(struct fxp_ctrl), 0, BUS_DMA_NOWAIT,
        !           363:            &sc->tx_cb_map)) {
        !           364:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
        !           365:                    sizeof(struct fxp_ctrl));
        !           366:                bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
        !           367:                goto fail;
        !           368:        }
        !           369:        if (bus_dmamap_load(sc->sc_dmat, sc->tx_cb_map, (caddr_t)sc->sc_ctrl,
        !           370:            sizeof(struct fxp_ctrl), NULL, BUS_DMA_NOWAIT)) {
        !           371:                bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
        !           372:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
        !           373:                    sizeof(struct fxp_ctrl));
        !           374:                bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
        !           375:                goto fail;
        !           376:        }
        !           377:
        !           378:        for (i = 0; i < FXP_NTXCB; i++) {
        !           379:                if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
        !           380:                    FXP_NTXSEG, MCLBYTES, 0, 0, &sc->txs[i].tx_map)) != 0) {
        !           381:                        printf("%s: unable to create tx dma map %d, error %d\n",
        !           382:                            sc->sc_dev.dv_xname, i, err);
        !           383:                        goto fail;
        !           384:                }
        !           385:                sc->txs[i].tx_mbuf = NULL;
        !           386:                sc->txs[i].tx_cb = sc->sc_ctrl->tx_cb + i;
        !           387:                sc->txs[i].tx_off = offsetof(struct fxp_ctrl, tx_cb[i]);
        !           388:                sc->txs[i].tx_next = &sc->txs[(i + 1) & FXP_TXCB_MASK];
        !           389:        }
        !           390:        bzero(sc->sc_ctrl, sizeof(struct fxp_ctrl));
        !           391:
        !           392:        /*
        !           393:         * Pre-allocate some receive buffers.
        !           394:         */
        !           395:        sc->sc_rxfree = 0;
        !           396:        for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
        !           397:                if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
        !           398:                    MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
        !           399:                        printf("%s: unable to create rx dma map %d, error %d\n",
        !           400:                            sc->sc_dev.dv_xname, i, err);
        !           401:                        goto fail;
        !           402:                }
        !           403:                sc->rx_bufs++;
        !           404:        }
        !           405:        for (i = 0; i < FXP_NRFABUFS_MIN; i++)
        !           406:                if (fxp_add_rfabuf(sc, NULL) != 0)
        !           407:                        goto fail;
        !           408:
        !           409:        /*
        !           410:         * Find out how large of an SEEPROM we have.
        !           411:         */
        !           412:        fxp_autosize_eeprom(sc);
        !           413:
        !           414:        /*
        !           415:         * Get info about the primary PHY
        !           416:         */
        !           417:        fxp_read_eeprom(sc, (u_int16_t *)&data, 6, 1);
        !           418:        sc->phy_primary_addr = data & 0xff;
        !           419:        sc->phy_primary_device = (data >> 8) & 0x3f;
        !           420:        sc->phy_10Mbps_only = data >> 15;
        !           421:
        !           422:        /*
        !           423:         * Only 82558 and newer cards can do this.
        !           424:         */
        !           425:        if (sc->sc_revision >= FXP_REV_82558_A4) {
        !           426:                sc->sc_int_delay = fxp_int_delay;
        !           427:                sc->sc_bundle_max = fxp_bundle_max;
        !           428:                sc->sc_min_size_mask = fxp_min_size_mask;
        !           429:        }
        !           430:        /*
        !           431:         * Read MAC address.
        !           432:         */
        !           433:        fxp_read_eeprom(sc, (u_int16_t *)enaddr, 0, 3);
        !           434:
        !           435:        ifp = &sc->sc_arpcom.ac_if;
        !           436:        bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
        !           437:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
        !           438:        ifp->if_softc = sc;
        !           439:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        !           440:        ifp->if_ioctl = fxp_ioctl;
        !           441:        ifp->if_start = fxp_start;
        !           442:        ifp->if_watchdog = fxp_watchdog;
        !           443:        IFQ_SET_MAXLEN(&ifp->if_snd, FXP_NTXCB - 1);
        !           444:        IFQ_SET_READY(&ifp->if_snd);
        !           445:
        !           446:        ifp->if_capabilities = IFCAP_VLAN_MTU;
        !           447:
        !           448:        printf(": %s, address %s\n", intrstr,
        !           449:            ether_sprintf(sc->sc_arpcom.ac_enaddr));
        !           450:
        !           451:        if (sc->sc_flags & FXPF_DISABLE_STANDBY) {
        !           452:                fxp_read_eeprom(sc, &data, 10, 1);
        !           453:                if (data & 0x02) {                      /* STB enable */
        !           454:                        u_int16_t cksum;
        !           455:                        int i;
        !           456:
        !           457:                        printf("%s: Disabling dynamic standby mode in EEPROM",
        !           458:                            sc->sc_dev.dv_xname);
        !           459:                        data &= ~0x02;
        !           460:                        fxp_write_eeprom(sc, &data, 10, 1);
        !           461:                        printf(", New ID 0x%x", data);
        !           462:                        cksum = 0;
        !           463:                        for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
        !           464:                                fxp_read_eeprom(sc, &data, i, 1);
        !           465:                                cksum += data;
        !           466:                        }
        !           467:                        i = (1 << sc->eeprom_size) - 1;
        !           468:                        cksum = 0xBABA - cksum;
        !           469:                        fxp_read_eeprom(sc, &data, i, 1);
        !           470:                        fxp_write_eeprom(sc, &cksum, i, 1);
        !           471:                        printf(", cksum @ 0x%x: 0x%x -> 0x%x\n",
        !           472:                            i, data, cksum);
        !           473:                }
        !           474:        }
        !           475:
        !           476:        /* Receiver lock-up workaround detection. */
        !           477:        fxp_read_eeprom(sc, &data, 3, 1);
        !           478:        if ((data & 0x03) != 0x03)
        !           479:                sc->sc_flags |= FXPF_RECV_WORKAROUND;
        !           480:
        !           481:        /*
        !           482:         * Initialize our media structures and probe the MII.
        !           483:         */
        !           484:        sc->sc_mii.mii_ifp = ifp;
        !           485:        sc->sc_mii.mii_readreg = fxp_mdi_read;
        !           486:        sc->sc_mii.mii_writereg = fxp_mdi_write;
        !           487:        sc->sc_mii.mii_statchg = fxp_statchg;
        !           488:        ifmedia_init(&sc->sc_mii.mii_media, 0, fxp_mediachange,
        !           489:            fxp_mediastatus);
        !           490:        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
        !           491:            MII_OFFSET_ANY, MIIF_NOISOLATE);
        !           492:        /* If no phy found, just use auto mode */
        !           493:        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
        !           494:                ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
        !           495:                    0, NULL);
        !           496:                printf("%s: no phy found, using manual mode\n",
        !           497:                    sc->sc_dev.dv_xname);
        !           498:        }
        !           499:
        !           500:        if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL, 0))
        !           501:                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
        !           502:        else if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0))
        !           503:                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
        !           504:        else
        !           505:                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_10_T);
        !           506:
        !           507:        /*
        !           508:         * Attach the interface.
        !           509:         */
        !           510:        if_attach(ifp);
        !           511:        ether_ifattach(ifp);
        !           512:
        !           513:        /*
        !           514:         * Add shutdown hook so that DMA is disabled prior to reboot. Not
        !           515:         * doing so could allow DMA to corrupt kernel memory during the
        !           516:         * reboot before the driver initializes.
        !           517:         */
        !           518:        sc->sc_sdhook = shutdownhook_establish(fxp_shutdown, sc);
        !           519:
        !           520:        /*
        !           521:         * Add suspend hook, for similiar reasons..
        !           522:         */
        !           523:        sc->sc_powerhook = powerhook_establish(fxp_power, sc);
        !           524:
        !           525:        /*
        !           526:         * Initialize timeout for statistics update.
        !           527:         */
        !           528:        timeout_set(&sc->stats_update_to, fxp_stats_update, sc);
        !           529:
        !           530:        return (0);
        !           531:
        !           532:  fail:
        !           533:        printf("%s: Failed to malloc memory\n", sc->sc_dev.dv_xname);
        !           534:        if (sc->tx_cb_map != NULL) {
        !           535:                bus_dmamap_unload(sc->sc_dmat, sc->tx_cb_map);
        !           536:                bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
        !           537:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
        !           538:                    sizeof(struct fxp_cb_tx) * FXP_NTXCB);
        !           539:                bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
        !           540:        }
        !           541:        m = sc->rfa_headm;
        !           542:        while (m != NULL) {
        !           543:                rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
        !           544:                bus_dmamap_unload(sc->sc_dmat, rxmap);
        !           545:                FXP_RXMAP_PUT(sc, rxmap);
        !           546:                m = m_free(m);
        !           547:        }
        !           548:        return (ENOMEM);
        !           549: }
        !           550:
        !           551: /*
        !           552:  * From NetBSD:
        !           553:  *
        !           554:  * Figure out EEPROM size.
        !           555:  *
        !           556:  * 559's can have either 64-word or 256-word EEPROMs, the 558
        !           557:  * datasheet only talks about 64-word EEPROMs, and the 557 datasheet
        !           558:  * talks about the existence of 16 to 256 word EEPROMs.
        !           559:  *
        !           560:  * The only known sizes are 64 and 256, where the 256 version is used
        !           561:  * by CardBus cards to store CIS information.
        !           562:  *
        !           563:  * The address is shifted in msb-to-lsb, and after the last
        !           564:  * address-bit the EEPROM is supposed to output a `dummy zero' bit,
        !           565:  * after which follows the actual data. We try to detect this zero, by
        !           566:  * probing the data-out bit in the EEPROM control register just after
        !           567:  * having shifted in a bit. If the bit is zero, we assume we've
        !           568:  * shifted enough address bits. The data-out should be tri-state,
        !           569:  * before this, which should translate to a logical one.
        !           570:  *
        !           571:  * Other ways to do this would be to try to read a register with known
        !           572:  * contents with a varying number of address bits, but no such
        !           573:  * register seem to be available. The high bits of register 10 are 01
        !           574:  * on the 558 and 559, but apparently not on the 557.
        !           575:  *
        !           576:  * The Linux driver computes a checksum on the EEPROM data, but the
        !           577:  * value of this checksum is not very well documented.
        !           578:  */
        !           579: void
        !           580: fxp_autosize_eeprom(struct fxp_softc *sc)
        !           581: {
        !           582:        u_int16_t reg;
        !           583:        int x;
        !           584:
        !           585:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           586:        /*
        !           587:         * Shift in read opcode.
        !           588:         */
        !           589:        for (x = 3; x > 0; x--) {
        !           590:                if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
        !           591:                        reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
        !           592:                } else {
        !           593:                        reg = FXP_EEPROM_EECS;
        !           594:                }
        !           595:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           596:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
        !           597:                    reg | FXP_EEPROM_EESK);
        !           598:                DELAY(4);
        !           599:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           600:                DELAY(4);
        !           601:        }
        !           602:        /*
        !           603:         * Shift in address.
        !           604:         * Wait for the dummy zero following a correct address shift.
        !           605:         */
        !           606:        for (x = 1; x <= 8; x++) {
        !           607:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           608:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
        !           609:                        FXP_EEPROM_EECS | FXP_EEPROM_EESK);
        !           610:                DELAY(4);
        !           611:                if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) == 0)
        !           612:                        break;
        !           613:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           614:                DELAY(4);
        !           615:        }
        !           616:        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           617:        DELAY(4);
        !           618:        sc->eeprom_size = x;
        !           619: }
        !           620:
        !           621: /*
        !           622:  * Read from the serial EEPROM. Basically, you manually shift in
        !           623:  * the read opcode (one bit at a time) and then shift in the address,
        !           624:  * and then you shift out the data (all of this one bit at a time).
        !           625:  * The word size is 16 bits, so you have to provide the address for
        !           626:  * every 16 bits of data.
        !           627:  */
        !           628: void
        !           629: fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset,
        !           630:     int words)
        !           631: {
        !           632:        u_int16_t reg;
        !           633:        int i, x;
        !           634:
        !           635:        for (i = 0; i < words; i++) {
        !           636:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
        !           637:                /*
        !           638:                 * Shift in read opcode.
        !           639:                 */
        !           640:                for (x = 3; x > 0; x--) {
        !           641:                        if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
        !           642:                                reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
        !           643:                        } else {
        !           644:                                reg = FXP_EEPROM_EECS;
        !           645:                        }
        !           646:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           647:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
        !           648:                            reg | FXP_EEPROM_EESK);
        !           649:                        DELAY(4);
        !           650:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           651:                        DELAY(4);
        !           652:                }
        !           653:                /*
        !           654:                 * Shift in address.
        !           655:                 */
        !           656:                for (x = sc->eeprom_size; x > 0; x--) {
        !           657:                        if ((i + offset) & (1 << (x - 1))) {
        !           658:                                reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
        !           659:                        } else {
        !           660:                                reg = FXP_EEPROM_EECS;
        !           661:                        }
        !           662:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           663:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
        !           664:                            reg | FXP_EEPROM_EESK);
        !           665:                        DELAY(4);
        !           666:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           667:                        DELAY(4);
        !           668:                }
        !           669:                reg = FXP_EEPROM_EECS;
        !           670:                data[i] = 0;
        !           671:                /*
        !           672:                 * Shift out data.
        !           673:                 */
        !           674:                for (x = 16; x > 0; x--) {
        !           675:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
        !           676:                            reg | FXP_EEPROM_EESK);
        !           677:                        DELAY(4);
        !           678:                        if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) &
        !           679:                            FXP_EEPROM_EEDO)
        !           680:                                data[i] |= (1 << (x - 1));
        !           681:                        CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
        !           682:                        DELAY(4);
        !           683:                }
        !           684:                data[i] = letoh16(data[i]);
        !           685:                CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
        !           686:                DELAY(4);
        !           687:        }
        !           688: }
        !           689:
        !           690: /*
        !           691:  * Start packet transmission on the interface.
        !           692:  */
        !           693: void
        !           694: fxp_start(struct ifnet *ifp)
        !           695: {
        !           696:        struct fxp_softc *sc = ifp->if_softc;
        !           697:        struct fxp_txsw *txs = sc->sc_cbt_prod;
        !           698:        struct fxp_cb_tx *txc;
        !           699:        struct mbuf *m0, *m = NULL;
        !           700:        int cnt = sc->sc_cbt_cnt, seg;
        !           701:
        !           702:        if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
        !           703:                return;
        !           704:
        !           705:        while (1) {
        !           706:                if (cnt >= (FXP_NTXCB - 2)) {
        !           707:                        ifp->if_flags |= IFF_OACTIVE;
        !           708:                        break;
        !           709:                }
        !           710:
        !           711:                txs = txs->tx_next;
        !           712:
        !           713:                IFQ_POLL(&ifp->if_snd, m0);
        !           714:                if (m0 == NULL)
        !           715:                        break;
        !           716:
        !           717:                if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
        !           718:                    m0, BUS_DMA_NOWAIT) != 0) {
        !           719:                        MGETHDR(m, M_DONTWAIT, MT_DATA);
        !           720:                        if (m == NULL)
        !           721:                                break;
        !           722:                        if (m0->m_pkthdr.len > MHLEN) {
        !           723:                                MCLGET(m, M_DONTWAIT);
        !           724:                                if (!(m->m_flags & M_EXT)) {
        !           725:                                        m_freem(m);
        !           726:                                        break;
        !           727:                                }
        !           728:                        }
        !           729:                        m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
        !           730:                        m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
        !           731:                        if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
        !           732:                            m, BUS_DMA_NOWAIT) != 0) {
        !           733:                                m_freem(m);
        !           734:                                break;
        !           735:                        }
        !           736:                }
        !           737:
        !           738:                IFQ_DEQUEUE(&ifp->if_snd, m0);
        !           739:                if (m != NULL) {
        !           740:                        m_freem(m0);
        !           741:                        m0 = m;
        !           742:                        m = NULL;
        !           743:                }
        !           744:
        !           745:                txs->tx_mbuf = m0;
        !           746:
        !           747: #if NBPFILTER > 0
        !           748:                if (ifp->if_bpf)
        !           749:                        bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
        !           750: #endif
        !           751:
        !           752:                FXP_MBUF_SYNC(sc, txs->tx_map, BUS_DMASYNC_PREWRITE);
        !           753:
        !           754:                txc = txs->tx_cb;
        !           755:                txc->tbd_number = txs->tx_map->dm_nsegs;
        !           756:                txc->cb_status = 0;
        !           757:                txc->cb_command = htole16(FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF);
        !           758:                txc->tx_threshold = tx_threshold;
        !           759:                for (seg = 0; seg < txs->tx_map->dm_nsegs; seg++) {
        !           760:                        txc->tbd[seg].tb_addr =
        !           761:                            htole32(txs->tx_map->dm_segs[seg].ds_addr);
        !           762:                        txc->tbd[seg].tb_size =
        !           763:                            htole32(txs->tx_map->dm_segs[seg].ds_len);
        !           764:                }
        !           765:                FXP_TXCB_SYNC(sc, txs,
        !           766:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !           767:
        !           768:                ++cnt;
        !           769:                sc->sc_cbt_prod = txs;
        !           770:        }
        !           771:
        !           772:        if (cnt != sc->sc_cbt_cnt) {
        !           773:                /* We enqueued at least one. */
        !           774:                ifp->if_timer = 5;
        !           775:
        !           776:                txs = sc->sc_cbt_prod;
        !           777:                txs = txs->tx_next;
        !           778:                sc->sc_cbt_prod = txs;
        !           779:                txs->tx_cb->cb_command =
        !           780:                    htole16(FXP_CB_COMMAND_I | FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S);
        !           781:                FXP_TXCB_SYNC(sc, txs,
        !           782:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !           783:
        !           784:                FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
        !           785:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !           786:                sc->sc_cbt_prev->tx_cb->cb_command &=
        !           787:                    htole16(~(FXP_CB_COMMAND_S | FXP_CB_COMMAND_I));
        !           788:                FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
        !           789:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !           790:
        !           791:                sc->sc_cbt_prev = txs;
        !           792:
        !           793:                fxp_scb_wait(sc);
        !           794:                fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
        !           795:
        !           796:                sc->sc_cbt_cnt = cnt + 1;
        !           797:        }
        !           798: }
        !           799:
        !           800: /*
        !           801:  * Process interface interrupts.
        !           802:  */
        !           803: int
        !           804: fxp_intr(void *arg)
        !           805: {
        !           806:        struct fxp_softc *sc = arg;
        !           807:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           808:        u_int8_t statack;
        !           809:        bus_dmamap_t rxmap;
        !           810:        int claimed = 0;
        !           811:        int rnr = 0;
        !           812:
        !           813:        /*
        !           814:         * If the interface isn't running, don't try to
        !           815:         * service the interrupt.. just ack it and bail.
        !           816:         */
        !           817:        if ((ifp->if_flags & IFF_RUNNING) == 0) {
        !           818:                statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK);
        !           819:                if (statack) {
        !           820:                        claimed = 1;
        !           821:                        CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
        !           822:                }
        !           823:                return claimed;
        !           824:        }
        !           825:
        !           826:        while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
        !           827:                claimed = 1;
        !           828:                rnr = (statack & (FXP_SCB_STATACK_RNR |
        !           829:                                  FXP_SCB_STATACK_SWI)) ? 1 : 0;
        !           830:                /*
        !           831:                 * First ACK all the interrupts in this pass.
        !           832:                 */
        !           833:                CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
        !           834:
        !           835:                /*
        !           836:                 * Free any finished transmit mbuf chains.
        !           837:                 */
        !           838:                if (statack & (FXP_SCB_STATACK_CXTNO|FXP_SCB_STATACK_CNA)) {
        !           839:                        int txcnt = sc->sc_cbt_cnt;
        !           840:                        struct fxp_txsw *txs = sc->sc_cbt_cons;
        !           841:
        !           842:                        FXP_TXCB_SYNC(sc, txs,
        !           843:                            BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
        !           844:
        !           845:                        while ((txcnt > 0) &&
        !           846:                           ((txs->tx_cb->cb_status & htole16(FXP_CB_STATUS_C)) ||
        !           847:                           (txs->tx_cb->cb_command & htole16(FXP_CB_COMMAND_NOP)))) {
        !           848:                                if (txs->tx_mbuf != NULL) {
        !           849:                                        FXP_MBUF_SYNC(sc, txs->tx_map,
        !           850:                                            BUS_DMASYNC_POSTWRITE);
        !           851:                                        bus_dmamap_unload(sc->sc_dmat,
        !           852:                                            txs->tx_map);
        !           853:                                        m_freem(txs->tx_mbuf);
        !           854:                                        txs->tx_mbuf = NULL;
        !           855:                                }
        !           856:                                --txcnt;
        !           857:                                txs = txs->tx_next;
        !           858:                                FXP_TXCB_SYNC(sc, txs,
        !           859:                                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !           860:                        }
        !           861:                        sc->sc_cbt_cons = txs;
        !           862:                        sc->sc_cbt_cnt = txcnt;
        !           863:                        ifp->if_timer = 0;
        !           864:                        ifp->if_flags &= ~IFF_OACTIVE;
        !           865:
        !           866:                        if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
        !           867:                                /*
        !           868:                                 * Try to start more packets transmitting.
        !           869:                                 */
        !           870:                                fxp_start(ifp);
        !           871:                        }
        !           872:                }
        !           873:                /*
        !           874:                 * Process receiver interrupts. If a Receive Unit
        !           875:                 * not ready (RNR) condition exists, get whatever
        !           876:                 * packets we can and re-start the receiver.
        !           877:                 */
        !           878:                if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR |
        !           879:                               FXP_SCB_STATACK_SWI)) {
        !           880:                        struct mbuf *m;
        !           881:                        u_int8_t *rfap;
        !           882: rcvloop:
        !           883:                        m = sc->rfa_headm;
        !           884:                        rfap = m->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
        !           885:                        rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
        !           886:                        bus_dmamap_sync(sc->sc_dmat, rxmap,
        !           887:                            0, MCLBYTES, BUS_DMASYNC_POSTREAD |
        !           888:                            BUS_DMASYNC_POSTWRITE);
        !           889:
        !           890:                        if (*(u_int16_t *)(rfap +
        !           891:                            offsetof(struct fxp_rfa, rfa_status)) &
        !           892:                            htole16(FXP_RFA_STATUS_C)) {
        !           893:                                if (*(u_int16_t *)(rfap +
        !           894:                                    offsetof(struct fxp_rfa, rfa_status)) &
        !           895:                                    htole16(FXP_RFA_STATUS_RNR))
        !           896:                                        rnr = 1;
        !           897:
        !           898:                                /*
        !           899:                                 * Remove first packet from the chain.
        !           900:                                 */
        !           901:                                sc->rfa_headm = m->m_next;
        !           902:                                m->m_next = NULL;
        !           903:
        !           904:                                /*
        !           905:                                 * Add a new buffer to the receive chain.
        !           906:                                 * If this fails, the old buffer is recycled
        !           907:                                 * instead.
        !           908:                                 */
        !           909:                                if (fxp_add_rfabuf(sc, m) == 0) {
        !           910:                                        u_int16_t total_len;
        !           911:
        !           912:                                        total_len = htole16(*(u_int16_t *)(rfap +
        !           913:                                            offsetof(struct fxp_rfa,
        !           914:                                            actual_size))) &
        !           915:                                            (MCLBYTES - 1);
        !           916:                                        if (total_len <
        !           917:                                            sizeof(struct ether_header)) {
        !           918:                                                m_freem(m);
        !           919:                                                goto rcvloop;
        !           920:                                        }
        !           921:                                        if (*(u_int16_t *)(rfap +
        !           922:                                            offsetof(struct fxp_rfa,
        !           923:                                            rfa_status)) &
        !           924:                                            htole16(FXP_RFA_STATUS_CRC)) {
        !           925:                                                m_freem(m);
        !           926:                                                goto rcvloop;
        !           927:                                        }
        !           928:
        !           929:                                        m->m_pkthdr.rcvif = ifp;
        !           930:                                        m->m_pkthdr.len = m->m_len =
        !           931:                                            total_len;
        !           932: #if NBPFILTER > 0
        !           933:                                        if (ifp->if_bpf)
        !           934:                                                bpf_mtap(ifp->if_bpf, m,
        !           935:                                                    BPF_DIRECTION_IN);
        !           936: #endif /* NBPFILTER > 0 */
        !           937:                                        ether_input_mbuf(ifp, m);
        !           938:                                }
        !           939:                                goto rcvloop;
        !           940:                        }
        !           941:                }
        !           942:                if (rnr) {
        !           943:                        rxmap = *((bus_dmamap_t *)
        !           944:                            sc->rfa_headm->m_ext.ext_buf);
        !           945:                        fxp_scb_wait(sc);
        !           946:                        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
        !           947:                                    rxmap->dm_segs[0].ds_addr +
        !           948:                                    RFA_ALIGNMENT_FUDGE);
        !           949:                        fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
        !           950:
        !           951:                }
        !           952:        }
        !           953:        return (claimed);
        !           954: }
        !           955:
        !           956: /*
        !           957:  * Update packet in/out/collision statistics. The i82557 doesn't
        !           958:  * allow you to access these counters without doing a fairly
        !           959:  * expensive DMA to get _all_ of the statistics it maintains, so
        !           960:  * we do this operation here only once per second. The statistics
        !           961:  * counters in the kernel are updated from the previous dump-stats
        !           962:  * DMA and then a new dump-stats DMA is started. The on-chip
        !           963:  * counters are zeroed when the DMA completes. If we can't start
        !           964:  * the DMA immediately, we don't wait - we just prepare to read
        !           965:  * them again next time.
        !           966:  */
        !           967: void
        !           968: fxp_stats_update(void *arg)
        !           969: {
        !           970:        struct fxp_softc *sc = arg;
        !           971:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           972:        struct fxp_stats *sp = &sc->sc_ctrl->stats;
        !           973:        int s;
        !           974:
        !           975:        FXP_STATS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !           976:        ifp->if_opackets += letoh32(sp->tx_good);
        !           977:        ifp->if_collisions += letoh32(sp->tx_total_collisions);
        !           978:        if (sp->rx_good) {
        !           979:                ifp->if_ipackets += letoh32(sp->rx_good);
        !           980:                sc->rx_idle_secs = 0;
        !           981:        } else if (sc->sc_flags & FXPF_RECV_WORKAROUND)
        !           982:                sc->rx_idle_secs++;
        !           983:        ifp->if_ierrors +=
        !           984:            letoh32(sp->rx_crc_errors) +
        !           985:            letoh32(sp->rx_alignment_errors) +
        !           986:            letoh32(sp->rx_rnr_errors) +
        !           987:            letoh32(sp->rx_overrun_errors);
        !           988:        /*
        !           989:         * If any transmit underruns occurred, bump up the transmit
        !           990:         * threshold by another 512 bytes (64 * 8).
        !           991:         */
        !           992:        if (sp->tx_underruns) {
        !           993:                ifp->if_oerrors += letoh32(sp->tx_underruns);
        !           994:                if (tx_threshold < 192)
        !           995:                        tx_threshold += 64;
        !           996:        }
        !           997:        s = splnet();
        !           998:        /*
        !           999:         * If we haven't received any packets in FXP_MAX_RX_IDLE seconds,
        !          1000:         * then assume the receiver has locked up and attempt to clear
        !          1001:         * the condition by reprogramming the multicast filter. This is
        !          1002:         * a work-around for a bug in the 82557 where the receiver locks
        !          1003:         * up if it gets certain types of garbage in the synchronization
        !          1004:         * bits prior to the packet header. This bug is supposed to only
        !          1005:         * occur in 10Mbps mode, but has been seen to occur in 100Mbps
        !          1006:         * mode as well (perhaps due to a 10/100 speed transition).
        !          1007:         */
        !          1008:        if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
        !          1009:                sc->rx_idle_secs = 0;
        !          1010:                fxp_init(sc);
        !          1011:                splx(s);
        !          1012:                return;
        !          1013:        }
        !          1014:        /*
        !          1015:         * If there is no pending command, start another stats
        !          1016:         * dump. Otherwise punt for now.
        !          1017:         */
        !          1018:        FXP_STATS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1019:        if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) {
        !          1020:                /*
        !          1021:                 * Start another stats dump.
        !          1022:                 */
        !          1023:                fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
        !          1024:        } else {
        !          1025:                /*
        !          1026:                 * A previous command is still waiting to be accepted.
        !          1027:                 * Just zero our copy of the stats and wait for the
        !          1028:                 * next timer event to update them.
        !          1029:                 */
        !          1030:                sp->tx_good = 0;
        !          1031:                sp->tx_underruns = 0;
        !          1032:                sp->tx_total_collisions = 0;
        !          1033:
        !          1034:                sp->rx_good = 0;
        !          1035:                sp->rx_crc_errors = 0;
        !          1036:                sp->rx_alignment_errors = 0;
        !          1037:                sp->rx_rnr_errors = 0;
        !          1038:                sp->rx_overrun_errors = 0;
        !          1039:        }
        !          1040:
        !          1041:        /* Tick the MII clock. */
        !          1042:        mii_tick(&sc->sc_mii);
        !          1043:
        !          1044:        splx(s);
        !          1045:        /*
        !          1046:         * Schedule another timeout one second from now.
        !          1047:         */
        !          1048:        timeout_add(&sc->stats_update_to, hz);
        !          1049: }
        !          1050:
        !          1051: /*
        !          1052:  * Stop the interface. Cancels the statistics updater and resets
        !          1053:  * the interface.
        !          1054:  */
        !          1055: void
        !          1056: fxp_stop(struct fxp_softc *sc, int drain)
        !          1057: {
        !          1058:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1059:        int i;
        !          1060:
        !          1061:        /*
        !          1062:         * Turn down interface (done early to avoid bad interactions
        !          1063:         * between panics, shutdown hooks, and the watchdog timer)
        !          1064:         */
        !          1065:        ifp->if_timer = 0;
        !          1066:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
        !          1067:
        !          1068:        /*
        !          1069:         * Cancel stats updater.
        !          1070:         */
        !          1071:        timeout_del(&sc->stats_update_to);
        !          1072:        mii_down(&sc->sc_mii);
        !          1073:
        !          1074:        /*
        !          1075:         * Issue software reset.
        !          1076:         */
        !          1077:        CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
        !          1078:        DELAY(10);
        !          1079:
        !          1080:        /*
        !          1081:         * Release any xmit buffers.
        !          1082:         */
        !          1083:        for (i = 0; i < FXP_NTXCB; i++) {
        !          1084:                if (sc->txs[i].tx_mbuf != NULL) {
        !          1085:                        bus_dmamap_unload(sc->sc_dmat, sc->txs[i].tx_map);
        !          1086:                        m_freem(sc->txs[i].tx_mbuf);
        !          1087:                        sc->txs[i].tx_mbuf = NULL;
        !          1088:                }
        !          1089:        }
        !          1090:        sc->sc_cbt_cnt = 0;
        !          1091:
        !          1092:        if (drain) {
        !          1093:                bus_dmamap_t rxmap;
        !          1094:                struct mbuf *m;
        !          1095:
        !          1096:                /*
        !          1097:                 * Free all the receive buffers then reallocate/reinitialize
        !          1098:                 */
        !          1099:                m = sc->rfa_headm;
        !          1100:                while (m != NULL) {
        !          1101:                        rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
        !          1102:                        bus_dmamap_unload(sc->sc_dmat, rxmap);
        !          1103:                        FXP_RXMAP_PUT(sc, rxmap);
        !          1104:                        m = m_free(m);
        !          1105:                        sc->rx_bufs--;
        !          1106:                }
        !          1107:                sc->rfa_headm = NULL;
        !          1108:                sc->rfa_tailm = NULL;
        !          1109:                for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
        !          1110:                        if (fxp_add_rfabuf(sc, NULL) != 0) {
        !          1111:                                /*
        !          1112:                                 * This "can't happen" - we're at splnet()
        !          1113:                                 * and we just freed all the buffers we need
        !          1114:                                 * above.
        !          1115:                                 */
        !          1116:                                panic("fxp_stop: no buffers!");
        !          1117:                        }
        !          1118:                        sc->rx_bufs++;
        !          1119:                }
        !          1120:        }
        !          1121: }
        !          1122:
        !          1123: /*
        !          1124:  * Watchdog/transmission transmit timeout handler. Called when a
        !          1125:  * transmission is started on the interface, but no interrupt is
        !          1126:  * received before the timeout. This usually indicates that the
        !          1127:  * card has wedged for some reason.
        !          1128:  */
        !          1129: void
        !          1130: fxp_watchdog(struct ifnet *ifp)
        !          1131: {
        !          1132:        struct fxp_softc *sc = ifp->if_softc;
        !          1133:
        !          1134:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
        !          1135:        ifp->if_oerrors++;
        !          1136:
        !          1137:        fxp_init(sc);
        !          1138: }
        !          1139:
        !          1140: /*
        !          1141:  * Submit a command to the i82557.
        !          1142:  */
        !          1143: void
        !          1144: fxp_scb_cmd(struct fxp_softc *sc, u_int8_t cmd)
        !          1145: {
        !          1146:        CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
        !          1147: }
        !          1148:
        !          1149: void
        !          1150: fxp_init(void *xsc)
        !          1151: {
        !          1152:        struct fxp_softc *sc = xsc;
        !          1153:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1154:        struct fxp_cb_config *cbp;
        !          1155:        struct fxp_cb_ias *cb_ias;
        !          1156:        struct fxp_cb_tx *txp;
        !          1157:        bus_dmamap_t rxmap;
        !          1158:        int i, prm, save_bf, lrxen, allm, s, bufs;
        !          1159:
        !          1160:        s = splnet();
        !          1161:
        !          1162:        /*
        !          1163:         * Cancel any pending I/O
        !          1164:         */
        !          1165:        fxp_stop(sc, 0);
        !          1166:
        !          1167:        /*
        !          1168:         * Initialize base of CBL and RFA memory. Loading with zero
        !          1169:         * sets it up for regular linear addressing.
        !          1170:         */
        !          1171:        fxp_scb_wait(sc);
        !          1172:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
        !          1173:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
        !          1174:
        !          1175:        fxp_scb_wait(sc);
        !          1176:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
        !          1177:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
        !          1178:
        !          1179: #ifndef SMALL_KERNEL
        !          1180:        fxp_load_ucode(sc);
        !          1181: #endif
        !          1182:        /* Once through to set flags */
        !          1183:        fxp_mc_setup(sc, 0);
        !          1184:
        !          1185:         /*
        !          1186:         * In order to support receiving 802.1Q VLAN frames, we have to
        !          1187:         * enable "save bad frames", since they are 4 bytes larger than
        !          1188:         * the normal Ethernet maximum frame length. On i82558 and later,
        !          1189:         * we have a better mechanism for this.
        !          1190:         */
        !          1191:        save_bf = 0;
        !          1192:        lrxen = 0;
        !          1193:
        !          1194:        if (sc->sc_revision >= FXP_REV_82558_A4)
        !          1195:                lrxen = 1;
        !          1196:        else
        !          1197:                save_bf = 1;
        !          1198:
        !          1199:        /*
        !          1200:         * Initialize base of dump-stats buffer.
        !          1201:         */
        !          1202:        fxp_scb_wait(sc);
        !          1203:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
        !          1204:            sc->tx_cb_map->dm_segs->ds_addr +
        !          1205:            offsetof(struct fxp_ctrl, stats));
        !          1206:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
        !          1207:
        !          1208:        cbp = &sc->sc_ctrl->u.cfg;
        !          1209:        /*
        !          1210:         * This bcopy is kind of disgusting, but there are a bunch of must be
        !          1211:         * zero and must be one bits in this structure and this is the easiest
        !          1212:         * way to initialize them all to proper values.
        !          1213:         */
        !          1214:        bcopy(fxp_cb_config_template, (void *)&cbp->cb_status,
        !          1215:                sizeof(fxp_cb_config_template));
        !          1216:
        !          1217:        prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;
        !          1218:        allm = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;
        !          1219:
        !          1220: #if 0
        !          1221:        cbp->cb_status =        0;
        !          1222:        cbp->cb_command =       FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
        !          1223:        cbp->link_addr =        0xffffffff;     /* (no) next command */
        !          1224:        cbp->byte_count =       22;             /* (22) bytes to config */
        !          1225:        cbp->rx_fifo_limit =    8;      /* rx fifo threshold (32 bytes) */
        !          1226:        cbp->tx_fifo_limit =    0;      /* tx fifo threshold (0 bytes) */
        !          1227:        cbp->adaptive_ifs =     0;      /* (no) adaptive interframe spacing */
        !          1228:        cbp->rx_dma_bytecount = 0;      /* (no) rx DMA max */
        !          1229:        cbp->tx_dma_bytecount = 0;      /* (no) tx DMA max */
        !          1230:        cbp->dma_bce =          0;      /* (disable) dma max counters */
        !          1231:        cbp->late_scb =         0;      /* (don't) defer SCB update */
        !          1232:        cbp->tno_int =          0;      /* (disable) tx not okay interrupt */
        !          1233:        cbp->ci_int =           1;      /* interrupt on CU idle */
        !          1234:        cbp->save_bf =          save_bf ? 1 : prm; /* save bad frames */
        !          1235:        cbp->disc_short_rx =    !prm;   /* discard short packets */
        !          1236:        cbp->underrun_retry =   1;      /* retry mode (1) on DMA underrun */
        !          1237:        cbp->mediatype =        !sc->phy_10Mbps_only; /* interface mode */
        !          1238:        cbp->nsai =             1;      /* (don't) disable source addr insert */
        !          1239:        cbp->preamble_length =  2;      /* (7 byte) preamble */
        !          1240:        cbp->loopback =         0;      /* (don't) loopback */
        !          1241:        cbp->linear_priority =  0;      /* (normal CSMA/CD operation) */
        !          1242:        cbp->linear_pri_mode =  0;      /* (wait after xmit only) */
        !          1243:        cbp->interfrm_spacing = 6;      /* (96 bits of) interframe spacing */
        !          1244:        cbp->promiscuous =      prm;    /* promiscuous mode */
        !          1245:        cbp->bcast_disable =    0;      /* (don't) disable broadcasts */
        !          1246:        cbp->crscdt =           0;      /* (CRS only) */
        !          1247:        cbp->stripping =        !prm;   /* truncate rx packet to byte count */
        !          1248:        cbp->padding =          1;      /* (do) pad short tx packets */
        !          1249:        cbp->rcv_crc_xfer =     0;      /* (don't) xfer CRC to host */
        !          1250:        cbp->long_rx =          lrxen;  /* (enable) long packets */
        !          1251:        cbp->force_fdx =        0;      /* (don't) force full duplex */
        !          1252:        cbp->fdx_pin_en =       1;      /* (enable) FDX# pin */
        !          1253:        cbp->multi_ia =         0;      /* (don't) accept multiple IAs */
        !          1254:        cbp->mc_all =           allm;
        !          1255: #else
        !          1256:        cbp->cb_command = htole16(FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL);
        !          1257:        if (allm)
        !          1258:                cbp->mc_all |= 0x08;            /* accept all multicasts */
        !          1259:        else
        !          1260:                cbp->mc_all &= ~0x08;           /* reject all multicasts */
        !          1261:
        !          1262:        if (prm) {
        !          1263:                cbp->promiscuous |= 1;          /* promiscuous mode */
        !          1264:                cbp->ctrl2 &= ~0x01;            /* save short packets */
        !          1265:                cbp->stripping &= ~0x01;        /* don't truncate rx packets */
        !          1266:        } else {
        !          1267:                cbp->promiscuous &= ~1;         /* no promiscuous mode */
        !          1268:                cbp->ctrl2 |= 0x01;             /* discard short packets */
        !          1269:                cbp->stripping |= 0x01;         /* truncate rx packets */
        !          1270:        }
        !          1271:
        !          1272:        if (prm || save_bf)
        !          1273:                cbp->ctrl1 |= 0x80;             /* save bad frames */
        !          1274:        else
        !          1275:                cbp->ctrl1 &= ~0x80;            /* discard bad frames */
        !          1276:
        !          1277:        if (sc->sc_flags & FXPF_MWI_ENABLE)
        !          1278:                cbp->ctrl0 |= 0x01;             /* enable PCI MWI command */
        !          1279:
        !          1280:        if(!sc->phy_10Mbps_only)                        /* interface mode */
        !          1281:                cbp->mediatype |= 0x01;
        !          1282:        else
        !          1283:                cbp->mediatype &= ~0x01;
        !          1284:
        !          1285:        if(lrxen)                       /* long packets */
        !          1286:                cbp->stripping |= 0x08;
        !          1287:        else
        !          1288:                cbp->stripping &= ~0x08;
        !          1289:
        !          1290:        cbp->tx_dma_bytecount = 0; /* (no) tx DMA max, dma_dce = 0 ??? */
        !          1291:        cbp->ctrl1 |= 0x08;     /* ci_int = 1 */
        !          1292:        cbp->ctrl3 |= 0x08;     /* nsai */
        !          1293:        cbp->fifo_limit = 0x08; /* tx and rx fifo limit */
        !          1294:        cbp->fdx_pin |= 0x80;   /* Enable full duplex setting by pin */
        !          1295: #endif
        !          1296:
        !          1297:        /*
        !          1298:         * Start the config command/DMA.
        !          1299:         */
        !          1300:        fxp_scb_wait(sc);
        !          1301:        FXP_CFG_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1302:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
        !          1303:            offsetof(struct fxp_ctrl, u.cfg));
        !          1304:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
        !          1305:        /* ...and wait for it to complete. */
        !          1306:        do {
        !          1307:                DELAY(1);
        !          1308:                FXP_CFG_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          1309:        } while ((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0);
        !          1310:
        !          1311:        /*
        !          1312:         * Now initialize the station address.
        !          1313:         */
        !          1314:        cb_ias = &sc->sc_ctrl->u.ias;
        !          1315:        cb_ias->cb_status = htole16(0);
        !          1316:        cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL);
        !          1317:        cb_ias->link_addr = htole32(0xffffffff);
        !          1318:        bcopy(sc->sc_arpcom.ac_enaddr, (void *)cb_ias->macaddr,
        !          1319:            sizeof(sc->sc_arpcom.ac_enaddr));
        !          1320:
        !          1321:        /*
        !          1322:         * Start the IAS (Individual Address Setup) command/DMA.
        !          1323:         */
        !          1324:        fxp_scb_wait(sc);
        !          1325:        FXP_IAS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1326:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
        !          1327:            offsetof(struct fxp_ctrl, u.ias));
        !          1328:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
        !          1329:        /* ...and wait for it to complete. */
        !          1330:        do {
        !          1331:                DELAY(1);
        !          1332:                FXP_IAS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          1333:        } while (!(cb_ias->cb_status & htole16(FXP_CB_STATUS_C)));
        !          1334:
        !          1335:        /* Again, this time really upload the multicast addresses */
        !          1336:        fxp_mc_setup(sc, 1);
        !          1337:
        !          1338:        /*
        !          1339:         * Initialize transmit control block (TxCB) list.
        !          1340:         */
        !          1341:        bzero(sc->sc_ctrl->tx_cb, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
        !          1342:        txp = sc->sc_ctrl->tx_cb;
        !          1343:        for (i = 0; i < FXP_NTXCB; i++) {
        !          1344:                txp[i].cb_command = htole16(FXP_CB_COMMAND_NOP);
        !          1345:                txp[i].link_addr = htole32(sc->tx_cb_map->dm_segs->ds_addr +
        !          1346:                    offsetof(struct fxp_ctrl, tx_cb[(i + 1) & FXP_TXCB_MASK]));
        !          1347:                txp[i].tbd_array_addr =htole32(sc->tx_cb_map->dm_segs->ds_addr +
        !          1348:                    offsetof(struct fxp_ctrl, tx_cb[i].tbd[0]));
        !          1349:        }
        !          1350:        /*
        !          1351:         * Set the suspend flag on the first TxCB and start the control
        !          1352:         * unit. It will execute the NOP and then suspend.
        !          1353:         */
        !          1354:        sc->sc_cbt_prev = sc->sc_cbt_prod = sc->sc_cbt_cons = sc->txs;
        !          1355:        sc->sc_cbt_cnt = 1;
        !          1356:        sc->sc_ctrl->tx_cb[0].cb_command = htole16(FXP_CB_COMMAND_NOP |
        !          1357:            FXP_CB_COMMAND_S | FXP_CB_COMMAND_I);
        !          1358:        bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, 0,
        !          1359:            sc->tx_cb_map->dm_mapsize,
        !          1360:            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
        !          1361:
        !          1362:        fxp_scb_wait(sc);
        !          1363:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
        !          1364:            offsetof(struct fxp_ctrl, tx_cb[0]));
        !          1365:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
        !          1366:
        !          1367:        /*
        !          1368:         * Initialize receiver buffer area - RFA.
        !          1369:         */
        !          1370:        if (ifp->if_flags & IFF_UP)
        !          1371:                bufs = FXP_NRFABUFS_MAX;
        !          1372:        else
        !          1373:                bufs = FXP_NRFABUFS_MIN;
        !          1374:        if (sc->rx_bufs > bufs) {
        !          1375:                while (sc->rfa_headm != NULL && sc->rx_bufs-- > bufs) {
        !          1376:                        rxmap = *((bus_dmamap_t *)sc->rfa_headm->m_ext.ext_buf);
        !          1377:                        bus_dmamap_unload(sc->sc_dmat, rxmap);
        !          1378:                        FXP_RXMAP_PUT(sc, rxmap);
        !          1379:                        sc->rfa_headm = m_free(sc->rfa_headm);
        !          1380:                }
        !          1381:        } else if (sc->rx_bufs < bufs) {
        !          1382:                int err, tmp_rx_bufs = sc->rx_bufs;
        !          1383:                for (i = sc->rx_bufs; i < bufs; i++) {
        !          1384:                        if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
        !          1385:                            MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
        !          1386:                                printf("%s: unable to create rx dma map %d, "
        !          1387:                                  "error %d\n", sc->sc_dev.dv_xname, i, err);
        !          1388:                                break;
        !          1389:                        }
        !          1390:                        sc->rx_bufs++;
        !          1391:                }
        !          1392:                for (i = tmp_rx_bufs; i < sc->rx_bufs; i++)
        !          1393:                        if (fxp_add_rfabuf(sc, NULL) != 0)
        !          1394:                                break;
        !          1395:        }
        !          1396:        fxp_scb_wait(sc);
        !          1397:
        !          1398:        /*
        !          1399:         * Set current media.
        !          1400:         */
        !          1401:        mii_mediachg(&sc->sc_mii);
        !          1402:
        !          1403:        ifp->if_flags |= IFF_RUNNING;
        !          1404:        ifp->if_flags &= ~IFF_OACTIVE;
        !          1405:
        !          1406:        /*
        !          1407:         * Request a software generated interrupt that will be used to
        !          1408:         * (re)start the RU processing.  If we direct the chip to start
        !          1409:         * receiving from the start of queue now, instead of letting the
        !          1410:         * interrupt handler first process all received packets, we run
        !          1411:         * the risk of having it overwrite mbuf clusters while they are
        !          1412:         * being processed or after they have been returned to the pool.
        !          1413:         */
        !          1414:        CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTRCNTL_REQUEST_SWI);
        !          1415:        splx(s);
        !          1416:
        !          1417:        /*
        !          1418:         * Start stats updater.
        !          1419:         */
        !          1420:        timeout_add(&sc->stats_update_to, hz);
        !          1421: }
        !          1422:
        !          1423: /*
        !          1424:  * Change media according to request.
        !          1425:  */
        !          1426: int
        !          1427: fxp_mediachange(struct ifnet *ifp)
        !          1428: {
        !          1429:        struct fxp_softc *sc = ifp->if_softc;
        !          1430:        struct mii_data *mii = &sc->sc_mii;
        !          1431:
        !          1432:        if (mii->mii_instance) {
        !          1433:                struct mii_softc *miisc;
        !          1434:                LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
        !          1435:                        mii_phy_reset(miisc);
        !          1436:        }
        !          1437:        mii_mediachg(&sc->sc_mii);
        !          1438:        return (0);
        !          1439: }
        !          1440:
        !          1441: /*
        !          1442:  * Notify the world which media we're using.
        !          1443:  */
        !          1444: void
        !          1445: fxp_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
        !          1446: {
        !          1447:        struct fxp_softc *sc = ifp->if_softc;
        !          1448:
        !          1449:        mii_pollstat(&sc->sc_mii);
        !          1450:        ifmr->ifm_status = sc->sc_mii.mii_media_status;
        !          1451:        ifmr->ifm_active = sc->sc_mii.mii_media_active;
        !          1452: }
        !          1453:
        !          1454: /*
        !          1455:  * Add a buffer to the end of the RFA buffer list.
        !          1456:  * Return 0 if successful, 1 for failure. A failure results in
        !          1457:  * adding the 'oldm' (if non-NULL) on to the end of the list -
        !          1458:  * tossing out its old contents and recycling it.
        !          1459:  * The RFA struct is stuck at the beginning of mbuf cluster and the
        !          1460:  * data pointer is fixed up to point just past it.
        !          1461:  */
        !          1462: int
        !          1463: fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm)
        !          1464: {
        !          1465:        u_int32_t v;
        !          1466:        struct mbuf *m;
        !          1467:        u_int8_t *rfap;
        !          1468:        bus_dmamap_t rxmap = NULL;
        !          1469:
        !          1470:        MGETHDR(m, M_DONTWAIT, MT_DATA);
        !          1471:        if (m != NULL) {
        !          1472:                MCLGET(m, M_DONTWAIT);
        !          1473:                if ((m->m_flags & M_EXT) == 0) {
        !          1474:                        m_freem(m);
        !          1475:                        if (oldm == NULL)
        !          1476:                                return 1;
        !          1477:                        m = oldm;
        !          1478:                        m->m_data = m->m_ext.ext_buf;
        !          1479:                }
        !          1480:                if (oldm == NULL) {
        !          1481:                        rxmap = FXP_RXMAP_GET(sc);
        !          1482:                        *((bus_dmamap_t *)m->m_ext.ext_buf) = rxmap;
        !          1483:                        bus_dmamap_load(sc->sc_dmat, rxmap,
        !          1484:                            m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
        !          1485:                            BUS_DMA_NOWAIT);
        !          1486:                } else if (oldm == m)
        !          1487:                        rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
        !          1488:                else {
        !          1489:                        rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
        !          1490:                        bus_dmamap_unload(sc->sc_dmat, rxmap);
        !          1491:                        bus_dmamap_load(sc->sc_dmat, rxmap,
        !          1492:                            m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
        !          1493:                            BUS_DMA_NOWAIT);
        !          1494:                        *mtod(m, bus_dmamap_t *) = rxmap;
        !          1495:                }
        !          1496:        } else {
        !          1497:                if (oldm == NULL)
        !          1498:                        return 1;
        !          1499:                m = oldm;
        !          1500:                m->m_data = m->m_ext.ext_buf;
        !          1501:                rxmap = *mtod(m, bus_dmamap_t *);
        !          1502:        }
        !          1503:
        !          1504:        /*
        !          1505:         * Move the data pointer up so that the incoming data packet
        !          1506:         * will be 32-bit aligned.
        !          1507:         */
        !          1508:        m->m_data += RFA_ALIGNMENT_FUDGE;
        !          1509:
        !          1510:        /*
        !          1511:         * Get a pointer to the base of the mbuf cluster and move
        !          1512:         * data start past it.
        !          1513:         */
        !          1514:        rfap = m->m_data;
        !          1515:        m->m_data += sizeof(struct fxp_rfa);
        !          1516:        *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, size)) =
        !          1517:            htole16(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
        !          1518:
        !          1519:        /*
        !          1520:         * Initialize the rest of the RFA.  Note that since the RFA
        !          1521:         * is misaligned, we cannot store values directly.  Instead,
        !          1522:         * we use an optimized, inline copy.
        !          1523:         */
        !          1524:        *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_status)) = 0;
        !          1525:        *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) =
        !          1526:            htole16(FXP_RFA_CONTROL_EL);
        !          1527:        *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, actual_size)) = 0;
        !          1528:
        !          1529:        v = -1;
        !          1530:        fxp_lwcopy(&v,
        !          1531:            (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
        !          1532:        fxp_lwcopy(&v,
        !          1533:            (u_int32_t *)(rfap + offsetof(struct fxp_rfa, rbd_addr)));
        !          1534:
        !          1535:        bus_dmamap_sync(sc->sc_dmat, rxmap, 0, MCLBYTES,
        !          1536:            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
        !          1537:
        !          1538:        /*
        !          1539:         * If there are other buffers already on the list, attach this
        !          1540:         * one to the end by fixing up the tail to point to this one.
        !          1541:         */
        !          1542:        if (sc->rfa_headm != NULL) {
        !          1543:                sc->rfa_tailm->m_next = m;
        !          1544:                v = htole32(rxmap->dm_segs[0].ds_addr + RFA_ALIGNMENT_FUDGE);
        !          1545:                rfap = sc->rfa_tailm->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
        !          1546:                fxp_lwcopy(&v,
        !          1547:                    (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
        !          1548:                *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) &=
        !          1549:                    htole16((u_int16_t)~FXP_RFA_CONTROL_EL);
        !          1550:                /* XXX we only need to sync the control struct */
        !          1551:                bus_dmamap_sync(sc->sc_dmat,
        !          1552:                    *((bus_dmamap_t *)sc->rfa_tailm->m_ext.ext_buf), 0,
        !          1553:                        MCLBYTES, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
        !          1554:        } else
        !          1555:                sc->rfa_headm = m;
        !          1556:
        !          1557:        sc->rfa_tailm = m;
        !          1558:
        !          1559:        return (m == oldm);
        !          1560: }
        !          1561:
        !          1562: int
        !          1563: fxp_mdi_read(struct device *self, int phy, int reg)
        !          1564: {
        !          1565:        struct fxp_softc *sc = (struct fxp_softc *)self;
        !          1566:        int count = 10000;
        !          1567:        int value;
        !          1568:
        !          1569:        CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
        !          1570:            (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
        !          1571:
        !          1572:        while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0
        !          1573:            && count--)
        !          1574:                DELAY(10);
        !          1575:
        !          1576:        if (count <= 0)
        !          1577:                printf("%s: fxp_mdi_read: timed out\n", sc->sc_dev.dv_xname);
        !          1578:
        !          1579:        return (value & 0xffff);
        !          1580: }
        !          1581:
        !          1582: void
        !          1583: fxp_statchg(struct device *self)
        !          1584: {
        !          1585:        /* Nothing to do. */
        !          1586: }
        !          1587:
        !          1588: void
        !          1589: fxp_mdi_write(struct device *self, int phy, int reg, int value)
        !          1590: {
        !          1591:        struct fxp_softc *sc = (struct fxp_softc *)self;
        !          1592:        int count = 10000;
        !          1593:
        !          1594:        CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
        !          1595:            (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) |
        !          1596:            (value & 0xffff));
        !          1597:
        !          1598:        while((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 &&
        !          1599:            count--)
        !          1600:                DELAY(10);
        !          1601:
        !          1602:        if (count <= 0)
        !          1603:                printf("%s: fxp_mdi_write: timed out\n", sc->sc_dev.dv_xname);
        !          1604: }
        !          1605:
        !          1606: int
        !          1607: fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
        !          1608: {
        !          1609:        struct fxp_softc *sc = ifp->if_softc;
        !          1610:        struct ifreq *ifr = (struct ifreq *)data;
        !          1611:        struct ifaddr *ifa = (struct ifaddr *)data;
        !          1612:        int s, error = 0;
        !          1613:
        !          1614:        s = splnet();
        !          1615:
        !          1616:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command, data)) > 0) {
        !          1617:                splx(s);
        !          1618:                return (error);
        !          1619:        }
        !          1620:
        !          1621:        switch (command) {
        !          1622:        case SIOCSIFADDR:
        !          1623:                ifp->if_flags |= IFF_UP;
        !          1624:                if (!(ifp->if_flags & IFF_RUNNING))
        !          1625:                        fxp_init(sc);
        !          1626: #ifdef INET
        !          1627:                if (ifa->ifa_addr->sa_family == AF_INET)
        !          1628:                        arp_ifinit(&sc->sc_arpcom, ifa);
        !          1629: #endif
        !          1630:                break;
        !          1631:
        !          1632:        case SIOCSIFMTU:
        !          1633:                if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN)
        !          1634:                        error = EINVAL;
        !          1635:                else if (ifp->if_mtu != ifr->ifr_mtu)
        !          1636:                        ifp->if_mtu = ifr->ifr_mtu;
        !          1637:                break;
        !          1638:
        !          1639:        case SIOCSIFFLAGS:
        !          1640:                /*
        !          1641:                 * If interface is marked up and not running, then start it.
        !          1642:                 * If it is marked down and running, stop it.
        !          1643:                 * XXX If it's up then re-initialize it. This is so flags
        !          1644:                 * such as IFF_PROMISC are handled.
        !          1645:                 */
        !          1646:                if (ifp->if_flags & IFF_UP)
        !          1647:                        fxp_init(sc);
        !          1648:                else if (ifp->if_flags & IFF_RUNNING)
        !          1649:                        fxp_stop(sc, 1);
        !          1650:                break;
        !          1651:
        !          1652:        case SIOCADDMULTI:
        !          1653:        case SIOCDELMULTI:
        !          1654:                error = (command == SIOCADDMULTI) ?
        !          1655:                    ether_addmulti(ifr, &sc->sc_arpcom) :
        !          1656:                    ether_delmulti(ifr, &sc->sc_arpcom);
        !          1657:                if (error == ENETRESET) {
        !          1658:                        /*
        !          1659:                         * Multicast list has changed; set the hardware
        !          1660:                         * filter accordingly.
        !          1661:                         */
        !          1662:                        if (ifp->if_flags & IFF_RUNNING)
        !          1663:                                fxp_init(sc);
        !          1664:                        error = 0;
        !          1665:                }
        !          1666:                break;
        !          1667:
        !          1668:        case SIOCSIFMEDIA:
        !          1669:        case SIOCGIFMEDIA:
        !          1670:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
        !          1671:                break;
        !          1672:
        !          1673:        default:
        !          1674:                error = EINVAL;
        !          1675:        }
        !          1676:        splx(s);
        !          1677:        return (error);
        !          1678: }
        !          1679:
        !          1680: /*
        !          1681:  * Program the multicast filter.
        !          1682:  *
        !          1683:  * We have an artificial restriction that the multicast setup command
        !          1684:  * must be the first command in the chain, so we take steps to ensure
        !          1685:  * this. By requiring this, it allows us to keep up the performance of
        !          1686:  * the pre-initialized command ring (esp. link pointers) by not actually
        !          1687:  * inserting the mcsetup command in the ring - i.e. its link pointer
        !          1688:  * points to the TxCB ring, but the mcsetup descriptor itself is not part
        !          1689:  * of it. We then can do 'CU_START' on the mcsetup descriptor and have it
        !          1690:  * lead into the regular TxCB ring when it completes.
        !          1691:  *
        !          1692:  * This function must be called at splnet.
        !          1693:  */
        !          1694: void
        !          1695: fxp_mc_setup(struct fxp_softc *sc, int doit)
        !          1696: {
        !          1697:        struct fxp_cb_mcs *mcsp = &sc->sc_ctrl->u.mcs;
        !          1698:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1699:        struct ether_multistep step;
        !          1700:        struct ether_multi *enm;
        !          1701:        int nmcasts;
        !          1702:
        !          1703:        /*
        !          1704:         * Initialize multicast setup descriptor.
        !          1705:         */
        !          1706:        mcsp->cb_status = htole16(0);
        !          1707:        mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL);
        !          1708:        mcsp->link_addr = htole32(-1);
        !          1709:
        !          1710:        nmcasts = 0;
        !          1711:        if (!(ifp->if_flags & IFF_ALLMULTI)) {
        !          1712:                ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
        !          1713:                while (enm != NULL) {
        !          1714:                        if (nmcasts >= MAXMCADDR) {
        !          1715:                                ifp->if_flags |= IFF_ALLMULTI;
        !          1716:                                nmcasts = 0;
        !          1717:                                break;
        !          1718:                        }
        !          1719:
        !          1720:                        /* Punt on ranges. */
        !          1721:                        if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
        !          1722:                            sizeof(enm->enm_addrlo)) != 0) {
        !          1723:                                ifp->if_flags |= IFF_ALLMULTI;
        !          1724:                                nmcasts = 0;
        !          1725:                                break;
        !          1726:                        }
        !          1727:                        bcopy(enm->enm_addrlo,
        !          1728:                            (void *)&mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN);
        !          1729:                        nmcasts++;
        !          1730:                        ETHER_NEXT_MULTI(step, enm);
        !          1731:                }
        !          1732:        }
        !          1733:        if (doit == 0)
        !          1734:                return;
        !          1735:        mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN);
        !          1736:
        !          1737:        /*
        !          1738:         * Wait until command unit is not active. This should never
        !          1739:         * be the case when nothing is queued, but make sure anyway.
        !          1740:         */
        !          1741:        while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) != FXP_SCB_CUS_IDLE);
        !          1742:
        !          1743:        /*
        !          1744:         * Start the multicast setup command.
        !          1745:         */
        !          1746:        fxp_scb_wait(sc);
        !          1747:        FXP_MCS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1748:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
        !          1749:            offsetof(struct fxp_ctrl, u.mcs));
        !          1750:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
        !          1751:
        !          1752:        do {
        !          1753:                DELAY(1);
        !          1754:                FXP_MCS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          1755:        } while (!(mcsp->cb_status & htole16(FXP_CB_STATUS_C)));
        !          1756: }
        !          1757:
        !          1758: #ifndef SMALL_KERNEL
        !          1759: #include <dev/microcode/fxp/rcvbundl.h>
        !          1760: struct ucode {
        !          1761:        u_int16_t       revision;
        !          1762:        u_int16_t       int_delay_offset;
        !          1763:        u_int16_t       bundle_max_offset;
        !          1764:        u_int16_t       min_size_mask_offset;
        !          1765:        const char      *uname;
        !          1766: } const ucode_table[] = {
        !          1767:        { FXP_REV_82558_A4, D101_CPUSAVER_DWORD,
        !          1768:          0, 0,
        !          1769:          "fxp-d101a" },
        !          1770:
        !          1771:        { FXP_REV_82558_B0, D101_CPUSAVER_DWORD,
        !          1772:          0, 0,
        !          1773:          "fxp-d101b0" },
        !          1774:
        !          1775:        { FXP_REV_82559_A0, D101M_CPUSAVER_DWORD,
        !          1776:          D101M_CPUSAVER_BUNDLE_MAX_DWORD, D101M_CPUSAVER_MIN_SIZE_DWORD,
        !          1777:          "fxp-d101ma" },
        !          1778:
        !          1779:        { FXP_REV_82559S_A, D101S_CPUSAVER_DWORD,
        !          1780:          D101S_CPUSAVER_BUNDLE_MAX_DWORD, D101S_CPUSAVER_MIN_SIZE_DWORD,
        !          1781:          "fxp-d101s" },
        !          1782:
        !          1783:        { FXP_REV_82550, D102_B_CPUSAVER_DWORD,
        !          1784:          D102_B_CPUSAVER_BUNDLE_MAX_DWORD, D102_B_CPUSAVER_MIN_SIZE_DWORD,
        !          1785:          "fxp-d102" },
        !          1786:
        !          1787:        { FXP_REV_82550_C, D102_C_CPUSAVER_DWORD,
        !          1788:          D102_C_CPUSAVER_BUNDLE_MAX_DWORD, D102_C_CPUSAVER_MIN_SIZE_DWORD,
        !          1789:          "fxp-d102c" },
        !          1790:
        !          1791:        { FXP_REV_82551_F, D102_E_CPUSAVER_DWORD,
        !          1792:          D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
        !          1793:          "fxp-d102e" },
        !          1794:
        !          1795:        { FXP_REV_82551_10, D102_E_CPUSAVER_DWORD,
        !          1796:          D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
        !          1797:          "fxp-d102e" },
        !          1798:
        !          1799:        { 0, 0,
        !          1800:          0, 0,
        !          1801:          NULL }
        !          1802: };
        !          1803:
        !          1804: void
        !          1805: fxp_load_ucode(struct fxp_softc *sc)
        !          1806: {
        !          1807:        const struct ucode *uc;
        !          1808:        struct fxp_cb_ucode *cbp = &sc->sc_ctrl->u.code;
        !          1809:        int i, error;
        !          1810:        u_int32_t *ucode_buf;
        !          1811:        size_t ucode_len;
        !          1812:
        !          1813:        if (sc->sc_flags & FXPF_UCODE)
        !          1814:                return;
        !          1815:
        !          1816:        for (uc = ucode_table; uc->revision != 0; uc++)
        !          1817:                if (sc->sc_revision == uc->revision)
        !          1818:                        break;
        !          1819:        if (uc->revision == NULL)
        !          1820:                return; /* no ucode for this chip is found */
        !          1821:
        !          1822:        error = loadfirmware(uc->uname, (u_char **)&ucode_buf, &ucode_len);
        !          1823:        if (error) {
        !          1824:                printf("%s: failed loadfirmware of file %s: errno %d\n",
        !          1825:                    sc->sc_dev.dv_xname, uc->uname, error);
        !          1826:                sc->sc_flags |= FXPF_UCODE;
        !          1827:                return;
        !          1828:        }
        !          1829:
        !          1830:        cbp->cb_status = 0;
        !          1831:        cbp->cb_command = htole16(FXP_CB_COMMAND_UCODE|FXP_CB_COMMAND_EL);
        !          1832:        cbp->link_addr = 0xffffffff;    /* (no) next command */
        !          1833:        for (i = 0; i < (ucode_len / sizeof(u_int32_t)); i++)
        !          1834:                cbp->ucode[i] = ucode_buf[i];
        !          1835:
        !          1836:        if (uc->int_delay_offset)
        !          1837:                *((u_int16_t *)&cbp->ucode[uc->int_delay_offset]) =
        !          1838:                        htole16(sc->sc_int_delay + sc->sc_int_delay / 2);
        !          1839:
        !          1840:        if (uc->bundle_max_offset)
        !          1841:                *((u_int16_t *)&cbp->ucode[uc->bundle_max_offset]) =
        !          1842:                        htole16(sc->sc_bundle_max);
        !          1843:
        !          1844:        if (uc->min_size_mask_offset)
        !          1845:                *((u_int16_t *)&cbp->ucode[uc->min_size_mask_offset]) =
        !          1846:                        htole16(sc->sc_min_size_mask);
        !          1847:
        !          1848:        FXP_UCODE_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1849:
        !          1850:        /*
        !          1851:         * Download the ucode to the chip.
        !          1852:         */
        !          1853:        fxp_scb_wait(sc);
        !          1854:        CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr
        !          1855:              + offsetof(struct fxp_ctrl, u.code));
        !          1856:        fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
        !          1857:
        !          1858:        /* ...and wait for it to complete. */
        !          1859:        i = 10000;
        !          1860:        do {
        !          1861:                DELAY(2);
        !          1862:                FXP_UCODE_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          1863:        } while (((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0) && --i);
        !          1864:        if (i == 0) {
        !          1865:                printf("%s: timeout loading microcode\n", sc->sc_dev.dv_xname);
        !          1866:                free(ucode_buf, M_DEVBUF);
        !          1867:                return;
        !          1868:        }
        !          1869:
        !          1870: #ifdef DEBUG
        !          1871:        printf("%s: microcode loaded, int_delay: %d usec",
        !          1872:            sc->sc_dev.dv_xname, sc->sc_int_delay);
        !          1873:
        !          1874:        if (uc->bundle_max_offset)
        !          1875:                printf(", bundle_max %d\n", sc->sc_bundle_max);
        !          1876:        else
        !          1877:                printf("\n");
        !          1878: #endif
        !          1879:
        !          1880:        free(ucode_buf, M_DEVBUF);
        !          1881:        sc->sc_flags |= FXPF_UCODE;
        !          1882: }
        !          1883: #endif /* SMALL_KERNEL */

CVSweb