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

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

1.1     ! nbrk        1: /*     $OpenBSD: elink3.c,v 1.69 2007/01/19 01:33:44 krw Exp $ */
        !             2: /*     $NetBSD: elink3.c,v 1.32 1997/05/14 00:22:00 thorpej Exp $      */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1996, 1997 Jonathan Stone <jonathan@NetBSD.org>
        !             6:  * Copyright (c) 1994 Herb Peyerl <hpeyerl@beer.org>
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *      This product includes software developed by Herb Peyerl.
        !            20:  * 4. The name of Herb Peyerl may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: #include "bpfilter.h"
        !            36:
        !            37: #include <sys/param.h>
        !            38: #include <sys/systm.h>
        !            39: #include <sys/mbuf.h>
        !            40: #include <sys/socket.h>
        !            41: #include <sys/ioctl.h>
        !            42: #include <sys/errno.h>
        !            43: #include <sys/syslog.h>
        !            44: #include <sys/selinfo.h>
        !            45: #include <sys/timeout.h>
        !            46: #include <sys/device.h>
        !            47:
        !            48: #include <net/if.h>
        !            49: #include <net/if_dl.h>
        !            50: #include <net/if_types.h>
        !            51: #include <net/netisr.h>
        !            52: #include <net/if_media.h>
        !            53:
        !            54: #ifdef INET
        !            55: #include <netinet/in.h>
        !            56: #include <netinet/in_systm.h>
        !            57: #include <netinet/in_var.h>
        !            58: #include <netinet/ip.h>
        !            59: #include <netinet/if_ether.h>
        !            60: #endif
        !            61:
        !            62: #if NBPFILTER > 0
        !            63: #include <net/bpf.h>
        !            64: #endif
        !            65:
        !            66: #include <machine/cpu.h>
        !            67: #include <machine/bus.h>
        !            68:
        !            69: #include <dev/mii/mii.h>
        !            70: #include <dev/mii/miivar.h>
        !            71:
        !            72: #include <dev/ic/elink3var.h>
        !            73: #include <dev/ic/elink3reg.h>
        !            74:
        !            75: /*
        !            76:  * Structure to map media-present bits in boards to
        !            77:  * ifmedia codes and printable media names. Used for table-driven
        !            78:  * ifmedia initialization.
        !            79:  */
        !            80: struct ep_media {
        !            81:        int     epm_eeprom_data;        /* bitmask for eeprom config */
        !            82:        int     epm_conn;               /* sc->ep_connectors code for medium */
        !            83:        char   *epm_name;               /* name of medium */
        !            84:        int     epm_ifmedia;            /* ifmedia word for medium */
        !            85:        int     epm_ifdata;
        !            86: };
        !            87:
        !            88: /*
        !            89:  * ep_media table for Vortex/Demon/Boomerang:
        !            90:  * map from media-present bits in register RESET_OPTIONS+2
        !            91:  * to  ifmedia "media words" and printable names.
        !            92:  *
        !            93:  * XXX indexed directly by INTERNAL_CONFIG default_media field,
        !            94:  * (i.e., EPMEDIA_ constants)  forcing order of entries.
        !            95:  *  Note that 3 is reserved.
        !            96:  */
        !            97: const struct ep_media ep_vortex_media[8] = {
        !            98:   { EP_PCI_UTP,        EPC_UTP, "utp",     IFM_ETHER|IFM_10_T,
        !            99:        EPMEDIA_10BASE_T },
        !           100:   { EP_PCI_AUI,        EPC_AUI, "aui",     IFM_ETHER|IFM_10_5,
        !           101:        EPMEDIA_AUI },
        !           102:   { 0,                 0,      "reserved", IFM_NONE,  EPMEDIA_RESV1 },
        !           103:   { EP_PCI_BNC,        EPC_BNC, "bnc",     IFM_ETHER|IFM_10_2,
        !           104:        EPMEDIA_10BASE_2 },
        !           105:   { EP_PCI_100BASE_TX, EPC_100TX, "100-TX", IFM_ETHER|IFM_100_TX,
        !           106:        EPMEDIA_100BASE_TX },
        !           107:   { EP_PCI_100BASE_FX, EPC_100FX, "100-FX", IFM_ETHER|IFM_100_FX,
        !           108:        EPMEDIA_100BASE_FX },
        !           109:   { EP_PCI_100BASE_MII,EPC_MII,   "mii",    IFM_ETHER|IFM_100_TX,
        !           110:        EPMEDIA_MII },
        !           111:   { EP_PCI_100BASE_T4, EPC_100T4, "100-T4", IFM_ETHER|IFM_100_T4,
        !           112:        EPMEDIA_100BASE_T4 }
        !           113: };
        !           114:
        !           115: /*
        !           116:  * ep_media table for 3c509/3c509b/3c579/3c589:
        !           117:  * map from media-present bits in register CNFG_CNTRL
        !           118:  * (window 0, offset ?) to  ifmedia "media words" and printable names.
        !           119:  */
        !           120: struct ep_media ep_isa_media[3] = {
        !           121:   { EP_W0_CC_UTP,  EPC_UTP, "utp",   IFM_ETHER|IFM_10_T, EPMEDIA_10BASE_T },
        !           122:   { EP_W0_CC_AUI,  EPC_AUI, "aui",   IFM_ETHER|IFM_10_5, EPMEDIA_AUI },
        !           123:   { EP_W0_CC_BNC,  EPC_BNC, "bnc",   IFM_ETHER|IFM_10_2, EPMEDIA_10BASE_2 },
        !           124: };
        !           125:
        !           126: /* Map vortex reset_options bits to if_media codes. */
        !           127: const u_int ep_default_to_media[8] = {
        !           128:        IFM_ETHER | IFM_10_T,
        !           129:        IFM_ETHER | IFM_10_5,
        !           130:        0,                      /* reserved by 3Com */
        !           131:        IFM_ETHER | IFM_10_2,
        !           132:        IFM_ETHER | IFM_100_TX,
        !           133:        IFM_ETHER | IFM_100_FX,
        !           134:        IFM_ETHER | IFM_100_TX, /* XXX really MII: need to talk to PHY */
        !           135:        IFM_ETHER | IFM_100_T4,
        !           136: };
        !           137:
        !           138: struct cfdriver ep_cd = {
        !           139:        NULL, "ep", DV_IFNET
        !           140: };
        !           141:
        !           142: void ep_vortex_probemedia(struct ep_softc *sc);
        !           143: void ep_isa_probemedia(struct ep_softc *sc);
        !           144:
        !           145: void eptxstat(struct ep_softc *);
        !           146: int epstatus(struct ep_softc *);
        !           147: int epioctl(struct ifnet *, u_long, caddr_t);
        !           148: void epstart(struct ifnet *);
        !           149: void epwatchdog(struct ifnet *);
        !           150: void epreset(struct ep_softc *);
        !           151: void epread(struct ep_softc *);
        !           152: struct mbuf *epget(struct ep_softc *, int);
        !           153: void epmbuffill(void *);
        !           154: void epmbufempty(struct ep_softc *);
        !           155: void epsetfilter(struct ep_softc *);
        !           156: void ep_roadrunner_mii_enable(struct ep_softc *);
        !           157: int epsetmedia(struct ep_softc *, int);
        !           158:
        !           159: /* ifmedia callbacks */
        !           160: int ep_media_change(struct ifnet *);
        !           161: void ep_media_status(struct ifnet *, struct ifmediareq *);
        !           162:
        !           163: /* MII callbacks */
        !           164: int ep_mii_readreg(struct device *, int, int);
        !           165: void ep_mii_writereg(struct device *, int, int, int);
        !           166: void ep_statchg(struct device *);
        !           167:
        !           168: void    ep_mii_setbit(struct ep_softc *, u_int16_t);
        !           169: void    ep_mii_clrbit(struct ep_softc *, u_int16_t);
        !           170: u_int16_t ep_mii_readbit(struct ep_softc *, u_int16_t);
        !           171: void    ep_mii_sync(struct ep_softc *);
        !           172: void    ep_mii_sendbits(struct ep_softc *, u_int32_t, int);
        !           173:
        !           174: int epbusyeeprom(struct ep_softc *);
        !           175: u_int16_t ep_read_eeprom(struct ep_softc *, u_int16_t);
        !           176:
        !           177: static inline void ep_reset_cmd(struct ep_softc *sc, u_int cmd,u_int arg);
        !           178: static inline void ep_finish_reset(bus_space_tag_t, bus_space_handle_t);
        !           179: static inline void ep_discard_rxtop(bus_space_tag_t, bus_space_handle_t);
        !           180: static __inline int ep_w1_reg(struct ep_softc *, int);
        !           181:
        !           182: /*
        !           183:  * Issue a (reset) command, and be sure it has completed.
        !           184:  * Used for global reset, TX_RESET, RX_RESET.
        !           185:  */
        !           186: static inline void
        !           187: ep_reset_cmd(sc, cmd, arg)
        !           188:        struct ep_softc *sc;
        !           189:        u_int cmd, arg;
        !           190: {
        !           191:        bus_space_tag_t iot = sc->sc_iot;
        !           192:        bus_space_handle_t ioh = sc->sc_ioh;
        !           193:
        !           194:        bus_space_write_2(iot, ioh, cmd, arg);
        !           195:        ep_finish_reset(iot, ioh);
        !           196: }
        !           197:
        !           198: /*
        !           199:  * Wait for any pending reset to complete.
        !           200:  */
        !           201: static inline void
        !           202: ep_finish_reset(iot, ioh)
        !           203:        bus_space_tag_t iot;
        !           204:        bus_space_handle_t ioh;
        !           205: {
        !           206:        int i;
        !           207:
        !           208:        for (i = 0; i < 10000; i++) {
        !           209:                if ((bus_space_read_2(iot, ioh, EP_STATUS) &
        !           210:                    S_COMMAND_IN_PROGRESS) == 0)
        !           211:                        break;
        !           212:                DELAY(10);
        !           213:        }
        !           214: }
        !           215:
        !           216: static inline void
        !           217: ep_discard_rxtop(iot, ioh)
        !           218:        bus_space_tag_t iot;
        !           219:        bus_space_handle_t ioh;
        !           220: {
        !           221:        int i;
        !           222:
        !           223:        bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISCARD_TOP_PACK);
        !           224:
        !           225:        /*
        !           226:         * Spin for about 1 msec, to avoid forcing a DELAY() between
        !           227:         * every received packet (adding latency and limiting pkt-recv rate).
        !           228:         * On PCI, at 4 30-nsec PCI bus cycles for a read, 8000 iterations
        !           229:         * is about right.
        !           230:         */
        !           231:        for (i = 0; i < 8000; i++) {
        !           232:                if ((bus_space_read_2(iot, ioh, EP_STATUS) &
        !           233:                    S_COMMAND_IN_PROGRESS) == 0)
        !           234:                        return;
        !           235:        }
        !           236:
        !           237:        /* not fast enough, do DELAY()s */
        !           238:        ep_finish_reset(iot, ioh);
        !           239: }
        !           240:
        !           241: /*
        !           242:  * Some chips (i.e., 3c574 RoadRunner) have Window 1 registers offset.
        !           243:  */
        !           244: static __inline int
        !           245: ep_w1_reg(sc, reg)
        !           246:        struct ep_softc *sc;
        !           247:        int reg;
        !           248: {
        !           249:        switch (sc->ep_chipset) {
        !           250:        case EP_CHIPSET_ROADRUNNER:
        !           251:                switch (reg) {
        !           252:                case EP_W1_FREE_TX:
        !           253:                case EP_W1_RUNNER_RDCTL:
        !           254:                case EP_W1_RUNNER_WRCTL:
        !           255:                        return (reg);
        !           256:                }
        !           257:                return (reg + 0x10);
        !           258:        }
        !           259:        return (reg);
        !           260: }
        !           261:
        !           262: /*
        !           263:  * Back-end attach and configure.
        !           264:  */
        !           265: void
        !           266: epconfig(sc, chipset, enaddr)
        !           267:        struct ep_softc *sc;
        !           268:        u_short chipset;
        !           269:        u_int8_t *enaddr;
        !           270: {
        !           271:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           272:        bus_space_tag_t iot = sc->sc_iot;
        !           273:        bus_space_handle_t ioh = sc->sc_ioh;
        !           274:        u_int16_t i;
        !           275:
        !           276:        sc->ep_chipset = chipset;
        !           277:
        !           278:        /*
        !           279:         * We could have been groveling around in other register
        !           280:         * windows in the front-end; make sure we're in window 0
        !           281:         * to read the EEPROM.
        !           282:         */
        !           283:        GO_WINDOW(0);
        !           284:
        !           285:        if (enaddr == NULL) {
        !           286:                /*
        !           287:                 * Read the station address from the eeprom.
        !           288:                 */
        !           289:                for (i = 0; i < 3; i++) {
        !           290:                        u_int16_t x = ep_read_eeprom(sc, i);
        !           291:
        !           292:                        sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8;
        !           293:                        sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x;
        !           294:                }
        !           295:        } else {
        !           296:                bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
        !           297:        }
        !           298:
        !           299:        printf(" address %s", ether_sprintf(sc->sc_arpcom.ac_enaddr));
        !           300:        if (sc->ep_flags & EP_FLAGS_MII)
        !           301:                printf("\n");
        !           302:        else
        !           303:                printf(", ");
        !           304:
        !           305:        /*
        !           306:         * Vortex-based (3c59x pci,eisa) cards allow FDDI-sized (4500) byte
        !           307:         * packets.  Commands only take an 11-bit parameter, and  11 bits
        !           308:         * isn't enough to hold a full-size packet length.
        !           309:         * Commands to these cards implicitly upshift a packet size
        !           310:         * or threshold by 2 bits.
        !           311:         * To detect  cards with large-packet support, we probe by setting
        !           312:         * the transmit threshold register, then change windows and
        !           313:         * read back the threshold register directly, and see if the
        !           314:         * threshold value was shifted or not.
        !           315:         */
        !           316:        bus_space_write_2(iot, ioh, EP_COMMAND,
        !           317:                          SET_TX_AVAIL_THRESH | EP_LARGEWIN_PROBE );
        !           318:        GO_WINDOW(5);
        !           319:        i = bus_space_read_2(iot, ioh, EP_W5_TX_AVAIL_THRESH);
        !           320:        GO_WINDOW(1);
        !           321:        switch (i)  {
        !           322:        case EP_LARGEWIN_PROBE:
        !           323:        case (EP_LARGEWIN_PROBE & EP_LARGEWIN_MASK):
        !           324:                sc->txashift = 0;
        !           325:                break;
        !           326:
        !           327:        case (EP_LARGEWIN_PROBE << 2):
        !           328:                sc->txashift = 2;
        !           329:                /* XXX does the 3c515 support Vortex-style RESET_OPTIONS? */
        !           330:                break;
        !           331:
        !           332:        default:
        !           333:                printf("wrote %x to TX_AVAIL_THRESH, read back %x. "
        !           334:                    "Interface disabled\n", EP_THRESH_DISABLE, (int) i);
        !           335:                return;
        !           336:        }
        !           337:
        !           338:        timeout_set(&sc->sc_epmbuffill_tmo, epmbuffill, sc);
        !           339:
        !           340:        /*
        !           341:         * Ensure Tx-available interrupts are enabled for
        !           342:         * start the interface.
        !           343:         * XXX should be in epinit()?
        !           344:         */
        !           345:        bus_space_write_2(iot, ioh, EP_COMMAND,
        !           346:            SET_TX_AVAIL_THRESH | (1600 >> sc->txashift));
        !           347:
        !           348:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
        !           349:        ifp->if_softc = sc;
        !           350:        ifp->if_start = epstart;
        !           351:        ifp->if_ioctl = epioctl;
        !           352:        ifp->if_watchdog = epwatchdog;
        !           353:        ifp->if_flags =
        !           354:            IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
        !           355:        IFQ_SET_READY(&ifp->if_snd);
        !           356:
        !           357:        if_attach(ifp);
        !           358:        ether_ifattach(ifp);
        !           359:
        !           360:        /*
        !           361:         * Finish configuration:
        !           362:         * determine chipset if the front-end couldn't do so,
        !           363:         * show board details, set media.
        !           364:         */
        !           365:
        !           366:        GO_WINDOW(0);
        !           367:
        !           368:        ifmedia_init(&sc->sc_mii.mii_media, 0, ep_media_change,
        !           369:            ep_media_status);
        !           370:        sc->sc_mii.mii_ifp = ifp;
        !           371:        sc->sc_mii.mii_readreg = ep_mii_readreg;
        !           372:        sc->sc_mii.mii_writereg = ep_mii_writereg;
        !           373:        sc->sc_mii.mii_statchg = ep_statchg;
        !           374:
        !           375:        /*
        !           376:         * If we've got an indirect (ISA, PCMCIA?) board, the chipset
        !           377:         * is unknown.  If the board has large-packet support, it's a
        !           378:         * Vortex/Boomerang, otherwise it's a 3c509.
        !           379:         * XXX use eeprom capability word instead?
        !           380:         */
        !           381:        if (sc->ep_chipset == EP_CHIPSET_UNKNOWN && sc->txashift)  {
        !           382:                printf("warning: unknown chipset, possibly 3c515?\n");
        !           383: #ifdef notyet
        !           384:                sc->sc_chipset = EP_CHIPSET_VORTEX;
        !           385: #endif /* notyet */
        !           386:        }
        !           387:
        !           388:        /*
        !           389:         * Ascertain which media types are present and inform ifmedia.
        !           390:         */
        !           391:        switch (sc->ep_chipset) {
        !           392:        case EP_CHIPSET_ROADRUNNER:
        !           393:                if (sc->ep_flags & EP_FLAGS_MII) {
        !           394:                        ep_roadrunner_mii_enable(sc);
        !           395:                        GO_WINDOW(0);
        !           396:                }
        !           397:                /* FALLTHROUGH */
        !           398:
        !           399:        case EP_CHIPSET_BOOMERANG:
        !           400:                /*
        !           401:                 * If the device has MII, probe it.  We won't be using
        !           402:                 * any `native' media in this case, only PHYs.  If
        !           403:                 * we don't, just treat the Boomerang like the Vortex.
        !           404:                 */
        !           405:                if (sc->ep_flags & EP_FLAGS_MII) {
        !           406:                        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff,
        !           407:                            MII_PHY_ANY, MII_OFFSET_ANY, 0);
        !           408:                        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
        !           409:                                ifmedia_add(&sc->sc_mii.mii_media,
        !           410:                                    IFM_ETHER|IFM_NONE, 0, NULL);
        !           411:                                ifmedia_set(&sc->sc_mii.mii_media,
        !           412:                                    IFM_ETHER|IFM_NONE);
        !           413:                        } else {
        !           414:                                ifmedia_set(&sc->sc_mii.mii_media,
        !           415:                                    IFM_ETHER|IFM_AUTO);
        !           416:                        }
        !           417:                        break;
        !           418:                }
        !           419:                /* FALLTHROUGH */
        !           420:
        !           421:        /* on a direct bus, the attach routine can tell, but check anyway. */
        !           422:        case EP_CHIPSET_VORTEX:
        !           423:        case EP_CHIPSET_BOOMERANG2:
        !           424:                ep_vortex_probemedia(sc);
        !           425:                break;
        !           426:
        !           427:        /* on ISA we can't yet tell 3c509 from 3c515. Assume the former. */
        !           428:        case EP_CHIPSET_3C509:
        !           429:        default:
        !           430:                ep_isa_probemedia(sc);
        !           431:                break;
        !           432:        }
        !           433:
        !           434:        GO_WINDOW(1);           /* Window 1 is operating window */
        !           435:
        !           436:        sc->tx_start_thresh = 20;       /* probably a good starting point. */
        !           437:
        !           438:        ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
        !           439:        ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
        !           440: }
        !           441:
        !           442: int
        !           443: ep_detach(self)
        !           444:        struct device *self;
        !           445: {
        !           446:        struct ep_softc *sc = (struct ep_softc *)self;
        !           447:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           448:
        !           449:        if (sc->ep_flags & EP_FLAGS_MII)
        !           450:                mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
        !           451:
        !           452:        ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
        !           453:
        !           454:        ether_ifdetach(ifp);
        !           455:        if_detach(ifp);
        !           456:
        !           457:        return (0);
        !           458: }
        !           459:
        !           460: /*
        !           461:  * Find supported media on 3c509-generation hardware that doesn't have
        !           462:  * a "reset_options" register in window 3.
        !           463:  * Use the config_cntrl register  in window 0 instead.
        !           464:  * Used on original, 10Mbit ISA (3c509), 3c509B, and pre-Demon EISA cards
        !           465:  * that implement  CONFIG_CTRL.  We don't have a good way to set the
        !           466:  * default active medium; punt to ifconfig instead.
        !           467:  *
        !           468:  * XXX what about 3c515, pcmcia 10/100?
        !           469:  */
        !           470: void
        !           471: ep_isa_probemedia(sc)
        !           472:        struct ep_softc *sc;
        !           473: {
        !           474:        bus_space_tag_t iot = sc->sc_iot;
        !           475:        bus_space_handle_t ioh = sc->sc_ioh;
        !           476:        struct ifmedia *ifm = &sc->sc_mii.mii_media;
        !           477:        int     conn, i;
        !           478:        u_int16_t ep_w0_config, port;
        !           479:
        !           480:        conn = 0;
        !           481:        GO_WINDOW(0);
        !           482:        ep_w0_config = bus_space_read_2(iot, ioh, EP_W0_CONFIG_CTRL);
        !           483:        for (i = 0; i < 3; i++) {
        !           484:                struct ep_media * epm = ep_isa_media + i;
        !           485:
        !           486:                if ((ep_w0_config & epm->epm_eeprom_data) != 0) {
        !           487:                        ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
        !           488:                        if (conn)
        !           489:                                printf("/");
        !           490:                        printf("%s", epm->epm_name);
        !           491:                        conn |= epm->epm_conn;
        !           492:                }
        !           493:        }
        !           494:        sc->ep_connectors = conn;
        !           495:
        !           496:        /* get default medium from EEPROM */
        !           497:        if (epbusyeeprom(sc))
        !           498:                return;         /* XXX why is eeprom busy? */
        !           499:        bus_space_write_2(iot, ioh, EP_W0_EEPROM_COMMAND,
        !           500:            READ_EEPROM | EEPROM_ADDR_CFG);
        !           501:        if (epbusyeeprom(sc))
        !           502:                return;         /* XXX why is  eeprom busy? */
        !           503:        port = bus_space_read_2(iot, ioh, EP_W0_EEPROM_DATA);
        !           504:        port = port >> 14;
        !           505:
        !           506:        printf(" (default %s)\n", ep_vortex_media[port].epm_name);
        !           507:
        !           508:        /* tell ifconfig what currently-active media is. */
        !           509:        ifmedia_set(ifm, ep_default_to_media[port]);
        !           510:
        !           511:        /* XXX autoselect not yet implemented */
        !           512: }
        !           513:
        !           514:
        !           515: /*
        !           516:  * Find media present on large-packet-capable elink3 devices.
        !           517:  * Show onboard configuration of large-packet-capable elink3 devices
        !           518:  * (Demon, Vortex, Boomerang), which do not implement CONFIG_CTRL in window 0.
        !           519:  * Use media and card-version info in window 3 instead.
        !           520:  *
        !           521:  * XXX how much of this works with 3c515, pcmcia 10/100?
        !           522:  */
        !           523: void
        !           524: ep_vortex_probemedia(sc)
        !           525:        struct ep_softc *sc;
        !           526: {
        !           527:        bus_space_tag_t iot = sc->sc_iot;
        !           528:        bus_space_handle_t ioh = sc->sc_ioh;
        !           529:        struct ifmedia *ifm = &sc->sc_mii.mii_media;
        !           530:        u_int config1, conn;
        !           531:        int reset_options;
        !           532:        int default_media;      /* 3-bit encoding of default (EEPROM) media */
        !           533:        int autoselect;         /* boolean: should default to autoselect */
        !           534:        const char *medium_name;
        !           535:        register int i;
        !           536:
        !           537:        GO_WINDOW(3);
        !           538:        config1 = (u_int)bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2);
        !           539:        reset_options  = (int)bus_space_read_1(iot, ioh, EP_W3_RESET_OPTIONS);
        !           540:        GO_WINDOW(0);
        !           541:
        !           542:        default_media = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
        !           543:         autoselect = (config1 & CONFIG_AUTOSELECT) >> CONFIG_AUTOSELECT_SHIFT;
        !           544:
        !           545:        /* set available media options */
        !           546:        conn = 0;
        !           547:        for (i = 0; i < 8; i++) {
        !           548:                const struct ep_media *epm = ep_vortex_media + i;
        !           549:
        !           550:                if ((reset_options & epm->epm_eeprom_data) != 0) {
        !           551:                        if (conn)
        !           552:                                printf("/");
        !           553:                        printf("%s", epm->epm_name);
        !           554:                        conn |= epm->epm_conn;
        !           555:                        ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
        !           556:                }
        !           557:        }
        !           558:
        !           559:        sc->ep_connectors = conn;
        !           560:
        !           561:        /* Show  eeprom's idea of default media.  */
        !           562:        medium_name = (default_media > 8)
        !           563:                ? "(unknown/impossible media)"
        !           564:                : ep_vortex_media[default_media].epm_name;
        !           565:        printf(" default %s%s",
        !           566:               medium_name, (autoselect) ? "/autoselect" : "");
        !           567: /*     sc->sc_media = ep_vortex_media[default_media].epm_ifdata;*/
        !           568:
        !           569: #ifdef notyet
        !           570:        /*
        !           571:         * Set default: either the active interface the card
        !           572:         * reads  from the EEPROM, or if autoselect is true,
        !           573:         * whatever we find is actually connected.
        !           574:         *
        !           575:         * XXX autoselect not yet implemented.
        !           576:         */
        !           577: #endif /* notyet */
        !           578:
        !           579:        /* tell ifconfig what currently-active media is. */
        !           580:        ifmedia_set(ifm, ep_default_to_media[default_media]);
        !           581: }
        !           582:
        !           583: /*
        !           584:  * Bring device up.
        !           585:  *
        !           586:  * The order in here seems important. Otherwise we may not receive
        !           587:  * interrupts. ?!
        !           588:  */
        !           589: void
        !           590: epinit(sc)
        !           591:        register struct ep_softc *sc;
        !           592: {
        !           593:        register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           594:        bus_space_tag_t iot = sc->sc_iot;
        !           595:        bus_space_handle_t ioh = sc->sc_ioh;
        !           596:        int i;
        !           597:
        !           598:        /* make sure any pending reset has completed before touching board */
        !           599:        ep_finish_reset(iot, ioh);
        !           600:
        !           601:        /* cancel any pending I/O */
        !           602:        epstop(sc);
        !           603:
        !           604:        if (sc->bustype != EP_BUS_PCI) {
        !           605:                GO_WINDOW(0);
        !           606:                bus_space_write_2(iot, ioh, EP_W0_CONFIG_CTRL, 0);
        !           607:                bus_space_write_2(iot, ioh, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
        !           608:        }
        !           609:
        !           610:        if (sc->bustype == EP_BUS_PCMCIA) {
        !           611:                bus_space_write_2(iot, ioh, EP_W0_RESOURCE_CFG, 0x3f00);
        !           612:        }
        !           613:
        !           614:        GO_WINDOW(2);
        !           615:        for (i = 0; i < 6; i++) /* Reload the ether_addr. */
        !           616:                bus_space_write_1(iot, ioh, EP_W2_ADDR_0 + i,
        !           617:                    sc->sc_arpcom.ac_enaddr[i]);
        !           618:
        !           619:        if (sc->bustype == EP_BUS_PCI || sc->bustype == EP_BUS_EISA)
        !           620:                /*
        !           621:                 * Reset the station-address receive filter.
        !           622:                 * A bug workaround for busmastering  (Vortex, Demon) cards.
        !           623:                 */
        !           624:                for (i = 0; i < 6; i++)
        !           625:                        bus_space_write_1(iot, ioh, EP_W2_RECVMASK_0 + i, 0);
        !           626:
        !           627:        ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
        !           628:        ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
        !           629:
        !           630:        GO_WINDOW(1);           /* Window 1 is operating window */
        !           631:        for (i = 0; i < 31; i++)
        !           632:                bus_space_read_1(iot, ioh, ep_w1_reg(sc, EP_W1_TX_STATUS));
        !           633:
        !           634:        /* Set threshold for for Tx-space available interrupt. */
        !           635:        bus_space_write_2(iot, ioh, EP_COMMAND,
        !           636:            SET_TX_AVAIL_THRESH | (1600 >> sc->txashift));
        !           637:
        !           638:        if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
        !           639:                /* Enable options in the PCMCIA LAN COR register, via
        !           640:                 * RoadRunner Window 1.
        !           641:                 *
        !           642:                 * XXX MAGIC CONSTANTS!
        !           643:                 */
        !           644:                u_int16_t cor;
        !           645:
        !           646:                bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, (1 << 11));
        !           647:
        !           648:                cor = bus_space_read_2(iot, ioh, 0) & ~0x30;
        !           649:                bus_space_write_2(iot, ioh, 0, cor);
        !           650:
        !           651:                bus_space_write_2(iot, ioh, EP_W1_RUNNER_WRCTL, 0);
        !           652:                bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, 0);
        !           653:
        !           654:                if (sc->ep_flags & EP_FLAGS_MII) {
        !           655:                        ep_roadrunner_mii_enable(sc);
        !           656:                        GO_WINDOW(1);
        !           657:                }
        !           658:        }
        !           659:
        !           660:        /* Enable interrupts. */
        !           661:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK |
        !           662:            S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
        !           663:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK |
        !           664:            S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
        !           665:
        !           666:        /*
        !           667:         * Attempt to get rid of any stray interrupts that occurred during
        !           668:         * configuration.  On the i386 this isn't possible because one may
        !           669:         * already be queued.  However, a single stray interrupt is
        !           670:         * unimportant.
        !           671:         */
        !           672:        bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | 0xff);
        !           673:
        !           674:        epsetfilter(sc);
        !           675:        epsetmedia(sc, sc->sc_mii.mii_media.ifm_cur->ifm_data);
        !           676:
        !           677:        bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE);
        !           678:        bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
        !           679:
        !           680:        epmbuffill(sc);
        !           681:
        !           682:        /* Interface is now `running', with no output active. */
        !           683:        ifp->if_flags |= IFF_RUNNING;
        !           684:        ifp->if_flags &= ~IFF_OACTIVE;
        !           685:
        !           686:        /* Attempt to start output, if any. */
        !           687:        epstart(ifp);
        !           688: }
        !           689:
        !           690: /*
        !           691:  * Set multicast receive filter.
        !           692:  * elink3 hardware has no selective multicast filter in hardware.
        !           693:  * Enable reception of all multicasts and filter in software.
        !           694:  */
        !           695: void
        !           696: epsetfilter(sc)
        !           697:        register struct ep_softc *sc;
        !           698: {
        !           699:        register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !           700:
        !           701:        GO_WINDOW(1);           /* Window 1 is operating window */
        !           702:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_COMMAND, SET_RX_FILTER |
        !           703:            FIL_INDIVIDUAL | FIL_BRDCST |
        !           704:            ((ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0 ) |
        !           705:            ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0 ));
        !           706: }
        !           707:
        !           708:
        !           709: int
        !           710: ep_media_change(ifp)
        !           711:        struct ifnet *ifp;
        !           712: {
        !           713:        register struct ep_softc *sc = ifp->if_softc;
        !           714:
        !           715:        return  epsetmedia(sc, sc->sc_mii.mii_media.ifm_cur->ifm_data);
        !           716: }
        !           717:
        !           718: /*
        !           719:  * Reset and enable the MII on the RoadRunner.
        !           720:  */
        !           721: void
        !           722: ep_roadrunner_mii_enable(sc)
        !           723:        struct ep_softc *sc;
        !           724: {
        !           725:        bus_space_tag_t iot = sc->sc_iot;
        !           726:        bus_space_handle_t ioh = sc->sc_ioh;
        !           727:
        !           728:        GO_WINDOW(3);
        !           729:        bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
        !           730:            EP_PCI_100BASE_MII|EP_RUNNER_ENABLE_MII);
        !           731:        delay(1000);
        !           732:        bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
        !           733:            EP_PCI_100BASE_MII|EP_RUNNER_MII_RESET|EP_RUNNER_ENABLE_MII);
        !           734:        ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
        !           735:        ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
        !           736:        delay(1000);
        !           737:        bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
        !           738:            EP_PCI_100BASE_MII|EP_RUNNER_ENABLE_MII);
        !           739: }
        !           740:
        !           741: /*
        !           742:  * Set active media to a specific given EPMEDIA_<> value.
        !           743:  * For vortex/demon/boomerang cards, update media field in w3_internal_config,
        !           744:  *       and power on selected transceiver.
        !           745:  * For 3c509-generation cards (3c509/3c579/3c589/3c509B),
        !           746:  *     update media field in w0_address_config, and power on selected xcvr.
        !           747:  */
        !           748: int
        !           749: epsetmedia(sc, medium)
        !           750:        struct ep_softc *sc;
        !           751:        int medium;
        !           752: {
        !           753:        bus_space_tag_t iot = sc->sc_iot;
        !           754:        bus_space_handle_t ioh = sc->sc_ioh;
        !           755:        int w4_media;
        !           756:        int config0, config1;
        !           757:
        !           758:        /*
        !           759:         * you can `ifconfig (link0|-link0) ep0' to get the following
        !           760:         * behaviour:
        !           761:         *      -link0  disable AUI/UTP. enable BNC.
        !           762:         *      link0   disable BNC. enable AUI.
        !           763:         *      link1   if the card has a UTP connector, and link0 is
        !           764:         *              set too, then you get the UTP port.
        !           765:         */
        !           766:
        !           767:        /*
        !           768:         * First, change the media-control bits in EP_W4_MEDIA_TYPE.
        !           769:         */
        !           770:
        !           771:         /* Turn everything off.  First turn off linkbeat and UTP. */
        !           772:        GO_WINDOW(4);
        !           773:        w4_media = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
        !           774:        w4_media =  w4_media & ~(ENABLE_UTP|SQE_ENABLE);
        !           775:        bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, w4_media);
        !           776:
        !           777:        /* Turn off coax */
        !           778:        bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
        !           779:        delay(1000);
        !           780:
        !           781:        /* If the device has MII, select it, and then tell the
        !           782:         * PHY which media to use.
        !           783:         */
        !           784:        if (sc->ep_flags & EP_FLAGS_MII) {
        !           785:                int config0, config1;
        !           786:
        !           787:                GO_WINDOW(3);
        !           788:
        !           789:                if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
        !           790:                        int resopt;
        !           791:
        !           792:                        resopt = bus_space_read_2(iot, ioh,
        !           793:                            EP_W3_RESET_OPTIONS);
        !           794:                        bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
        !           795:                            resopt | EP_RUNNER_ENABLE_MII);
        !           796:                }
        !           797:
        !           798:                config0 = (u_int)bus_space_read_2(iot, ioh,
        !           799:                    EP_W3_INTERNAL_CONFIG);
        !           800:                config1 = (u_int)bus_space_read_2(iot, ioh,
        !           801:                    EP_W3_INTERNAL_CONFIG + 2);
        !           802:
        !           803:                config1 = config1 & ~CONFIG_MEDIAMASK;
        !           804:                config1 |= (EPMEDIA_MII << CONFIG_MEDIAMASK_SHIFT);
        !           805:
        !           806:                bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG, config0);
        !           807:                bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2, config1);
        !           808:                GO_WINDOW(1);   /* back to operating window */
        !           809:
        !           810:                mii_mediachg(&sc->sc_mii);
        !           811:                return (0);
        !           812:        }
        !           813:
        !           814:        /*
        !           815:         * Now turn on the selected media/transceiver.
        !           816:         */
        !           817:        GO_WINDOW(4);
        !           818:        switch (medium) {
        !           819:        case EPMEDIA_10BASE_T:
        !           820:                bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, (ENABLE_UTP |
        !           821:                    (sc->bustype == EP_BUS_PCMCIA ? MEDIA_LED : 0)));
        !           822:                break;
        !           823:
        !           824:        case EPMEDIA_10BASE_2:
        !           825:                bus_space_write_2(iot, ioh, EP_COMMAND, START_TRANSCEIVER);
        !           826:                DELAY(1000);    /* 50ms not enough? */
        !           827:                break;
        !           828:
        !           829:        /* XXX following only for new-generation cards */
        !           830:        case EPMEDIA_100BASE_TX:
        !           831:        case EPMEDIA_100BASE_FX:
        !           832:        case EPMEDIA_100BASE_T4:        /* XXX check documentation */
        !           833:                bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
        !           834:                    w4_media | LINKBEAT_ENABLE);
        !           835:                DELAY(1000);    /* not strictly necessary? */
        !           836:                break;
        !           837:
        !           838:        case EPMEDIA_AUI:
        !           839:                bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
        !           840:                    w4_media | SQE_ENABLE);
        !           841:                DELAY(1000);    /*  not strictly necessary? */
        !           842:                break;
        !           843:        case EPMEDIA_MII:
        !           844:                break;
        !           845:        default:
        !           846: #if defined(EP_DEBUG)
        !           847:                printf("%s unknown media 0x%x\n", sc->sc_dev.dv_xname, medium);
        !           848: #endif
        !           849:                break;
        !           850:
        !           851:        }
        !           852:
        !           853:        /*
        !           854:         * Tell the chip which PHY [sic] to use.
        !           855:         */
        !           856:        switch (sc->ep_chipset) {
        !           857:        case EP_CHIPSET_VORTEX:
        !           858:        case EP_CHIPSET_BOOMERANG2:
        !           859:                GO_WINDOW(3);
        !           860:                config0 = (u_int)bus_space_read_2(iot, ioh,
        !           861:                    EP_W3_INTERNAL_CONFIG);
        !           862:                config1 = (u_int)bus_space_read_2(iot, ioh,
        !           863:                    EP_W3_INTERNAL_CONFIG + 2);
        !           864:
        !           865: #if defined(EP_DEBUG)
        !           866:                printf("%s:  read 0x%x, 0x%x from EP_W3_CONFIG register\n",
        !           867:                       sc->sc_dev.dv_xname, config0, config1);
        !           868: #endif
        !           869:                config1 = config1 & ~CONFIG_MEDIAMASK;
        !           870:                config1 |= (medium << CONFIG_MEDIAMASK_SHIFT);
        !           871:
        !           872: #if defined(EP_DEBUG)
        !           873:                printf("epsetmedia: %s: medium 0x%x, 0x%x to EP_W3_CONFIG\n",
        !           874:                    sc->sc_dev.dv_xname, medium, config1);
        !           875: #endif
        !           876:                bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG, config0);
        !           877:                bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2, config1);
        !           878:                break;
        !           879:
        !           880:        default:
        !           881:                GO_WINDOW(0);
        !           882:                config0 = bus_space_read_2(iot, ioh, EP_W0_ADDRESS_CFG);
        !           883:                config0 &= 0x3fff;
        !           884:                bus_space_write_2(iot, ioh, EP_W0_ADDRESS_CFG,
        !           885:                    config0 | (medium << 14));
        !           886:                DELAY(1000);
        !           887:                break;
        !           888:        }
        !           889:
        !           890:        GO_WINDOW(1);           /* Window 1 is operating window */
        !           891:        return (0);
        !           892: }
        !           893:
        !           894:
        !           895: /*
        !           896:  * Get currently-selected media from card.
        !           897:  * (if_media callback, may be called before interface is brought up).
        !           898:  */
        !           899: void
        !           900: ep_media_status(ifp, req)
        !           901:        struct ifnet *ifp;
        !           902:        struct ifmediareq *req;
        !           903: {
        !           904:        register struct ep_softc *sc = ifp->if_softc;
        !           905:        bus_space_tag_t iot = sc->sc_iot;
        !           906:        bus_space_handle_t ioh = sc->sc_ioh;
        !           907:        u_int config1;
        !           908:        u_int ep_mediastatus;
        !           909:
        !           910:        /*
        !           911:         * If we have MII, go ask the PHY what's going on.
        !           912:         */
        !           913:        if (sc->ep_flags & EP_FLAGS_MII) {
        !           914:                mii_pollstat(&sc->sc_mii);
        !           915:                req->ifm_active = sc->sc_mii.mii_media_active;
        !           916:                req->ifm_status = sc->sc_mii.mii_media_status;
        !           917:                return;
        !           918:        }
        !           919:
        !           920:        /* XXX read from softc when we start autosensing media */
        !           921:        req->ifm_active = sc->sc_mii.mii_media.ifm_cur->ifm_media;
        !           922:
        !           923:        switch (sc->ep_chipset) {
        !           924:        case EP_CHIPSET_VORTEX:
        !           925:        case EP_CHIPSET_BOOMERANG:
        !           926:                GO_WINDOW(3);
        !           927:                delay(5000);
        !           928:
        !           929:                config1 = bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2);
        !           930:                GO_WINDOW(1);
        !           931:
        !           932:                config1 =
        !           933:                    (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
        !           934:                req->ifm_active = ep_default_to_media[config1];
        !           935:
        !           936:                /* XXX check full-duplex bits? */
        !           937:
        !           938:                GO_WINDOW(4);
        !           939:                req->ifm_status = IFM_AVALID;   /* XXX */
        !           940:                ep_mediastatus = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
        !           941:                if (ep_mediastatus & LINKBEAT_DETECT)
        !           942:                        req->ifm_status |= IFM_ACTIVE;  /* XXX  automedia */
        !           943:
        !           944:                break;
        !           945:
        !           946:        case EP_CHIPSET_UNKNOWN:
        !           947:        case EP_CHIPSET_3C509:
        !           948:                req->ifm_status = 0;    /* XXX */
        !           949:                break;
        !           950:
        !           951:        default:
        !           952:                printf("%s: media_status on unknown chipset 0x%x\n",
        !           953:                       ifp->if_xname, sc->ep_chipset);
        !           954:                break;
        !           955:        }
        !           956:
        !           957:        /* XXX look for softc heartbeat for other chips or media */
        !           958:
        !           959:        GO_WINDOW(1);
        !           960:        return;
        !           961: }
        !           962:
        !           963:
        !           964:
        !           965: /*
        !           966:  * Start outputting on the interface.
        !           967:  * Always called as splnet().
        !           968:  */
        !           969: void
        !           970: epstart(ifp)
        !           971:        struct ifnet *ifp;
        !           972: {
        !           973:        register struct ep_softc *sc = ifp->if_softc;
        !           974:        bus_space_tag_t iot = sc->sc_iot;
        !           975:        bus_space_handle_t ioh = sc->sc_ioh;
        !           976:        struct mbuf *m, *m0;
        !           977:        int sh, len, pad, txreg;
        !           978:
        !           979:        /* Don't transmit if interface is busy or not running */
        !           980:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
        !           981:                return;
        !           982:
        !           983: startagain:
        !           984:        /* Sneak a peek at the next packet */
        !           985:        IFQ_POLL(&ifp->if_snd, m0);
        !           986:        if (m0 == NULL)
        !           987:                return;
        !           988:
        !           989:        /* We need to use m->m_pkthdr.len, so require the header */
        !           990:        if ((m0->m_flags & M_PKTHDR) == 0)
        !           991:                panic("epstart: no header mbuf");
        !           992:        len = m0->m_pkthdr.len;
        !           993:
        !           994:        pad = (4 - len) & 3;
        !           995:
        !           996:        /*
        !           997:         * The 3c509 automatically pads short packets to minimum ethernet
        !           998:         * length, but we drop packets that are too large. Perhaps we should
        !           999:         * truncate them instead?
        !          1000:         */
        !          1001:        if (len + pad > ETHER_MAX_LEN) {
        !          1002:                /* packet is obviously too large: toss it */
        !          1003:                ++ifp->if_oerrors;
        !          1004:                IFQ_DEQUEUE(&ifp->if_snd, m0);
        !          1005:                m_freem(m0);
        !          1006:                goto readcheck;
        !          1007:        }
        !          1008:
        !          1009:        if (bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_FREE_TX)) <
        !          1010:            len + pad + 4) {
        !          1011:                bus_space_write_2(iot, ioh, EP_COMMAND,
        !          1012:                    SET_TX_AVAIL_THRESH | ((len + pad + 4) >> sc->txashift));
        !          1013:                /* not enough room in FIFO */
        !          1014:                ifp->if_flags |= IFF_OACTIVE;
        !          1015:                return;
        !          1016:        } else {
        !          1017:                bus_space_write_2(iot, ioh, EP_COMMAND,
        !          1018:                    SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
        !          1019:        }
        !          1020:
        !          1021:        IFQ_DEQUEUE(&ifp->if_snd, m0);
        !          1022:        if (m0 == NULL)
        !          1023:                return;
        !          1024:
        !          1025:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_TX_START_THRESH |
        !          1026:            ((len / 4 + sc->tx_start_thresh) /*>> sc->txashift*/));
        !          1027:
        !          1028: #if NBPFILTER > 0
        !          1029:        if (ifp->if_bpf)
        !          1030:                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
        !          1031: #endif
        !          1032:
        !          1033:        /*
        !          1034:         * Do the output at splhigh() so that an interrupt from another device
        !          1035:         * won't cause a FIFO underrun.
        !          1036:         */
        !          1037:        sh = splhigh();
        !          1038:
        !          1039:        txreg = ep_w1_reg(sc, EP_W1_TX_PIO_WR_1);
        !          1040:
        !          1041:        bus_space_write_2(iot, ioh, txreg, len);
        !          1042:        bus_space_write_2(iot, ioh, txreg, 0xffff); /* Second is meaningless */
        !          1043:        if (EP_IS_BUS_32(sc->bustype)) {
        !          1044:                for (m = m0; m; ) {
        !          1045:                        if (m->m_len > 3)
        !          1046:                                bus_space_write_raw_multi_4(iot, ioh, txreg,
        !          1047:                                    mtod(m, u_int8_t *), m->m_len & ~3);
        !          1048:                        if (m->m_len & 3)
        !          1049:                                bus_space_write_multi_1(iot, ioh, txreg,
        !          1050:                                    mtod(m, u_int8_t *) + (m->m_len & ~3),
        !          1051:                                    m->m_len & 3);
        !          1052:                        MFREE(m, m0);
        !          1053:                        m = m0;
        !          1054:                }
        !          1055:        } else {
        !          1056:                for (m = m0; m; ) {
        !          1057:                        if (m->m_len > 1)
        !          1058:                                bus_space_write_raw_multi_2(iot, ioh, txreg,
        !          1059:                                    mtod(m, u_int8_t *), m->m_len & ~1);
        !          1060:                        if (m->m_len & 1)
        !          1061:                                bus_space_write_1(iot, ioh, txreg,
        !          1062:                                     *(mtod(m, u_int8_t *) + m->m_len - 1));
        !          1063:                        MFREE(m, m0);
        !          1064:                        m = m0;
        !          1065:                }
        !          1066:        }
        !          1067:        while (pad--)
        !          1068:                bus_space_write_1(iot, ioh, txreg, 0);
        !          1069:
        !          1070:        splx(sh);
        !          1071:
        !          1072:        ++ifp->if_opackets;
        !          1073:
        !          1074: readcheck:
        !          1075:        if ((bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_RX_STATUS)) &
        !          1076:            ERR_INCOMPLETE) == 0) {
        !          1077:                /* We received a complete packet. */
        !          1078:                u_int16_t status = bus_space_read_2(iot, ioh, EP_STATUS);
        !          1079:
        !          1080:                if ((status & S_INTR_LATCH) == 0) {
        !          1081:                        /*
        !          1082:                         * No interrupt, read the packet and continue
        !          1083:                         * Is  this supposed to happen? Is my motherboard
        !          1084:                         * completely busted?
        !          1085:                         */
        !          1086:                        epread(sc);
        !          1087:                } else
        !          1088:                        /* Got an interrupt, return to get it serviced. */
        !          1089:                        return;
        !          1090:        } else {
        !          1091:                /* Check if we are stuck and reset [see XXX comment] */
        !          1092:                if (epstatus(sc)) {
        !          1093: #ifdef EP_DEBUG
        !          1094:                        if (ifp->if_flags & IFF_DEBUG)
        !          1095:                                printf("%s: adapter reset\n",
        !          1096:                                    sc->sc_dev.dv_xname);
        !          1097: #endif
        !          1098:                        epreset(sc);
        !          1099:                }
        !          1100:        }
        !          1101:
        !          1102:        goto startagain;
        !          1103: }
        !          1104:
        !          1105:
        !          1106: /*
        !          1107:  * XXX: The 3c509 card can get in a mode where both the fifo status bit
        !          1108:  *     FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
        !          1109:  *     We detect this situation and we reset the adapter.
        !          1110:  *     It happens at times when there is a lot of broadcast traffic
        !          1111:  *     on the cable (once in a blue moon).
        !          1112:  */
        !          1113: int
        !          1114: epstatus(sc)
        !          1115:        register struct ep_softc *sc;
        !          1116: {
        !          1117:        bus_space_tag_t iot = sc->sc_iot;
        !          1118:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1119:        u_int16_t fifost;
        !          1120:
        !          1121:        /*
        !          1122:         * Check the FIFO status and act accordingly
        !          1123:         */
        !          1124:        GO_WINDOW(4);
        !          1125:        fifost = bus_space_read_2(iot, ioh, EP_W4_FIFO_DIAG);
        !          1126:        GO_WINDOW(1);
        !          1127:
        !          1128:        if (fifost & FIFOS_RX_UNDERRUN) {
        !          1129: #ifdef EP_DEBUG
        !          1130:                if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1131:                        printf("%s: RX underrun\n", sc->sc_dev.dv_xname);
        !          1132: #endif
        !          1133:                epreset(sc);
        !          1134:                return 0;
        !          1135:        }
        !          1136:
        !          1137:        if (fifost & FIFOS_RX_STATUS_OVERRUN) {
        !          1138: #ifdef EP_DEBUG
        !          1139:                if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1140:                        printf("%s: RX Status overrun\n", sc->sc_dev.dv_xname);
        !          1141: #endif
        !          1142:                return 1;
        !          1143:        }
        !          1144:
        !          1145:        if (fifost & FIFOS_RX_OVERRUN) {
        !          1146: #ifdef EP_DEBUG
        !          1147:                if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1148:                        printf("%s: RX overrun\n", sc->sc_dev.dv_xname);
        !          1149: #endif
        !          1150:                return 1;
        !          1151:        }
        !          1152:
        !          1153:        if (fifost & FIFOS_TX_OVERRUN) {
        !          1154: #ifdef EP_DEBUG
        !          1155:                if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1156:                        printf("%s: TX overrun\n", sc->sc_dev.dv_xname);
        !          1157: #endif
        !          1158:                epreset(sc);
        !          1159:                return 0;
        !          1160:        }
        !          1161:
        !          1162:        return 0;
        !          1163: }
        !          1164:
        !          1165:
        !          1166: void
        !          1167: eptxstat(sc)
        !          1168:        register struct ep_softc *sc;
        !          1169: {
        !          1170:        bus_space_tag_t iot = sc->sc_iot;
        !          1171:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1172:        int i;
        !          1173:
        !          1174:        /*
        !          1175:         * We need to read+write TX_STATUS until we get a 0 status
        !          1176:         * in order to turn off the interrupt flag.
        !          1177:         */
        !          1178:        while ((i = bus_space_read_1(iot, ioh,
        !          1179:            ep_w1_reg(sc, EP_W1_TX_STATUS))) & TXS_COMPLETE) {
        !          1180:                bus_space_write_1(iot, ioh, ep_w1_reg(sc, EP_W1_TX_STATUS),
        !          1181:                    0x0);
        !          1182:
        !          1183:                if (i & TXS_JABBER) {
        !          1184:                        ++sc->sc_arpcom.ac_if.if_oerrors;
        !          1185: #ifdef EP_DEBUG
        !          1186:                        if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1187:                                printf("%s: jabber (%x)\n",
        !          1188:                                       sc->sc_dev.dv_xname, i);
        !          1189: #endif
        !          1190:                        epreset(sc);
        !          1191:                } else if (i & TXS_UNDERRUN) {
        !          1192:                        ++sc->sc_arpcom.ac_if.if_oerrors;
        !          1193: #ifdef EP_DEBUG
        !          1194:                        if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
        !          1195:                                printf("%s: fifo underrun (%x) @%d\n",
        !          1196:                                       sc->sc_dev.dv_xname, i,
        !          1197:                                       sc->tx_start_thresh);
        !          1198: #endif
        !          1199:                        if (sc->tx_succ_ok < 100)
        !          1200:                                    sc->tx_start_thresh = min(ETHER_MAX_LEN,
        !          1201:                                            sc->tx_start_thresh + 20);
        !          1202:                        sc->tx_succ_ok = 0;
        !          1203:                        epreset(sc);
        !          1204:                } else if (i & TXS_MAX_COLLISION) {
        !          1205:                        ++sc->sc_arpcom.ac_if.if_collisions;
        !          1206:                        bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
        !          1207:                        sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
        !          1208:                } else
        !          1209:                        sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127;
        !          1210:        }
        !          1211: }
        !          1212:
        !          1213: int
        !          1214: epintr(arg)
        !          1215:        void *arg;
        !          1216: {
        !          1217:        register struct ep_softc *sc = arg;
        !          1218:        bus_space_tag_t iot = sc->sc_iot;
        !          1219:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1220:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1221:        u_int16_t status;
        !          1222:        int ret = 0;
        !          1223:
        !          1224:        for (;;) {
        !          1225:                bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
        !          1226:
        !          1227:                status = bus_space_read_2(iot, ioh, EP_STATUS);
        !          1228:
        !          1229:                if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
        !          1230:                               S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
        !          1231:                        break;
        !          1232:
        !          1233:                ret = 1;
        !          1234:
        !          1235:                /*
        !          1236:                 * Acknowledge any interrupts.  It's important that we do this
        !          1237:                 * first, since there would otherwise be a race condition.
        !          1238:                 * Due to the i386 interrupt queueing, we may get spurious
        !          1239:                 * interrupts occasionally.
        !          1240:                 */
        !          1241:                bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | status);
        !          1242:
        !          1243:                if (status & S_RX_COMPLETE)
        !          1244:                        epread(sc);
        !          1245:                if (status & S_TX_AVAIL) {
        !          1246:                        ifp->if_flags &= ~IFF_OACTIVE;
        !          1247:                        epstart(ifp);
        !          1248:                }
        !          1249:                if (status & S_CARD_FAILURE) {
        !          1250:                        epreset(sc);
        !          1251:                        return (1);
        !          1252:                }
        !          1253:                if (status & S_TX_COMPLETE) {
        !          1254:                        eptxstat(sc);
        !          1255:                        epstart(ifp);
        !          1256:                }
        !          1257:        }
        !          1258:
        !          1259:        /* no more interrupts */
        !          1260:        return (ret);
        !          1261: }
        !          1262:
        !          1263: void
        !          1264: epread(sc)
        !          1265:        register struct ep_softc *sc;
        !          1266: {
        !          1267:        bus_space_tag_t iot = sc->sc_iot;
        !          1268:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1269:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1270:        struct mbuf *m;
        !          1271:        int len;
        !          1272:
        !          1273:        len = bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_RX_STATUS));
        !          1274:
        !          1275: again:
        !          1276: #ifdef EP_DEBUG
        !          1277:        if (ifp->if_flags & IFF_DEBUG) {
        !          1278:                int err = len & ERR_MASK;
        !          1279:                char *s = NULL;
        !          1280:
        !          1281:                if (len & ERR_INCOMPLETE)
        !          1282:                        s = "incomplete packet";
        !          1283:                else if (err == ERR_OVERRUN)
        !          1284:                        s = "packet overrun";
        !          1285:                else if (err == ERR_RUNT)
        !          1286:                        s = "runt packet";
        !          1287:                else if (err == ERR_ALIGNMENT)
        !          1288:                        s = "bad alignment";
        !          1289:                else if (err == ERR_CRC)
        !          1290:                        s = "bad crc";
        !          1291:                else if (err == ERR_OVERSIZE)
        !          1292:                        s = "oversized packet";
        !          1293:                else if (err == ERR_DRIBBLE)
        !          1294:                        s = "dribble bits";
        !          1295:
        !          1296:                if (s)
        !          1297:                        printf("%s: %s\n", sc->sc_dev.dv_xname, s);
        !          1298:        }
        !          1299: #endif
        !          1300:
        !          1301:        if (len & ERR_INCOMPLETE)
        !          1302:                return;
        !          1303:
        !          1304:        if (len & ERR_RX) {
        !          1305:                ++ifp->if_ierrors;
        !          1306:                goto abort;
        !          1307:        }
        !          1308:
        !          1309:        len &= RX_BYTES_MASK;   /* Lower 11 bits = RX bytes. */
        !          1310:
        !          1311:        /* Pull packet off interface. */
        !          1312:        m = epget(sc, len);
        !          1313:        if (m == NULL) {
        !          1314:                ifp->if_ierrors++;
        !          1315:                goto abort;
        !          1316:        }
        !          1317:
        !          1318:        ++ifp->if_ipackets;
        !          1319:
        !          1320: #if NBPFILTER > 0
        !          1321:        /*
        !          1322:         * Check if there's a BPF listener on this interface.
        !          1323:         * If so, hand off the raw packet to BPF.
        !          1324:         */
        !          1325:        if (ifp->if_bpf)
        !          1326:                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
        !          1327: #endif
        !          1328:
        !          1329:        ether_input_mbuf(ifp, m);
        !          1330:
        !          1331:        /*
        !          1332:         * In periods of high traffic we can actually receive enough
        !          1333:         * packets so that the fifo overrun bit will be set at this point,
        !          1334:         * even though we just read a packet. In this case we
        !          1335:         * are not going to receive any more interrupts. We check for
        !          1336:         * this condition and read again until the fifo is not full.
        !          1337:         * We could simplify this test by not using epstatus(), but
        !          1338:         * rechecking the RX_STATUS register directly. This test could
        !          1339:         * result in unnecessary looping in cases where there is a new
        !          1340:         * packet but the fifo is not full, but it will not fix the
        !          1341:         * stuck behavior.
        !          1342:         *
        !          1343:         * Even with this improvement, we still get packet overrun errors
        !          1344:         * which are hurting performance. Maybe when I get some more time
        !          1345:         * I'll modify epread() so that it can handle RX_EARLY interrupts.
        !          1346:         */
        !          1347:        if (epstatus(sc)) {
        !          1348:                len = bus_space_read_2(iot, ioh,
        !          1349:                    ep_w1_reg(sc, EP_W1_RX_STATUS));
        !          1350:                /* Check if we are stuck and reset [see XXX comment] */
        !          1351:                if (len & ERR_INCOMPLETE) {
        !          1352: #ifdef EP_DEBUG
        !          1353:                        if (ifp->if_flags & IFF_DEBUG)
        !          1354:                                printf("%s: adapter reset\n",
        !          1355:                                    sc->sc_dev.dv_xname);
        !          1356: #endif
        !          1357:                        epreset(sc);
        !          1358:                        return;
        !          1359:                }
        !          1360:                goto again;
        !          1361:        }
        !          1362:
        !          1363:        return;
        !          1364:
        !          1365: abort:
        !          1366:        ep_discard_rxtop(iot, ioh);
        !          1367: }
        !          1368:
        !          1369: struct mbuf *
        !          1370: epget(sc, totlen)
        !          1371:        struct ep_softc *sc;
        !          1372:        int totlen;
        !          1373: {
        !          1374:        bus_space_tag_t iot = sc->sc_iot;
        !          1375:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1376:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        !          1377:        struct mbuf *top, **mp, *m;
        !          1378:        int len, pad, sh, rxreg;
        !          1379:
        !          1380:        m = sc->mb[sc->next_mb];
        !          1381:        sc->mb[sc->next_mb] = NULL;
        !          1382:        if (m == NULL) {
        !          1383:                MGETHDR(m, M_DONTWAIT, MT_DATA);
        !          1384:                if (m == NULL)
        !          1385:                        return (NULL);
        !          1386:        } else {
        !          1387:                /* If the queue is no longer full, refill. */
        !          1388:                if (sc->last_mb == sc->next_mb)
        !          1389:                        timeout_add(&sc->sc_epmbuffill_tmo, 1);
        !          1390:                /* Convert one of our saved mbuf's. */
        !          1391:                sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
        !          1392:                m->m_data = m->m_pktdat;
        !          1393:                m->m_flags = M_PKTHDR;
        !          1394:                m_tag_init(m);
        !          1395:                m->m_pkthdr.csum_flags = 0;
        !          1396:        }
        !          1397:        m->m_pkthdr.rcvif = ifp;
        !          1398:        m->m_pkthdr.len = totlen;
        !          1399:        pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
        !          1400:        len = MHLEN;
        !          1401:        if (totlen >= MINCLSIZE) {
        !          1402:                MCLGET(m, M_DONTWAIT);
        !          1403:                if (m->m_flags & M_EXT)
        !          1404:                        len = MCLBYTES;
        !          1405:        }
        !          1406:        m->m_data += pad;
        !          1407:        len -= pad;
        !          1408:        top = 0;
        !          1409:        mp = &top;
        !          1410:
        !          1411:        /*
        !          1412:         * We read the packet at splhigh() so that an interrupt from another
        !          1413:         * device doesn't cause the card's buffer to overflow while we're
        !          1414:         * reading it.  We may still lose packets at other times.
        !          1415:         */
        !          1416:        sh = splhigh();
        !          1417:
        !          1418:        rxreg = ep_w1_reg(sc, EP_W1_RX_PIO_RD_1);
        !          1419:
        !          1420:        while (totlen > 0) {
        !          1421:                if (top) {
        !          1422:                        m = sc->mb[sc->next_mb];
        !          1423:                        sc->mb[sc->next_mb] = NULL;
        !          1424:                        if (m == NULL) {
        !          1425:                                MGET(m, M_DONTWAIT, MT_DATA);
        !          1426:                                if (m == NULL) {
        !          1427:                                        splx(sh);
        !          1428:                                        m_freem(top);
        !          1429:                                        return (NULL);
        !          1430:                                }
        !          1431:                        } else
        !          1432:                                sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
        !          1433:
        !          1434:                        len = MLEN;
        !          1435:                }
        !          1436:                if (top && totlen >= MINCLSIZE) {
        !          1437:                        MCLGET(m, M_DONTWAIT);
        !          1438:                        if (m->m_flags & M_EXT)
        !          1439:                                len = MCLBYTES;
        !          1440:                }
        !          1441:                len = min(totlen, len);
        !          1442:                if (EP_IS_BUS_32(sc->bustype)) {
        !          1443:                        if (len > 3) {
        !          1444:                                len &= ~3;
        !          1445:                                bus_space_read_raw_multi_4(iot, ioh, rxreg,
        !          1446:                                    mtod(m, u_int8_t *), len);
        !          1447:                        } else
        !          1448:                                bus_space_read_multi_1(iot, ioh, rxreg,
        !          1449:                                    mtod(m, u_int8_t *), len);
        !          1450:                } else {
        !          1451:                        if (len > 1) {
        !          1452:                                len &= ~1;
        !          1453:                                bus_space_read_raw_multi_2(iot, ioh, rxreg,
        !          1454:                                    mtod(m, u_int8_t *), len);
        !          1455:                        } else
        !          1456:                                *(mtod(m, u_int8_t *)) =
        !          1457:                                    bus_space_read_1(iot, ioh, rxreg);
        !          1458:                }
        !          1459:                m->m_len = len;
        !          1460:                totlen -= len;
        !          1461:                *mp = m;
        !          1462:                mp = &m->m_next;
        !          1463:        }
        !          1464:
        !          1465:        ep_discard_rxtop(iot, ioh);
        !          1466:
        !          1467:        splx(sh);
        !          1468:
        !          1469:        return top;
        !          1470: }
        !          1471:
        !          1472: int
        !          1473: epioctl(ifp, cmd, data)
        !          1474:        register struct ifnet *ifp;
        !          1475:        u_long cmd;
        !          1476:        caddr_t data;
        !          1477: {
        !          1478:        struct ep_softc *sc = ifp->if_softc;
        !          1479:        struct ifaddr *ifa = (struct ifaddr *)data;
        !          1480:        struct ifreq *ifr = (struct ifreq *)data;
        !          1481:        int s, error = 0;
        !          1482:
        !          1483:        s = splnet();
        !          1484:
        !          1485:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
        !          1486:                splx(s);
        !          1487:                return error;
        !          1488:        }
        !          1489:
        !          1490:        switch (cmd) {
        !          1491:
        !          1492:        case SIOCSIFADDR:
        !          1493:                ifp->if_flags |= IFF_UP;
        !          1494:
        !          1495:                switch (ifa->ifa_addr->sa_family) {
        !          1496: #ifdef INET
        !          1497:                case AF_INET:
        !          1498:                        epinit(sc);
        !          1499:                        arp_ifinit(&sc->sc_arpcom, ifa);
        !          1500:                        break;
        !          1501: #endif
        !          1502:                default:
        !          1503:                        epinit(sc);
        !          1504:                        break;
        !          1505:                }
        !          1506:                break;
        !          1507:
        !          1508:        case SIOCSIFMEDIA:
        !          1509:        case SIOCGIFMEDIA:
        !          1510:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
        !          1511:                break;
        !          1512:
        !          1513:        case SIOCSIFMTU:
        !          1514:                if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
        !          1515:                        error = EINVAL;
        !          1516:                } else if (ifp->if_mtu != ifr->ifr_mtu) {
        !          1517:                        ifp->if_mtu = ifr->ifr_mtu;
        !          1518:                }
        !          1519:                break;
        !          1520:
        !          1521:        case SIOCSIFFLAGS:
        !          1522:                if ((ifp->if_flags & IFF_UP) == 0 &&
        !          1523:                    (ifp->if_flags & IFF_RUNNING) != 0) {
        !          1524:                        /*
        !          1525:                         * If interface is marked down and it is running, then
        !          1526:                         * stop it.
        !          1527:                         */
        !          1528:                        epstop(sc);
        !          1529:                        ifp->if_flags &= ~IFF_RUNNING;
        !          1530:                } else if ((ifp->if_flags & IFF_UP) != 0 &&
        !          1531:                           (ifp->if_flags & IFF_RUNNING) == 0) {
        !          1532:                        /*
        !          1533:                         * If interface is marked up and it is stopped, then
        !          1534:                         * start it.
        !          1535:                         */
        !          1536:                        epinit(sc);
        !          1537:                } else if ((ifp->if_flags & IFF_UP) != 0) {
        !          1538:                        /*
        !          1539:                         * Reset the interface to pick up changes in any other
        !          1540:                         * flags that affect hardware registers.
        !          1541:                         */
        !          1542:                        epinit(sc);
        !          1543:                }
        !          1544:                break;
        !          1545:
        !          1546:        case SIOCADDMULTI:
        !          1547:        case SIOCDELMULTI:
        !          1548:                error = (cmd == SIOCADDMULTI) ?
        !          1549:                    ether_addmulti(ifr, &sc->sc_arpcom) :
        !          1550:                    ether_delmulti(ifr, &sc->sc_arpcom);
        !          1551:
        !          1552:                if (error == ENETRESET) {
        !          1553:                        /*
        !          1554:                         * Multicast list has changed; set the hardware filter
        !          1555:                         * accordingly.
        !          1556:                         */
        !          1557:                        if (ifp->if_flags & IFF_RUNNING)
        !          1558:                                epreset(sc);
        !          1559:                        error = 0;
        !          1560:                }
        !          1561:                break;
        !          1562:
        !          1563:        default:
        !          1564:                error = EINVAL;
        !          1565:                break;
        !          1566:        }
        !          1567:
        !          1568:        splx(s);
        !          1569:        return (error);
        !          1570: }
        !          1571:
        !          1572: void
        !          1573: epreset(sc)
        !          1574:        struct ep_softc *sc;
        !          1575: {
        !          1576:        int s;
        !          1577:
        !          1578:        s = splnet();
        !          1579:        epinit(sc);
        !          1580:        splx(s);
        !          1581: }
        !          1582:
        !          1583: void
        !          1584: epwatchdog(ifp)
        !          1585:        struct ifnet *ifp;
        !          1586: {
        !          1587:        struct ep_softc *sc = ifp->if_softc;
        !          1588:
        !          1589:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
        !          1590:        ++sc->sc_arpcom.ac_if.if_oerrors;
        !          1591:
        !          1592:        epreset(sc);
        !          1593: }
        !          1594:
        !          1595: void
        !          1596: epstop(sc)
        !          1597:        register struct ep_softc *sc;
        !          1598: {
        !          1599:        bus_space_tag_t iot = sc->sc_iot;
        !          1600:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1601:
        !          1602:        if (sc->ep_flags & EP_FLAGS_MII) {
        !          1603:                mii_down(&sc->sc_mii);
        !          1604:        }
        !          1605:
        !          1606:        if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
        !          1607:                /* Clear the FIFO buffer count, thus halting
        !          1608:                 * any currently-running transactions.
        !          1609:                 */
        !          1610:                GO_WINDOW(1);           /* sanity */
        !          1611:                bus_space_write_2(iot, ioh, EP_W1_RUNNER_WRCTL, 0);
        !          1612:                bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, 0);
        !          1613:        }
        !          1614:
        !          1615:        bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISABLE);
        !          1616:        ep_discard_rxtop(iot, ioh);
        !          1617:
        !          1618:        bus_space_write_2(iot, ioh, EP_COMMAND, TX_DISABLE);
        !          1619:        bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
        !          1620:
        !          1621:        ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
        !          1622:        ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
        !          1623:
        !          1624:        bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
        !          1625:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK);
        !          1626:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK);
        !          1627:        bus_space_write_2(iot, ioh, EP_COMMAND, SET_RX_FILTER);
        !          1628:
        !          1629:        epmbufempty(sc);
        !          1630: }
        !          1631:
        !          1632: /*
        !          1633:  * We get eeprom data from the id_port given an offset into the
        !          1634:  * eeprom.  Basically; after the ID_sequence is sent to all of
        !          1635:  * the cards; they enter the ID_CMD state where they will accept
        !          1636:  * command requests. 0x80-0xbf loads the eeprom data.  We then
        !          1637:  * read the port 16 times and with every read; the cards check
        !          1638:  * for contention (ie: if one card writes a 0 bit and another
        !          1639:  * writes a 1 bit then the host sees a 0. At the end of the cycle;
        !          1640:  * each card compares the data on the bus; if there is a difference
        !          1641:  * then that card goes into ID_WAIT state again). In the meantime;
        !          1642:  * one bit of data is returned in the AX register which is conveniently
        !          1643:  * returned to us by bus_space_read_1().  Hence; we read 16 times getting one
        !          1644:  * bit of data with each read.
        !          1645:  *
        !          1646:  * NOTE: the caller must provide an i/o handle for ELINK_ID_PORT!
        !          1647:  */
        !          1648: u_int16_t
        !          1649: epreadeeprom(iot, ioh, offset)
        !          1650:        bus_space_tag_t iot;
        !          1651:        bus_space_handle_t ioh;
        !          1652:        int offset;
        !          1653: {
        !          1654:        u_int16_t data = 0;
        !          1655:        int i;
        !          1656:
        !          1657:        bus_space_write_1(iot, ioh, 0, 0x80 + offset);
        !          1658:        delay(1000);
        !          1659:        for (i = 0; i < 16; i++)
        !          1660:                data = (data << 1) | (bus_space_read_2(iot, ioh, 0) & 1);
        !          1661:        return (data);
        !          1662: }
        !          1663:
        !          1664: int
        !          1665: epbusyeeprom(sc)
        !          1666:        struct ep_softc *sc;
        !          1667: {
        !          1668:        bus_space_tag_t iot = sc->sc_iot;
        !          1669:        bus_space_handle_t ioh = sc->sc_ioh;
        !          1670:        int i = 100, j;
        !          1671:
        !          1672:        while (i--) {
        !          1673:                j = bus_space_read_2(iot, ioh, EP_W0_EEPROM_COMMAND);
        !          1674:                if (j & EEPROM_BUSY)
        !          1675:                        delay(100);
        !          1676:                else
        !          1677:                        break;
        !          1678:        }
        !          1679:        if (!i) {
        !          1680:                printf("\n%s: eeprom failed to come ready\n",
        !          1681:                    sc->sc_dev.dv_xname);
        !          1682:                return (1);
        !          1683:        }
        !          1684:        if (sc->bustype != EP_BUS_PCMCIA && sc->bustype != EP_BUS_PCI &&
        !          1685:            (j & EEPROM_TST_MODE)) {
        !          1686:                printf("\n%s: erase pencil mark, or disable PnP mode!\n",
        !          1687:                    sc->sc_dev.dv_xname);
        !          1688:                return (1);
        !          1689:        }
        !          1690:        return (0);
        !          1691: }
        !          1692:
        !          1693: u_int16_t
        !          1694: ep_read_eeprom(sc, offset)
        !          1695:        struct ep_softc *sc;
        !          1696:        u_int16_t offset;
        !          1697: {
        !          1698:        u_int16_t readcmd;
        !          1699:
        !          1700:        /*
        !          1701:         * RoadRunner has a larger EEPROM, so a different read command
        !          1702:         * is required.
        !          1703:         */
        !          1704:        if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER)
        !          1705:                readcmd = READ_EEPROM_RR;
        !          1706:        else
        !          1707:                readcmd = READ_EEPROM;
        !          1708:
        !          1709:        if (epbusyeeprom(sc))
        !          1710:                return (0);                     /* XXX why is eeprom busy? */
        !          1711:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W0_EEPROM_COMMAND,
        !          1712:            readcmd | offset);
        !          1713:        if (epbusyeeprom(sc))
        !          1714:                return (0);                     /* XXX why is eeprom busy? */
        !          1715:
        !          1716:        return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W0_EEPROM_DATA));
        !          1717: }
        !          1718:
        !          1719: void
        !          1720: epmbuffill(v)
        !          1721:        void *v;
        !          1722: {
        !          1723:        struct ep_softc *sc = v;
        !          1724:        int s, i;
        !          1725:
        !          1726:        s = splnet();
        !          1727:        i = sc->last_mb;
        !          1728:        do {
        !          1729:                if (sc->mb[i] == NULL)
        !          1730:                        MGET(sc->mb[i], M_DONTWAIT, MT_DATA);
        !          1731:                if (sc->mb[i] == NULL)
        !          1732:                        break;
        !          1733:                i = (i + 1) % MAX_MBS;
        !          1734:        } while (i != sc->next_mb);
        !          1735:        sc->last_mb = i;
        !          1736:        /* If the queue was not filled, try again. */
        !          1737:        if (sc->last_mb != sc->next_mb)
        !          1738:                timeout_add(&sc->sc_epmbuffill_tmo, 1);
        !          1739:        splx(s);
        !          1740: }
        !          1741:
        !          1742: void
        !          1743: epmbufempty(sc)
        !          1744:        struct ep_softc *sc;
        !          1745: {
        !          1746:        int s, i;
        !          1747:
        !          1748:        s = splnet();
        !          1749:        for (i = 0; i<MAX_MBS; i++) {
        !          1750:                if (sc->mb[i]) {
        !          1751:                        m_freem(sc->mb[i]);
        !          1752:                        sc->mb[i] = NULL;
        !          1753:                }
        !          1754:        }
        !          1755:        sc->last_mb = sc->next_mb = 0;
        !          1756:        timeout_del(&sc->sc_epmbuffill_tmo);
        !          1757:        splx(s);
        !          1758: }
        !          1759:
        !          1760: void
        !          1761: ep_mii_setbit(sc, bit)
        !          1762:         struct ep_softc *sc;
        !          1763:         u_int16_t bit;
        !          1764: {
        !          1765:         u_int16_t val;
        !          1766:
        !          1767:         /* We assume we're already in Window 4 */
        !          1768:         val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT);
        !          1769:         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT,
        !          1770:             val | bit);
        !          1771: }
        !          1772:
        !          1773: void
        !          1774: ep_mii_clrbit(sc, bit)
        !          1775:         struct ep_softc *sc;
        !          1776:         u_int16_t bit;
        !          1777: {
        !          1778:         u_int16_t val;
        !          1779:
        !          1780:         /* We assume we're already in Window 4 */
        !          1781:         val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT);
        !          1782:         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT,
        !          1783:             val & ~bit);
        !          1784: }
        !          1785:
        !          1786: u_int16_t
        !          1787: ep_mii_readbit(sc, bit)
        !          1788:         struct ep_softc *sc;
        !          1789:         u_int16_t bit;
        !          1790: {
        !          1791:
        !          1792:         /* We assume we're already in Window 4 */
        !          1793:         return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT) &
        !          1794:             bit);
        !          1795: }
        !          1796:
        !          1797: void
        !          1798: ep_mii_sync(sc)
        !          1799:         struct ep_softc *sc;
        !          1800: {
        !          1801:         int i;
        !          1802:
        !          1803:         /* We assume we're already in Window 4 */
        !          1804:         ep_mii_clrbit(sc, PHYSMGMT_DIR);
        !          1805:         for (i = 0; i < 32; i++) {
        !          1806:                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1807:                 ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1808:         }
        !          1809: }
        !          1810:
        !          1811: void
        !          1812: ep_mii_sendbits(sc, data, nbits)
        !          1813:         struct ep_softc *sc;
        !          1814:         u_int32_t data;
        !          1815:         int nbits;
        !          1816: {
        !          1817:         int i;
        !          1818:
        !          1819:         /* We assume we're already in Window 4 */
        !          1820:         ep_mii_setbit(sc, PHYSMGMT_DIR);
        !          1821:         for (i = 1 << (nbits - 1); i; i = i >> 1) {
        !          1822:                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1823:                 ep_mii_readbit(sc, PHYSMGMT_CLK);
        !          1824:                 if (data & i)
        !          1825:                         ep_mii_setbit(sc, PHYSMGMT_DATA);
        !          1826:                 else
        !          1827:                         ep_mii_clrbit(sc, PHYSMGMT_DATA);
        !          1828:                 ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1829:                 ep_mii_readbit(sc, PHYSMGMT_CLK);
        !          1830:         }
        !          1831: }
        !          1832:
        !          1833: int
        !          1834: ep_mii_readreg(self, phy, reg)
        !          1835:        struct device *self;
        !          1836:        int phy, reg;
        !          1837: {
        !          1838:         struct ep_softc *sc = (struct ep_softc *)self;
        !          1839:         int val = 0, i, err;
        !          1840:
        !          1841:         /*
        !          1842:          * Read the PHY register by manually driving the MII control lines.
        !          1843:          */
        !          1844:
        !          1845:         GO_WINDOW(4);
        !          1846:
        !          1847:         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT, 0);
        !          1848:
        !          1849:         ep_mii_sync(sc);
        !          1850:         ep_mii_sendbits(sc, MII_COMMAND_START, 2);
        !          1851:         ep_mii_sendbits(sc, MII_COMMAND_READ, 2);
        !          1852:         ep_mii_sendbits(sc, phy, 5);
        !          1853:         ep_mii_sendbits(sc, reg, 5);
        !          1854:
        !          1855:         ep_mii_clrbit(sc, PHYSMGMT_DIR);
        !          1856:         ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1857:         ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1858:         ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1859:
        !          1860:         err = ep_mii_readbit(sc, PHYSMGMT_DATA);
        !          1861:         ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1862:
        !          1863:         /* Even if an error occurs, must still clock out the cycle. */
        !          1864:         for (i = 0; i < 16; i++) {
        !          1865:                 val <<= 1;
        !          1866:                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1867:                 if (err == 0 && ep_mii_readbit(sc, PHYSMGMT_DATA))
        !          1868:                         val |= 1;
        !          1869:                 ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1870:         }
        !          1871:         ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1872:         ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1873:
        !          1874:         GO_WINDOW(1);   /* back to operating window */
        !          1875:
        !          1876:         return (err ? 0 : val);
        !          1877: }
        !          1878:
        !          1879: void
        !          1880: ep_mii_writereg(self, phy, reg, val)
        !          1881:         struct device *self;
        !          1882:         int phy, reg, val;
        !          1883: {
        !          1884:         struct ep_softc *sc = (struct ep_softc *)self;
        !          1885:
        !          1886:         /*
        !          1887:          * Write the PHY register by manually driving the MII control lines.
        !          1888:          */
        !          1889:
        !          1890:         GO_WINDOW(4);
        !          1891:
        !          1892:         ep_mii_sync(sc);
        !          1893:         ep_mii_sendbits(sc, MII_COMMAND_START, 2);
        !          1894:         ep_mii_sendbits(sc, MII_COMMAND_WRITE, 2);
        !          1895:         ep_mii_sendbits(sc, phy, 5);
        !          1896:         ep_mii_sendbits(sc, reg, 5);
        !          1897:         ep_mii_sendbits(sc, MII_COMMAND_ACK, 2);
        !          1898:         ep_mii_sendbits(sc, val, 16);
        !          1899:
        !          1900:         ep_mii_clrbit(sc, PHYSMGMT_CLK);
        !          1901:         ep_mii_setbit(sc, PHYSMGMT_CLK);
        !          1902:
        !          1903:         GO_WINDOW(1);   /* back to operating window */
        !          1904: }
        !          1905:
        !          1906: void
        !          1907: ep_statchg(self)
        !          1908:         struct device *self;
        !          1909: {
        !          1910:         struct ep_softc *sc = (struct ep_softc *)self;
        !          1911:         bus_space_tag_t iot = sc->sc_iot;
        !          1912:         bus_space_handle_t ioh = sc->sc_ioh;
        !          1913:         int mctl;
        !          1914:
        !          1915:         /* XXX Update ifp->if_baudrate */
        !          1916:
        !          1917:         GO_WINDOW(3);
        !          1918:         mctl = bus_space_read_2(iot, ioh, EP_W3_MAC_CONTROL);
        !          1919:         if (sc->sc_mii.mii_media_active & IFM_FDX)
        !          1920:                 mctl |= MAC_CONTROL_FDX;
        !          1921:         else
        !          1922:                 mctl &= ~MAC_CONTROL_FDX;
        !          1923:         bus_space_write_2(iot, ioh, EP_W3_MAC_CONTROL, mctl);
        !          1924:         GO_WINDOW(1);   /* back to operating window */
        !          1925: }

CVSweb