[BACK]Return to elink3.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ic

Annotation of src/sys/dev/ic/elink3.c, Revision 1.58.2.1

1.58.2.1! wrstuden    1: /*     $NetBSD: elink3.c,v 1.67 1999/11/19 18:17:14 thorpej Exp $      */
1.41      thorpej     2:
                      3: /*-
                      4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                      9:  * NASA Ames Research Center.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
1.1       thorpej    39:
                     40: /*
1.19      jonathan   41:  * Copyright (c) 1996, 1997 Jonathan Stone <jonathan@NetBSD.org>
1.6       thorpej    42:  * Copyright (c) 1994 Herb Peyerl <hpeyerl@beer.org>
1.1       thorpej    43:  * All rights reserved.
                     44:  *
                     45:  * Redistribution and use in source and binary forms, with or without
                     46:  * modification, are permitted provided that the following conditions
                     47:  * are met:
                     48:  * 1. Redistributions of source code must retain the above copyright
                     49:  *    notice, this list of conditions and the following disclaimer.
                     50:  * 2. Redistributions in binary form must reproduce the above copyright
                     51:  *    notice, this list of conditions and the following disclaimer in the
                     52:  *    documentation and/or other materials provided with the distribution.
                     53:  * 3. All advertising materials mentioning features or use of this software
                     54:  *    must display the following acknowledgement:
                     55:  *      This product includes software developed by Herb Peyerl.
                     56:  * 4. The name of Herb Peyerl may not be used to endorse or promote products
                     57:  *    derived from this software without specific prior written permission.
                     58:  *
                     59:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     60:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     61:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     62:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     63:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     64:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     65:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     66:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     67:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     68:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     69:  */
                     70:
1.39      jonathan   71: #include "opt_inet.h"
1.40      jonathan   72: #include "opt_ns.h"
1.1       thorpej    73: #include "bpfilter.h"
1.35      explorer   74: #include "rnd.h"
1.1       thorpej    75:
                     76: #include <sys/param.h>
1.3       christos   77: #include <sys/systm.h>
1.41      thorpej    78: #include <sys/kernel.h>
1.1       thorpej    79: #include <sys/mbuf.h>
                     80: #include <sys/socket.h>
                     81: #include <sys/ioctl.h>
                     82: #include <sys/errno.h>
                     83: #include <sys/syslog.h>
                     84: #include <sys/select.h>
                     85: #include <sys/device.h>
1.35      explorer   86: #if NRND > 0
                     87: #include <sys/rnd.h>
                     88: #endif
1.1       thorpej    89:
                     90: #include <net/if.h>
                     91: #include <net/if_dl.h>
1.21      is         92: #include <net/if_ether.h>
1.22      jonathan   93: #include <net/if_media.h>
1.1       thorpej    94:
                     95: #ifdef INET
                     96: #include <netinet/in.h>
                     97: #include <netinet/in_systm.h>
                     98: #include <netinet/in_var.h>
                     99: #include <netinet/ip.h>
1.21      is        100: #include <netinet/if_inarp.h>
1.1       thorpej   101: #endif
                    102:
                    103: #ifdef NS
                    104: #include <netns/ns.h>
                    105: #include <netns/ns_if.h>
                    106: #endif
                    107:
                    108: #if NBPFILTER > 0
                    109: #include <net/bpf.h>
                    110: #include <net/bpfdesc.h>
                    111: #endif
                    112:
                    113: #include <machine/cpu.h>
1.2       thorpej   114: #include <machine/bus.h>
1.7       thorpej   115: #include <machine/intr.h>
1.1       thorpej   116:
1.41      thorpej   117: #include <dev/mii/mii.h>
                    118: #include <dev/mii/miivar.h>
1.58.2.1! wrstuden  119: #include <dev/mii/mii_bitbang.h>
1.41      thorpej   120:
1.1       thorpej   121: #include <dev/ic/elink3var.h>
                    122: #include <dev/ic/elink3reg.h>
                    123:
1.36      jonathan  124: #ifdef DEBUG
                    125: int epdebug = 0;
                    126: #endif
                    127:
1.23      jonathan  128: /*
1.55      jonathan  129:  * XXX endian workaround for big-endian CPUs  with pcmcia:
                    130:  * if stream methods for bus_space_multi are not provided, define them
                    131:  * using non-stream bus_space_{read,write}_multi_.
                    132:  * Assumes host CPU is same endian-ness as bus.
                    133:  */
                    134: #ifndef __BUS_SPACE_HAS_STREAM_METHODS
                    135: #define bus_space_read_multi_stream_2  bus_space_read_multi_2
                    136: #define bus_space_read_multi_stream_4  bus_space_read_multi_4
                    137: #define bus_space_write_multi_stream_2 bus_space_write_multi_2
                    138: #define bus_space_write_multi_stream_4 bus_space_write_multi_4
                    139: #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
                    140:
                    141: /*
1.41      thorpej   142:  * Structure to map media-present bits in boards to ifmedia codes and
                    143:  * printable media names. Used for table-driven ifmedia initialization.
1.23      jonathan  144:  */
                    145: struct ep_media {
1.41      thorpej   146:        int     epm_mpbit;              /* media present bit */
                    147:        const char *epm_name;           /* name of medium */
1.23      jonathan  148:        int     epm_ifmedia;            /* ifmedia word for medium */
1.47      fvdl      149:        int     epm_epmedia;            /* ELINKMEDIA_* constant */
1.23      jonathan  150: };
                    151:
                    152: /*
1.41      thorpej   153:  * Media table for the Demon/Vortex/Boomerang chipsets.
                    154:  *
                    155:  * Note that MII on the Demon and Vortex (3c59x) indicates an external
                    156:  * MII connector (for connecting an external PHY) ... I think.  Treat
                    157:  * it as `manual' on these chips.
1.23      jonathan  158:  *
1.41      thorpej   159:  * Any Boomerang (3c90x) chips with MII really do have an internal
                    160:  * MII and real PHYs attached; no `native' media.
1.23      jonathan  161:  */
1.41      thorpej   162: struct ep_media ep_vortex_media[] = {
1.47      fvdl      163:        { ELINK_PCI_10BASE_T,   "10baseT",      IFM_ETHER|IFM_10_T,
                    164:          ELINKMEDIA_10BASE_T },
                    165:        { ELINK_PCI_10BASE_T,   "10baseT-FDX",  IFM_ETHER|IFM_10_T|IFM_FDX,
                    166:          ELINKMEDIA_10BASE_T },
1.48      thorpej   167:        { ELINK_PCI_AUI,        "10base5",      IFM_ETHER|IFM_10_5,
1.47      fvdl      168:          ELINKMEDIA_AUI },
1.48      thorpej   169:        { ELINK_PCI_BNC,        "10base2",      IFM_ETHER|IFM_10_2,
1.47      fvdl      170:          ELINKMEDIA_10BASE_2 },
                    171:        { ELINK_PCI_100BASE_TX, "100baseTX",    IFM_ETHER|IFM_100_TX,
                    172:          ELINKMEDIA_100BASE_TX },
                    173:        { ELINK_PCI_100BASE_TX, "100baseTX-FDX",IFM_ETHER|IFM_100_TX|IFM_FDX,
                    174:          ELINKMEDIA_100BASE_TX },
                    175:        { ELINK_PCI_100BASE_FX, "100baseFX",    IFM_ETHER|IFM_100_FX,
                    176:          ELINKMEDIA_100BASE_FX },
1.48      thorpej   177:        { ELINK_PCI_100BASE_MII,"manual",       IFM_ETHER|IFM_MANUAL,
1.47      fvdl      178:          ELINKMEDIA_MII },
                    179:        { ELINK_PCI_100BASE_T4, "100baseT4",    IFM_ETHER|IFM_100_T4,
                    180:          ELINKMEDIA_100BASE_T4 },
1.41      thorpej   181:        { 0,                    NULL,           0,
                    182:          0 },
1.23      jonathan  183: };
                    184:
                    185: /*
1.41      thorpej   186:  * Media table for the older 3Com Etherlink III chipset, used
                    187:  * in the 3c509, 3c579, and 3c589.
1.23      jonathan  188:  */
1.41      thorpej   189: struct ep_media ep_509_media[] = {
1.48      thorpej   190:        { ELINK_W0_CC_UTP,      "10baseT",      IFM_ETHER|IFM_10_T,
1.47      fvdl      191:          ELINKMEDIA_10BASE_T },
1.48      thorpej   192:        { ELINK_W0_CC_AUI,      "10base5",      IFM_ETHER|IFM_10_5,
1.47      fvdl      193:          ELINKMEDIA_AUI },
1.48      thorpej   194:        { ELINK_W0_CC_BNC,      "10base2",      IFM_ETHER|IFM_10_2,
1.47      fvdl      195:          ELINKMEDIA_10BASE_2 },
1.41      thorpej   196:        { 0,                    NULL,           0,
                    197:          0 },
1.23      jonathan  198: };
                    199:
1.15      jonathan  200: void   ep_internalconfig __P((struct ep_softc *sc));
1.20      jonathan  201: void   ep_vortex_probemedia __P((struct ep_softc *sc));
1.41      thorpej   202: void   ep_509_probemedia __P((struct ep_softc *sc));
1.20      jonathan  203:
1.3       christos  204: static void eptxstat __P((struct ep_softc *));
1.1       thorpej   205: static int epstatus __P((struct ep_softc *));
1.58.2.1! wrstuden  206: void   epinit __P((struct ep_softc *));
        !           207: int    epioctl __P((struct ifnet *, u_long, caddr_t));
        !           208: void   epstart __P((struct ifnet *));
        !           209: void   epwatchdog __P((struct ifnet *));
        !           210: void   epreset __P((struct ep_softc *));
1.16      jonathan  211: static void epshutdown __P((void *));
1.23      jonathan  212: void   epread __P((struct ep_softc *));
1.1       thorpej   213: struct mbuf *epget __P((struct ep_softc *, int));
1.23      jonathan  214: void   epmbuffill __P((void *));
                    215: void   epmbufempty __P((struct ep_softc *));
                    216: void   epsetfilter __P((struct ep_softc *));
1.58.2.1! wrstuden  217: void   ep_roadrunner_mii_enable __P((struct ep_softc *));
1.41      thorpej   218: void   epsetmedia __P((struct ep_softc *));
1.23      jonathan  219:
                    220: /* ifmedia callbacks */
                    221: int    ep_media_change __P((struct ifnet *ifp));
                    222: void   ep_media_status __P((struct ifnet *ifp, struct ifmediareq *req));
1.1       thorpej   223:
1.41      thorpej   224: /* MII callbacks */
                    225: int    ep_mii_readreg __P((struct device *, int, int));
                    226: void   ep_mii_writereg __P((struct device *, int, int, int));
                    227: void   ep_statchg __P((struct device *));
                    228:
                    229: void   ep_tick __P((void *));
                    230:
1.1       thorpej   231: static int epbusyeeprom __P((struct ep_softc *));
1.58.2.1! wrstuden  232: u_int16_t ep_read_eeprom __P((struct ep_softc *, u_int16_t));
1.56      jonathan  233: static inline void ep_reset_cmd __P((struct ep_softc *sc,
1.19      jonathan  234:                                        u_int cmd, u_int arg));
1.56      jonathan  235: static inline void ep_finish_reset __P((bus_space_tag_t, bus_space_handle_t));
                    236: static inline void ep_discard_rxtop __P((bus_space_tag_t, bus_space_handle_t));
1.42      thorpej   237: static __inline int ep_w1_reg __P((struct ep_softc *, int));
1.19      jonathan  238:
1.42      thorpej   239: /*
1.58.2.1! wrstuden  240:  * MII bit-bang glue.
        !           241:  */
        !           242: u_int32_t ep_mii_bitbang_read __P((struct device *));
        !           243: void ep_mii_bitbang_write __P((struct device *, u_int32_t));
        !           244:
        !           245: const struct mii_bitbang_ops ep_mii_bitbang_ops = {
        !           246:        ep_mii_bitbang_read,
        !           247:        ep_mii_bitbang_write,
        !           248:        {
        !           249:                PHYSMGMT_DATA,          /* MII_BIT_MDO */
        !           250:                PHYSMGMT_DATA,          /* MII_BIT_MDI */
        !           251:                PHYSMGMT_CLK,           /* MII_BIT_MDC */
        !           252:                PHYSMGMT_DIR,           /* MII_BIT_DIR_HOST_PHY */
        !           253:                0,                      /* MII_BIT_DIR_PHY_HOST */
        !           254:        }
        !           255: };
        !           256:
        !           257: /*
1.42      thorpej   258:  * Some chips (3c515 [Corkscrew] and 3c574 [RoadRunner]) have
                    259:  * Window 1 registers offset!
                    260:  */
                    261: static __inline int
                    262: ep_w1_reg(sc, reg)
                    263:        struct ep_softc *sc;
                    264:        int reg;
                    265: {
                    266:
                    267:        switch (sc->ep_chipset) {
1.47      fvdl      268:        case ELINK_CHIPSET_CORKSCREW:
1.42      thorpej   269:                return (reg + 0x10);
                    270:
1.47      fvdl      271:        case ELINK_CHIPSET_ROADRUNNER:
1.42      thorpej   272:                switch (reg) {
1.47      fvdl      273:                case ELINK_W1_FREE_TX:
                    274:                case ELINK_W1_RUNNER_RDCTL:
                    275:                case ELINK_W1_RUNNER_WRCTL:
1.42      thorpej   276:                        return (reg);
                    277:                }
                    278:                return (reg + 0x10);
                    279:        }
                    280:
                    281:        return (reg);
                    282: }
