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

Annotation of sys/dev/ic/hme.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: hme.c,v 1.46 2006/12/21 22:13:36 jason Exp $  */
                      2: /*     $NetBSD: hme.c,v 1.21 2001/07/07 15:59:37 thorpej Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1999 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Paul Kranenburg.
                     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, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: /*
                     41:  * HME Ethernet module driver.
                     42:  */
                     43:
                     44: #include "bpfilter.h"
                     45: #include "vlan.h"
                     46:
                     47: #undef HMEDEBUG
                     48:
                     49: #include <sys/param.h>
                     50: #include <sys/systm.h>
                     51: #include <sys/kernel.h>
                     52: #include <sys/mbuf.h>
                     53: #include <sys/syslog.h>
                     54: #include <sys/socket.h>
                     55: #include <sys/device.h>
                     56: #include <sys/malloc.h>
                     57: #include <sys/ioctl.h>
                     58: #include <sys/errno.h>
                     59:
                     60: #include <net/if.h>
                     61: #include <net/if_dl.h>
                     62: #include <net/if_media.h>
                     63:
                     64: #ifdef INET
                     65: #include <netinet/in.h>
                     66: #include <netinet/in_systm.h>
                     67: #include <netinet/in_var.h>
                     68: #include <netinet/ip.h>
                     69: #include <netinet/if_ether.h>
                     70: #include <netinet/tcp.h>
                     71: #include <netinet/udp.h>
                     72: #endif
                     73:
                     74: #if NBPFILTER > 0
                     75: #include <net/bpf.h>
                     76: #endif
                     77:
                     78: #include <dev/mii/mii.h>
                     79: #include <dev/mii/miivar.h>
                     80:
                     81: #include <machine/bus.h>
                     82:
                     83: #include <dev/ic/hmereg.h>
                     84: #include <dev/ic/hmevar.h>
                     85:
                     86: struct cfdriver hme_cd = {
                     87:        NULL, "hme", DV_IFNET
                     88: };
                     89:
                     90: #define        HME_RX_OFFSET   2
                     91:
                     92: void           hme_start(struct ifnet *);
                     93: void           hme_stop(struct hme_softc *);
                     94: int            hme_ioctl(struct ifnet *, u_long, caddr_t);
                     95: void           hme_tick(void *);
                     96: void           hme_watchdog(struct ifnet *);
                     97: void           hme_shutdown(void *);
                     98: void           hme_init(struct hme_softc *);
                     99: void           hme_meminit(struct hme_softc *);
                    100: void           hme_mifinit(struct hme_softc *);
                    101: void           hme_reset(struct hme_softc *);
                    102: void           hme_setladrf(struct hme_softc *);
                    103: int            hme_newbuf(struct hme_softc *, struct hme_sxd *, int);
                    104: int            hme_encap(struct hme_softc *, struct mbuf *, int *);
                    105:
                    106: /* MII methods & callbacks */
                    107: static int     hme_mii_readreg(struct device *, int, int);
                    108: static void    hme_mii_writereg(struct device *, int, int, int);
                    109: static void    hme_mii_statchg(struct device *);
                    110:
                    111: int            hme_mediachange(struct ifnet *);
                    112: void           hme_mediastatus(struct ifnet *, struct ifmediareq *);
                    113:
                    114: int            hme_eint(struct hme_softc *, u_int);
                    115: int            hme_rint(struct hme_softc *);
                    116: int            hme_tint(struct hme_softc *);
                    117: /* TCP/UDP checksum offload support */
                    118: void           hme_rxcksum(struct mbuf *, u_int32_t);
                    119:
                    120: void
                    121: hme_config(sc)
                    122:        struct hme_softc *sc;
                    123: {
                    124:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    125:        struct mii_data *mii = &sc->sc_mii;
                    126:        struct mii_softc *child;
                    127:        bus_dma_tag_t dmatag = sc->sc_dmatag;
                    128:        bus_dma_segment_t seg;
                    129:        bus_size_t size;
                    130:        int rseg, error, i;
                    131:
                    132:        /*
                    133:         * HME common initialization.
                    134:         *
                    135:         * hme_softc fields that must be initialized by the front-end:
                    136:         *
                    137:         * the bus tag:
                    138:         *      sc_bustag
                    139:         *
                    140:         * the dma bus tag:
                    141:         *      sc_dmatag
                    142:         *
                    143:         * the bus handles:
                    144:         *      sc_seb          (Shared Ethernet Block registers)
                    145:         *      sc_erx          (Receiver Unit registers)
                    146:         *      sc_etx          (Transmitter Unit registers)
                    147:         *      sc_mac          (MAC registers)
                    148:         *      sc_mif          (Management Interface registers)
                    149:         *
                    150:         * the maximum bus burst size:
                    151:         *      sc_burst
                    152:         *
                    153:         * the local Ethernet address:
                    154:         *      sc_arpcom.ac_enaddr
                    155:         *
                    156:         */
                    157:
                    158:        /* Make sure the chip is stopped. */
                    159:        hme_stop(sc);
                    160:
                    161:        for (i = 0; i < HME_TX_RING_SIZE; i++) {
                    162:                if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1,
                    163:                    MCLBYTES, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    164:                    &sc->sc_txd[i].sd_map) != 0) {
                    165:                        sc->sc_txd[i].sd_map = NULL;
                    166:                        goto fail;
                    167:                }
                    168:        }
                    169:        for (i = 0; i < HME_RX_RING_SIZE; i++) {
                    170:                if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1,
                    171:                    MCLBYTES, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    172:                    &sc->sc_rxd[i].sd_map) != 0) {
                    173:                        sc->sc_rxd[i].sd_map = NULL;
                    174:                        goto fail;
                    175:                }
                    176:        }
                    177:        if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1, MCLBYTES, 0,
                    178:            BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_rxmap_spare) != 0) {
                    179:                sc->sc_rxmap_spare = NULL;
                    180:                goto fail;
                    181:        }
                    182:
                    183:        /*
                    184:         * Allocate DMA capable memory
                    185:         * Buffer descriptors must be aligned on a 2048 byte boundary;
                    186:         * take this into account when calculating the size. Note that
                    187:         * the maximum number of descriptors (256) occupies 2048 bytes,
                    188:         * so we allocate that much regardless of the number of descriptors.
                    189:         */
                    190:        size = (HME_XD_SIZE * HME_RX_RING_MAX) +        /* RX descriptors */
                    191:            (HME_XD_SIZE * HME_TX_RING_MAX);            /* TX descriptors */
                    192:
                    193:        /* Allocate DMA buffer */
                    194:        if ((error = bus_dmamem_alloc(dmatag, size, 2048, 0, &seg, 1, &rseg,
                    195:            BUS_DMA_NOWAIT)) != 0) {
                    196:                printf("\n%s: DMA buffer alloc error %d\n",
                    197:                    sc->sc_dev.dv_xname, error);
                    198:                return;
                    199:        }
                    200:
                    201:        /* Map DMA memory in CPU addressable space */
                    202:        if ((error = bus_dmamem_map(dmatag, &seg, rseg, size,
                    203:            &sc->sc_rb.rb_membase, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
                    204:                printf("\n%s: DMA buffer map error %d\n",
                    205:                    sc->sc_dev.dv_xname, error);
                    206:                bus_dmamap_unload(dmatag, sc->sc_dmamap);
                    207:                bus_dmamem_free(dmatag, &seg, rseg);
                    208:                return;
                    209:        }
                    210:
                    211:        if ((error = bus_dmamap_create(dmatag, size, 1, size, 0,
                    212:            BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
                    213:                printf("\n%s: DMA map create error %d\n",
                    214:                    sc->sc_dev.dv_xname, error);
                    215:                return;
                    216:        }
                    217:
                    218:        /* Load the buffer */
                    219:        if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap,
                    220:            sc->sc_rb.rb_membase, size, NULL,
                    221:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
                    222:                printf("\n%s: DMA buffer map load error %d\n",
                    223:                    sc->sc_dev.dv_xname, error);
                    224:                bus_dmamem_free(dmatag, &seg, rseg);
                    225:                return;
                    226:        }
                    227:        sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
                    228:
                    229:        printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
                    230:
                    231:        /* Initialize ifnet structure. */
                    232:        strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
                    233:        ifp->if_softc = sc;
                    234:        ifp->if_start = hme_start;
                    235:        ifp->if_ioctl = hme_ioctl;
                    236:        ifp->if_watchdog = hme_watchdog;
                    237:        ifp->if_flags =
                    238:            IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
                    239:        sc->sc_if_flags = ifp->if_flags;
                    240:        IFQ_SET_READY(&ifp->if_snd);
                    241:        ifp->if_capabilities = IFCAP_VLAN_MTU;
                    242:
                    243:        /* Initialize ifmedia structures and MII info */
                    244:        mii->mii_ifp = ifp;
                    245:        mii->mii_readreg = hme_mii_readreg;
                    246:        mii->mii_writereg = hme_mii_writereg;
                    247:        mii->mii_statchg = hme_mii_statchg;
                    248:
                    249:        ifmedia_init(&mii->mii_media, IFM_IMASK,
                    250:            hme_mediachange, hme_mediastatus);
                    251:
                    252:        hme_mifinit(sc);
                    253:
                    254:        if (sc->sc_tcvr == -1)
                    255:                mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
                    256:                    MII_OFFSET_ANY, 0);
                    257:        else
                    258:                mii_attach(&sc->sc_dev, mii, 0xffffffff, sc->sc_tcvr,
                    259:                    MII_OFFSET_ANY, 0);
                    260:
                    261:        child = LIST_FIRST(&mii->mii_phys);
                    262:        if (child == NULL) {
                    263:                /* No PHY attached */
                    264:                ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
                    265:                ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
                    266:        } else {
                    267:                /*
                    268:                 * Walk along the list of attached MII devices and
                    269:                 * establish an `MII instance' to `phy number'
                    270:                 * mapping. We'll use this mapping in media change
                    271:                 * requests to determine which phy to use to program
                    272:                 * the MIF configuration register.
                    273:                 */
                    274:                for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
                    275:                        /*
                    276:                         * Note: we support just two PHYs: the built-in
                    277:                         * internal device and an external on the MII
                    278:                         * connector.
                    279:                         */
                    280:                        if (child->mii_phy > 1 || child->mii_inst > 1) {
                    281:                                printf("%s: cannot accommodate MII device %s"
                    282:                                    " at phy %d, instance %d\n",
                    283:                                    sc->sc_dev.dv_xname,
                    284:                                    child->mii_dev.dv_xname,
                    285:                                    child->mii_phy, child->mii_inst);
                    286:                                continue;
                    287:                        }
                    288:
                    289:                        sc->sc_phys[child->mii_inst] = child->mii_phy;
                    290:                }
                    291:
                    292:                /*
                    293:                 * XXX - we can really do the following ONLY if the
                    294:                 * phy indeed has the auto negotiation capability!!
                    295:                 */
                    296:                ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
                    297:        }
                    298:
                    299:        /* Attach the interface. */
                    300:        if_attach(ifp);
                    301:        ether_ifattach(ifp);
                    302:
                    303:        sc->sc_sh = shutdownhook_establish(hme_shutdown, sc);
                    304:        if (sc->sc_sh == NULL)
                    305:                panic("hme_config: can't establish shutdownhook");
                    306:
                    307:        timeout_set(&sc->sc_tick_ch, hme_tick, sc);
                    308:        return;
                    309:
                    310: fail:
                    311:        if (sc->sc_rxmap_spare != NULL)
                    312:                bus_dmamap_destroy(sc->sc_dmatag, sc->sc_rxmap_spare);
                    313:        for (i = 0; i < HME_TX_RING_SIZE; i++)
                    314:                if (sc->sc_txd[i].sd_map != NULL)
                    315:                        bus_dmamap_destroy(sc->sc_dmatag, sc->sc_txd[i].sd_map);
                    316:        for (i = 0; i < HME_RX_RING_SIZE; i++)
                    317:                if (sc->sc_rxd[i].sd_map != NULL)
                    318:                        bus_dmamap_destroy(sc->sc_dmatag, sc->sc_rxd[i].sd_map);
                    319: }
                    320:
                    321: void
                    322: hme_tick(arg)
                    323:        void *arg;
                    324: {
                    325:        struct hme_softc *sc = arg;
                    326:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    327:        bus_space_tag_t t = sc->sc_bustag;
                    328:        bus_space_handle_t mac = sc->sc_mac;
                    329:        int s;
                    330:
                    331:        s = splnet();
                    332:        /*
                    333:         * Unload collision counters
                    334:         */
                    335:        ifp->if_collisions +=
                    336:            bus_space_read_4(t, mac, HME_MACI_NCCNT) +
                    337:            bus_space_read_4(t, mac, HME_MACI_FCCNT) +
                    338:            bus_space_read_4(t, mac, HME_MACI_EXCNT) +
                    339:            bus_space_read_4(t, mac, HME_MACI_LTCNT);
                    340:
                    341:        /*
                    342:         * then clear the hardware counters.
                    343:         */
                    344:        bus_space_write_4(t, mac, HME_MACI_NCCNT, 0);
                    345:        bus_space_write_4(t, mac, HME_MACI_FCCNT, 0);
                    346:        bus_space_write_4(t, mac, HME_MACI_EXCNT, 0);
                    347:        bus_space_write_4(t, mac, HME_MACI_LTCNT, 0);
                    348:
                    349:        mii_tick(&sc->sc_mii);
                    350:        splx(s);
                    351:
                    352:        timeout_add(&sc->sc_tick_ch, hz);
                    353: }
                    354:
                    355: void
                    356: hme_reset(sc)
                    357:        struct hme_softc *sc;
                    358: {
                    359:        int s;
                    360:
                    361:        s = splnet();
                    362:        hme_init(sc);
                    363:        splx(s);
                    364: }
                    365:
                    366: void
                    367: hme_stop(sc)
                    368:        struct hme_softc *sc;
                    369: {
                    370:        bus_space_tag_t t = sc->sc_bustag;
                    371:        bus_space_handle_t seb = sc->sc_seb;
                    372:        int n;
                    373:
                    374:        timeout_del(&sc->sc_tick_ch);
                    375:        mii_down(&sc->sc_mii);
                    376:
                    377:        /* Mask all interrupts */
                    378:        bus_space_write_4(t, seb, HME_SEBI_IMASK, 0xffffffff);
                    379:
                    380:        /* Reset transmitter and receiver */
                    381:        bus_space_write_4(t, seb, HME_SEBI_RESET,
                    382:            (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX));
                    383:
                    384:        for (n = 0; n < 20; n++) {
                    385:                u_int32_t v = bus_space_read_4(t, seb, HME_SEBI_RESET);
                    386:                if ((v & (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)) == 0)
                    387:                        break;
                    388:                DELAY(20);
                    389:        }
                    390:        if (n >= 20)
                    391:                printf("%s: hme_stop: reset failed\n", sc->sc_dev.dv_xname);
                    392:
                    393:        for (n = 0; n < HME_TX_RING_SIZE; n++) {
                    394:                if (sc->sc_txd[n].sd_loaded) {
                    395:                        bus_dmamap_sync(sc->sc_dmatag, sc->sc_txd[n].sd_map,
                    396:                            0, sc->sc_txd[n].sd_map->dm_mapsize,
                    397:                            BUS_DMASYNC_POSTWRITE);
                    398:                        bus_dmamap_unload(sc->sc_dmatag, sc->sc_txd[n].sd_map);
                    399:                        sc->sc_txd[n].sd_loaded = 0;
                    400:                }
                    401:                if (sc->sc_txd[n].sd_mbuf != NULL) {
                    402:                        m_freem(sc->sc_txd[n].sd_mbuf);
                    403:                        sc->sc_txd[n].sd_mbuf = NULL;
                    404:                }
                    405:        }
                    406: }
                    407:
                    408: void
                    409: hme_meminit(sc)
                    410:        struct hme_softc *sc;
                    411: {
                    412:        bus_addr_t dma;
                    413:        caddr_t p;
                    414:        unsigned int i;
                    415:        struct hme_ring *hr = &sc->sc_rb;
                    416:
                    417:        p = hr->rb_membase;
                    418:        dma = hr->rb_dmabase;
                    419:
                    420:        /*
                    421:         * Allocate transmit descriptors
                    422:         */
                    423:        hr->rb_txd = p;
                    424:        hr->rb_txddma = dma;
                    425:        p += HME_TX_RING_SIZE * HME_XD_SIZE;
                    426:        dma += HME_TX_RING_SIZE * HME_XD_SIZE;
                    427:        /* We have reserved descriptor space until the next 2048 byte boundary.*/
                    428:        dma = (bus_addr_t)roundup((u_long)dma, 2048);
                    429:        p = (caddr_t)roundup((u_long)p, 2048);
                    430:
                    431:        /*
                    432:         * Allocate receive descriptors
                    433:         */
                    434:        hr->rb_rxd = p;
                    435:        hr->rb_rxddma = dma;
                    436:        p += HME_RX_RING_SIZE * HME_XD_SIZE;
                    437:        dma += HME_RX_RING_SIZE * HME_XD_SIZE;
                    438:        /* Again move forward to the next 2048 byte boundary.*/
                    439:        dma = (bus_addr_t)roundup((u_long)dma, 2048);
                    440:        p = (caddr_t)roundup((u_long)p, 2048);
                    441:
                    442:        /*
                    443:         * Initialize transmit descriptors
                    444:         */
                    445:        for (i = 0; i < HME_TX_RING_SIZE; i++) {
                    446:                HME_XD_SETADDR(sc->sc_pci, hr->rb_txd, i, 0);
                    447:                HME_XD_SETFLAGS(sc->sc_pci, hr->rb_txd, i, 0);
                    448:                sc->sc_txd[i].sd_mbuf = NULL;
                    449:        }
                    450:
                    451:        /*
                    452:         * Initialize receive descriptors
                    453:         */
                    454:        for (i = 0; i < HME_RX_RING_SIZE; i++) {
                    455:                if (hme_newbuf(sc, &sc->sc_rxd[i], 1)) {
                    456:                        printf("%s: rx allocation failed\n",
                    457:                            sc->sc_dev.dv_xname);
                    458:                        break;
                    459:                }
                    460:                HME_XD_SETADDR(sc->sc_pci, hr->rb_rxd, i,
                    461:                    sc->sc_rxd[i].sd_map->dm_segs[0].ds_addr);
                    462:                HME_XD_SETFLAGS(sc->sc_pci, hr->rb_rxd, i,
                    463:                    HME_XD_OWN | HME_XD_ENCODE_RSIZE(HME_RX_PKTSIZE));
                    464:        }
                    465:
                    466:        sc->sc_tx_prod = sc->sc_tx_cons = sc->sc_tx_cnt = 0;
                    467:        sc->sc_last_rd = 0;
                    468: }
                    469:
                    470: /*
                    471:  * Initialization of interface; set up initialization block
                    472:  * and transmit/receive descriptor rings.
                    473:  */
                    474: void
                    475: hme_init(sc)
                    476:        struct hme_softc *sc;
                    477: {
                    478:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    479:        bus_space_tag_t t = sc->sc_bustag;
                    480:        bus_space_handle_t seb = sc->sc_seb;
                    481:        bus_space_handle_t etx = sc->sc_etx;
                    482:        bus_space_handle_t erx = sc->sc_erx;
                    483:        bus_space_handle_t mac = sc->sc_mac;
                    484:        u_int8_t *ea;
                    485:        u_int32_t v, n;
                    486:
                    487:        /*
                    488:         * Initialization sequence. The numbered steps below correspond
                    489:         * to the sequence outlined in section 6.3.5.1 in the Ethernet
                    490:         * Channel Engine manual (part of the PCIO manual).
                    491:         * See also the STP2002-STQ document from Sun Microsystems.
                    492:         */
                    493:
                    494:        /* step 1 & 2. Reset the Ethernet Channel */
                    495:        hme_stop(sc);
                    496:
                    497:        /* Re-initialize the MIF */
                    498:        hme_mifinit(sc);
                    499:
                    500:        /* Call MI reset function if any */
                    501:        if (sc->sc_hwreset)
                    502:                (*sc->sc_hwreset)(sc);
                    503:
                    504: #if 0
                    505:        /* Mask all MIF interrupts, just in case */
                    506:        bus_space_write_4(t, mif, HME_MIFI_IMASK, 0xffff);
                    507: #endif
                    508:
                    509:        /* step 3. Setup data structures in host memory */
                    510:        hme_meminit(sc);
                    511:
                    512:        /* step 4. TX MAC registers & counters */
                    513:        bus_space_write_4(t, mac, HME_MACI_NCCNT, 0);
                    514:        bus_space_write_4(t, mac, HME_MACI_FCCNT, 0);
                    515:        bus_space_write_4(t, mac, HME_MACI_EXCNT, 0);
                    516:        bus_space_write_4(t, mac, HME_MACI_LTCNT, 0);
                    517:        bus_space_write_4(t, mac, HME_MACI_TXSIZE, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
                    518:
                    519:        /* Load station MAC address */
                    520:        ea = sc->sc_arpcom.ac_enaddr;
                    521:        bus_space_write_4(t, mac, HME_MACI_MACADDR0, (ea[0] << 8) | ea[1]);
                    522:        bus_space_write_4(t, mac, HME_MACI_MACADDR1, (ea[2] << 8) | ea[3]);
                    523:        bus_space_write_4(t, mac, HME_MACI_MACADDR2, (ea[4] << 8) | ea[5]);
                    524:
                    525:        /*
                    526:         * Init seed for backoff
                    527:         * (source suggested by manual: low 10 bits of MAC address)
                    528:         */
                    529:        v = ((ea[4] << 8) | ea[5]) & 0x3fff;
                    530:        bus_space_write_4(t, mac, HME_MACI_RANDSEED, v);
                    531:
                    532:
                    533:        /* Note: Accepting power-on default for other MAC registers here.. */
                    534:
                    535:
                    536:        /* step 5. RX MAC registers & counters */
                    537:        hme_setladrf(sc);
                    538:
                    539:        /* step 6 & 7. Program Descriptor Ring Base Addresses */
                    540:        bus_space_write_4(t, etx, HME_ETXI_RING, sc->sc_rb.rb_txddma);
                    541:        bus_space_write_4(t, etx, HME_ETXI_RSIZE, HME_TX_RING_SIZE);
                    542:
                    543:        bus_space_write_4(t, erx, HME_ERXI_RING, sc->sc_rb.rb_rxddma);
                    544:        bus_space_write_4(t, mac, HME_MACI_RXSIZE, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
                    545:
                    546:        /* step 8. Global Configuration & Interrupt Mask */
                    547:        bus_space_write_4(t, seb, HME_SEBI_IMASK,
                    548:            ~(HME_SEB_STAT_HOSTTOTX | HME_SEB_STAT_RXTOHOST |
                    549:              HME_SEB_STAT_TXALL | HME_SEB_STAT_TXPERR |
                    550:              HME_SEB_STAT_RCNTEXP | HME_SEB_STAT_ALL_ERRORS));
                    551:
                    552:        switch (sc->sc_burst) {
                    553:        default:
                    554:                v = 0;
                    555:                break;
                    556:        case 16:
                    557:                v = HME_SEB_CFG_BURST16;
                    558:                break;
                    559:        case 32:
                    560:                v = HME_SEB_CFG_BURST32;
                    561:                break;
                    562:        case 64:
                    563:                v = HME_SEB_CFG_BURST64;
                    564:                break;
                    565:        }
                    566:        bus_space_write_4(t, seb, HME_SEBI_CFG, v);
                    567:
                    568:        /* step 9. ETX Configuration: use mostly default values */
                    569:
                    570:        /* Enable DMA */
                    571:        v = bus_space_read_4(t, etx, HME_ETXI_CFG);
                    572:        v |= HME_ETX_CFG_DMAENABLE;
                    573:        bus_space_write_4(t, etx, HME_ETXI_CFG, v);
                    574:
                    575:        /* Transmit Descriptor ring size: in increments of 16 */
                    576:        bus_space_write_4(t, etx, HME_ETXI_RSIZE, HME_TX_RING_SIZE / 16 - 1);
                    577:
                    578:        /* step 10. ERX Configuration */
                    579:        v = bus_space_read_4(t, erx, HME_ERXI_CFG);
                    580:        v &= ~HME_ERX_CFG_RINGSIZE256;
                    581: #if HME_RX_RING_SIZE == 32
                    582:        v |= HME_ERX_CFG_RINGSIZE32;
                    583: #elif HME_RX_RING_SIZE == 64
                    584:        v |= HME_ERX_CFG_RINGSIZE64;
                    585: #elif HME_RX_RING_SIZE == 128
                    586:        v |= HME_ERX_CFG_RINGSIZE128;
                    587: #elif HME_RX_RING_SIZE == 256
                    588:        v |= HME_ERX_CFG_RINGSIZE256;
                    589: #else
                    590: # error        "RX ring size must be 32, 64, 128, or 256"
                    591: #endif
                    592:        /* Enable DMA */
                    593:        v |= HME_ERX_CFG_DMAENABLE | (HME_RX_OFFSET << 3);
                    594:        /* RX TCP/UDP cksum offset */
                    595:        n = (ETHER_HDR_LEN + sizeof(struct ip)) / 2;
                    596:        n = (n << HME_ERX_CFG_CSUM_SHIFT) & HME_ERX_CFG_CSUMSTART;
                    597:        v |= n;
                    598:        bus_space_write_4(t, erx, HME_ERXI_CFG, v);
                    599:
                    600:        /* step 11. XIF Configuration */
                    601:        v = bus_space_read_4(t, mac, HME_MACI_XIF);
                    602:        v |= HME_MAC_XIF_OE;
                    603:        bus_space_write_4(t, mac, HME_MACI_XIF, v);
                    604:
                    605:        /* step 12. RX_MAC Configuration Register */
                    606:        v = bus_space_read_4(t, mac, HME_MACI_RXCFG);
                    607:        v |= HME_MAC_RXCFG_ENABLE;
                    608:        bus_space_write_4(t, mac, HME_MACI_RXCFG, v);
                    609:
                    610:        /* step 13. TX_MAC Configuration Register */
                    611:        v = bus_space_read_4(t, mac, HME_MACI_TXCFG);
                    612:        v |= (HME_MAC_TXCFG_ENABLE | HME_MAC_TXCFG_DGIVEUP);
                    613:        bus_space_write_4(t, mac, HME_MACI_TXCFG, v);
                    614:
                    615:        /* step 14. Issue Transmit Pending command */
                    616:
                    617:        /* Call MI initialization function if any */
                    618:        if (sc->sc_hwinit)
                    619:                (*sc->sc_hwinit)(sc);
                    620:
                    621:        /* Set the current media. */
                    622:        mii_mediachg(&sc->sc_mii);
                    623:
                    624:        /* Start the one second timer. */
                    625:        timeout_add(&sc->sc_tick_ch, hz);
                    626:
                    627:        ifp->if_flags |= IFF_RUNNING;
                    628:        ifp->if_flags &= ~IFF_OACTIVE;
                    629:        sc->sc_if_flags = ifp->if_flags;
                    630:        ifp->if_timer = 0;
                    631:        hme_start(ifp);
                    632: }
                    633:
                    634: void
                    635: hme_start(ifp)
                    636:        struct ifnet *ifp;
                    637: {
                    638:        struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
                    639:        struct mbuf *m;
                    640:        int bix, cnt = 0;
                    641:
                    642:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                    643:                return;
                    644:
                    645:        bix = sc->sc_tx_prod;
                    646:        while (sc->sc_txd[bix].sd_mbuf == NULL) {
                    647:                IFQ_POLL(&ifp->if_snd, m);
                    648:                if (m == NULL)
                    649:                        break;
                    650:
                    651: #if NBPFILTER > 0
                    652:                /*
                    653:                 * If BPF is listening on this interface, let it see the
                    654:                 * packet before we commit it to the wire.
                    655:                 */
                    656:                if (ifp->if_bpf)
                    657:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
                    658: #endif
                    659:
                    660:                if (hme_encap(sc, m, &bix)) {
                    661:                        ifp->if_flags |= IFF_OACTIVE;
                    662:                        break;
                    663:                }
                    664:
                    665:                IFQ_DEQUEUE(&ifp->if_snd, m);
                    666:
                    667:                bus_space_write_4(sc->sc_bustag, sc->sc_etx, HME_ETXI_PENDING,
                    668:                    HME_ETX_TP_DMAWAKEUP);
                    669:                cnt++;
                    670:        }
                    671:
                    672:        if (cnt != 0) {
                    673:                sc->sc_tx_prod = bix;
                    674:                ifp->if_timer = 5;
                    675:        }
                    676: }
                    677:
                    678: /*
                    679:  * Transmit interrupt.
                    680:  */
                    681: int
                    682: hme_tint(sc)
                    683:        struct hme_softc *sc;
                    684: {
                    685:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    686:        unsigned int ri, txflags;
                    687:        struct hme_sxd *sd;
                    688:        int cnt = sc->sc_tx_cnt;
                    689:
                    690:        /* Fetch current position in the transmit ring */
                    691:        ri = sc->sc_tx_cons;
                    692:        sd = &sc->sc_txd[ri];
                    693:
                    694:        for (;;) {
                    695:                if (cnt <= 0)
                    696:                        break;
                    697:
                    698:                txflags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri);
                    699:
                    700:                if (txflags & HME_XD_OWN)
                    701:                        break;
                    702:
                    703:                ifp->if_flags &= ~IFF_OACTIVE;
                    704:                if (txflags & HME_XD_EOP)
                    705:                        ifp->if_opackets++;
                    706:
                    707:                bus_dmamap_sync(sc->sc_dmatag, sd->sd_map,
                    708:                    0, sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                    709:                bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
                    710:                sd->sd_loaded = 0;
                    711:
                    712:                if (sd->sd_mbuf != NULL) {
                    713:                        m_freem(sd->sd_mbuf);
                    714:                        sd->sd_mbuf = NULL;
                    715:                }
                    716:
                    717:                if (++ri == HME_TX_RING_SIZE) {
                    718:                        ri = 0;
                    719:                        sd = sc->sc_txd;
                    720:                } else
                    721:                        sd++;
                    722:
                    723:                --cnt;
                    724:        }
                    725:
                    726:        sc->sc_tx_cnt = cnt;
                    727:        ifp->if_timer = cnt > 0 ? 5 : 0;
                    728:
                    729:        /* Update ring */
                    730:        sc->sc_tx_cons = ri;
                    731:
                    732:        hme_start(ifp);
                    733:
                    734:        return (1);
                    735: }
                    736:
                    737: /*
                    738:  * XXX layering violation
                    739:  *
                    740:  * If we can have additional csum data member in 'struct pkthdr' for
                    741:  * these incomplete checksum offload capable hardware, things would be
                    742:  * much simpler. That member variable will carry partial checksum
                    743:  * data and it may be evaluated in TCP/UDP input handler after
                    744:  * computing pseudo header checksumming.
                    745:  */
                    746: void
                    747: hme_rxcksum(struct mbuf *m, u_int32_t flags)
                    748: {
                    749:        struct ether_header *eh;
                    750:        struct ip *ip;
                    751:        struct udphdr *uh;
                    752:        int32_t hlen, len, pktlen;
                    753:        u_int16_t cksum, *opts;
                    754:        u_int32_t temp32;
                    755:        union pseudoh {
                    756:                struct hdr {
                    757:                        u_int16_t len;
                    758:                        u_int8_t ttl;
                    759:                        u_int8_t proto;
                    760:                        u_int32_t src;
                    761:                        u_int32_t dst;
                    762:                } h;
                    763:                u_int16_t w[6];
                    764:        } ph;
                    765:
                    766:        pktlen = m->m_pkthdr.len;
                    767:        if (pktlen < sizeof(struct ether_header))
                    768:                return;
                    769:        eh = mtod(m, struct ether_header *);
                    770:        if (eh->ether_type != htons(ETHERTYPE_IP))
                    771:                return;
                    772:        ip = (struct ip *)(eh + 1);
                    773:        if (ip->ip_v != IPVERSION)
                    774:                return;
                    775:
                    776:        hlen = ip->ip_hl << 2;
                    777:        pktlen -= sizeof(struct ether_header);
                    778:        if (hlen < sizeof(struct ip))
                    779:                return;
                    780:        if (ntohs(ip->ip_len) < hlen)
                    781:                return;
                    782:        if (ntohs(ip->ip_len) != pktlen)
                    783:                return;
                    784:        if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
                    785:                return; /* can't handle fragmented packet */
                    786:
                    787:        switch (ip->ip_p) {
                    788:        case IPPROTO_TCP:
                    789:                if (pktlen < (hlen + sizeof(struct tcphdr)))
                    790:                        return;
                    791:                break;
                    792:        case IPPROTO_UDP:
                    793:                if (pktlen < (hlen + sizeof(struct udphdr)))
                    794:                        return;
                    795:                uh = (struct udphdr *)((caddr_t)ip + hlen);
                    796:                if (uh->uh_sum == 0)
                    797:                        return; /* no checksum */
                    798:                break;
                    799:        default:
                    800:                return;
                    801:        }
                    802:
                    803:        cksum = htons(~(flags & HME_XD_RXCKSUM));
                    804:        /* cksum fixup for IP options */
                    805:        len = hlen - sizeof(struct ip);
                    806:        if (len > 0) {
                    807:                opts = (u_int16_t *)(ip + 1);
                    808:                for (; len > 0; len -= sizeof(u_int16_t), opts++) {
                    809:                        temp32 = cksum - *opts;
                    810:                        temp32 = (temp32 >> 16) + (temp32 & 65535);
                    811:                        cksum = temp32 & 65535;
                    812:                }
                    813:        }
                    814:        /* cksum fixup for pseudo-header, replace with in_cksum_phdr()? */
                    815:        ph.h.len = htons(ntohs(ip->ip_len) - hlen);
                    816:        ph.h.ttl = 0;
                    817:        ph.h.proto = ip->ip_p;
                    818:        ph.h.src = ip->ip_src.s_addr;
                    819:        ph.h.dst = ip->ip_dst.s_addr;
                    820:        temp32 = cksum;
                    821:        opts = &ph.w[0];
                    822:        temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5];
                    823:        temp32 = (temp32 >> 16) + (temp32 & 65535);
                    824:        temp32 += (temp32 >> 16);
                    825:        cksum = ~temp32;
                    826:        if (cksum == 0) {
                    827:                m->m_pkthdr.csum_flags |=
                    828:                        M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
                    829:        }
                    830: }
                    831:
                    832: /*
                    833:  * Receive interrupt.
                    834:  */
                    835: int
                    836: hme_rint(sc)
                    837:        struct hme_softc *sc;
                    838: {
                    839:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    840:        struct mbuf *m;
                    841:        struct hme_sxd *sd;
                    842:        unsigned int ri, len;
                    843:        u_int32_t flags;
                    844:
                    845:        ri = sc->sc_last_rd;
                    846:        sd = &sc->sc_rxd[ri];
                    847:
                    848:        /*
                    849:         * Process all buffers with valid data.
                    850:         */
                    851:        for (;;) {
                    852:                flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ri);
                    853:                if (flags & HME_XD_OWN)
                    854:                        break;
                    855:
                    856:                if (flags & HME_XD_OFL) {
                    857:                        printf("%s: buffer overflow, ri=%d; flags=0x%x\n",
                    858:                            sc->sc_dev.dv_xname, ri, flags);
                    859:                        goto again;
                    860:                }
                    861:
                    862:                m = sd->sd_mbuf;
                    863:                len = HME_XD_DECODE_RSIZE(flags);
                    864:                m->m_pkthdr.len = m->m_len = len;
                    865:
                    866:                if (hme_newbuf(sc, sd, 0)) {
                    867:                        /*
                    868:                         * Allocation of new mbuf cluster failed, leave the
                    869:                         * old one in place and keep going.
                    870:                         */
                    871:                        ifp->if_ierrors++;
                    872:                        goto again;
                    873:                }
                    874:
                    875:                ifp->if_ipackets++;
                    876:                hme_rxcksum(m, flags);
                    877:
                    878: #if NBPFILTER > 0
                    879:                if (ifp->if_bpf)
                    880:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                    881: #endif
                    882:
                    883:                ether_input_mbuf(ifp, m);
                    884:
                    885: again:
                    886:                HME_XD_SETADDR(sc->sc_pci, sc->sc_rb.rb_rxd, ri,
                    887:                    sd->sd_map->dm_segs[0].ds_addr);
                    888:                HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ri,
                    889:                    HME_XD_OWN | HME_XD_ENCODE_RSIZE(HME_RX_PKTSIZE));
                    890:
                    891:                if (++ri == HME_RX_RING_SIZE) {
                    892:                        ri = 0;
                    893:                        sd = sc->sc_rxd;
                    894:                } else
                    895:                        sd++;
                    896:        }
                    897:
                    898:        sc->sc_last_rd = ri;
                    899:        return (1);
                    900: }
                    901:
                    902: int
                    903: hme_eint(sc, status)
                    904:        struct hme_softc *sc;
                    905:        u_int status;
                    906: {
                    907:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    908:
                    909:        if (status & HME_SEB_STAT_MIFIRQ) {
                    910:                printf("%s: XXXlink status changed\n", sc->sc_dev.dv_xname);
                    911:                status &= ~HME_SEB_STAT_MIFIRQ;
                    912:        }
                    913:
                    914:        if (status & HME_SEB_STAT_DTIMEXP) {
                    915:                ifp->if_oerrors++;
                    916:                status &= ~HME_SEB_STAT_DTIMEXP;
                    917:        }
                    918:
                    919:        if (status & HME_SEB_STAT_NORXD) {
                    920:                ifp->if_ierrors++;
                    921:                status &= ~HME_SEB_STAT_NORXD;
                    922:        }
                    923:
                    924:        status &= ~(HME_SEB_STAT_RXTOHOST | HME_SEB_STAT_GOTFRAME |
                    925:            HME_SEB_STAT_SENTFRAME | HME_SEB_STAT_HOSTTOTX |
                    926:            HME_SEB_STAT_TXALL);
                    927:
                    928:        if (status == 0)
                    929:                return (1);
                    930:
                    931: #ifdef HME_DEBUG
                    932:        printf("%s: status=%b\n", sc->sc_dev.dv_xname, status, HME_SEB_STAT_BITS);
                    933: #endif
                    934:        return (1);
                    935: }
                    936:
                    937: int
                    938: hme_intr(v)
                    939:        void *v;
                    940: {
                    941:        struct hme_softc *sc = (struct hme_softc *)v;
                    942:        bus_space_tag_t t = sc->sc_bustag;
                    943:        bus_space_handle_t seb = sc->sc_seb;
                    944:        u_int32_t status;
                    945:        int r = 0;
                    946:
                    947:        status = bus_space_read_4(t, seb, HME_SEBI_STAT);
                    948:
                    949:        if ((status & HME_SEB_STAT_ALL_ERRORS) != 0)
                    950:                r |= hme_eint(sc, status);
                    951:
                    952:        if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0)
                    953:                r |= hme_tint(sc);
                    954:
                    955:        if ((status & HME_SEB_STAT_RXTOHOST) != 0)
                    956:                r |= hme_rint(sc);
                    957:
                    958:        return (r);
                    959: }
                    960:
                    961:
                    962: void
                    963: hme_watchdog(ifp)
                    964:        struct ifnet *ifp;
                    965: {
                    966:        struct hme_softc *sc = ifp->if_softc;
                    967:
                    968:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
                    969:        ifp->if_oerrors++;
                    970:
                    971:        hme_reset(sc);
                    972: }
                    973:
                    974: /*
                    975:  * Initialize the MII Management Interface
                    976:  */
                    977: void
                    978: hme_mifinit(sc)
                    979:        struct hme_softc *sc;
                    980: {
                    981:        bus_space_tag_t t = sc->sc_bustag;
                    982:        bus_space_handle_t mif = sc->sc_mif;
                    983:        bus_space_handle_t mac = sc->sc_mac;
                    984:        int phy;
                    985:        u_int32_t v;
                    986:
                    987:        v = bus_space_read_4(t, mif, HME_MIFI_CFG);
                    988:        phy = HME_PHYAD_EXTERNAL;
                    989:        if (v & HME_MIF_CFG_MDI1)
                    990:                phy = sc->sc_tcvr = HME_PHYAD_EXTERNAL;
                    991:        else if (v & HME_MIF_CFG_MDI0)
                    992:                phy = sc->sc_tcvr = HME_PHYAD_INTERNAL;
                    993:        else
                    994:                sc->sc_tcvr = -1;
                    995:
                    996:        /* Configure the MIF in frame mode, no poll, current phy select */
                    997:        v = 0;
                    998:        if (phy == HME_PHYAD_EXTERNAL)
                    999:                v |= HME_MIF_CFG_PHY;
                   1000:        bus_space_write_4(t, mif, HME_MIFI_CFG, v);
                   1001:
                   1002:        /* If an external transceiver is selected, enable its MII drivers */
                   1003:        v = bus_space_read_4(t, mac, HME_MACI_XIF);
                   1004:        v &= ~HME_MAC_XIF_MIIENABLE;
                   1005:        if (phy == HME_PHYAD_EXTERNAL)
                   1006:                v |= HME_MAC_XIF_MIIENABLE;
                   1007:        bus_space_write_4(t, mac, HME_MACI_XIF, v);
                   1008: }
                   1009:
                   1010: /*
                   1011:  * MII interface
                   1012:  */
                   1013: static int
                   1014: hme_mii_readreg(self, phy, reg)
                   1015:        struct device *self;
                   1016:        int phy, reg;
                   1017: {
                   1018:        struct hme_softc *sc = (struct hme_softc *)self;
                   1019:        bus_space_tag_t t = sc->sc_bustag;
                   1020:        bus_space_handle_t mif = sc->sc_mif;
                   1021:        bus_space_handle_t mac = sc->sc_mac;
                   1022:        u_int32_t v, xif_cfg, mifi_cfg;
                   1023:        int n;
                   1024:
                   1025:        if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
                   1026:                return (0);
                   1027:
                   1028:        /* Select the desired PHY in the MIF configuration register */
                   1029:        v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
                   1030:        v &= ~HME_MIF_CFG_PHY;
                   1031:        if (phy == HME_PHYAD_EXTERNAL)
                   1032:                v |= HME_MIF_CFG_PHY;
                   1033:        bus_space_write_4(t, mif, HME_MIFI_CFG, v);
                   1034:
                   1035:        /* Enable MII drivers on external transceiver */
                   1036:        v = xif_cfg = bus_space_read_4(t, mac, HME_MACI_XIF);
                   1037:        if (phy == HME_PHYAD_EXTERNAL)
                   1038:                v |= HME_MAC_XIF_MIIENABLE;
                   1039:        else
                   1040:                v &= ~HME_MAC_XIF_MIIENABLE;
                   1041:        bus_space_write_4(t, mac, HME_MACI_XIF, v);
                   1042:
                   1043:        /* Construct the frame command */
                   1044:        v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
                   1045:            HME_MIF_FO_TAMSB |
                   1046:            (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) |
                   1047:            (phy << HME_MIF_FO_PHYAD_SHIFT) |
                   1048:            (reg << HME_MIF_FO_REGAD_SHIFT);
                   1049:
                   1050:        bus_space_write_4(t, mif, HME_MIFI_FO, v);
                   1051:        for (n = 0; n < 100; n++) {
                   1052:                DELAY(1);
                   1053:                v = bus_space_read_4(t, mif, HME_MIFI_FO);
                   1054:                if (v & HME_MIF_FO_TALSB) {
                   1055:                        v &= HME_MIF_FO_DATA;
                   1056:                        goto out;
                   1057:                }
                   1058:        }
                   1059:
                   1060:        v = 0;
                   1061:        printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
                   1062:
                   1063: out:
                   1064:        /* Restore MIFI_CFG register */
                   1065:        bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
                   1066:        /* Restore XIF register */
                   1067:        bus_space_write_4(t, mac, HME_MACI_XIF, xif_cfg);
                   1068:        return (v);
                   1069: }
                   1070:
                   1071: static void
                   1072: hme_mii_writereg(self, phy, reg, val)
                   1073:        struct device *self;
                   1074:        int phy, reg, val;
                   1075: {
                   1076:        struct hme_softc *sc = (void *)self;
                   1077:        bus_space_tag_t t = sc->sc_bustag;
                   1078:        bus_space_handle_t mif = sc->sc_mif;
                   1079:        bus_space_handle_t mac = sc->sc_mac;
                   1080:        u_int32_t v, xif_cfg, mifi_cfg;
                   1081:        int n;
                   1082:
                   1083:        /* We can at most have two PHYs */
                   1084:        if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
                   1085:                return;
                   1086:
                   1087:        /* Select the desired PHY in the MIF configuration register */
                   1088:        v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
                   1089:        v &= ~HME_MIF_CFG_PHY;
                   1090:        if (phy == HME_PHYAD_EXTERNAL)
                   1091:                v |= HME_MIF_CFG_PHY;
                   1092:        bus_space_write_4(t, mif, HME_MIFI_CFG, v);
                   1093:
                   1094:        /* Enable MII drivers on external transceiver */
                   1095:        v = xif_cfg = bus_space_read_4(t, mac, HME_MACI_XIF);
                   1096:        if (phy == HME_PHYAD_EXTERNAL)
                   1097:                v |= HME_MAC_XIF_MIIENABLE;
                   1098:        else
                   1099:                v &= ~HME_MAC_XIF_MIIENABLE;
                   1100:        bus_space_write_4(t, mac, HME_MACI_XIF, v);
                   1101:
                   1102:        /* Construct the frame command */
                   1103:        v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT)  |
                   1104:            HME_MIF_FO_TAMSB                            |
                   1105:            (MII_COMMAND_WRITE << HME_MIF_FO_OPC_SHIFT) |
                   1106:            (phy << HME_MIF_FO_PHYAD_SHIFT)             |
                   1107:            (reg << HME_MIF_FO_REGAD_SHIFT)             |
                   1108:            (val & HME_MIF_FO_DATA);
                   1109:
                   1110:        bus_space_write_4(t, mif, HME_MIFI_FO, v);
                   1111:        for (n = 0; n < 100; n++) {
                   1112:                DELAY(1);
                   1113:                v = bus_space_read_4(t, mif, HME_MIFI_FO);
                   1114:                if (v & HME_MIF_FO_TALSB)
                   1115:                        goto out;
                   1116:        }
                   1117:
                   1118:        printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
                   1119: out:
                   1120:        /* Restore MIFI_CFG register */
                   1121:        bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
                   1122:        /* Restore XIF register */
                   1123:        bus_space_write_4(t, mac, HME_MACI_XIF, xif_cfg);
                   1124: }
                   1125:
                   1126: static void
                   1127: hme_mii_statchg(dev)
                   1128:        struct device *dev;
                   1129: {
                   1130:        struct hme_softc *sc = (void *)dev;
                   1131:        bus_space_tag_t t = sc->sc_bustag;
                   1132:        bus_space_handle_t mac = sc->sc_mac;
                   1133:        u_int32_t v;
                   1134:
                   1135: #ifdef HMEDEBUG
                   1136:        if (sc->sc_debug)
                   1137:                printf("hme_mii_statchg: status change\n", phy);
                   1138: #endif
                   1139:
                   1140:        /* Set the MAC Full Duplex bit appropriately */
                   1141:        /* Apparently the hme chip is SIMPLEX if working in full duplex mode,
                   1142:           but not otherwise. */
                   1143:        v = bus_space_read_4(t, mac, HME_MACI_TXCFG);
                   1144:        if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) {
                   1145:                v |= HME_MAC_TXCFG_FULLDPLX;
                   1146:                sc->sc_arpcom.ac_if.if_flags |= IFF_SIMPLEX;
                   1147:        } else {
                   1148:                v &= ~HME_MAC_TXCFG_FULLDPLX;
                   1149:                sc->sc_arpcom.ac_if.if_flags &= ~IFF_SIMPLEX;
                   1150:        }
                   1151:        sc->sc_if_flags = sc->sc_arpcom.ac_if.if_flags;
                   1152:        bus_space_write_4(t, mac, HME_MACI_TXCFG, v);
                   1153: }
                   1154:
                   1155: int
                   1156: hme_mediachange(ifp)
                   1157:        struct ifnet *ifp;
                   1158: {
                   1159:        struct hme_softc *sc = ifp->if_softc;
                   1160:        bus_space_tag_t t = sc->sc_bustag;
                   1161:        bus_space_handle_t mif = sc->sc_mif;
                   1162:        bus_space_handle_t mac = sc->sc_mac;
                   1163:        int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
                   1164:        int phy = sc->sc_phys[instance];
                   1165:        u_int32_t v;
                   1166:
                   1167: #ifdef HMEDEBUG
                   1168:        if (sc->sc_debug)
                   1169:                printf("hme_mediachange: phy = %d\n", phy);
                   1170: #endif
                   1171:        if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER)
                   1172:                return (EINVAL);
                   1173:
                   1174:        /* Select the current PHY in the MIF configuration register */
                   1175:        v = bus_space_read_4(t, mif, HME_MIFI_CFG);
                   1176:        v &= ~HME_MIF_CFG_PHY;
                   1177:        if (phy == HME_PHYAD_EXTERNAL)
                   1178:                v |= HME_MIF_CFG_PHY;
                   1179:        bus_space_write_4(t, mif, HME_MIFI_CFG, v);
                   1180:
                   1181:        /* If an external transceiver is selected, enable its MII drivers */
                   1182:        v = bus_space_read_4(t, mac, HME_MACI_XIF);
                   1183:        v &= ~HME_MAC_XIF_MIIENABLE;
                   1184:        if (phy == HME_PHYAD_EXTERNAL)
                   1185:                v |= HME_MAC_XIF_MIIENABLE;
                   1186:        bus_space_write_4(t, mac, HME_MACI_XIF, v);
                   1187:
                   1188:        return (mii_mediachg(&sc->sc_mii));
                   1189: }
                   1190:
                   1191: void
                   1192: hme_mediastatus(ifp, ifmr)
                   1193:        struct ifnet *ifp;
                   1194:        struct ifmediareq *ifmr;
                   1195: {
                   1196:        struct hme_softc *sc = ifp->if_softc;
                   1197:
                   1198:        if ((ifp->if_flags & IFF_UP) == 0)
                   1199:                return;
                   1200:
                   1201:        mii_pollstat(&sc->sc_mii);
                   1202:        ifmr->ifm_active = sc->sc_mii.mii_media_active;
                   1203:        ifmr->ifm_status = sc->sc_mii.mii_media_status;
                   1204: }
                   1205:
                   1206: /*
                   1207:  * Process an ioctl request.
                   1208:  */
                   1209: int
                   1210: hme_ioctl(ifp, cmd, data)
                   1211:        struct ifnet *ifp;
                   1212:        u_long cmd;
                   1213:        caddr_t data;
                   1214: {
                   1215:        struct hme_softc *sc = ifp->if_softc;
                   1216:        struct ifaddr *ifa = (struct ifaddr *)data;
                   1217:        struct ifreq *ifr = (struct ifreq *)data;
                   1218:        int s, error = 0;
                   1219:
                   1220:        s = splnet();
                   1221:
                   1222:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
                   1223:                splx(s);
                   1224:                return (error);
                   1225:        }
                   1226:
                   1227:        switch (cmd) {
                   1228:
                   1229:        case SIOCSIFADDR:
                   1230:                switch (ifa->ifa_addr->sa_family) {
                   1231: #ifdef INET
                   1232:                case AF_INET:
                   1233:                        if (ifp->if_flags & IFF_UP)
                   1234:                                hme_setladrf(sc);
                   1235:                        else {
                   1236:                                ifp->if_flags |= IFF_UP;
                   1237:                                hme_init(sc);
                   1238:                        }
                   1239:                        arp_ifinit(&sc->sc_arpcom, ifa);
                   1240:                        break;
                   1241: #endif
                   1242:                default:
                   1243:                        hme_init(sc);
                   1244:                        break;
                   1245:                }
                   1246:                break;
                   1247:
                   1248:        case SIOCSIFFLAGS:
                   1249:                if ((ifp->if_flags & IFF_UP) == 0 &&
                   1250:                    (ifp->if_flags & IFF_RUNNING) != 0) {
                   1251:                        /*
                   1252:                         * If interface is marked down and it is running, then
                   1253:                         * stop it.
                   1254:                         */
                   1255:                        hme_stop(sc);
                   1256:                        ifp->if_flags &= ~IFF_RUNNING;
                   1257:                } else if ((ifp->if_flags & IFF_UP) != 0 &&
                   1258:                           (ifp->if_flags & IFF_RUNNING) == 0) {
                   1259:                        /*
                   1260:                         * If interface is marked up and it is stopped, then
                   1261:                         * start it.
                   1262:                         */
                   1263:                        hme_init(sc);
                   1264:                } else if ((ifp->if_flags & IFF_UP) != 0) {
                   1265:                        /*
                   1266:                         * If setting debug or promiscuous mode, do not reset
                   1267:                         * the chip; for everything else, call hme_init()
                   1268:                         * which will trigger a reset.
                   1269:                         */
                   1270: #define RESETIGN (IFF_CANTCHANGE | IFF_DEBUG)
                   1271:                        if (ifp->if_flags == sc->sc_if_flags)
                   1272:                                break;
                   1273:                        if ((ifp->if_flags & (~RESETIGN))
                   1274:                            == (sc->sc_if_flags & (~RESETIGN)))
                   1275:                                hme_setladrf(sc);
                   1276:                        else
                   1277:                                hme_init(sc);
                   1278: #undef RESETIGN
                   1279:                }
                   1280: #ifdef HMEDEBUG
                   1281:                sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
                   1282: #endif
                   1283:                break;
                   1284:
                   1285:        case SIOCADDMULTI:
                   1286:        case SIOCDELMULTI:
                   1287:                error = (cmd == SIOCADDMULTI) ?
                   1288:                    ether_addmulti(ifr, &sc->sc_arpcom) :
                   1289:                    ether_delmulti(ifr, &sc->sc_arpcom);
                   1290:
                   1291:                if (error == ENETRESET) {
                   1292:                        /*
                   1293:                         * Multicast list has changed; set the hardware filter
                   1294:                         * accordingly.
                   1295:                         */
                   1296:                        if (ifp->if_flags & IFF_RUNNING)
                   1297:                                hme_setladrf(sc);
                   1298:                        error = 0;
                   1299:                }
                   1300:                break;
                   1301:
                   1302:        case SIOCGIFMEDIA:
                   1303:        case SIOCSIFMEDIA:
                   1304:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
                   1305:                break;
                   1306:
                   1307:        default:
                   1308:                error = ENOTTY;
                   1309:                break;
                   1310:        }
                   1311:
                   1312:        sc->sc_if_flags = ifp->if_flags;
                   1313:        splx(s);
                   1314:        return (error);
                   1315: }
                   1316:
                   1317: void
                   1318: hme_shutdown(arg)
                   1319:        void *arg;
                   1320: {
                   1321:        hme_stop((struct hme_softc *)arg);
                   1322: }
                   1323:
                   1324: /*
                   1325:  * Set up the logical address filter.
                   1326:  */
                   1327: void
                   1328: hme_setladrf(sc)
                   1329:        struct hme_softc *sc;
                   1330: {
                   1331:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   1332:        struct ether_multi *enm;
                   1333:        struct ether_multistep step;
                   1334:        struct arpcom *ac = &sc->sc_arpcom;
                   1335:        bus_space_tag_t t = sc->sc_bustag;
                   1336:        bus_space_handle_t mac = sc->sc_mac;
                   1337:        u_int32_t hash[4];
                   1338:        u_int32_t v, crc;
                   1339:
                   1340:        /* Clear hash table */
                   1341:        hash[3] = hash[2] = hash[1] = hash[0] = 0;
                   1342:
                   1343:        /* Get current RX configuration */
                   1344:        v = bus_space_read_4(t, mac, HME_MACI_RXCFG);
                   1345:
                   1346:        if ((ifp->if_flags & IFF_PROMISC) != 0) {
                   1347:                /* Turn on promiscuous mode; turn off the hash filter */
                   1348:                v |= HME_MAC_RXCFG_PMISC;
                   1349:                v &= ~HME_MAC_RXCFG_HENABLE;
                   1350:                ifp->if_flags |= IFF_ALLMULTI;
                   1351:                goto chipit;
                   1352:        }
                   1353:
                   1354:        /* Turn off promiscuous mode; turn on the hash filter */
                   1355:        v &= ~HME_MAC_RXCFG_PMISC;
                   1356:        v |= HME_MAC_RXCFG_HENABLE;
                   1357:
                   1358:        /*
                   1359:         * Set up multicast address filter by passing all multicast addresses
                   1360:         * through a crc generator, and then using the high order 6 bits as an
                   1361:         * index into the 64 bit logical address filter.  The high order bit
                   1362:         * selects the word, while the rest of the bits select the bit within
                   1363:         * the word.
                   1364:         */
                   1365:
                   1366:        ETHER_FIRST_MULTI(step, ac, enm);
                   1367:        while (enm != NULL) {
                   1368:                if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
                   1369:                        /*
                   1370:                         * We must listen to a range of multicast addresses.
                   1371:                         * For now, just accept all multicasts, rather than
                   1372:                         * trying to set only those filter bits needed to match
                   1373:                         * the range.  (At this time, the only use of address
                   1374:                         * ranges is for IP multicast routing, for which the
                   1375:                         * range is big enough to require all bits set.)
                   1376:                         */
                   1377:                        hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
                   1378:                        ifp->if_flags |= IFF_ALLMULTI;
                   1379:                        goto chipit;
                   1380:                }
                   1381:
                   1382:                crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN)>> 26;
                   1383:
                   1384:                /* Set the corresponding bit in the filter. */
                   1385:                hash[crc >> 4] |= 1 << (crc & 0xf);
                   1386:
                   1387:                ETHER_NEXT_MULTI(step, enm);
                   1388:        }
                   1389:
                   1390:        ifp->if_flags &= ~IFF_ALLMULTI;
                   1391:
                   1392: chipit:
                   1393:        /* Now load the hash table into the chip */
                   1394:        bus_space_write_4(t, mac, HME_MACI_HASHTAB0, hash[0]);
                   1395:        bus_space_write_4(t, mac, HME_MACI_HASHTAB1, hash[1]);
                   1396:        bus_space_write_4(t, mac, HME_MACI_HASHTAB2, hash[2]);
                   1397:        bus_space_write_4(t, mac, HME_MACI_HASHTAB3, hash[3]);
                   1398:        bus_space_write_4(t, mac, HME_MACI_RXCFG, v);
                   1399: }
                   1400:
                   1401: int
                   1402: hme_encap(sc, mhead, bixp)
                   1403:        struct hme_softc *sc;
                   1404:        struct mbuf *mhead;
                   1405:        int *bixp;
                   1406: {
                   1407:        struct hme_sxd *sd;
                   1408:        struct mbuf *m;
                   1409:        int frag, cur, cnt = 0;
                   1410:        u_int32_t flags;
                   1411:        struct hme_ring *hr = &sc->sc_rb;
                   1412:
                   1413:        cur = frag = *bixp;
                   1414:        sd = &sc->sc_txd[frag];
                   1415:
                   1416:        for (m = mhead; m != NULL; m = m->m_next) {
                   1417:                if (m->m_len == 0)
                   1418:                        continue;
                   1419:
                   1420:                if ((HME_TX_RING_SIZE - (sc->sc_tx_cnt + cnt)) < 5)
                   1421:                        goto err;
                   1422:
                   1423:                if (bus_dmamap_load(sc->sc_dmatag, sd->sd_map,
                   1424:                    mtod(m, caddr_t), m->m_len, NULL, BUS_DMA_NOWAIT) != 0)
                   1425:                        goto err;
                   1426:
                   1427:                sd->sd_loaded = 1;
                   1428:                bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
                   1429:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
                   1430:
                   1431:                sd->sd_mbuf = NULL;
                   1432:
                   1433:                flags = HME_XD_ENCODE_TSIZE(m->m_len);
                   1434:                if (cnt == 0)
                   1435:                        flags |= HME_XD_SOP;
                   1436:                else
                   1437:                        flags |= HME_XD_OWN;
                   1438:
                   1439:                HME_XD_SETADDR(sc->sc_pci, hr->rb_txd, frag,
                   1440:                    sd->sd_map->dm_segs[0].ds_addr);
                   1441:                HME_XD_SETFLAGS(sc->sc_pci, hr->rb_txd, frag, flags);
                   1442:
                   1443:                cur = frag;
                   1444:                cnt++;
                   1445:                if (++frag == HME_TX_RING_SIZE) {
                   1446:                        frag = 0;
                   1447:                        sd = sc->sc_txd;
                   1448:                } else
                   1449:                        sd++;
                   1450:        }
                   1451:
                   1452:        /* Set end of packet on last descriptor. */
                   1453:        flags = HME_XD_GETFLAGS(sc->sc_pci, hr->rb_txd, cur);
                   1454:        flags |= HME_XD_EOP;
                   1455:        HME_XD_SETFLAGS(sc->sc_pci, hr->rb_txd, cur, flags);
                   1456:        sc->sc_txd[cur].sd_mbuf = mhead;
                   1457:
                   1458:        /* Give first frame over to the hardware. */
                   1459:        flags = HME_XD_GETFLAGS(sc->sc_pci, hr->rb_txd, (*bixp));
                   1460:        flags |= HME_XD_OWN;
                   1461:        HME_XD_SETFLAGS(sc->sc_pci, hr->rb_txd, (*bixp), flags);
                   1462:
                   1463:        sc->sc_tx_cnt += cnt;
                   1464:        *bixp = frag;
                   1465:
                   1466:        /* sync descriptors */
                   1467:
                   1468:        return (0);
                   1469:
                   1470: err:
                   1471:        /*
                   1472:         * Invalidate the stuff we may have already put into place. We
                   1473:         * will be called again to queue it later.
                   1474:         */
                   1475:        for (; cnt > 0; cnt--) {
                   1476:                if (--frag == -1)
                   1477:                        frag = HME_TX_RING_SIZE - 1;
                   1478:                sd = &sc->sc_txd[frag];
                   1479:                bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
                   1480:                    sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1481:                bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
                   1482:                sd->sd_loaded = 0;
                   1483:                sd->sd_mbuf = NULL;
                   1484:        }
                   1485:        return (ENOBUFS);
                   1486: }
                   1487:
                   1488: int
                   1489: hme_newbuf(sc, d, freeit)
                   1490:        struct hme_softc *sc;
                   1491:        struct hme_sxd *d;
                   1492:        int freeit;
                   1493: {
                   1494:        struct mbuf *m;
                   1495:        bus_dmamap_t map;
                   1496:
                   1497:        /*
                   1498:         * All operations should be on local variables and/or rx spare map
                   1499:         * until we're sure everything is a success.
                   1500:         */
                   1501:
                   1502:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1503:        if (m == NULL)
                   1504:                return (ENOBUFS);
                   1505:        m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
                   1506:
                   1507:        MCLGET(m, M_DONTWAIT);
                   1508:        if ((m->m_flags & M_EXT) == 0) {
                   1509:                m_freem(m);
                   1510:                return (ENOBUFS);
                   1511:        }
                   1512:
                   1513:        if (bus_dmamap_load(sc->sc_dmatag, sc->sc_rxmap_spare,
                   1514:            mtod(m, caddr_t), MCLBYTES - HME_RX_OFFSET, NULL,
                   1515:            BUS_DMA_NOWAIT) != 0) {
                   1516:                m_freem(m);
                   1517:                return (ENOBUFS);
                   1518:        }
                   1519:
                   1520:        /*
                   1521:         * At this point we have a new buffer loaded into the spare map.
                   1522:         * Just need to clear out the old mbuf/map and put the new one
                   1523:         * in place.
                   1524:         */
                   1525:
                   1526:        if (d->sd_loaded) {
                   1527:                bus_dmamap_sync(sc->sc_dmatag, d->sd_map,
                   1528:                    0, d->sd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1529:                bus_dmamap_unload(sc->sc_dmatag, d->sd_map);
                   1530:                d->sd_loaded = 0;
                   1531:        }
                   1532:
                   1533:        if ((d->sd_mbuf != NULL) && freeit) {
                   1534:                m_freem(d->sd_mbuf);
                   1535:                d->sd_mbuf = NULL;
                   1536:        }
                   1537:
                   1538:        map = d->sd_map;
                   1539:        d->sd_map = sc->sc_rxmap_spare;
                   1540:        sc->sc_rxmap_spare = map;
                   1541:
                   1542:        d->sd_loaded = 1;
                   1543:
                   1544:        bus_dmamap_sync(sc->sc_dmatag, d->sd_map, 0, d->sd_map->dm_mapsize,
                   1545:            BUS_DMASYNC_PREREAD);
                   1546:
                   1547:        m->m_data += HME_RX_OFFSET;
                   1548:        d->sd_mbuf = m;
                   1549:        return (0);
                   1550: }

CVSweb