1.19      jonathan  283:
                    284: /*
1.56      jonathan  285:  * Wait for any pending reset to complete.
1.19      jonathan  286:  * On newer hardware we could poll SC_COMMAND_IN_PROGRESS,
                    287:  * but older hardware doesn't implement it and we must delay.
                    288:  */
                    289: static inline void
1.56      jonathan  290: ep_finish_reset(iot, ioh)
                    291:        bus_space_tag_t iot;
                    292:        bus_space_handle_t ioh;
                    293: {
1.57      jonathan  294:        int i;
1.56      jonathan  295:
1.57      jonathan  296:        for (i = 0; i < 10000; i++) {
1.58.2.1! wrstuden  297:                if ((bus_space_read_2(iot, ioh, ELINK_STATUS) &
        !           298:                    S_COMMAND_IN_PROGRESS) == 0)
1.57      jonathan  299:                        break;
                    300:                DELAY(10);
1.56      jonathan  301:        }
                    302: }
                    303:
                    304: /*
                    305:  * Issue a (reset) command, and be sure it has completed.
                    306:  * Used for global reset, TX_RESET, RX_RESET.
                    307:  */
                    308: static inline void
                    309: ep_reset_cmd(sc, cmd, arg)
1.19      jonathan  310:        struct ep_softc *sc;
                    311:        u_int cmd, arg;
                    312: {
                    313:        register bus_space_tag_t iot = sc->sc_iot;
                    314:        register bus_space_handle_t ioh = sc->sc_ioh;
                    315:
                    316:        bus_space_write_2(iot, ioh, cmd, arg);
1.56      jonathan  317:        ep_finish_reset(iot, ioh);
                    318: }
                    319:
                    320:
                    321: static inline void
                    322: ep_discard_rxtop(iot, ioh)
                    323:        register bus_space_tag_t iot;
                    324:        register bus_space_handle_t ioh;
                    325: {
1.57      jonathan  326:        int i;
1.56      jonathan  327:
                    328:        bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_DISCARD_TOP_PACK);
1.57      jonathan  329:
                    330:         /*
                    331:         * Spin for about 1 msec, to avoid forcing a DELAY() between
                    332:         * every received packet (adding latency and  limiting pkt-recv rate).
                    333:         * On PCI, at 4 30-nsec PCI bus cycles for a read, 8000 iterations
                    334:         * is about right.
                    335:         */
                    336:        for (i = 0; i < 8000; i++) {
1.58.2.1! wrstuden  337:                if ((bus_space_read_2(iot, ioh, ELINK_STATUS) &
        !           338:                    S_COMMAND_IN_PROGRESS) == 0)
1.57      jonathan  339:                    return;
                    340:        }
                    341:
                    342:        /*  Didn't complete in a hurry. Do DELAY()s. */
1.56      jonathan  343:        ep_finish_reset(iot, ioh);
1.19      jonathan  344: }
                    345:
1.20      jonathan  346: /*
                    347:  * Back-end attach and configure.
                    348:  */
1.1       thorpej   349: void
1.34      thorpej   350: epconfig(sc, chipset, enaddr)
1.1       thorpej   351:        struct ep_softc *sc;
1.20      jonathan  352:        u_short chipset;
1.34      thorpej   353:        u_int8_t *enaddr;
1.1       thorpej   354: {
1.21      is        355:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.11      thorpej   356:        bus_space_tag_t iot = sc->sc_iot;
                    357:        bus_space_handle_t ioh = sc->sc_ioh;
1.7       thorpej   358:        u_int16_t i;
1.21      is        359:        u_int8_t myla[6];
1.1       thorpej   360:
1.20      jonathan  361:        sc->ep_chipset = chipset;
1.32      thorpej   362:
                    363:        /*
                    364:         * We could have been groveling around in other register
                    365:         * windows in the front-end; make sure we're in window 0
                    366:         * to read the EEPROM.
                    367:         */
                    368:        GO_WINDOW(0);
1.1       thorpej   369:
1.34      thorpej   370:        if (enaddr == NULL) {
                    371:                /*
1.58.2.1! wrstuden  372:                 * Read the station address from the eeprom.
1.34      thorpej   373:                 */
                    374:                for (i = 0; i < 3; i++) {
1.58.2.1! wrstuden  375:                        u_int16_t x = ep_read_eeprom(sc, i);
1.34      thorpej   376:                        myla[(i << 1)] = x >> 8;
                    377:                        myla[(i << 1) + 1] = x;
                    378:                }
                    379:                enaddr = myla;
1.1       thorpej   380:        }
                    381:
1.12      jonathan  382:        /*
1.41      thorpej   383:         * Vortex-based (3c59x pci,eisa) and Boomerang (3c900) cards
1.23      jonathan  384:         * allow FDDI-sized (4500) byte packets.  Commands only take an
                    385:         * 11-bit parameter, and  11 bits isn't enough to hold a full-size
                    386:         * packet length.
1.12      jonathan  387:         * Commands to these cards implicitly upshift a packet size
                    388:         * or threshold by 2 bits.
                    389:         * To detect  cards with large-packet support, we probe by setting
                    390:         * the transmit threshold register, then change windows and
                    391:         * read back the threshold register directly, and see if the
                    392:         * threshold value was shifted or not.
                    393:         */
1.47      fvdl      394:        bus_space_write_2(iot, ioh, ELINK_COMMAND,
1.58.2.1! wrstuden  395:            SET_TX_AVAIL_THRESH | ELINK_LARGEWIN_PROBE);
1.12      jonathan  396:        GO_WINDOW(5);
1.47      fvdl      397:        i = bus_space_read_2(iot, ioh, ELINK_W5_TX_AVAIL_THRESH);
1.12      jonathan  398:        GO_WINDOW(1);
                    399:        switch (i)  {
1.47      fvdl      400:        case ELINK_LARGEWIN_PROBE:
                    401:        case (ELINK_LARGEWIN_PROBE & ELINK_LARGEWIN_MASK):
1.12      jonathan  402:                sc->ep_pktlenshift = 0;
                    403:                break;
                    404:
1.47      fvdl      405:        case (ELINK_LARGEWIN_PROBE << 2):
1.12      jonathan  406:                sc->ep_pktlenshift = 2;
                    407:                break;
                    408:
                    409:        default:
1.34      thorpej   410:                printf("%s: wrote 0x%x to TX_AVAIL_THRESH, read back 0x%x. "
1.14      cjs       411:                    "Interface disabled\n",
1.47      fvdl      412:                    sc->sc_dev.dv_xname, ELINK_LARGEWIN_PROBE, (int) i);
1.12      jonathan  413:                return;
                    414:        }
1.20      jonathan  415:
1.12      jonathan  416:        /*
                    417:         * Ensure Tx-available interrupts are enabled for
                    418:         * start the interface.
1.23      jonathan  419:         * XXX should be in epinit()?
1.12      jonathan  420:         */
1.47      fvdl      421:        bus_space_write_2(iot, ioh, ELINK_COMMAND,
1.12      jonathan  422:            SET_TX_AVAIL_THRESH | (1600 >> sc->ep_pktlenshift));
                    423:
1.23      jonathan  424:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                    425:        ifp->if_softc = sc;
                    426:        ifp->if_start = epstart;
                    427:        ifp->if_ioctl = epioctl;
                    428:        ifp->if_watchdog = epwatchdog;
                    429:        ifp->if_flags =
                    430:            IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
                    431:
                    432:        if_attach(ifp);
1.34      thorpej   433:        ether_ifattach(ifp, enaddr);
1.23      jonathan  434:
                    435:        /*
                    436:         * Finish configuration:
                    437:         * determine chipset if the front-end couldn't do so,
                    438:         * show board details, set media.
                    439:         */
                    440:
1.41      thorpej   441:        /*
                    442:         * Print RAM size.  We also print the Ethernet address in here.
                    443:         * It's extracted from the ifp, so we have to make sure it's
                    444:         * been attached first.
                    445:         */
1.23      jonathan  446:        ep_internalconfig(sc);
                    447:        GO_WINDOW(0);
                    448:
1.41      thorpej   449:        /*
1.44      thorpej   450:         * Display some additional information, if pertinent.
                    451:         */
1.47      fvdl      452:        if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER)
1.44      thorpej   453:                printf("%s: RoadRunner FIFO buffer enabled\n",
                    454:                    sc->sc_dev.dv_xname);
                    455:
                    456:        /*
1.41      thorpej   457:         * Initialize our media structures and MII info.  We'll
                    458:         * probe the MII if we discover that we have one.
1.20      jonathan  459:         */
1.41      thorpej   460:        sc->sc_mii.mii_ifp = ifp;
                    461:        sc->sc_mii.mii_readreg = ep_mii_readreg;
                    462:        sc->sc_mii.mii_writereg = ep_mii_writereg;
                    463:        sc->sc_mii.mii_statchg = ep_statchg;
                    464:        ifmedia_init(&sc->sc_mii.mii_media, 0, ep_media_change,
                    465:            ep_media_status);
1.20      jonathan  466:
                    467:        /*
1.41      thorpej   468:         * Now, determine which media we have.
1.20      jonathan  469:         */
                    470:        switch (sc->ep_chipset) {
1.47      fvdl      471:        case ELINK_CHIPSET_ROADRUNNER:
1.58.2.1! wrstuden  472:                if (sc->ep_flags & ELINK_FLAGS_MII) {
        !           473:                        ep_roadrunner_mii_enable(sc);
        !           474:                        GO_WINDOW(0);
        !           475:                }
        !           476:                /* FALLTHROUGH */
        !           477:
        !           478:        case ELINK_CHIPSET_BOOMERANG:
1.41      thorpej   479:                /*
                    480:                 * If the device has MII, probe it.  We won't be using
                    481:                 * any `native' media in this case, only PHYs.  If
                    482:                 * we don't, just treat the Boomerang like the Vortex.
                    483:                 */
1.47      fvdl      484:                if (sc->ep_flags & ELINK_FLAGS_MII) {
1.58.2.1! wrstuden  485:                        mii_phy_probe(&sc->sc_dev, &sc->sc_mii, 0xffffffff,
        !           486:                            MII_PHY_ANY, MII_OFFSET_ANY);
1.41      thorpej   487:                        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
                    488:                                ifmedia_add(&sc->sc_mii.mii_media,
                    489:                                    IFM_ETHER|IFM_NONE, 0, NULL);
                    490:                                ifmedia_set(&sc->sc_mii.mii_media,
                    491:                                    IFM_ETHER|IFM_NONE);
                    492:                        } else {
                    493:                                ifmedia_set(&sc->sc_mii.mii_media,
                    494:                                    IFM_ETHER|IFM_AUTO);
                    495:                        }
                    496:                        break;
                    497:                }
                    498:                /* FALLTHROUGH */
                    499:
1.47      fvdl      500:        case ELINK_CHIPSET_VORTEX:
1.20      jonathan  501:                ep_vortex_probemedia(sc);
                    502:                break;
                    503:
                    504:        default:
1.41      thorpej   505:                ep_509_probemedia(sc);
1.20      jonathan  506:                break;
                    507:        }
1.23      jonathan  508:
1.20      jonathan  509:        GO_WINDOW(1);           /* Window 1 is operating window */
                    510:
1.1       thorpej   511: #if NBPFILTER > 0
1.58.2.1! wrstuden  512:        bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
1.1       thorpej   513: #endif
                    514:
1.35      explorer  515: #if NRND > 0
1.53      explorer  516:        rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
1.58.2.1! wrstuden  517:            RND_TYPE_NET, 0);
1.35      explorer  518: #endif
                    519:
1.1       thorpej   520:        sc->tx_start_thresh = 20;       /* probably a good starting point. */
1.12      jonathan  521:
1.16      jonathan  522:        /*  Establish callback to reset card when we reboot. */
                    523:        shutdownhook_establish(epshutdown, sc);
                    524:
1.56      jonathan  525:        ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET);
                    526:        ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
1.1       thorpej   527: }
                    528:
1.23      jonathan  529:
1.1       thorpej   530: /*
1.15      jonathan  531:  * Show interface-model-independent info from window 3
                    532:  * internal-configuration register.
                    533:  */
                    534: void
                    535: ep_internalconfig(sc)
                    536:        struct ep_softc *sc;
                    537: {
                    538:        bus_space_tag_t iot = sc->sc_iot;
                    539:        bus_space_handle_t ioh = sc->sc_ioh;
                    540:
                    541:        u_int config0;
                    542:        u_int config1;
                    543:
                    544:        int  ram_size, ram_width, ram_speed, rom_size, ram_split;
                    545:        /*
                    546:         * NVRAM buffer Rx:Tx config names for busmastering cards
                    547:         * (Demon, Vortex, and later).
                    548:         */
                    549:        const char *onboard_ram_config[] = {
1.38      augustss  550:                "5:3", "3:1", "1:1", "3:5" };
1.15      jonathan  551:
                    552:        GO_WINDOW(3);
1.47      fvdl      553:        config0 = (u_int)bus_space_read_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG);
1.58.2.1! wrstuden  554:        config1 = (u_int)bus_space_read_2(iot, ioh,
        !           555:            ELINK_W3_INTERNAL_CONFIG + 2);
1.15      jonathan  556:        GO_WINDOW(0);
                    557:
                    558:        ram_size  = (config0 & CONFIG_RAMSIZE) >> CONFIG_RAMSIZE_SHIFT;
                    559:        ram_width = (config0 & CONFIG_RAMWIDTH) >> CONFIG_RAMWIDTH_SHIFT;
                    560:        ram_speed = (config0 & CONFIG_RAMSPEED) >> CONFIG_RAMSPEED_SHIFT;
                    561:        rom_size  = (config0 & CONFIG_ROMSIZE) >> CONFIG_ROMSIZE_SHIFT;
                    562:
                    563:        ram_split  = (config1 & CONFIG_RAMSPLIT) >> CONFIG_RAMSPLIT_SHIFT;
                    564:
1.41      thorpej   565:        printf("%s: address %s, %dKB %s-wide FIFO, %s Rx:Tx split\n",
1.23      jonathan  566:               sc->sc_dev.dv_xname,
1.41      thorpej   567:               ether_sprintf(LLADDR(sc->sc_ethercom.ec_if.if_sadl)),
1.23      jonathan  568:               8 << ram_size,
                    569:               (ram_width) ? "word" : "byte",
                    570:               onboard_ram_config[ram_split]);
1.15      jonathan  571: }
                    572:
1.23      jonathan  573:
1.20      jonathan  574: /*
1.23      jonathan  575:  * Find supported media on 3c509-generation hardware that doesn't have
1.20      jonathan  576:  * a "reset_options" register in window 3.
1.23      jonathan  577:  * Use the config_cntrl register  in window 0 instead.
                    578:  * Used on original, 10Mbit ISA (3c509), 3c509B, and pre-Demon EISA cards
                    579:  * that implement  CONFIG_CTRL.  We don't have a good way to set the
                    580:  * default active mediuim; punt to ifconfig  instead.
1.20      jonathan  581:  */
                    582: void
1.41      thorpej   583: ep_509_probemedia(sc)
1.20      jonathan  584:        struct ep_softc *sc;
                    585: {
                    586:        bus_space_tag_t iot = sc->sc_iot;
                    587:        bus_space_handle_t ioh = sc->sc_ioh;
1.41      thorpej   588:        struct ifmedia *ifm = &sc->sc_mii.mii_media;
1.23      jonathan  589:        u_int16_t ep_w0_config, port;
1.41      thorpej   590:        struct ep_media *epm;
                    591:        const char *sep = "", *defmedianame = NULL;
                    592:        int defmedia = 0;
1.23      jonathan  593:
1.20      jonathan  594:        GO_WINDOW(0);
1.47      fvdl      595:        ep_w0_config = bus_space_read_2(iot, ioh, ELINK_W0_CONFIG_CTRL);
1.23      jonathan  596:
1.41      thorpej   597:        printf("%s: ", sc->sc_dev.dv_xname);
1.23      jonathan  598:
1.41      thorpej   599:        /* Sanity check that there are any media! */
1.47      fvdl      600:        if ((ep_w0_config & ELINK_W0_CC_MEDIAMASK) == 0) {
1.41      thorpej   601:                printf("no media present!\n");
                    602:                ifmedia_add(ifm, IFM_ETHER|IFM_NONE, 0, NULL);
                    603:                ifmedia_set(ifm, IFM_ETHER|IFM_NONE);
                    604:                return;
1.23      jonathan  605:        }
                    606:
1.41      thorpej   607:        /*
                    608:         * Get the default media from the EEPROM.
                    609:         */
1.58.2.1! wrstuden  610:        port = ep_read_eeprom(sc, EEPROM_ADDR_CFG) >> 14;
1.23      jonathan  611:
1.41      thorpej   612: #define        PRINT(s)        printf("%s%s", sep, s); sep = ", "
1.23      jonathan  613:
1.41      thorpej   614:        for (epm = ep_509_media; epm->epm_name != NULL; epm++) {
                    615:                if (ep_w0_config & epm->epm_mpbit) {
1.46      thorpej   616:                        /*
                    617:                         * This simple test works because 509 chipsets
                    618:                         * don't do full-duplex.
                    619:                         */
1.41      thorpej   620:                        if (epm->epm_epmedia == port || defmedia == 0) {
                    621:                                defmedia = epm->epm_ifmedia;
                    622:                                defmedianame = epm->epm_name;
                    623:                        }
                    624:                        ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_epmedia,
                    625:                            NULL);
                    626:                        PRINT(epm->epm_name);
                    627:                }
                    628:        }
                    629:
                    630: #undef PRINT
                    631:
                    632: #ifdef DIAGNOSTIC
                    633:        if (defmedia == 0)
                    634:                panic("ep_509_probemedia: impossible");
                    635: #endif
                    636:
                    637:        printf(" (default %s)\n", defmedianame);
                    638:        ifmedia_set(ifm, defmedia);
1.20      jonathan  639: }
                    640:
1.15      jonathan  641: /*
1.23      jonathan  642:  * Find media present on large-packet-capable elink3 devices.
                    643:  * Show onboard configuration of large-packet-capable elink3 devices
                    644:  * (Demon, Vortex, Boomerang), which do not implement CONFIG_CTRL in window 0.
                    645:  * Use media and card-version info in window 3 instead.
1.15      jonathan  646:  */
                    647: void
1.20      jonathan  648: ep_vortex_probemedia(sc)
1.15      jonathan  649:        struct ep_softc *sc;
                    650: {
                    651:        bus_space_tag_t iot = sc->sc_iot;
                    652:        bus_space_handle_t ioh = sc->sc_ioh;
1.41      thorpej   653:        struct ifmedia *ifm = &sc->sc_mii.mii_media;
                    654:        struct ep_media *epm;
                    655:        u_int config1;
1.15      jonathan  656:        int reset_options;
1.28      veego     657:        int default_media;      /* 3-bit encoding of default (EEPROM) media */
1.41      thorpej   658:        int defmedia = 0;
                    659:        const char *sep = "", *defmedianame = NULL;
1.15      jonathan  660:
                    661:        GO_WINDOW(3);
1.58.2.1! wrstuden  662:        config1 = (u_int)bus_space_read_2(iot, ioh,
        !           663:            ELINK_W3_INTERNAL_CONFIG + 2);
1.47      fvdl      664:        reset_options = (int)bus_space_read_1(iot, ioh, ELINK_W3_RESET_OPTIONS);
1.15      jonathan  665:        GO_WINDOW(0);
                    666:
1.23      jonathan  667:        default_media = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
1.15      jonathan  668:
1.41      thorpej   669:        printf("%s: ", sc->sc_dev.dv_xname);
                    670:
                    671:        /* Sanity check that there are any media! */
1.47      fvdl      672:        if ((reset_options & ELINK_PCI_MEDIAMASK) == 0) {
1.41      thorpej   673:                printf("no media present!\n");
                    674:                ifmedia_add(ifm, IFM_ETHER|IFM_NONE, 0, NULL);
                    675:                ifmedia_set(ifm, IFM_ETHER|IFM_NONE);
                    676:                return;
                    677:        }
                    678:
                    679: #define        PRINT(s)        printf("%s%s", sep, s); sep = ", "
1.23      jonathan  680:
1.41      thorpej   681:        for (epm = ep_vortex_media; epm->epm_name != NULL; epm++) {
                    682:                if (reset_options & epm->epm_mpbit) {
1.46      thorpej   683:                        /*
                    684:                         * Default media is a little more complicated
                    685:                         * on the Vortex.  We support full-duplex which
                    686:                         * uses the same reset options bit.
                    687:                         *
                    688:                         * XXX Check EEPROM for default to FDX?
                    689:                         */
                    690:                        if (epm->epm_epmedia == default_media) {
                    691:                                if ((epm->epm_ifmedia & IFM_FDX) == 0) {
                    692:                                        defmedia = epm->epm_ifmedia;
                    693:                                        defmedianame = epm->epm_name;
                    694:                                }
                    695:                        } else if (defmedia == 0) {
1.41      thorpej   696:                                defmedia = epm->epm_ifmedia;
                    697:                                defmedianame = epm->epm_name;
                    698:                        }
                    699:                        ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_epmedia,
                    700:                            NULL);
                    701:                        PRINT(epm->epm_name);
1.23      jonathan  702:                }
                    703:        }
1.15      jonathan  704:
1.41      thorpej   705: #undef PRINT
                    706:
                    707: #ifdef DIAGNOSTIC
                    708:        if (defmedia == 0)
                    709:                panic("ep_vortex_probemedia: impossible");
                    710: #endif
                    711:
                    712:        printf(" (default %s)\n", defmedianame);
                    713:        ifmedia_set(ifm, defmedia);
                    714: }
                    715:
                    716: /*
                    717:  * One second timer, used to tick the MII.
                    718:  */
                    719: void
                    720: ep_tick(arg)
                    721:        void *arg;
                    722: {
                    723:        struct ep_softc *sc = arg;
                    724:        int s;
1.15      jonathan  725:
1.41      thorpej   726: #ifdef DIAGNOSTIC
1.47      fvdl      727:        if ((sc->ep_flags & ELINK_FLAGS_MII) == 0)
1.41      thorpej   728:                panic("ep_tick");
                    729: #endif
1.31      jonathan  730:
1.41      thorpej   731:        s = splnet();
                    732:        mii_tick(&sc->sc_mii);
                    733:        splx(s);
1.15      jonathan  734:
1.41      thorpej   735:        timeout(ep_tick, sc, hz);
1.15      jonathan  736: }
                    737:
                    738: /*
1.20      jonathan  739:  * Bring device up.
                    740:  *
1.1       thorpej   741:  * The order in here seems important. Otherwise we may not receive
                    742:  * interrupts. ?!
                    743:  */
                    744: void
                    745: epinit(sc)
                    746:        register struct ep_softc *sc;
                    747: {
1.21      is        748:        register struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.11      thorpej   749:        bus_space_tag_t iot = sc->sc_iot;
                    750:        bus_space_handle_t ioh = sc->sc_ioh;
1.1       thorpej   751:        int i;
                    752:
1.56      jonathan  753:        /* Make sure any pending reset has completed before touching board. */
                    754:        ep_finish_reset(iot, ioh);
                    755:
1.58.2.1! wrstuden  756:        /*
        !           757:         * Cance any pending I/O.
        !           758:         */
        !           759:        epstop(sc);
1.1       thorpej   760:
1.47      fvdl      761:        if (sc->bustype != ELINK_BUS_PCI) {
1.1       thorpej   762:                GO_WINDOW(0);
1.47      fvdl      763:                bus_space_write_2(iot, ioh, ELINK_W0_CONFIG_CTRL, 0);
1.58.2.1! wrstuden  764:                bus_space_write_2(iot, ioh, ELINK_W0_CONFIG_CTRL,
        !           765:                    ENABLE_DRQ_IRQ);
1.1       thorpej   766:        }
                    767:
1.47      fvdl      768:        if (sc->bustype == ELINK_BUS_PCMCIA) {
                    769:                bus_space_write_2(iot, ioh, ELINK_W0_RESOURCE_CFG, 0x3f00);
1.1       thorpej   770:        }
                    771:
                    772:        GO_WINDOW(2);
                    773:        for (i = 0; i < 6; i++) /* Reload the ether_addr. */
1.47      fvdl      774:                bus_space_write_1(iot, ioh, ELINK_W2_ADDR_0 + i,
1.21      is        775:                    LLADDR(ifp->if_sadl)[i]);
1.8       christos  776:
1.12      jonathan  777:        /*
                    778:         * Reset the station-address receive filter.
1.41      thorpej   779:         * A bug workaround for busmastering (Vortex, Demon) cards.
1.12      jonathan  780:         */
                    781:        for (i = 0; i < 6; i++)
1.47      fvdl      782:                bus_space_write_1(iot, ioh, ELINK_W2_RECVMASK_0 + i, 0);
1.1       thorpej   783:
1.56      jonathan  784:        ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET);
                    785:        ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
1.1       thorpej   786:
                    787:        GO_WINDOW(1);           /* Window 1 is operating window */
                    788:        for (i = 0; i < 31; i++)
1.47      fvdl      789:                bus_space_read_1(iot, ioh, ep_w1_reg(sc, ELINK_W1_TX_STATUS));
1.31      jonathan  790:
                    791:        /* Set threshhold for for Tx-space avaiable interrupt. */
1.47      fvdl      792:        bus_space_write_2(iot, ioh, ELINK_COMMAND,
1.31      jonathan  793:            SET_TX_AVAIL_THRESH | (1600 >> sc->ep_pktlenshift));
1.1       thorpej   794:
1.47      fvdl      795:        if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) {
1.44      thorpej   796:                /*
                    797:                 * Enable options in the PCMCIA LAN COR register, via
                    798:                 * RoadRunner Window 1.
                    799:                 *
                    800:                 * XXX MAGIC CONSTANTS!
                    801:                 */
                    802:                u_int16_t cor;
                    803:
1.47      fvdl      804:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, (1 << 11));
1.44      thorpej   805:
                    806:                cor = bus_space_read_2(iot, ioh, 0) & ~0x30;
1.47      fvdl      807:                if (sc->ep_flags & ELINK_FLAGS_USESHAREDMEM)
1.44      thorpej   808:                        cor |= 0x10;
1.47      fvdl      809:                if (sc->ep_flags & ELINK_FLAGS_FORCENOWAIT)
1.44      thorpej   810:                        cor |= 0x20;
                    811:                bus_space_write_2(iot, ioh, 0, cor);
                    812:
1.47      fvdl      813:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 0);
                    814:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0);
1.58.2.1! wrstuden  815:
        !           816:                if (sc->ep_flags & ELINK_FLAGS_MII) {
        !           817:                        ep_roadrunner_mii_enable(sc);
        !           818:                        GO_WINDOW(1);
        !           819:                }
1.44      thorpej   820:        }
                    821:
1.18      jonathan  822:        /* Enable interrupts. */
1.58.2.1! wrstuden  823:        bus_space_write_2(iot, ioh, ELINK_COMMAND,
        !           824:            SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE |
        !           825:            S_TX_AVAIL);
        !           826:        bus_space_write_2(iot, ioh, ELINK_COMMAND,
        !           827:            SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE |
        !           828:            S_TX_AVAIL);
1.1       thorpej   829:
                    830:        /*
                    831:         * Attempt to get rid of any stray interrupts that occured during
                    832:         * configuration.  On the i386 this isn't possible because one may
                    833:         * already be queued.  However, a single stray interrupt is
                    834:         * unimportant.
                    835:         */
1.47      fvdl      836:        bus_space_write_2(iot, ioh, ELINK_COMMAND, ACK_INTR | 0xff);
1.1       thorpej   837:
                    838:        epsetfilter(sc);
1.41      thorpej   839:        epsetmedia(sc);
1.1       thorpej   840:
1.47      fvdl      841:        bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_ENABLE);
                    842:        bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE);
1.1       thorpej   843:
                    844:        epmbuffill(sc);
                    845:
                    846:        /* Interface is now `running', with no output active. */
                    847:        ifp->if_flags |= IFF_RUNNING;
                    848:        ifp->if_flags &= ~IFF_OACTIVE;
                    849:
1.47      fvdl      850:        if (sc->ep_flags & ELINK_FLAGS_MII) {
1.41      thorpej   851:                /* Start the one second clock. */
                    852:                timeout(ep_tick, sc, hz);
                    853:        }
                    854:
1.1       thorpej   855:        /* Attempt to start output, if any. */
                    856:        epstart(ifp);
                    857: }
                    858:
1.20      jonathan  859:
                    860: /*
                    861:  * Set multicast receive filter.
                    862:  * elink3 hardware has no selective multicast filter in hardware.
                    863:  * Enable reception of all multicasts and filter in software.
                    864:  */
1.1       thorpej   865: void
                    866: epsetfilter(sc)
                    867:        register struct ep_softc *sc;
                    868: {
1.21      is        869:        register struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.1       thorpej   870:
                    871:        GO_WINDOW(1);           /* Window 1 is operating window */
1.58.2.1! wrstuden  872:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND,
        !           873:            SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST |
        !           874:            ((ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0) |
        !           875:            ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0));
1.1       thorpej   876: }
                    877:
1.23      jonathan  878: int
                    879: ep_media_change(ifp)
                    880:        struct ifnet *ifp;
                    881: {
                    882:        register struct ep_softc *sc = ifp->if_softc;
                    883:
1.41      thorpej   884:        if (sc->enabled && (ifp->if_flags & IFF_UP) != 0)
                    885:                epreset(sc);
1.34      thorpej   886:
                    887:        return (0);
1.23      jonathan  888: }
                    889:
1.15      jonathan  890: /*
1.58.2.1! wrstuden  891:  * Reset and enable the MII on the RoadRunner.
        !           892:  */
        !           893: void
        !           894: ep_roadrunner_mii_enable(sc)
        !           895:        struct ep_softc *sc;
        !           896: {
        !           897:        bus_space_tag_t iot = sc->sc_iot;
        !           898:        bus_space_handle_t ioh = sc->sc_ioh;
        !           899:
        !           900:        GO_WINDOW(3);
        !           901:        bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
        !           902:            ELINK_PCI_100BASE_MII|ELINK_RUNNER_ENABLE_MII);
        !           903:        delay(1000);
        !           904:        bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
        !           905:            ELINK_PCI_100BASE_MII|ELINK_RUNNER_MII_RESET|
        !           906:            ELINK_RUNNER_ENABLE_MII);
        !           907:        ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
        !           908:        ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET);
        !           909:        delay(1000);
        !           910:        bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
        !           911:            ELINK_PCI_100BASE_MII|ELINK_RUNNER_ENABLE_MII);
        !           912: }
        !           913:
        !           914: /*
1.41      thorpej   915:  * Set the card to use the specified media.
1.15      jonathan  916:  */
1.34      thorpej   917: void
1.41      thorpej   918: epsetmedia(sc)
                    919:        struct ep_softc *sc;
1.1       thorpej   920: {
1.11      thorpej   921:        bus_space_tag_t iot = sc->sc_iot;
                    922:        bus_space_handle_t ioh = sc->sc_ioh;
1.23      jonathan  923:
1.41      thorpej   924:        /* Turn everything off.  First turn off linkbeat and UTP. */
1.1       thorpej   925:        GO_WINDOW(4);
1.47      fvdl      926:        bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE, 0x0);
1.23      jonathan  927:
                    928:        /* Turn off coax */
1.47      fvdl      929:        bus_space_write_2(iot, ioh, ELINK_COMMAND, STOP_TRANSCEIVER);
1.23      jonathan  930:        delay(1000);
                    931:
1.29      jonathan  932:        /*
1.41      thorpej   933:         * If the device has MII, select it, and then tell the
                    934:         * PHY which media to use.
                    935:         */
1.47      fvdl      936:        if (sc->ep_flags & ELINK_FLAGS_MII) {
1.41      thorpej   937:                int config0, config1;
                    938:
                    939:                GO_WINDOW(3);
1.44      thorpej   940:
1.47      fvdl      941:                if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) {
1.44      thorpej   942:                        int resopt;
                    943:
                    944:                        resopt = bus_space_read_2(iot, ioh,
1.47      fvdl      945:                            ELINK_W3_RESET_OPTIONS);
1.58.2.1! wrstuden  946:                        bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
        !           947:                            resopt | ELINK_RUNNER_ENABLE_MII);
1.44      thorpej   948:                }
                    949:
1.41      thorpej   950:                config0 = (u_int)bus_space_read_2(iot, ioh,
1.47      fvdl      951:                    ELINK_W3_INTERNAL_CONFIG);
1.41      thorpej   952:                config1 = (u_int)bus_space_read_2(iot, ioh,
1.47      fvdl      953:                    ELINK_W3_INTERNAL_CONFIG + 2);
1.41      thorpej   954:
                    955:                config1 = config1 & ~CONFIG_MEDIAMASK;
1.47      fvdl      956:                config1 |= (ELINKMEDIA_MII << CONFIG_MEDIAMASK_SHIFT);
1.41      thorpej   957:
1.47      fvdl      958:                bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG, config0);
1.58.2.1! wrstuden  959:                bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG + 2,
        !           960:                    config1);
1.41      thorpej   961:                GO_WINDOW(1);   /* back to operating window */
                    962:
                    963:                mii_mediachg(&sc->sc_mii);
                    964:                return;
                    965:        }
                    966:
                    967:        /*
1.29      jonathan  968:         * Now turn on the selected media/transceiver.
                    969:         */
                    970:        GO_WINDOW(4);
1.41      thorpej   971:        switch (IFM_SUBTYPE(sc->sc_mii.mii_media.ifm_cur->ifm_media)) {
                    972:        case IFM_10_T:
1.47      fvdl      973:                bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE,
1.41      thorpej   974:                    JABBER_GUARD_ENABLE|LINKBEAT_ENABLE);
1.23      jonathan  975:                break;
                    976:
1.41      thorpej   977:        case IFM_10_2:
1.47      fvdl      978:                bus_space_write_2(iot, ioh, ELINK_COMMAND, START_TRANSCEIVER);
1.23      jonathan  979:                DELAY(1000);    /* 50ms not enmough? */
                    980:                break;
                    981:
1.41      thorpej   982:        case IFM_100_TX:
                    983:        case IFM_100_FX:
                    984:        case IFM_100_T4:                /* XXX check documentation */
1.47      fvdl      985:                bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE,
1.41      thorpej   986:                    LINKBEAT_ENABLE);
1.23      jonathan  987:                DELAY(1000);    /* not strictly necessary? */
                    988:                break;
                    989:
1.41      thorpej   990:        case IFM_10_5:
1.47      fvdl      991:                bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE,
1.41      thorpej   992:                    SQE_ENABLE);
                    993:                DELAY(1000);    /* not strictly necessary? */
                    994:                break;
                    995:
                    996:        case IFM_MANUAL:
                    997:                /*
                    998:                 * Nothing to do here; we are actually enabling the
                    999:                 * external PHY on the MII port.
                   1000:                 */
1.23      jonathan 1001:                break;
1.41      thorpej  1002:
                   1003:        case IFM_NONE:
                   1004:                printf("%s: interface disabled\n", sc->sc_dev.dv_xname);
                   1005:                return;
                   1006:
1.23      jonathan 1007:        default:
1.41      thorpej  1008:                panic("epsetmedia: impossible");
1.1       thorpej  1009:        }
1.23      jonathan 1010:
                   1011:        /*
1.41      thorpej  1012:         * Tell the chip which port to use.
1.23      jonathan 1013:         */
1.41      thorpej  1014:        switch (sc->ep_chipset) {
1.47      fvdl     1015:        case ELINK_CHIPSET_VORTEX:
                   1016:        case ELINK_CHIPSET_BOOMERANG:
1.41      thorpej  1017:            {
1.45      thorpej  1018:                int mctl, config0, config1;
1.23      jonathan 1019:
                   1020:                GO_WINDOW(3);
                   1021:                config0 = (u_int)bus_space_read_2(iot, ioh,
1.47      fvdl     1022:                    ELINK_W3_INTERNAL_CONFIG);
1.23      jonathan 1023:                config1 = (u_int)bus_space_read_2(iot, ioh,
1.47      fvdl     1024:                    ELINK_W3_INTERNAL_CONFIG + 2);
1.23      jonathan 1025:
                   1026:                config1 = config1 & ~CONFIG_MEDIAMASK;
1.41      thorpej  1027:                config1 |= (sc->sc_mii.mii_media.ifm_cur->ifm_data <<
                   1028:                    CONFIG_MEDIAMASK_SHIFT);
                   1029:
1.47      fvdl     1030:                bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG, config0);
                   1031:                bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG + 2,
                   1032:                    config1);
1.45      thorpej  1033:
1.47      fvdl     1034:                mctl = bus_space_read_2(iot, ioh, ELINK_W3_MAC_CONTROL);
1.45      thorpej  1035:                if (sc->sc_mii.mii_media.ifm_cur->ifm_media & IFM_FDX)
                   1036:                        mctl |= MAC_CONTROL_FDX;
                   1037:                else
                   1038:                        mctl &= ~MAC_CONTROL_FDX;
1.47      fvdl     1039:                bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl);
1.41      thorpej  1040:                break;
                   1041:            }
                   1042:        default:
                   1043:            {
                   1044:                int w0_addr_cfg;
1.28      veego    1045:
                   1046:                GO_WINDOW(0);
1.47      fvdl     1047:                w0_addr_cfg = bus_space_read_2(iot, ioh, ELINK_W0_ADDRESS_CFG);
1.29      jonathan 1048:                w0_addr_cfg &= 0x3fff;
1.47      fvdl     1049:                bus_space_write_2(iot, ioh, ELINK_W0_ADDRESS_CFG, w0_addr_cfg |
1.41      thorpej  1050:                    (sc->sc_mii.mii_media.ifm_cur->ifm_data << 14));
1.28      veego    1051:                DELAY(1000);
1.41      thorpej  1052:                break;
                   1053:            }
1.23      jonathan 1054:        }
                   1055:
                   1056:        GO_WINDOW(1);           /* Window 1 is operating window */
                   1057: }
                   1058:
                   1059: /*
                   1060:  * Get currently-selected media from card.
                   1061:  * (if_media callback, may be called before interface is brought up).
                   1062:  */
                   1063: void
                   1064: ep_media_status(ifp, req)
                   1065:        struct ifnet *ifp;
                   1066:        struct ifmediareq *req;
                   1067: {
                   1068:        register struct ep_softc *sc = ifp->if_softc;
                   1069:        bus_space_tag_t iot = sc->sc_iot;
                   1070:        bus_space_handle_t ioh = sc->sc_ioh;
                   1071:
1.34      thorpej  1072:        if (sc->enabled == 0) {
                   1073:                req->ifm_active = IFM_ETHER|IFM_NONE;
                   1074:                req->ifm_status = 0;
                   1075:                return;
                   1076:        }
                   1077:
1.41      thorpej  1078:        /*
                   1079:         * If we have MII, go ask the PHY what's going on.
                   1080:         */
1.47      fvdl     1081:        if (sc->ep_flags & ELINK_FLAGS_MII) {
1.41      thorpej  1082:                mii_pollstat(&sc->sc_mii);
                   1083:                req->ifm_active = sc->sc_mii.mii_media_active;
                   1084:                req->ifm_status = sc->sc_mii.mii_media_status;
                   1085:                return;
                   1086:        }
                   1087:
                   1088:        /*
                   1089:         * Ok, at this point we claim that our active media is
                   1090:         * the currently selected media.  We'll update our status
                   1091:         * if our chipset allows us to detect link.
                   1092:         */
                   1093:        req->ifm_active = sc->sc_mii.mii_media.ifm_cur->ifm_media;
                   1094:        req->ifm_status = 0;
                   1095:
1.23      jonathan 1096:        switch (sc->ep_chipset) {
1.47      fvdl     1097:        case ELINK_CHIPSET_VORTEX:
                   1098:        case ELINK_CHIPSET_BOOMERANG:
1.23      jonathan 1099:                GO_WINDOW(4);
1.41      thorpej  1100:                req->ifm_status = IFM_AVALID;
1.47      fvdl     1101:                if (bus_space_read_2(iot, ioh, ELINK_W4_MEDIA_TYPE) &
1.41      thorpej  1102:                    LINKBEAT_DETECT)
                   1103:                        req->ifm_status |= IFM_ACTIVE;
                   1104:                GO_WINDOW(1);   /* back to operating window */
1.23      jonathan 1105:                break;
1.1       thorpej  1106:        }
                   1107: }
                   1108:
1.23      jonathan 1109:
                   1110:
1.1       thorpej  1111: /*
                   1112:  * Start outputting on the interface.
                   1113:  * Always called as splnet().
                   1114:  */
                   1115: void
                   1116: epstart(ifp)
                   1117:        struct ifnet *ifp;
                   1118: {
1.5       thorpej  1119:        register struct ep_softc *sc = ifp->if_softc;
1.11      thorpej  1120:        bus_space_tag_t iot = sc->sc_iot;
                   1121:        bus_space_handle_t ioh = sc->sc_ioh;
1.1       thorpej  1122:        struct mbuf *m, *m0;
                   1123:        int sh, len, pad;
1.42      thorpej  1124:        bus_addr_t txreg;
1.1       thorpej  1125:
                   1126:        /* Don't transmit if interface is busy or not running */
1.28      veego    1127:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1.1       thorpej  1128:                return;
                   1129:
                   1130: startagain:
                   1131:        /* Sneak a peek at the next packet */
                   1132:        m0 = ifp->if_snd.ifq_head;
                   1133:        if (m0 == 0)
                   1134:                return;
                   1135:
                   1136:        /* We need to use m->m_pkthdr.len, so require the header */
                   1137:        if ((m0->m_flags & M_PKTHDR) == 0)
                   1138:                panic("epstart: no header mbuf");
                   1139:        len = m0->m_pkthdr.len;
                   1140:
                   1141:        pad = (4 - len) & 3;
                   1142:
                   1143:        /*
                   1144:         * The 3c509 automatically pads short packets to minimum ethernet
                   1145:         * length, but we drop packets that are too large. Perhaps we should
                   1146:         * truncate them instead?
                   1147:         */
                   1148:        if (len + pad > ETHER_MAX_LEN) {
                   1149:                /* packet is obviously too large: toss it */
                   1150:                ++ifp->if_oerrors;
                   1151:                IF_DEQUEUE(&ifp->if_snd, m0);
                   1152:                m_freem(m0);
                   1153:                goto readcheck;
                   1154:        }
                   1155:
1.47      fvdl     1156:        if (bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_FREE_TX)) <
1.42      thorpej  1157:            len + pad + 4) {
1.47      fvdl     1158:                bus_space_write_2(iot, ioh, ELINK_COMMAND,
1.12      jonathan 1159:                    SET_TX_AVAIL_THRESH |
                   1160:                    ((len + pad + 4) >> sc->ep_pktlenshift));
1.1       thorpej  1161:                /* not enough room in FIFO */
                   1162:                ifp->if_flags |= IFF_OACTIVE;
                   1163:                return;
                   1164:        } else {
1.47      fvdl     1165:                bus_space_write_2(iot, ioh, ELINK_COMMAND,
1.58.2.1! wrstuden 1166:                    SET_TX_AVAIL_THRESH | ELINK_THRESH_DISABLE);
1.1       thorpej  1167:        }
                   1168:
                   1169:        IF_DEQUEUE(&ifp->if_snd, m0);
                   1170:        if (m0 == 0)            /* not really needed */
                   1171:                return;
                   1172:
1.47      fvdl     1173:        bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_TX_START_THRESH |
1.58.2.1! wrstuden 1174:            ((len / 4 + sc->tx_start_thresh) /* >> sc->ep_pktlenshift*/));
1.1       thorpej  1175:
                   1176: #if NBPFILTER > 0
                   1177:        if (ifp->if_bpf)
                   1178:                bpf_mtap(ifp->if_bpf, m0);
                   1179: #endif
                   1180:
                   1181:        /*
                   1182:         * Do the output at splhigh() so that an interrupt from another device
                   1183:         * won't cause a FIFO underrun.
                   1184:         */
                   1185:        sh = splhigh();
                   1186:
1.47      fvdl     1187:        txreg = ep_w1_reg(sc, ELINK_W1_TX_PIO_WR_1);
1.42      thorpej  1188:
1.47      fvdl     1189:        if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) {
1.44      thorpej  1190:                /*
                   1191:                 * Prime the FIFO buffer counter (number of 16-bit
                   1192:                 * words about to be written to the FIFO).
                   1193:                 *
                   1194:                 * NOTE: NO OTHER ACCESS CAN BE PERFORMED WHILE THIS
                   1195:                 * COUNTER IS NON-ZERO!
                   1196:                 */
1.47      fvdl     1197:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL,
1.44      thorpej  1198:                    (len + pad) >> 1);
                   1199:        }
                   1200:
1.42      thorpej  1201:        bus_space_write_2(iot, ioh, txreg, len);
                   1202:        bus_space_write_2(iot, ioh, txreg, 0xffff); /* Second is meaningless */
1.47      fvdl     1203:        if (ELINK_IS_BUS_32(sc->bustype)) {
1.58.2.1! wrstuden 1204:                for (m = m0; m;) {
1.14      cjs      1205:                        if (m->m_len > 3)  {
                   1206:                                /* align our reads from core */
                   1207:                                if (mtod(m, u_long) & 3)  {
                   1208:                                        u_long count =
                   1209:                                            4 - (mtod(m, u_long) & 3);
                   1210:                                        bus_space_write_multi_1(iot, ioh,
1.42      thorpej  1211:                                            txreg, mtod(m, u_int8_t *), count);
1.14      cjs      1212:                                        m->m_data =
                   1213:                                            (void *)(mtod(m, u_long) + count);
                   1214:                                        m->m_len -= count;
                   1215:                                }
1.55      jonathan 1216:                                bus_space_write_multi_stream_4(iot, ioh,
1.42      thorpej  1217:                                    txreg, mtod(m, u_int32_t *), m->m_len >> 2);
1.14      cjs      1218:                                m->m_data = (void *)(mtod(m, u_long) +
                   1219:                                        (u_long)(m->m_len & ~3));
                   1220:                                m->m_len -= m->m_len & ~3;
                   1221:                        }
                   1222:                        if (m->m_len)  {
1.11      thorpej  1223:                                bus_space_write_multi_1(iot, ioh,
1.42      thorpej  1224:                                    txreg, mtod(m, u_int8_t *), m->m_len);
1.14      cjs      1225:                        }
1.1       thorpej  1226:                        MFREE(m, m0);
                   1227:                        m = m0;
                   1228:                }
                   1229:        } else {
1.58.2.1! wrstuden 1230:                for (m = m0; m;) {
1.14      cjs      1231:                        if (m->m_len > 1)  {
                   1232:                                if (mtod(m, u_long) & 1)  {
                   1233:                                        bus_space_write_1(iot, ioh,
1.42      thorpej  1234:                                            txreg, *(mtod(m, u_int8_t *)));
1.14      cjs      1235:                                        m->m_data =
                   1236:                                            (void *)(mtod(m, u_long) + 1);
                   1237:                                        m->m_len -= 1;
                   1238:                                }
1.55      jonathan 1239:                                bus_space_write_multi_stream_2(iot, ioh,
1.42      thorpej  1240:                                    txreg, mtod(m, u_int16_t *),
1.14      cjs      1241:                                    m->m_len >> 1);
                   1242:                        }
                   1243:                        if (m->m_len & 1)  {
1.42      thorpej  1244:                                bus_space_write_1(iot, ioh, txreg,
1.2       thorpej  1245:                                     *(mtod(m, u_int8_t *) + m->m_len - 1));
1.14      cjs      1246:                        }
1.1       thorpej  1247:                        MFREE(m, m0);
                   1248:                        m = m0;
                   1249:                }
                   1250:        }
                   1251:        while (pad--)
1.42      thorpej  1252:                bus_space_write_1(iot, ioh, txreg, 0);
1.1       thorpej  1253:
                   1254:        splx(sh);
                   1255:
                   1256:        ++ifp->if_opackets;
                   1257:
                   1258: readcheck:
1.47      fvdl     1259:        if ((bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_RX_STATUS)) &
1.42      thorpej  1260:            ERR_INCOMPLETE) == 0) {
1.1       thorpej  1261:                /* We received a complete packet. */
1.47      fvdl     1262:                u_int16_t status = bus_space_read_2(iot, ioh, ELINK_STATUS);
1.1       thorpej  1263:
                   1264:                if ((status & S_INTR_LATCH) == 0) {
                   1265:                        /*
                   1266:                         * No interrupt, read the packet and continue
                   1267:                         * Is  this supposed to happen? Is my motherboard
                   1268:                         * completely busted?
                   1269:                         */
                   1270:                        epread(sc);
1.28      veego    1271:                } else {
1.1       thorpej  1272:                        /* Got an interrupt, return so that it gets serviced. */
                   1273:                        return;
1.28      veego    1274:                }
                   1275:        } else {
1.1       thorpej  1276:                /* Check if we are stuck and reset [see XXX comment] */
                   1277:                if (epstatus(sc)) {
                   1278:                        if (ifp->if_flags & IFF_DEBUG)
1.10      christos 1279:                                printf("%s: adapter reset\n",
1.9       christos 1280:                                    sc->sc_dev.dv_xname);
1.1       thorpej  1281:                        epreset(sc);
                   1282:                }
                   1283:        }
                   1284:
                   1285:        goto startagain;
                   1286: }
                   1287:
                   1288:
                   1289: /*
                   1290:  * XXX: The 3c509 card can get in a mode where both the fifo status bit
                   1291:  *     FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
                   1292:  *     We detect this situation and we reset the adapter.
                   1293:  *     It happens at times when there is a lot of broadcast traffic
                   1294:  *     on the cable (once in a blue moon).
                   1295:  */
                   1296: static int
                   1297: epstatus(sc)
                   1298:        register struct ep_softc *sc;
                   1299: {
1.11      thorpej  1300:        bus_space_tag_t iot = sc->sc_iot;
                   1301:        bus_space_handle_t ioh = sc->sc_ioh;
1.7       thorpej  1302:        u_int16_t fifost;
1.1       thorpej  1303:
                   1304:        /*
                   1305:         * Check the FIFO status and act accordingly
                   1306:         */
                   1307:        GO_WINDOW(4);
1.47      fvdl     1308:        fifost = bus_space_read_2(iot, ioh, ELINK_W4_FIFO_DIAG);
1.1       thorpej  1309:        GO_WINDOW(1);
                   1310:
                   1311:        if (fifost & FIFOS_RX_UNDERRUN) {
1.21      is       1312:                if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1313:                        printf("%s: RX underrun\n", sc->sc_dev.dv_xname);
1.1       thorpej  1314:                epreset(sc);
                   1315:                return 0;
                   1316:        }
                   1317:
                   1318:        if (fifost & FIFOS_RX_STATUS_OVERRUN) {
1.21      is       1319:                if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1320:                        printf("%s: RX Status overrun\n", sc->sc_dev.dv_xname);
1.1       thorpej  1321:                return 1;
                   1322:        }
                   1323:
                   1324:        if (fifost & FIFOS_RX_OVERRUN) {
1.21      is       1325:                if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1326:                        printf("%s: RX overrun\n", sc->sc_dev.dv_xname);
1.1       thorpej  1327:                return 1;
                   1328:        }
                   1329:
                   1330:        if (fifost & FIFOS_TX_OVERRUN) {
1.21      is       1331:                if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1332:                        printf("%s: TX overrun\n", sc->sc_dev.dv_xname);
1.1       thorpej  1333:                epreset(sc);
                   1334:                return 0;
                   1335:        }
                   1336:
                   1337:        return 0;
                   1338: }
                   1339:
                   1340:
                   1341: static void
                   1342: eptxstat(sc)
                   1343:        register struct ep_softc *sc;
                   1344: {
1.11      thorpej  1345:        bus_space_tag_t iot = sc->sc_iot;
                   1346:        bus_space_handle_t ioh = sc->sc_ioh;
1.1       thorpej  1347:        int i;
                   1348:
                   1349:        /*
                   1350:         * We need to read+write TX_STATUS until we get a 0 status
                   1351:         * in order to turn off the interrupt flag.
                   1352:         */
1.58.2.1! wrstuden 1353:        while ((i = bus_space_read_1(iot, ioh,
        !          1354:             ep_w1_reg(sc, ELINK_W1_TX_STATUS))) & TXS_COMPLETE) {
1.47      fvdl     1355:                bus_space_write_1(iot, ioh, ep_w1_reg(sc, ELINK_W1_TX_STATUS),
1.42      thorpej  1356:                    0x0);
1.1       thorpej  1357:
                   1358:                if (i & TXS_JABBER) {
1.21      is       1359:                        ++sc->sc_ethercom.ec_if.if_oerrors;
                   1360:                        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1361:                                printf("%s: jabber (%x)\n",
1.1       thorpej  1362:                                       sc->sc_dev.dv_xname, i);
                   1363:                        epreset(sc);
                   1364:                } else if (i & TXS_UNDERRUN) {
1.21      is       1365:                        ++sc->sc_ethercom.ec_if.if_oerrors;
                   1366:                        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
1.10      christos 1367:                                printf("%s: fifo underrun (%x) @%d\n",
1.1       thorpej  1368:                                       sc->sc_dev.dv_xname, i,
                   1369:                                       sc->tx_start_thresh);
                   1370:                        if (sc->tx_succ_ok < 100)
                   1371:                                    sc->tx_start_thresh = min(ETHER_MAX_LEN,
                   1372:                                            sc->tx_start_thresh + 20);
                   1373:                        sc->tx_succ_ok = 0;
                   1374:                        epreset(sc);
                   1375:                } else if (i & TXS_MAX_COLLISION) {
1.21      is       1376:                        ++sc->sc_ethercom.ec_if.if_collisions;
1.47      fvdl     1377:                        bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE);
1.21      is       1378:                        sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
1.1       thorpej  1379:                } else
                   1380:                        sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127;
                   1381:        }
                   1382: }
                   1383:
                   1384: int
                   1385: epintr(arg)
                   1386:        void *arg;
                   1387: {
                   1388:        register struct ep_softc *sc = arg;
1.11      thorpej  1389:        bus_space_tag_t iot = sc->sc_iot;
                   1390:        bus_space_handle_t ioh = sc->sc_ioh;
1.21      is       1391:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.7       thorpej  1392:        u_int16_t status;
1.1       thorpej  1393:        int ret = 0;
1.35      explorer 1394:        int addrandom = 0;
1.1       thorpej  1395:
1.34      thorpej  1396:        if (sc->enabled == 0)
                   1397:                return (0);
                   1398:
1.1       thorpej  1399:        for (;;) {
1.47      fvdl     1400:                bus_space_write_2(iot, ioh, ELINK_COMMAND, C_INTR_LATCH);
1.1       thorpej  1401:
1.47      fvdl     1402:                status = bus_space_read_2(iot, ioh, ELINK_STATUS);
1.1       thorpej  1403:
                   1404:                if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
1.34      thorpej  1405:                               S_RX_COMPLETE | S_CARD_FAILURE)) == 0) {
                   1406:                        if ((status & S_INTR_LATCH) == 0) {
                   1407: #if 0
                   1408:                                printf("%s: intr latch cleared\n",
                   1409:                                       sc->sc_dev.dv_xname);
                   1410: #endif
                   1411:                                break;
                   1412:                        }
                   1413:                }
1.1       thorpej  1414:
                   1415:                ret = 1;
                   1416:
                   1417:                /*
                   1418:                 * Acknowledge any interrupts.  It's important that we do this
                   1419:                 * first, since there would otherwise be a race condition.
                   1420:                 * Due to the i386 interrupt queueing, we may get spurious
                   1421:                 * interrupts occasionally.
                   1422:                 */
1.47      fvdl     1423:                bus_space_write_2(iot, ioh, ELINK_COMMAND, ACK_INTR |
1.34      thorpej  1424:                                  (status & (C_INTR_LATCH |
                   1425:                                             C_CARD_FAILURE |
                   1426:                                             C_TX_COMPLETE |
                   1427:                                             C_TX_AVAIL |
                   1428:                                             C_RX_COMPLETE |
                   1429:                                             C_RX_EARLY |
                   1430:                                             C_INT_RQD |
                   1431:                                             C_UPD_STATS)));
                   1432:
                   1433: #if 0
1.47      fvdl     1434:                status = bus_space_read_2(iot, ioh, ELINK_STATUS);
1.34      thorpej  1435:
                   1436:                printf("%s: intr%s%s%s%s\n", sc->sc_dev.dv_xname,
                   1437:                       (status & S_RX_COMPLETE)?" RX_COMPLETE":"",
                   1438:                       (status & S_TX_COMPLETE)?" TX_COMPLETE":"",
                   1439:                       (status & S_TX_AVAIL)?" TX_AVAIL":"",
                   1440:                       (status & S_CARD_FAILURE)?" CARD_FAILURE":"");
                   1441: #endif
1.1       thorpej  1442:
1.35      explorer 1443:                if (status & S_RX_COMPLETE) {
1.1       thorpej  1444:                        epread(sc);
1.35      explorer 1445:                        addrandom = 1;
                   1446:                }
1.1       thorpej  1447:                if (status & S_TX_AVAIL) {
1.21      is       1448:                        sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
                   1449:                        epstart(&sc->sc_ethercom.ec_if);
1.35      explorer 1450:                        addrandom = 1;
1.1       thorpej  1451:                }
                   1452:                if (status & S_CARD_FAILURE) {
1.10      christos 1453:                        printf("%s: adapter failure (%x)\n",
1.9       christos 1454:                            sc->sc_dev.dv_xname, status);
1.58.2.1! wrstuden 1455: #if 1
        !          1456:                        epinit(sc);
        !          1457: #else
1.1       thorpej  1458:                        epreset(sc);
1.58.2.1! wrstuden 1459: #endif
1.1       thorpej  1460:                        return (1);
                   1461:                }
                   1462:                if (status & S_TX_COMPLETE) {
                   1463:                        eptxstat(sc);
                   1464:                        epstart(ifp);
1.35      explorer 1465:                        addrandom = 1;
1.1       thorpej  1466:                }
1.35      explorer 1467:
                   1468: #if NRND > 0
                   1469:                if (status)
                   1470:                        rnd_add_uint32(&sc->rnd_source, status);
                   1471: #endif
1.1       thorpej  1472:        }
                   1473:
                   1474:        /* no more interrupts */
                   1475:        return (ret);
                   1476: }
                   1477:
                   1478: void
                   1479: epread(sc)
                   1480:        register struct ep_softc *sc;
                   1481: {
1.11      thorpej  1482:        bus_space_tag_t iot = sc->sc_iot;
                   1483:        bus_space_handle_t ioh = sc->sc_ioh;
1.21      is       1484:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.1       thorpej  1485:        struct mbuf *m;
                   1486:        struct ether_header *eh;
                   1487:        int len;
                   1488:
1.47      fvdl     1489:        len = bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_RX_STATUS));
1.1       thorpej  1490:
                   1491: again:
                   1492:        if (ifp->if_flags & IFF_DEBUG) {
                   1493:                int err = len & ERR_MASK;
                   1494:                char *s = NULL;
                   1495:
                   1496:                if (len & ERR_INCOMPLETE)
                   1497:                        s = "incomplete packet";
                   1498:                else if (err == ERR_OVERRUN)
                   1499:                        s = "packet overrun";
                   1500:                else if (err == ERR_RUNT)
                   1501:                        s = "runt packet";
                   1502:                else if (err == ERR_ALIGNMENT)
                   1503:                        s = "bad alignment";
                   1504:                else if (err == ERR_CRC)
                   1505:                        s = "bad crc";
                   1506:                else if (err == ERR_OVERSIZE)
                   1507:                        s = "oversized packet";
                   1508:                else if (err == ERR_DRIBBLE)
                   1509:                        s = "dribble bits";
                   1510:
                   1511:                if (s)
1.10      christos 1512:                        printf("%s: %s\n", sc->sc_dev.dv_xname, s);
1.1       thorpej  1513:        }
                   1514:
                   1515:        if (len & ERR_INCOMPLETE)
                   1516:                return;
                   1517:
                   1518:        if (len & ERR_RX) {
                   1519:                ++ifp->if_ierrors;
                   1520:                goto abort;
                   1521:        }
                   1522:
                   1523:        len &= RX_BYTES_MASK;   /* Lower 11 bits = RX bytes. */
                   1524:
                   1525:        /* Pull packet off interface. */
                   1526:        m = epget(sc, len);
                   1527:        if (m == 0) {
                   1528:                ifp->if_ierrors++;
                   1529:                goto abort;
                   1530:        }
                   1531:
                   1532:        ++ifp->if_ipackets;
                   1533:
                   1534:        /* We assume the header fit entirely in one mbuf. */
                   1535:        eh = mtod(m, struct ether_header *);
                   1536:
                   1537: #if NBPFILTER > 0
                   1538:        /*
                   1539:         * Check if there's a BPF listener on this interface.
                   1540:         * If so, hand off the raw packet to BPF.
                   1541:         */
                   1542:        if (ifp->if_bpf) {
                   1543:                bpf_mtap(ifp->if_bpf, m);
                   1544:
                   1545:                /*
                   1546:                 * Note that the interface cannot be in promiscuous mode if
                   1547:                 * there are no BPF listeners.  And if we are in promiscuous
                   1548:                 * mode, we have to check if this packet is really ours.
                   1549:                 */
                   1550:                if ((ifp->if_flags & IFF_PROMISC) &&
                   1551:                    (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
1.21      is       1552:                    bcmp(eh->ether_dhost, LLADDR(sc->sc_ethercom.ec_if.if_sadl),
1.58.2.1! wrstuden 1553:                        sizeof(eh->ether_dhost)) != 0) {
1.1       thorpej  1554:                        m_freem(m);
                   1555:                        return;
                   1556:                }
                   1557:        }
                   1558: #endif
1.58      thorpej  1559:        (*ifp->if_input)(ifp, m);
1.1       thorpej  1560:
                   1561:        /*
                   1562:         * In periods of high traffic we can actually receive enough
                   1563:         * packets so that the fifo overrun bit will be set at this point,
                   1564:         * even though we just read a packet. In this case we
                   1565:         * are not going to receive any more interrupts. We check for
                   1566:         * this condition and read again until the fifo is not full.
                   1567:         * We could simplify this test by not using epstatus(), but
                   1568:         * rechecking the RX_STATUS register directly. This test could
                   1569:         * result in unnecessary looping in cases where there is a new
                   1570:         * packet but the fifo is not full, but it will not fix the
                   1571:         * stuck behavior.
                   1572:         *
                   1573:         * Even with this improvement, we still get packet overrun errors
                   1574:         * which are hurting performance. Maybe when I get some more time
                   1575:         * I'll modify epread() so that it can handle RX_EARLY interrupts.
                   1576:         */
                   1577:        if (epstatus(sc)) {
1.42      thorpej  1578:                len = bus_space_read_2(iot, ioh,
1.47      fvdl     1579:                    ep_w1_reg(sc, ELINK_W1_RX_STATUS));
1.1       thorpej  1580:                /* Check if we are stuck and reset [see XXX comment] */
                   1581:                if (len & ERR_INCOMPLETE) {
                   1582:                        if (ifp->if_flags & IFF_DEBUG)
1.10      christos 1583:                                printf("%s: adapter reset\n",
1.9       christos 1584:                                    sc->sc_dev.dv_xname);
1.1       thorpej  1585:                        epreset(sc);
                   1586:                        return;
                   1587:                }
                   1588:                goto again;
                   1589:        }
                   1590:
                   1591:        return;
                   1592:
                   1593: abort:
1.56      jonathan 1594:        ep_discard_rxtop(iot, ioh);
                   1595:
1.1       thorpej  1596: }
                   1597:
                   1598: struct mbuf *
                   1599: epget(sc, totlen)
                   1600:        struct ep_softc *sc;
                   1601:        int totlen;
                   1602: {
1.11      thorpej  1603:        bus_space_tag_t iot = sc->sc_iot;
                   1604:        bus_space_handle_t ioh = sc->sc_ioh;
1.21      is       1605:        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1.44      thorpej  1606:        struct mbuf *top, **mp, *m, *rv = NULL;
1.42      thorpej  1607:        bus_addr_t rxreg;
1.14      cjs      1608:        int len, remaining;
1.1       thorpej  1609:        int sh;
                   1610:
                   1611:        m = sc->mb[sc->next_mb];
                   1612:        sc->mb[sc->next_mb] = 0;
                   1613:        if (m == 0) {
                   1614:                MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1615:                if (m == 0)
                   1616:                        return 0;
                   1617:        } else {
                   1618:                /* If the queue is no longer full, refill. */
                   1619:                if (sc->last_mb == sc->next_mb)
                   1620:                        timeout(epmbuffill, sc, 1);
                   1621:                /* Convert one of our saved mbuf's. */
                   1622:                sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
                   1623:                m->m_data = m->m_pktdat;
                   1624:                m->m_flags = M_PKTHDR;
                   1625:        }
                   1626:        m->m_pkthdr.rcvif = ifp;
                   1627:        m->m_pkthdr.len = totlen;
                   1628:        len = MHLEN;
                   1629:        top = 0;
                   1630:        mp = &top;
                   1631:
                   1632:        /*
                   1633:         * We read the packet at splhigh() so that an interrupt from another
                   1634:         * device doesn't cause the card's buffer to overflow while we're
                   1635:         * reading it.  We may still lose packets at other times.
                   1636:         */
                   1637:        sh = splhigh();
                   1638:
1.47      fvdl     1639:        rxreg = ep_w1_reg(sc, ELINK_W1_RX_PIO_RD_1);
1.42      thorpej  1640:
1.47      fvdl     1641:        if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) {
1.44      thorpej  1642:                /*
                   1643:                 * Prime the FIFO buffer counter (number of 16-bit
                   1644:                 * words about to be read from the FIFO).
                   1645:                 *
                   1646:                 * NOTE: NO OTHER ACCESS CAN BE PERFORMED WHILE THIS
                   1647:                 * COUNTER IS NON-ZERO!
                   1648:                 */
1.47      fvdl     1649:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, totlen >> 1);
1.44      thorpej  1650:        }
                   1651:
1.1       thorpej  1652:        while (totlen > 0) {
                   1653:                if (top) {
                   1654:                        m = sc->mb[sc->next_mb];
                   1655:                        sc->mb[sc->next_mb] = 0;
                   1656:                        if (m == 0) {
                   1657:                                MGET(m, M_DONTWAIT, MT_DATA);
                   1658:                                if (m == 0) {
                   1659:                                        m_freem(top);
1.44      thorpej  1660:                                        goto out;
1.1       thorpej  1661:                                }
                   1662:                        } else {
                   1663:                                sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
                   1664:                        }
                   1665:                        len = MLEN;
                   1666:                }
                   1667:                if (totlen >= MINCLSIZE) {
                   1668:                        MCLGET(m, M_DONTWAIT);
1.27      mycroft  1669:                        if ((m->m_flags & M_EXT) == 0) {
1.30      mycroft  1670:                                m_free(m);
1.26      mycroft  1671:                                m_freem(top);
1.44      thorpej  1672:                                goto out;
1.26      mycroft  1673:                        }
                   1674:                        len = MCLBYTES;
1.1       thorpej  1675:                }
1.24      cjs      1676:                if (top == 0)  {
1.25      cjs      1677:                        /* align the struct ip header */
                   1678:                        caddr_t newdata = (caddr_t)
                   1679:                            ALIGN(m->m_data + sizeof(struct ether_header))
                   1680:                            - sizeof(struct ether_header);
                   1681:                        len -= newdata - m->m_data;
                   1682:                        m->m_data = newdata;
1.14      cjs      1683:                }
                   1684:                remaining = len = min(totlen, len);
1.47      fvdl     1685:                if (ELINK_IS_BUS_32(sc->bustype)) {
1.14      cjs      1686:                        u_long offset = mtod(m, u_long);
                   1687:                        /*
                   1688:                         * Read bytes up to the point where we are aligned.
                   1689:                         * (We can align to 4 bytes, rather than ALIGNBYTES,
                   1690:                         * here because we're later reading 4-byte chunks.)
                   1691:                         */
                   1692:                        if ((remaining > 3) && (offset & 3))  {
                   1693:                                int count = (4 - (offset & 3));
                   1694:                                bus_space_read_multi_1(iot, ioh,
1.42      thorpej  1695:                                    rxreg, (u_int8_t *) offset, count);
1.14      cjs      1696:                                offset += count;
                   1697:                                remaining -= count;
                   1698:                        }
                   1699:                        if (remaining > 3) {
1.55      jonathan 1700:                                bus_space_read_multi_stream_4(iot, ioh,
1.42      thorpej  1701:                                    rxreg, (u_int32_t *) offset,
                   1702:                                    remaining >> 2);
1.14      cjs      1703:                                offset += remaining & ~3;
                   1704:                                remaining &= 3;
                   1705:                        }
                   1706:                        if (remaining)  {
1.11      thorpej  1707:                                bus_space_read_multi_1(iot, ioh,
1.42      thorpej  1708:                                    rxreg, (u_int8_t *) offset, remaining);
1.14      cjs      1709:                        }
1.1       thorpej  1710:                } else {
1.14      cjs      1711:                        u_long offset = mtod(m, u_long);
                   1712:                        if ((remaining > 1) && (offset & 1))  {
                   1713:                                bus_space_read_multi_1(iot, ioh,
1.42      thorpej  1714:                                    rxreg, (u_int8_t *) offset, 1);
1.14      cjs      1715:                                remaining -= 1;
                   1716:                                offset += 1;
                   1717:                        }
                   1718:                        if (remaining > 1) {
1.55      jonathan 1719:                                bus_space_read_multi_stream_2(iot, ioh,
1.42      thorpej  1720:                                    rxreg, (u_int16_t *) offset,
                   1721:                                    remaining >> 1);
1.14      cjs      1722:                                offset += remaining & ~1;
                   1723:                        }
                   1724:                        if (remaining & 1)  {
                   1725:                                bus_space_read_multi_1(iot, ioh,
1.42      thorpej  1726:                                    rxreg, (u_int8_t *) offset, remaining & 1);
1.14      cjs      1727:                        }
1.1       thorpej  1728:                }
                   1729:                m->m_len = len;
                   1730:                totlen -= len;
                   1731:                *mp = m;
                   1732:                mp = &m->m_next;
                   1733:        }
                   1734:
1.44      thorpej  1735:        rv = top;
                   1736:
1.56      jonathan 1737:        ep_discard_rxtop(iot, ioh);
1.1       thorpej  1738:
1.44      thorpej  1739:  out:
1.47      fvdl     1740:        if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER)
                   1741:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0);
1.1       thorpej  1742:        splx(sh);
                   1743:
1.44      thorpej  1744:        return rv;
1.1       thorpej  1745: }
                   1746:
                   1747: int
                   1748: epioctl(ifp, cmd, data)
                   1749:        register struct ifnet *ifp;
                   1750:        u_long cmd;
                   1751:        caddr_t data;
                   1752: {
1.5       thorpej  1753:        struct ep_softc *sc = ifp->if_softc;
1.1       thorpej  1754:        struct ifaddr *ifa = (struct ifaddr *)data;
                   1755:        struct ifreq *ifr = (struct ifreq *)data;
                   1756:        int s, error = 0;
                   1757:
                   1758:        s = splnet();
                   1759:
                   1760:        switch (cmd) {
                   1761:
                   1762:        case SIOCSIFADDR:
1.34      thorpej  1763:                if ((error = epenable(sc)) != 0)
                   1764:                        break;
                   1765:                /* epinit is called just below */
1.1       thorpej  1766:                ifp->if_flags |= IFF_UP;
                   1767:                switch (ifa->ifa_addr->sa_family) {
                   1768: #ifdef INET
                   1769:                case AF_INET:
                   1770:                        epinit(sc);
1.21      is       1771:                        arp_ifinit(&sc->sc_ethercom.ec_if, ifa);
1.1       thorpej  1772:                        break;
                   1773: #endif
                   1774: #ifdef NS
                   1775:                case AF_NS:
                   1776:                    {
                   1777:                        register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
                   1778:
                   1779:                        if (ns_nullhost(*ina))
1.21      is       1780:                                ina->x_host = *(union ns_host *)
                   1781:                                    LLADDR(ifp->if_sadl);
1.1       thorpej  1782:                        else
                   1783:                                bcopy(ina->x_host.c_host,
1.21      is       1784:                                    LLADDR(ifp->if_sadl),
                   1785:                                    ifp->if_addrlen);
1.1       thorpej  1786:                        /* Set new address. */
                   1787:                        epinit(sc);
                   1788:                        break;
                   1789:                    }
                   1790: #endif
                   1791:                default:
                   1792:                        epinit(sc);
                   1793:                        break;
                   1794:                }
                   1795:                break;
                   1796:
1.23      jonathan 1797:        case SIOCSIFMEDIA:
                   1798:        case SIOCGIFMEDIA:
1.41      thorpej  1799:                error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1.23      jonathan 1800:                break;
                   1801:
1.1       thorpej  1802:        case SIOCSIFFLAGS:
                   1803:                if ((ifp->if_flags & IFF_UP) == 0 &&
                   1804:                    (ifp->if_flags & IFF_RUNNING) != 0) {
                   1805:                        /*
                   1806:                         * If interface is marked down and it is running, then
                   1807:                         * stop it.
                   1808:                         */
                   1809:                        epstop(sc);
                   1810:                        ifp->if_flags &= ~IFF_RUNNING;
1.34      thorpej  1811:                        epdisable(sc);
1.1       thorpej  1812:                } else if ((ifp->if_flags & IFF_UP) != 0 &&
                   1813:                           (ifp->if_flags & IFF_RUNNING) == 0) {
                   1814:                        /*
                   1815:                         * If interface is marked up and it is stopped, then
                   1816:                         * start it.
                   1817:                         */
1.34      thorpej  1818:                        if ((error = epenable(sc)) != 0)
                   1819:                                break;
1.1       thorpej  1820:                        epinit(sc);
1.52      thorpej  1821:                } else if ((ifp->if_flags & IFF_UP) != 0) {
1.1       thorpej  1822:                        /*
                   1823:                         * deal with flags changes:
1.23      jonathan 1824:                         * IFF_MULTICAST, IFF_PROMISC.
1.1       thorpej  1825:                         */
                   1826:                        epsetfilter(sc);
                   1827:                }
                   1828:                break;
                   1829:
                   1830:        case SIOCADDMULTI:
                   1831:        case SIOCDELMULTI:
1.34      thorpej  1832:                if (sc->enabled == 0) {
                   1833:                        error = EIO;
                   1834:                        break;
                   1835:                }
                   1836:
1.1       thorpej  1837:                error = (cmd == SIOCADDMULTI) ?
1.21      is       1838:                    ether_addmulti(ifr, &sc->sc_ethercom) :
                   1839:                    ether_delmulti(ifr, &sc->sc_ethercom);
1.1       thorpej  1840:
                   1841:                if (error == ENETRESET) {
                   1842:                        /*
                   1843:                         * Multicast list has changed; set the hardware filter
                   1844:                         * accordingly.
                   1845:                         */
                   1846:                        epreset(sc);
                   1847:                        error = 0;
                   1848:                }
                   1849:                break;
                   1850:
                   1851:        default:
                   1852:                error = EINVAL;
                   1853:                break;
                   1854:        }
                   1855:
                   1856:        splx(s);
                   1857:        return (error);
                   1858: }
                   1859:
                   1860: void
                   1861: epreset(sc)
                   1862:        struct ep_softc *sc;
                   1863: {
                   1864:        int s;
                   1865:
                   1866:        s = splnet();
                   1867:        epinit(sc);
                   1868:        splx(s);
                   1869: }
                   1870:
                   1871: void
1.5       thorpej  1872: epwatchdog(ifp)
                   1873:        struct ifnet *ifp;
1.1       thorpej  1874: {
1.5       thorpej  1875:        struct ep_softc *sc = ifp->if_softc;
1.1       thorpej  1876:
                   1877:        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1.21      is       1878:        ++sc->sc_ethercom.ec_if.if_oerrors;
1.1       thorpej  1879:
                   1880:        epreset(sc);
                   1881: }
                   1882:
                   1883: void
                   1884: epstop(sc)
                   1885:        register struct ep_softc *sc;
                   1886: {
1.11      thorpej  1887:        bus_space_tag_t iot = sc->sc_iot;
                   1888:        bus_space_handle_t ioh = sc->sc_ioh;
1.1       thorpej  1889:
1.47      fvdl     1890:        if (sc->ep_flags & ELINK_FLAGS_MII) {
1.41      thorpej  1891:                /* Stop the one second clock. */
                   1892:                untimeout(ep_tick, sc);
1.58.2.1! wrstuden 1893:
        !          1894:                /* Down the MII. */
        !          1895:                mii_down(&sc->sc_mii);
1.44      thorpej  1896:        }
                   1897:
1.47      fvdl     1898:        if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) {
1.44      thorpej  1899:                /*
                   1900:                 * Clear the FIFO buffer count, thus halting
                   1901:                 * any currently-running transactions.
                   1902:                 */
                   1903:                GO_WINDOW(1);           /* sanity */
1.47      fvdl     1904:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 0);
                   1905:                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0);
1.41      thorpej  1906:        }
                   1907:
1.47      fvdl     1908:        bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_DISABLE);
1.56      jonathan 1909:        ep_discard_rxtop(iot, ioh);
                   1910:
1.47      fvdl     1911:        bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_DISABLE);
                   1912:        bus_space_write_2(iot, ioh, ELINK_COMMAND, STOP_TRANSCEIVER);
1.18      jonathan 1913:
1.56      jonathan 1914:        ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET);
                   1915:        ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
1.18      jonathan 1916:
1.47      fvdl     1917:        bus_space_write_2(iot, ioh, ELINK_COMMAND, C_INTR_LATCH);
                   1918:        bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_RD_0_MASK);
                   1919:        bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_INTR_MASK);
                   1920:        bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_RX_FILTER);
1.1       thorpej  1921:
                   1922:        epmbufempty(sc);
                   1923: }
1.16      jonathan 1924:
                   1925:
                   1926: /*
                   1927:  * Before reboots, reset card completely.
                   1928:  */
                   1929: static void
                   1930: epshutdown(arg)
                   1931:        void *arg;
                   1932: {
                   1933:        register struct ep_softc *sc = arg;
1.56      jonathan 1934:        int s = splnet();
1.16      jonathan 1935:
1.34      thorpej  1936:        if (sc->enabled) {
                   1937:                epstop(sc);
1.56      jonathan 1938:                ep_reset_cmd(sc, ELINK_COMMAND, GLOBAL_RESET);
                   1939:                sc->enabled = 0;
1.34      thorpej  1940:        }
1.56      jonathan 1941:        splx(s);
1.16      jonathan 1942: }
1.1       thorpej  1943:
                   1944: /*
                   1945:  * We get eeprom data from the id_port given an offset into the
                   1946:  * eeprom.  Basically; after the ID_sequence is sent to all of
                   1947:  * the cards; they enter the ID_CMD state where they will accept
                   1948:  * command requests. 0x80-0xbf loads the eeprom data.  We then
                   1949:  * read the port 16 times and with every read; the cards check
                   1950:  * for contention (ie: if one card writes a 0 bit and another
                   1951:  * writes a 1 bit then the host sees a 0. At the end of the cycle;
                   1952:  * each card compares the data on the bus; if there is a difference
                   1953:  * then that card goes into ID_WAIT state again). In the meantime;
                   1954:  * one bit of data is returned in the AX register which is conveniently
1.11      thorpej  1955:  * returned to us by bus_space_read_1().  Hence; we read 16 times getting one
1.1       thorpej  1956:  * bit of data with each read.
1.2       thorpej  1957:  *
                   1958:  * NOTE: the caller must provide an i/o handle for ELINK_ID_PORT!
1.1       thorpej  1959:  */
1.2       thorpej  1960: u_int16_t
1.11      thorpej  1961: epreadeeprom(iot, ioh, offset)
                   1962:        bus_space_tag_t iot;
                   1963:        bus_space_handle_t ioh;
1.2       thorpej  1964:        int offset;
1.1       thorpej  1965: {
1.2       thorpej  1966:        u_int16_t data = 0;
                   1967:        int i;
1.1       thorpej  1968:
1.11      thorpej  1969:        bus_space_write_1(iot, ioh, 0, 0x80 + offset);
1.1       thorpej  1970:        delay(1000);
                   1971:        for (i = 0; i < 16; i++)
1.11      thorpej  1972:                data = (data << 1) | (bus_space_read_2(iot, ioh, 0) & 1);
1.1       thorpej  1973:        return (data);
                   1974: }
                   1975:
                   1976: static int
                   1977: epbusyeeprom(sc)
                   1978:        struct ep_softc *sc;
                   1979: {
1.11      thorpej  1980:        bus_space_tag_t iot = sc->sc_iot;
                   1981:        bus_space_handle_t ioh = sc->sc_ioh;
1.1       thorpej  1982:        int i = 100, j;
                   1983:
1.47      fvdl     1984:        if (sc->bustype == ELINK_BUS_PCMCIA) {
1.1       thorpej  1985:                delay(1000);
                   1986:                return 0;
                   1987:        }
                   1988:
1.33      jonathan 1989:        j = 0;          /* bad GCC flow analysis */
1.1       thorpej  1990:        while (i--) {
1.47      fvdl     1991:                j = bus_space_read_2(iot, ioh, ELINK_W0_EEPROM_COMMAND);
1.1       thorpej  1992:                if (j & EEPROM_BUSY)
                   1993:                        delay(100);
                   1994:                else
                   1995:                        break;
                   1996:        }
                   1997:        if (!i) {
1.10      christos 1998:                printf("\n%s: eeprom failed to come ready\n",
1.1       thorpej  1999:                    sc->sc_dev.dv_xname);
                   2000:                return (1);
                   2001:        }
                   2002:        if (j & EEPROM_TST_MODE) {
1.29      jonathan 2003:                /* XXX PnP mode? */
1.28      veego    2004:                printf("\n%s: erase pencil mark!\n", sc->sc_dev.dv_xname);
1.1       thorpej  2005:                return (1);
                   2006:        }
                   2007:        return (0);
                   2008: }
                   2009:
1.58.2.1! wrstuden 2010: u_int16_t
        !          2011: ep_read_eeprom(sc, offset)
        !          2012:        struct ep_softc *sc;
        !          2013:        u_int16_t offset;
        !          2014: {
        !          2015:        u_int16_t readcmd;
        !          2016:
        !          2017:        /*
        !          2018:         * RoadRunner has a larger EEPROM, so a different read command
        !          2019:         * is required.
        !          2020:         */
        !          2021:        if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER)
        !          2022:                readcmd = READ_EEPROM_RR;
        !          2023:        else
        !          2024:                readcmd = READ_EEPROM;
        !          2025:
        !          2026:        if (epbusyeeprom(sc))
        !          2027:                return (0);             /* XXX why is eeprom busy? */
        !          2028:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_W0_EEPROM_COMMAND,
        !          2029:            readcmd | offset);
        !          2030:        if (epbusyeeprom(sc))
        !          2031:                return (0);             /* XXX why is eeprom busy? */
        !          2032:        return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, ELINK_W0_EEPROM_DATA));
        !          2033: }
        !          2034:
1.1       thorpej  2035: void
1.3       christos 2036: epmbuffill(v)
                   2037:        void *v;
1.1       thorpej  2038: {
1.3       christos 2039:        struct ep_softc *sc = v;
1.51      mycroft  2040:        struct mbuf *m;
1.1       thorpej  2041:        int s, i;
                   2042:
                   2043:        s = splnet();
                   2044:        i = sc->last_mb;
                   2045:        do {
1.51      mycroft  2046:                if (sc->mb[i] == 0) {
                   2047:                        MGET(m, M_DONTWAIT, MT_DATA);
                   2048:                        if (m == 0)
                   2049:                                break;
                   2050:                        sc->mb[i] = m;
                   2051:                }
1.1       thorpej  2052:                i = (i + 1) % MAX_MBS;
                   2053:        } while (i != sc->next_mb);
                   2054:        sc->last_mb = i;
                   2055:        /* If the queue was not filled, try again. */
                   2056:        if (sc->last_mb != sc->next_mb)
                   2057:                timeout(epmbuffill, sc, 1);
                   2058:        splx(s);
                   2059: }
                   2060:
                   2061: void
                   2062: epmbufempty(sc)
                   2063:        struct ep_softc *sc;
                   2064: {
                   2065:        int s, i;
                   2066:
                   2067:        s = splnet();
                   2068:        for (i = 0; i<MAX_MBS; i++) {
                   2069:                if (sc->mb[i]) {
                   2070:                        m_freem(sc->mb[i]);
                   2071:                        sc->mb[i] = NULL;
                   2072:                }
                   2073:        }
                   2074:        sc->last_mb = sc->next_mb = 0;
                   2075:        untimeout(epmbuffill, sc);
                   2076:        splx(s);
1.34      thorpej  2077: }
                   2078:
                   2079: int
                   2080: epenable(sc)
                   2081:        struct ep_softc *sc;
                   2082: {
                   2083:
                   2084:        if (sc->enabled == 0 && sc->enable != NULL) {
                   2085:                if ((*sc->enable)(sc) != 0) {
                   2086:                        printf("%s: device enable failed\n",
                   2087:                            sc->sc_dev.dv_xname);
                   2088:                        return (EIO);
                   2089:                }
                   2090:        }
                   2091:
                   2092:        sc->enabled = 1;
                   2093:        return (0);
                   2094: }
                   2095:
                   2096: void
                   2097: epdisable(sc)
                   2098:        struct ep_softc *sc;
                   2099: {
                   2100:
                   2101:        if (sc->enabled != 0 && sc->disable != NULL) {
                   2102:                (*sc->disable)(sc);
                   2103:                sc->enabled = 0;
                   2104:        }
1.50      thorpej  2105: }
                   2106:
                   2107: int
                   2108: ep_activate(self, act)
                   2109:        struct device *self;
                   2110:        enum devact act;
                   2111: {
                   2112:        struct ep_softc *sc = (struct ep_softc *)self;
                   2113:        int rv = 0, s;
                   2114:
                   2115:        s = splnet();
                   2116:        switch (act) {
                   2117:        case DVACT_ACTIVATE:
                   2118:                rv = EOPNOTSUPP;
                   2119:                break;
                   2120:
                   2121:        case DVACT_DEACTIVATE:
                   2122: #ifdef notyet
                   2123:                /* First, kill off the interface. */
                   2124:                if_detach(sc->sc_ethercom.ec_if);
                   2125: #endif
                   2126:
                   2127:                /* Now disable the interface. */
                   2128:                epdisable(sc);
                   2129:                break;
                   2130:        }
                   2131:        splx(s);
                   2132:        return (rv);
1.41      thorpej  2133: }
                   2134:
1.58.2.1! wrstuden 2135: u_int32_t
        !          2136: ep_mii_bitbang_read(self)
        !          2137:        struct device *self;
1.41      thorpej  2138: {
1.58.2.1! wrstuden 2139:        struct ep_softc *sc = (void *) self;
1.41      thorpej  2140:
1.58.2.1! wrstuden 2141:        /* We're already in Window 4. */
        !          2142:        return (bus_space_read_2(sc->sc_iot, sc->sc_ioh,
        !          2143:            ELINK_W4_BOOM_PHYSMGMT));
1.41      thorpej  2144: }
                   2145:
                   2146: void
1.58.2.1! wrstuden 2147: ep_mii_bitbang_write(self, val)
        !          2148:        struct device *self;
        !          2149:        u_int32_t val;
1.41      thorpej  2150: {
1.58.2.1! wrstuden 2151:        struct ep_softc *sc = (void *) self;
1.41      thorpej  2152:
1.58.2.1! wrstuden 2153:        /* We're already in Window 4. */
        !          2154:        bus_space_write_2(sc->sc_iot, sc->sc_ioh,
        !          2155:            ELINK_W4_BOOM_PHYSMGMT, val);
1.41      thorpej  2156: }
                   2157:
                   2158: int
                   2159: ep_mii_readreg(self, phy, reg)
                   2160:        struct device *self;
                   2161:        int phy, reg;
                   2162: {
1.58.2.1! wrstuden 2163:        struct ep_softc *sc = (void *) self;
        !          2164:        int val;
1.41      thorpej  2165:
                   2166:        GO_WINDOW(4);
                   2167:
1.58.2.1! wrstuden 2168:        val = mii_bitbang_readreg(self, &ep_mii_bitbang_ops, phy, reg);
1.41      thorpej  2169:
1.58.2.1! wrstuden 2170:        GO_WINDOW(1);
1.41      thorpej  2171:
1.58.2.1! wrstuden 2172:        return (val);
1.41      thorpej  2173: }
                   2174:
                   2175: void
                   2176: ep_mii_writereg(self, phy, reg, val)
                   2177:        struct device *self;
                   2178:        int phy, reg, val;
                   2179: {
1.58.2.1! wrstuden 2180:        struct ep_softc *sc = (void *) self;
1.41      thorpej  2181:
                   2182:        GO_WINDOW(4);
                   2183:
1.58.2.1! wrstuden 2184:        mii_bitbang_writereg(self, &ep_mii_bitbang_ops, phy, reg, val);
1.41      thorpej  2185:
1.58.2.1! wrstuden 2186:        GO_WINDOW(1);
1.41      thorpej  2187: }
                   2188:
                   2189: void
                   2190: ep_statchg(self)
                   2191:        struct device *self;
                   2192: {
1.45      thorpej  2193:        struct ep_softc *sc = (struct ep_softc *)self;
                   2194:        bus_space_tag_t iot = sc->sc_iot;
                   2195:        bus_space_handle_t ioh = sc->sc_ioh;
                   2196:        int mctl;
1.41      thorpej  2197:
                   2198:        /* XXX Update ifp->if_baudrate */
1.45      thorpej  2199:
                   2200:        GO_WINDOW(3);
1.47      fvdl     2201:        mctl = bus_space_read_2(iot, ioh, ELINK_W3_MAC_CONTROL);
1.45      thorpej  2202:        if (sc->sc_mii.mii_media_active & IFM_FDX)
                   2203:                mctl |= MAC_CONTROL_FDX;
                   2204:        else
                   2205:                mctl &= ~MAC_CONTROL_FDX;
1.47      fvdl     2206:        bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl);
1.45      thorpej  2207:        GO_WINDOW(1);   /* back to operating window */
1.1       thorpej  2208: }

CVSweb <webmaster@jp.NetBSD.org>