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

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

1.1       nbrk        1: /*     $OpenBSD: xl.c,v 1.78 2007/05/19 16:51:57 kettenis Exp $        */
                      2:
                      3: /*
                      4:  * Copyright (c) 1997, 1998, 1999
                      5:  *     Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Bill Paul.
                     18:  * 4. Neither the name of the author nor the names of any co-contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
                     26:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     32:  * THE POSSIBILITY OF SUCH DAMAGE.
                     33:  *
                     34:  * $FreeBSD: if_xl.c,v 1.77 2000/08/28 20:40:03 wpaul Exp $
                     35:  */
                     36:
                     37: /*
                     38:  * 3Com 3c90x Etherlink XL PCI NIC driver
                     39:  *
                     40:  * Supports the 3Com "boomerang", "cyclone", and "hurricane" PCI
                     41:  * bus-master chips (3c90x cards and embedded controllers) including
                     42:  * the following:
                     43:  *
                     44:  * 3Com 3c900-TPO      10Mbps/RJ-45
                     45:  * 3Com 3c900-COMBO    10Mbps/RJ-45,AUI,BNC
                     46:  * 3Com 3c905-TX       10/100Mbps/RJ-45
                     47:  * 3Com 3c905-T4       10/100Mbps/RJ-45
                     48:  * 3Com 3c900B-TPO     10Mbps/RJ-45
                     49:  * 3Com 3c900B-COMBO   10Mbps/RJ-45,AUI,BNC
                     50:  * 3Com 3c900B-TPC     10Mbps/RJ-45,BNC
                     51:  * 3Com 3c900B-FL      10Mbps/Fiber-optic
                     52:  * 3Com 3c905B-COMBO   10/100Mbps/RJ-45,AUI,BNC
                     53:  * 3Com 3c905B-TX      10/100Mbps/RJ-45
                     54:  * 3Com 3c905B-FL/FX   10/100Mbps/Fiber-optic
                     55:  * 3Com 3c905C-TX      10/100Mbps/RJ-45 (Tornado ASIC)
                     56:  * 3Com 3c980-TX       10/100Mbps server adapter (Hurricane ASIC)
                     57:  * 3Com 3c980C-TX      10/100Mbps server adapter (Tornado ASIC)
                     58:  * 3Com 3cSOHO100-TX   10/100Mbps/RJ-45 (Hurricane ASIC)
                     59:  * 3Com 3c450-TX       10/100Mbps/RJ-45 (Tornado ASIC)
                     60:  * 3Com 3c555          10/100Mbps/RJ-45 (MiniPCI, Laptop Hurricane)
                     61:  * 3Com 3c556          10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
                     62:  * 3Com 3c556B         10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
                     63:  * 3Com 3c575TX                10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
                     64:  * 3Com 3c575B         10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
                     65:  * 3Com 3c575C         10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
                     66:  * 3Com 3cxfem656      10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
                     67:  * 3Com 3cxfem656b     10/100Mbps/RJ-45 (Cardbus, Hurricane ASIC)
                     68:  * 3Com 3cxfem656c     10/100Mbps/RJ-45 (Cardbus, Tornado ASIC)
                     69:  * Dell Optiplex GX1 on-board 3c918 10/100Mbps/RJ-45
                     70:  * Dell on-board 3c920 10/100Mbps/RJ-45
                     71:  * Dell Precision on-board 3c905B 10/100Mbps/RJ-45
                     72:  * Dell Latitude laptop docking station embedded 3c905-TX
                     73:  *
                     74:  * Written by Bill Paul <wpaul@ctr.columbia.edu>
                     75:  * Electrical Engineering Department
                     76:  * Columbia University, New York City
                     77:  */
                     78:
                     79: /*
                     80:  * The 3c90x series chips use a bus-master DMA interface for transfering
                     81:  * packets to and from the controller chip. Some of the "vortex" cards
                     82:  * (3c59x) also supported a bus master mode, however for those chips
                     83:  * you could only DMA packets to/from a contiguous memory buffer. For
                     84:  * transmission this would mean copying the contents of the queued mbuf
                     85:  * chain into an mbuf cluster and then DMAing the cluster. This extra
                     86:  * copy would sort of defeat the purpose of the bus master support for
                     87:  * any packet that doesn't fit into a single mbuf.
                     88:  *
                     89:  * By contrast, the 3c90x cards support a fragment-based bus master
                     90:  * mode where mbuf chains can be encapsulated using TX descriptors.
                     91:  * This is similar to other PCI chips such as the Texas Instruments
                     92:  * ThunderLAN and the Intel 82557/82558.
                     93:  *
                     94:  * The "vortex" driver (if_vx.c) happens to work for the "boomerang"
                     95:  * bus master chips because they maintain the old PIO interface for
                     96:  * backwards compatibility, but starting with the 3c905B and the
                     97:  * "cyclone" chips, the compatibility interface has been dropped.
                     98:  * Since using bus master DMA is a big win, we use this driver to
                     99:  * support the PCI "boomerang" chips even though they work with the
                    100:  * "vortex" driver in order to obtain better performance.
                    101:  */
                    102:
                    103: #include "bpfilter.h"
                    104:
                    105: #include <sys/param.h>
                    106: #include <sys/systm.h>
                    107: #include <sys/mbuf.h>
                    108: #include <sys/protosw.h>
                    109: #include <sys/socket.h>
                    110: #include <sys/ioctl.h>
                    111: #include <sys/errno.h>
                    112: #include <sys/malloc.h>
                    113: #include <sys/kernel.h>
                    114: #include <sys/proc.h>   /* only for declaration of wakeup() used by vm.h */
                    115: #include <sys/device.h>
                    116:
                    117: #include <net/if.h>
                    118: #include <net/if_dl.h>
                    119: #include <net/if_types.h>
                    120: #include <net/if_media.h>
                    121:
                    122: #ifdef INET
                    123: #include <netinet/in.h>
                    124: #include <netinet/in_systm.h>
                    125: #include <netinet/in_var.h>
                    126: #include <netinet/ip.h>
                    127: #include <netinet/if_ether.h>
                    128: #endif
                    129:
                    130: #include <dev/mii/mii.h>
                    131: #include <dev/mii/miivar.h>
                    132:
                    133: #include <machine/bus.h>
                    134:
                    135: #if NBPFILTER > 0
                    136: #include <net/bpf.h>
                    137: #endif
                    138:
                    139: #include <dev/ic/xlreg.h>
                    140:
                    141: /*
                    142:  * TX Checksumming is disabled by default for two reasons:
                    143:  * - TX Checksumming will occasionally produce corrupt packets
                    144:  * - TX Checksumming seems to reduce performance
                    145:  *
                    146:  * Only 905B/C cards were reported to have this problem, it is possible
                    147:  * that later chips _may_ be immune.
                    148:  */
                    149: #define        XL905B_TXCSUM_BROKEN    1
                    150:
                    151: int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *);
                    152: void xl_stats_update(void *);
                    153: int xl_encap(struct xl_softc *, struct xl_chain *,
                    154:     struct mbuf * );
                    155: void xl_rxeof(struct xl_softc *);
                    156: int xl_rx_resync(struct xl_softc *);
                    157: void xl_txeof(struct xl_softc *);
                    158: void xl_txeof_90xB(struct xl_softc *);
                    159: void xl_txeoc(struct xl_softc *);
                    160: int xl_intr(void *);
                    161: void xl_start(struct ifnet *);
                    162: void xl_start_90xB(struct ifnet *);
                    163: int xl_ioctl(struct ifnet *, u_long, caddr_t);
                    164: void xl_init(void *);
                    165: void xl_stop(struct xl_softc *);
                    166: void xl_freetxrx(struct xl_softc *);
                    167: void xl_watchdog(struct ifnet *);
                    168: void xl_shutdown(void *);
                    169: int xl_ifmedia_upd(struct ifnet *);
                    170: void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
                    171:
                    172: int xl_eeprom_wait(struct xl_softc *);
                    173: int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int);
                    174: void xl_mii_sync(struct xl_softc *);
                    175: void xl_mii_send(struct xl_softc *, u_int32_t, int);
                    176: int xl_mii_readreg(struct xl_softc *, struct xl_mii_frame *);
                    177: int xl_mii_writereg(struct xl_softc *, struct xl_mii_frame *);
                    178:
                    179: void xl_setcfg(struct xl_softc *);
                    180: void xl_setmode(struct xl_softc *, int);
                    181: void xl_setmulti(struct xl_softc *);
                    182: void xl_setmulti_hash(struct xl_softc *);
                    183: void xl_setpromisc(struct xl_softc *);
                    184: void xl_reset(struct xl_softc *);
                    185: int xl_list_rx_init(struct xl_softc *);
                    186: int xl_list_tx_init(struct xl_softc *);
                    187: int xl_list_tx_init_90xB(struct xl_softc *);
                    188: void xl_wait(struct xl_softc *);
                    189: void xl_mediacheck(struct xl_softc *);
                    190: void xl_choose_xcvr(struct xl_softc *, int);
                    191: #ifdef notdef
                    192: void xl_testpacket(struct xl_softc *);
                    193: #endif
                    194:
                    195: int xl_miibus_readreg(struct device *, int, int);
                    196: void xl_miibus_writereg(struct device *, int, int, int);
                    197: void xl_miibus_statchg(struct device *);
                    198:
                    199: void xl_power(int, void *);
                    200:
                    201: void
                    202: xl_power(int why, void *arg)
                    203: {
                    204:        struct xl_softc *sc = arg;
                    205:        struct ifnet *ifp;
                    206:        int s;
                    207:
                    208:        s = splnet();
                    209:        if (why != PWR_RESUME)
                    210:                xl_stop(sc);
                    211:        else {
                    212:                ifp = &sc->sc_arpcom.ac_if;
                    213:                if (ifp->if_flags & IFF_UP) {
                    214:                        xl_reset(sc);
                    215:                        xl_init(sc);
                    216:                }
                    217:        }
                    218:        splx(s);
                    219: }
                    220:
                    221: /*
                    222:  * Murphy's law says that it's possible the chip can wedge and
                    223:  * the 'command in progress' bit may never clear. Hence, we wait
                    224:  * only a finite amount of time to avoid getting caught in an
                    225:  * infinite loop. Normally this delay routine would be a macro,
                    226:  * but it isn't called during normal operation so we can afford
                    227:  * to make it a function.
                    228:  */
                    229: void
                    230: xl_wait(struct xl_softc *sc)
                    231: {
                    232:        int     i;
                    233:
                    234:        for (i = 0; i < XL_TIMEOUT; i++) {
                    235:                if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
                    236:                        break;
                    237:        }
                    238:
                    239:        if (i == XL_TIMEOUT)
                    240:                printf("%s: command never completed!\n", sc->sc_dev.dv_xname);
                    241: }
                    242:
                    243: /*
                    244:  * MII access routines are provided for adapters with external
                    245:  * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
                    246:  * autoneg logic that's faked up to look like a PHY (3c905B-TX).
                    247:  * Note: if you don't perform the MDIO operations just right,
                    248:  * it's possible to end up with code that works correctly with
                    249:  * some chips/CPUs/processor speeds/bus speeds/etc but not
                    250:  * with others.
                    251:  */
                    252: #define MII_SET(x)                                     \
                    253:        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
                    254:                CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x))
                    255:
                    256: #define MII_CLR(x)                                     \
                    257:        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
                    258:                CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x))
                    259:
                    260: /*
                    261:  * Sync the PHYs by setting data bit and strobing the clock 32 times.
                    262:  */
                    263: void
                    264: xl_mii_sync(struct xl_softc *sc)
                    265: {
                    266:        int     i;
                    267:
                    268:        XL_SEL_WIN(4);
                    269:        MII_SET(XL_MII_DIR|XL_MII_DATA);
                    270:
                    271:        for (i = 0; i < 32; i++) {
                    272:                MII_SET(XL_MII_CLK);
                    273:                MII_SET(XL_MII_DATA);
                    274:                MII_SET(XL_MII_DATA);
                    275:                MII_CLR(XL_MII_CLK);
                    276:                MII_SET(XL_MII_DATA);
                    277:                MII_SET(XL_MII_DATA);
                    278:        }
                    279: }
                    280:
                    281: /*
                    282:  * Clock a series of bits through the MII.
                    283:  */
                    284: void
                    285: xl_mii_send(struct xl_softc *sc, u_int32_t bits, int cnt)
                    286: {
                    287:        int     i;
                    288:
                    289:        XL_SEL_WIN(4);
                    290:        MII_CLR(XL_MII_CLK);
                    291:
                    292:        for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
                    293:                 if (bits & i) {
                    294:                        MII_SET(XL_MII_DATA);
                    295:                 } else {
                    296:                        MII_CLR(XL_MII_DATA);
                    297:                 }
                    298:                MII_CLR(XL_MII_CLK);
                    299:                MII_SET(XL_MII_CLK);
                    300:        }
                    301: }
                    302:
                    303: /*
                    304:  * Read an PHY register through the MII.
                    305:  */
                    306: int
                    307: xl_mii_readreg(struct xl_softc *sc, struct xl_mii_frame *frame)
                    308: {
                    309:        int     i, ack, s;
                    310:
                    311:        s = splnet();
                    312:
                    313:        /*
                    314:         * Set up frame for RX.
                    315:         */
                    316:        frame->mii_stdelim = XL_MII_STARTDELIM;
                    317:        frame->mii_opcode = XL_MII_READOP;
                    318:        frame->mii_turnaround = 0;
                    319:        frame->mii_data = 0;
                    320:
                    321:        /*
                    322:         * Select register window 4.
                    323:         */
                    324:
                    325:        XL_SEL_WIN(4);
                    326:
                    327:        CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0);
                    328:        /*
                    329:         * Turn on data xmit.
                    330:         */
                    331:        MII_SET(XL_MII_DIR);
                    332:
                    333:        xl_mii_sync(sc);
                    334:
                    335:        /*
                    336:         * Send command/address info.
                    337:         */
                    338:        xl_mii_send(sc, frame->mii_stdelim, 2);
                    339:        xl_mii_send(sc, frame->mii_opcode, 2);
                    340:        xl_mii_send(sc, frame->mii_phyaddr, 5);
                    341:        xl_mii_send(sc, frame->mii_regaddr, 5);
                    342:
                    343:        /* Idle bit */
                    344:        MII_CLR((XL_MII_CLK|XL_MII_DATA));
                    345:        MII_SET(XL_MII_CLK);
                    346:
                    347:        /* Turn off xmit. */
                    348:        MII_CLR(XL_MII_DIR);
                    349:
                    350:        /* Check for ack */
                    351:        MII_CLR(XL_MII_CLK);
                    352:        ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA;
                    353:        MII_SET(XL_MII_CLK);
                    354:
                    355:        /*
                    356:         * Now try reading data bits. If the ack failed, we still
                    357:         * need to clock through 16 cycles to keep the PHY(s) in sync.
                    358:         */
                    359:        if (ack) {
                    360:                for(i = 0; i < 16; i++) {
                    361:                        MII_CLR(XL_MII_CLK);
                    362:                        MII_SET(XL_MII_CLK);
                    363:                }
                    364:                goto fail;
                    365:        }
                    366:
                    367:        for (i = 0x8000; i; i >>= 1) {
                    368:                MII_CLR(XL_MII_CLK);
                    369:                if (!ack) {
                    370:                        if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA)
                    371:                                frame->mii_data |= i;
                    372:                }
                    373:                MII_SET(XL_MII_CLK);
                    374:        }
                    375:
                    376: fail:
                    377:
                    378:        MII_CLR(XL_MII_CLK);
                    379:        MII_SET(XL_MII_CLK);
                    380:
                    381:        splx(s);
                    382:
                    383:        if (ack)
                    384:                return (1);
                    385:        return (0);
                    386: }
                    387:
                    388: /*
                    389:  * Write to a PHY register through the MII.
                    390:  */
                    391: int
                    392: xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame)
                    393: {
                    394:        int     s;
                    395:
                    396:        s = splnet();
                    397:
                    398:        /*
                    399:         * Set up frame for TX.
                    400:         */
                    401:
                    402:        frame->mii_stdelim = XL_MII_STARTDELIM;
                    403:        frame->mii_opcode = XL_MII_WRITEOP;
                    404:        frame->mii_turnaround = XL_MII_TURNAROUND;
                    405:
                    406:        /*
                    407:         * Select the window 4.
                    408:         */
                    409:        XL_SEL_WIN(4);
                    410:
                    411:        /*
                    412:         * Turn on data output.
                    413:         */
                    414:        MII_SET(XL_MII_DIR);
                    415:
                    416:        xl_mii_sync(sc);
                    417:
                    418:        xl_mii_send(sc, frame->mii_stdelim, 2);
                    419:        xl_mii_send(sc, frame->mii_opcode, 2);
                    420:        xl_mii_send(sc, frame->mii_phyaddr, 5);
                    421:        xl_mii_send(sc, frame->mii_regaddr, 5);
                    422:        xl_mii_send(sc, frame->mii_turnaround, 2);
                    423:        xl_mii_send(sc, frame->mii_data, 16);
                    424:
                    425:        /* Idle bit. */
                    426:        MII_SET(XL_MII_CLK);
                    427:        MII_CLR(XL_MII_CLK);
                    428:
                    429:        /*
                    430:         * Turn off xmit.
                    431:         */
                    432:        MII_CLR(XL_MII_DIR);
                    433:
                    434:        splx(s);
                    435:
                    436:        return (0);
                    437: }
                    438:
                    439: int
                    440: xl_miibus_readreg(struct device *self, int phy, int reg)
                    441: {
                    442:        struct xl_softc *sc = (struct xl_softc *)self;
                    443:        struct xl_mii_frame     frame;
                    444:
                    445:        if (!(sc->xl_flags & XL_FLAG_PHYOK) && phy != 24)
                    446:                return (0);
                    447:
                    448:        bzero((char *)&frame, sizeof(frame));
                    449:
                    450:        frame.mii_phyaddr = phy;
                    451:        frame.mii_regaddr = reg;
                    452:        xl_mii_readreg(sc, &frame);
                    453:
                    454:        return (frame.mii_data);
                    455: }
                    456:
                    457: void
                    458: xl_miibus_writereg(struct device *self, int phy, int reg, int data)
                    459: {
                    460:        struct xl_softc *sc = (struct xl_softc *)self;
                    461:        struct xl_mii_frame     frame;
                    462:
                    463:        if (!(sc->xl_flags & XL_FLAG_PHYOK) && phy != 24)
                    464:                return;
                    465:
                    466:        bzero((char *)&frame, sizeof(frame));
                    467:
                    468:        frame.mii_phyaddr = phy;
                    469:        frame.mii_regaddr = reg;
                    470:        frame.mii_data = data;
                    471:
                    472:        xl_mii_writereg(sc, &frame);
                    473: }
                    474:
                    475: void
                    476: xl_miibus_statchg(struct device *self)
                    477: {
                    478:        struct xl_softc *sc = (struct xl_softc *)self;
                    479:
                    480:        xl_setcfg(sc);
                    481:
                    482:        /* Set ASIC's duplex mode to match the PHY. */
                    483:        XL_SEL_WIN(3);
                    484:        if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
                    485:                CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
                    486:        else
                    487:                CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
                    488:                    (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
                    489: }
                    490:
                    491: /*
                    492:  * The EEPROM is slow: give it time to come ready after issuing
                    493:  * it a command.
                    494:  */
                    495: int
                    496: xl_eeprom_wait(struct xl_softc *sc)
                    497: {
                    498:        int     i;
                    499:
                    500:        for (i = 0; i < 100; i++) {
                    501:                if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
                    502:                        DELAY(162);
                    503:                else
                    504:                        break;
                    505:        }
                    506:
                    507:        if (i == 100) {
                    508:                printf("%s: eeprom failed to come ready\n", sc->sc_dev.dv_xname);
                    509:                return (1);
                    510:        }
                    511:
                    512:        return (0);
                    513: }
                    514:
                    515: /*
                    516:  * Read a sequence of words from the EEPROM. Note that ethernet address
                    517:  * data is stored in the EEPROM in network byte order.
                    518:  */
                    519: int
                    520: xl_read_eeprom(struct xl_softc *sc, caddr_t dest, int off, int cnt, int swap)
                    521: {
                    522:        int             err = 0, i;
                    523:        u_int16_t       word = 0, *ptr;
                    524: #define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
                    525: #define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F)
                    526:        /* WARNING! DANGER!
                    527:         * It's easy to accidentally overwrite the rom content!
                    528:         * Note: the 3c575 uses 8bit EEPROM offsets.
                    529:         */
                    530:        XL_SEL_WIN(0);
                    531:
                    532:        if (xl_eeprom_wait(sc))
                    533:                return (1);
                    534:
                    535:        if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
                    536:                off += 0x30;
                    537:
                    538:        for (i = 0; i < cnt; i++) {
                    539:                if (sc->xl_flags & XL_FLAG_8BITROM)
                    540:                        CSR_WRITE_2(sc, XL_W0_EE_CMD,
                    541:                            XL_EE_8BIT_READ | EEPROM_8BIT_OFFSET(off + i));
                    542:                else
                    543:                        CSR_WRITE_2(sc, XL_W0_EE_CMD,
                    544:                            XL_EE_READ | EEPROM_5BIT_OFFSET(off + i));
                    545:                err = xl_eeprom_wait(sc);
                    546:                if (err)
                    547:                        break;
                    548:                word = CSR_READ_2(sc, XL_W0_EE_DATA);
                    549:                ptr = (u_int16_t *)(dest + (i * 2));
                    550:                if (swap)
                    551:                        *ptr = ntohs(word);
                    552:                else
                    553:                        *ptr = word;
                    554:        }
                    555:
                    556:        return (err ? 1 : 0);
                    557: }
                    558:
                    559: /*
                    560:  * NICs older than the 3c905B have only one multicast option, which
                    561:  * is to enable reception of all multicast frames.
                    562:  */
                    563: void
                    564: xl_setmulti(struct xl_softc *sc)
                    565: {
                    566:        struct ifnet    *ifp;
                    567:        struct arpcom   *ac = &sc->sc_arpcom;
                    568:        u_int8_t        rxfilt;
                    569:
                    570:        ifp = &sc->sc_arpcom.ac_if;
                    571:
                    572:        XL_SEL_WIN(5);
                    573:        rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
                    574:
                    575:        if (ifp->if_flags & IFF_ALLMULTI) {
                    576:                rxfilt |= XL_RXFILTER_ALLMULTI;
                    577:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                    578:                return;
                    579:        }
                    580:
                    581:        if (ac->ac_multicnt > 0)
                    582:                rxfilt |= XL_RXFILTER_ALLMULTI;
                    583:        else
                    584:                rxfilt &= ~XL_RXFILTER_ALLMULTI;
                    585:
                    586:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                    587: }
                    588:
                    589: /*
                    590:  * 3c905B adapters have a hash filter that we can program.
                    591:  */
                    592: void
                    593: xl_setmulti_hash(struct xl_softc *sc)
                    594: {
                    595:        struct ifnet    *ifp;
                    596:        int             h = 0, i;
                    597:        struct arpcom   *ac = &sc->sc_arpcom;
                    598:        struct ether_multi *enm;
                    599:        struct ether_multistep step;
                    600:        u_int8_t        rxfilt;
                    601:        int             mcnt = 0;
                    602:
                    603:        ifp = &sc->sc_arpcom.ac_if;
                    604:
                    605:        XL_SEL_WIN(5);
                    606:        rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
                    607:
                    608:        if (ifp->if_flags & IFF_ALLMULTI) {
                    609: allmulti:
                    610:                rxfilt |= XL_RXFILTER_ALLMULTI;
                    611:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                    612:                return;
                    613:        } else
                    614:                rxfilt &= ~XL_RXFILTER_ALLMULTI;
                    615:
                    616:
                    617:        /* first, zot all the existing hash bits */
                    618:        for (i = 0; i < XL_HASHFILT_SIZE; i++)
                    619:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|i);
                    620:
                    621:        /* now program new ones */
                    622:        ETHER_FIRST_MULTI(step, ac, enm);
                    623:        while (enm != NULL) {
                    624:                if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
                    625:                        ifp->if_flags |= IFF_ALLMULTI;
                    626:                        goto allmulti;
                    627:                }
                    628:                h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) &
                    629:                    0x000000FF;
                    630:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|XL_HASH_SET|h);
                    631:                mcnt++;
                    632:                ETHER_NEXT_MULTI(step, enm);
                    633:        }
                    634:
                    635:        if (mcnt)
                    636:                rxfilt |= XL_RXFILTER_MULTIHASH;
                    637:        else
                    638:                rxfilt &= ~XL_RXFILTER_MULTIHASH;
                    639:
                    640:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                    641: }
                    642:
                    643: void
                    644: xl_setpromisc(struct xl_softc *sc)
                    645: {
                    646:        struct ifnet *ifp;
                    647:        u_int8_t rxfilt;
                    648:
                    649:        ifp = &sc->sc_arpcom.ac_if;
                    650:
                    651:        XL_SEL_WIN(5);
                    652:        rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
                    653:
                    654:        if (ifp->if_flags & IFF_PROMISC)
                    655:                rxfilt |= XL_RXFILTER_ALLFRAMES;
                    656:        else
                    657:                rxfilt &= ~XL_RXFILTER_ALLFRAMES;
                    658:
                    659:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                    660: }
                    661:
                    662:
                    663: #ifdef notdef
                    664: void
                    665: xl_testpacket(struct xl_softc *sc)
                    666: {
                    667:        struct mbuf     *m;
                    668:        struct ifnet    *ifp;
                    669:        int             error;
                    670:
                    671:        ifp = &sc->sc_arpcom.ac_if;
                    672:
                    673:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    674:
                    675:        if (m == NULL)
                    676:                return;
                    677:
                    678:        bcopy(&sc->sc_arpcom.ac_enaddr,
                    679:                mtod(m, struct ether_header *)->ether_dhost, ETHER_ADDR_LEN);
                    680:        bcopy(&sc->sc_arpcom.ac_enaddr,
                    681:                mtod(m, struct ether_header *)->ether_shost, ETHER_ADDR_LEN);
                    682:        mtod(m, struct ether_header *)->ether_type = htons(3);
                    683:        mtod(m, unsigned char *)[14] = 0;
                    684:        mtod(m, unsigned char *)[15] = 0;
                    685:        mtod(m, unsigned char *)[16] = 0xE3;
                    686:        m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
                    687:        IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
                    688:        xl_start(ifp);
                    689: }
                    690: #endif
                    691:
                    692: void
                    693: xl_setcfg(struct xl_softc *sc)
                    694: {
                    695:        u_int32_t icfg;
                    696:
                    697:        XL_SEL_WIN(3);
                    698:        icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
                    699:        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    700:        if (sc->xl_media & XL_MEDIAOPT_MII ||
                    701:                sc->xl_media & XL_MEDIAOPT_BT4)
                    702:                icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
                    703:        if (sc->xl_media & XL_MEDIAOPT_BTX)
                    704:                icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
                    705:
                    706:        CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
                    707:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
                    708: }
                    709:
                    710: void
                    711: xl_setmode(struct xl_softc *sc, int media)
                    712: {
                    713:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                    714:        u_int32_t icfg;
                    715:        u_int16_t mediastat;
                    716:
                    717:        XL_SEL_WIN(4);
                    718:        mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
                    719:        XL_SEL_WIN(3);
                    720:        icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
                    721:
                    722:        if (sc->xl_media & XL_MEDIAOPT_BT) {
                    723:                if (IFM_SUBTYPE(media) == IFM_10_T) {
                    724:                        ifp->if_baudrate = IF_Mbps(10);
                    725:                        sc->xl_xcvr = XL_XCVR_10BT;
                    726:                        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    727:                        icfg |= (XL_XCVR_10BT << XL_ICFG_CONNECTOR_BITS);
                    728:                        mediastat |= XL_MEDIASTAT_LINKBEAT|
                    729:                                        XL_MEDIASTAT_JABGUARD;
                    730:                        mediastat &= ~XL_MEDIASTAT_SQEENB;
                    731:                }
                    732:        }
                    733:
                    734:        if (sc->xl_media & XL_MEDIAOPT_BFX) {
                    735:                if (IFM_SUBTYPE(media) == IFM_100_FX) {
                    736:                        ifp->if_baudrate = IF_Mbps(100);
                    737:                        sc->xl_xcvr = XL_XCVR_100BFX;
                    738:                        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    739:                        icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);
                    740:                        mediastat |= XL_MEDIASTAT_LINKBEAT;
                    741:                        mediastat &= ~XL_MEDIASTAT_SQEENB;
                    742:                }
                    743:        }
                    744:
                    745:        if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
                    746:                if (IFM_SUBTYPE(media) == IFM_10_5) {
                    747:                        ifp->if_baudrate = IF_Mbps(10);
                    748:                        sc->xl_xcvr = XL_XCVR_AUI;
                    749:                        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    750:                        icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
                    751:                        mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
                    752:                                        XL_MEDIASTAT_JABGUARD);
                    753:                        mediastat |= ~XL_MEDIASTAT_SQEENB;
                    754:                }
                    755:                if (IFM_SUBTYPE(media) == IFM_10_FL) {
                    756:                        ifp->if_baudrate = IF_Mbps(10);
                    757:                        sc->xl_xcvr = XL_XCVR_AUI;
                    758:                        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    759:                        icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
                    760:                        mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
                    761:                                        XL_MEDIASTAT_JABGUARD);
                    762:                        mediastat |= ~XL_MEDIASTAT_SQEENB;
                    763:                }
                    764:        }
                    765:
                    766:        if (sc->xl_media & XL_MEDIAOPT_BNC) {
                    767:                if (IFM_SUBTYPE(media) == IFM_10_2) {
                    768:                        ifp->if_baudrate = IF_Mbps(10);
                    769:                        sc->xl_xcvr = XL_XCVR_COAX;
                    770:                        icfg &= ~XL_ICFG_CONNECTOR_MASK;
                    771:                        icfg |= (XL_XCVR_COAX << XL_ICFG_CONNECTOR_BITS);
                    772:                        mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
                    773:                                        XL_MEDIASTAT_JABGUARD|
                    774:                                        XL_MEDIASTAT_SQEENB);
                    775:                }
                    776:        }
                    777:
                    778:        if ((media & IFM_GMASK) == IFM_FDX ||
                    779:                        IFM_SUBTYPE(media) == IFM_100_FX) {
                    780:                XL_SEL_WIN(3);
                    781:                CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
                    782:        } else {
                    783:                XL_SEL_WIN(3);
                    784:                CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
                    785:                        (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
                    786:        }
                    787:
                    788:        if (IFM_SUBTYPE(media) == IFM_10_2)
                    789:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
                    790:        else
                    791:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
                    792:        CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
                    793:        XL_SEL_WIN(4);
                    794:        CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
                    795:        DELAY(800);
                    796:        XL_SEL_WIN(7);
                    797: }
                    798:
                    799: void
                    800: xl_reset(struct xl_softc *sc)
                    801: {
                    802:        int     i;
                    803:
                    804:        XL_SEL_WIN(0);
                    805:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
                    806:                    ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
                    807:                     XL_RESETOPT_DISADVFD:0));
                    808:
                    809:        /*
                    810:         * Pause briefly after issuing the reset command before trying
                    811:         * to access any other registers. With my 3c575C cardbus card,
                    812:         * failing to do this results in the system locking up while
                    813:         * trying to poll the command busy bit in the status register.
                    814:         */
                    815:        DELAY(100000);
                    816:
                    817:        for (i = 0; i < XL_TIMEOUT; i++) {
                    818:                DELAY(10);
                    819:                if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
                    820:                        break;
                    821:        }
                    822:
                    823:        if (i == XL_TIMEOUT)
                    824:                printf("%s: reset didn't complete\n", sc->sc_dev.dv_xname);
                    825:
                    826:        /* Note: the RX reset takes an absurd amount of time
                    827:         * on newer versions of the Tornado chips such as those
                    828:         * on the 3c905CX and newer 3c908C cards. We wait an
                    829:         * extra amount of time so that xl_wait() doesn't complain
                    830:         * and annoy the users.
                    831:         */
                    832:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
                    833:        DELAY(100000);
                    834:        xl_wait(sc);
                    835:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
                    836:        xl_wait(sc);
                    837:
                    838:        if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||
                    839:            sc->xl_flags & XL_FLAG_INVERT_MII_PWR) {
                    840:                XL_SEL_WIN(2);
                    841:                CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,
                    842:                    XL_W2_RESET_OPTIONS)
                    843:                    | ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR)?XL_RESETOPT_INVERT_LED:0)
                    844:                    | ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR)?XL_RESETOPT_INVERT_MII:0)
                    845:                    );
                    846:        }
                    847:
                    848:        /* Wait a little while for the chip to get its brains in order. */
                    849:        DELAY(100000);
                    850: }
                    851:
                    852: /*
                    853:  * This routine is a kludge to work around possible hardware faults
                    854:  * or manufacturing defects that can cause the media options register
                    855:  * (or reset options register, as it's called for the first generation
                    856:  * 3c90x adapters) to return an incorrect result. I have encountered
                    857:  * one Dell Latitude laptop docking station with an integrated 3c905-TX
                    858:  * which doesn't have any of the 'mediaopt' bits set. This screws up
                    859:  * the attach routine pretty badly because it doesn't know what media
                    860:  * to look for. If we find ourselves in this predicament, this routine
                    861:  * will try to guess the media options values and warn the user of a
                    862:  * possible manufacturing defect with his adapter/system/whatever.
                    863:  */
                    864: void
                    865: xl_mediacheck(struct xl_softc *sc)
                    866: {
                    867:        /*
                    868:         * If some of the media options bits are set, assume they are
                    869:         * correct. If not, try to figure it out down below.
                    870:         * XXX I should check for 10baseFL, but I don't have an adapter
                    871:         * to test with.
                    872:         */
                    873:        if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
                    874:                /*
                    875:                 * Check the XCVR value. If it's not in the normal range
                    876:                 * of values, we need to fake it up here.
                    877:                 */
                    878:                if (sc->xl_xcvr <= XL_XCVR_AUTO)
                    879:                        return;
                    880:                else {
                    881:                        printf("%s: bogus xcvr value "
                    882:                        "in EEPROM (%x)\n", sc->sc_dev.dv_xname, sc->xl_xcvr);
                    883:                        printf("%s: choosing new default based "
                    884:                                "on card type\n", sc->sc_dev.dv_xname);
                    885:                }
                    886:        } else {
                    887:                if (sc->xl_type == XL_TYPE_905B &&
                    888:                    sc->xl_media & XL_MEDIAOPT_10FL)
                    889:                        return;
                    890:                printf("%s: WARNING: no media options bits set in "
                    891:                        "the media options register!!\n", sc->sc_dev.dv_xname);
                    892:                printf("%s: this could be a manufacturing defect in "
                    893:                        "your adapter or system\n", sc->sc_dev.dv_xname);
                    894:                printf("%s: attempting to guess media type; you "
                    895:                        "should probably consult your vendor\n", sc->sc_dev.dv_xname);
                    896:        }
                    897:
                    898:        xl_choose_xcvr(sc, 1);
                    899: }
                    900:
                    901: void
                    902: xl_choose_xcvr(struct xl_softc *sc, int verbose)
                    903: {
                    904:        u_int16_t devid;
                    905:
                    906:        /*
                    907:         * Read the device ID from the EEPROM.
                    908:         * This is what's loaded into the PCI device ID register, so it has
                    909:         * to be correct otherwise we wouldn't have gotten this far.
                    910:         */
                    911:        xl_read_eeprom(sc, (caddr_t)&devid, XL_EE_PRODID, 1, 0);
                    912:
                    913:        switch(devid) {
                    914:        case TC_DEVICEID_BOOMERANG_10BT:        /* 3c900-TPO */
                    915:        case TC_DEVICEID_KRAKATOA_10BT:         /* 3c900B-TPO */
                    916:                sc->xl_media = XL_MEDIAOPT_BT;
                    917:                sc->xl_xcvr = XL_XCVR_10BT;
                    918:                if (verbose)
                    919:                        printf("%s: guessing 10BaseT transceiver\n",
                    920:                            sc->sc_dev.dv_xname);
                    921:                break;
                    922:        case TC_DEVICEID_BOOMERANG_10BT_COMBO:  /* 3c900-COMBO */
                    923:        case TC_DEVICEID_KRAKATOA_10BT_COMBO:   /* 3c900B-COMBO */
                    924:                sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
                    925:                sc->xl_xcvr = XL_XCVR_10BT;
                    926:                if (verbose)
                    927:                        printf("%s: guessing COMBO (AUI/BNC/TP)\n",
                    928:                            sc->sc_dev.dv_xname);
                    929:                break;
                    930:        case TC_DEVICEID_KRAKATOA_10BT_TPC:     /* 3c900B-TPC */
                    931:                sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
                    932:                sc->xl_xcvr = XL_XCVR_10BT;
                    933:                if (verbose)
                    934:                        printf("%s: guessing TPC (BNC/TP)\n", sc->sc_dev.dv_xname);
                    935:                break;
                    936:        case TC_DEVICEID_CYCLONE_10FL:          /* 3c900B-FL */
                    937:                sc->xl_media = XL_MEDIAOPT_10FL;
                    938:                sc->xl_xcvr = XL_XCVR_AUI;
                    939:                if (verbose)
                    940:                        printf("%s: guessing 10baseFL\n", sc->sc_dev.dv_xname);
                    941:                break;
                    942:        case TC_DEVICEID_BOOMERANG_10_100BT:    /* 3c905-TX */
                    943:        case TC_DEVICEID_HURRICANE_555:         /* 3c555 */
                    944:        case TC_DEVICEID_HURRICANE_556:         /* 3c556 */
                    945:        case TC_DEVICEID_HURRICANE_556B:        /* 3c556B */
                    946:        case TC_DEVICEID_HURRICANE_575A:        /* 3c575TX */
                    947:        case TC_DEVICEID_HURRICANE_575B:        /* 3c575B */
                    948:        case TC_DEVICEID_HURRICANE_575C:        /* 3c575C */
                    949:        case TC_DEVICEID_HURRICANE_656:         /* 3c656 */
                    950:        case TC_DEVICEID_HURRICANE_656B:        /* 3c656B */
                    951:        case TC_DEVICEID_TORNADO_656C:          /* 3c656C */
                    952:        case TC_DEVICEID_TORNADO_10_100BT_920B: /* 3c920B-EMB */
                    953:                sc->xl_media = XL_MEDIAOPT_MII;
                    954:                sc->xl_xcvr = XL_XCVR_MII;
                    955:                if (verbose)
                    956:                        printf("%s: guessing MII\n", sc->sc_dev.dv_xname);
                    957:                break;
                    958:        case TC_DEVICEID_BOOMERANG_100BT4:      /* 3c905-T4 */
                    959:        case TC_DEVICEID_CYCLONE_10_100BT4:     /* 3c905B-T4 */
                    960:                sc->xl_media = XL_MEDIAOPT_BT4;
                    961:                sc->xl_xcvr = XL_XCVR_MII;
                    962:                if (verbose)
                    963:                        printf("%s: guessing 100BaseT4/MII\n", sc->sc_dev.dv_xname);
                    964:                break;
                    965:        case TC_DEVICEID_HURRICANE_10_100BT:    /* 3c905B-TX */
                    966:        case TC_DEVICEID_HURRICANE_10_100BT_SERV:/* 3c980-TX */
                    967:        case TC_DEVICEID_TORNADO_10_100BT_SERV: /* 3c980C-TX */
                    968:        case TC_DEVICEID_HURRICANE_SOHO100TX:   /* 3cSOHO100-TX */
                    969:        case TC_DEVICEID_TORNADO_10_100BT:      /* 3c905C-TX */
                    970:        case TC_DEVICEID_TORNADO_HOMECONNECT:   /* 3c450-TX */
                    971:                sc->xl_media = XL_MEDIAOPT_BTX;
                    972:                sc->xl_xcvr = XL_XCVR_AUTO;
                    973:                if (verbose)
                    974:                        printf("%s: guessing 10/100 internal\n",
                    975:                            sc->sc_dev.dv_xname);
                    976:                break;
                    977:        case TC_DEVICEID_CYCLONE_10_100_COMBO:  /* 3c905B-COMBO */
                    978:                sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
                    979:                sc->xl_xcvr = XL_XCVR_AUTO;
                    980:                if (verbose)
                    981:                        printf("%s: guessing 10/100 plus BNC/AUI\n",
                    982:                            sc->sc_dev.dv_xname);
                    983:                break;
                    984:        default:
                    985:                printf("%s: unknown device ID: %x -- "
                    986:                        "defaulting to 10baseT\n", sc->sc_dev.dv_xname, devid);
                    987:                sc->xl_media = XL_MEDIAOPT_BT;
                    988:                break;
                    989:        }
                    990: }
                    991:
                    992: /*
                    993:  * Initialize the transmit descriptors.
                    994:  */
                    995: int
                    996: xl_list_tx_init(struct xl_softc *sc)
                    997: {
                    998:        struct xl_chain_data    *cd;
                    999:        struct xl_list_data     *ld;
                   1000:        int                     i;
                   1001:
                   1002:        cd = &sc->xl_cdata;
                   1003:        ld = sc->xl_ldata;
                   1004:        for (i = 0; i < XL_TX_LIST_CNT; i++) {
                   1005:                cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
                   1006:                if (i == (XL_TX_LIST_CNT - 1))
                   1007:                        cd->xl_tx_chain[i].xl_next = NULL;
                   1008:                else
                   1009:                        cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[i + 1];
                   1010:        }
                   1011:
                   1012:        cd->xl_tx_free = &cd->xl_tx_chain[0];
                   1013:        cd->xl_tx_tail = cd->xl_tx_head = NULL;
                   1014:
                   1015:        return (0);
                   1016: }
                   1017:
                   1018: /*
                   1019:  * Initialize the transmit descriptors.
                   1020:  */
                   1021: int
                   1022: xl_list_tx_init_90xB(struct xl_softc *sc)
                   1023: {
                   1024:        struct xl_chain_data    *cd;
                   1025:        struct xl_list_data     *ld;
                   1026:        int                     i, next, prev;
                   1027:
                   1028:        cd = &sc->xl_cdata;
                   1029:        ld = sc->xl_ldata;
                   1030:        for (i = 0; i < XL_TX_LIST_CNT; i++) {
                   1031:                if (i == (XL_TX_LIST_CNT - 1))
                   1032:                        next = 0;
                   1033:                else
                   1034:                        next = i + 1;
                   1035:                if (i == 0)
                   1036:                        prev = XL_TX_LIST_CNT - 1;
                   1037:                else
                   1038:                        prev = i - 1;
                   1039:                cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
                   1040:                cd->xl_tx_chain[i].xl_phys =
                   1041:                    sc->sc_listmap->dm_segs[0].ds_addr +
                   1042:                    offsetof(struct xl_list_data, xl_tx_list[i]);
                   1043:                cd->xl_tx_chain[i].xl_next = &cd->xl_tx_chain[next];
                   1044:                cd->xl_tx_chain[i].xl_prev = &cd->xl_tx_chain[prev];
                   1045:        }
                   1046:
                   1047:        bzero((char *)ld->xl_tx_list, sizeof(struct xl_list) * XL_TX_LIST_CNT);
                   1048:        ld->xl_tx_list[0].xl_status = htole32(XL_TXSTAT_EMPTY);
                   1049:
                   1050:        cd->xl_tx_prod = 1;
                   1051:        cd->xl_tx_cons = 1;
                   1052:        cd->xl_tx_cnt = 0;
                   1053:
                   1054:        return (0);
                   1055: }
                   1056:
                   1057: /*
                   1058:  * Initialize the RX descriptors and allocate mbufs for them. Note that
                   1059:  * we arrange the descriptors in a closed ring, so that the last descriptor
                   1060:  * points back to the first.
                   1061:  */
                   1062: int
                   1063: xl_list_rx_init(struct xl_softc *sc)
                   1064: {
                   1065:        struct xl_chain_data    *cd;
                   1066:        struct xl_list_data     *ld;
                   1067:        int                     i, n;
                   1068:        bus_addr_t              next;
                   1069:
                   1070:        cd = &sc->xl_cdata;
                   1071:        ld = sc->xl_ldata;
                   1072:
                   1073:        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                   1074:                cd->xl_rx_chain[i].xl_ptr =
                   1075:                        (struct xl_list_onefrag *)&ld->xl_rx_list[i];
                   1076:                if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
                   1077:                        return(ENOBUFS);
                   1078:                if (i == (XL_RX_LIST_CNT - 1))
                   1079:                        n = 0;
                   1080:                else
                   1081:                        n = i + 1;
                   1082:                cd->xl_rx_chain[i].xl_next = &cd->xl_rx_chain[n];
                   1083:                next = sc->sc_listmap->dm_segs[0].ds_addr +
                   1084:                       offsetof(struct xl_list_data, xl_rx_list[n]);
                   1085:                ld->xl_rx_list[i].xl_next = htole32(next);
                   1086:        }
                   1087:
                   1088:        cd->xl_rx_head = &cd->xl_rx_chain[0];
                   1089:
                   1090:        return (0);
                   1091: }
                   1092:
                   1093: /*
                   1094:  * Initialize an RX descriptor and attach an MBUF cluster.
                   1095:  */
                   1096: int
                   1097: xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
                   1098: {
                   1099:        struct mbuf     *m_new = NULL;
                   1100:        bus_dmamap_t    map;
                   1101:
                   1102:        MGETHDR(m_new, M_DONTWAIT, MT_DATA);
                   1103:        if (m_new == NULL)
                   1104:                return (ENOBUFS);
                   1105:
                   1106:        MCLGET(m_new, M_DONTWAIT);
                   1107:        if (!(m_new->m_flags & M_EXT)) {
                   1108:                m_freem(m_new);
                   1109:                return (ENOBUFS);
                   1110:        }
                   1111:
                   1112:        m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                   1113:        if (bus_dmamap_load(sc->sc_dmat, sc->sc_rx_sparemap,
                   1114:            mtod(m_new, caddr_t), MCLBYTES, NULL, BUS_DMA_NOWAIT) != 0) {
                   1115:                m_freem(m_new);
                   1116:                return (ENOBUFS);
                   1117:        }
                   1118:
                   1119:        /* sync the old map, and unload it (if necessary) */
                   1120:        if (c->map->dm_nsegs != 0) {
                   1121:                bus_dmamap_sync(sc->sc_dmat, c->map,
                   1122:                    0, c->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1123:                bus_dmamap_unload(sc->sc_dmat, c->map);
                   1124:        }
                   1125:
                   1126:        map = c->map;
                   1127:        c->map = sc->sc_rx_sparemap;
                   1128:        sc->sc_rx_sparemap = map;
                   1129:
                   1130:        /* Force longword alignment for packet payload. */
                   1131:        m_adj(m_new, ETHER_ALIGN);
                   1132:
                   1133:        bus_dmamap_sync(sc->sc_dmat, c->map, 0, c->map->dm_mapsize,
                   1134:            BUS_DMASYNC_PREREAD);
                   1135:
                   1136:        c->xl_mbuf = m_new;
                   1137:        c->xl_ptr->xl_frag.xl_addr =
                   1138:            htole32(c->map->dm_segs[0].ds_addr + ETHER_ALIGN);
                   1139:        c->xl_ptr->xl_frag.xl_len =
                   1140:            htole32(c->map->dm_segs[0].ds_len | XL_LAST_FRAG);
                   1141:        c->xl_ptr->xl_status = htole32(0);
                   1142:
                   1143:        bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                   1144:            ((caddr_t)c->xl_ptr - sc->sc_listkva), sizeof(struct xl_list),
                   1145:            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                   1146:
                   1147:        return (0);
                   1148: }
                   1149:
                   1150: int
                   1151: xl_rx_resync(struct xl_softc *sc)
                   1152: {
                   1153:        struct xl_chain_onefrag *pos;
                   1154:        int i;
                   1155:
                   1156:        pos = sc->xl_cdata.xl_rx_head;
                   1157:
                   1158:        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                   1159:                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                   1160:                    ((caddr_t)pos->xl_ptr - sc->sc_listkva),
                   1161:                    sizeof(struct xl_list),
                   1162:                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                   1163:
                   1164:                if (pos->xl_ptr->xl_status)
                   1165:                        break;
                   1166:                pos = pos->xl_next;
                   1167:        }
                   1168:
                   1169:        if (i == XL_RX_LIST_CNT)
                   1170:                return (0);
                   1171:
                   1172:        sc->xl_cdata.xl_rx_head = pos;
                   1173:
                   1174:        return (EAGAIN);
                   1175: }
                   1176:
                   1177: /*
                   1178:  * A frame has been uploaded: pass the resulting mbuf chain up to
                   1179:  * the higher level protocols.
                   1180:  */
                   1181: void
                   1182: xl_rxeof(struct xl_softc *sc)
                   1183: {
                   1184:         struct mbuf            *m;
                   1185:         struct ifnet           *ifp;
                   1186:        struct xl_chain_onefrag *cur_rx;
                   1187:        int                     total_len = 0, sumflags = 0;
                   1188:        u_int32_t               rxstat;
                   1189:
                   1190:        ifp = &sc->sc_arpcom.ac_if;
                   1191:
                   1192: again:
                   1193:
                   1194:        while ((rxstat = letoh32(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))
                   1195:            != 0) {
                   1196:                cur_rx = sc->xl_cdata.xl_rx_head;
                   1197:                sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
                   1198:                total_len = rxstat & XL_RXSTAT_LENMASK;
                   1199:
                   1200:                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                   1201:                    ((caddr_t)cur_rx->xl_ptr - sc->sc_listkva),
                   1202:                    sizeof(struct xl_list),
                   1203:                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                   1204:
                   1205:                /*
                   1206:                 * Since we have told the chip to allow large frames,
                   1207:                 * we need to trap giant frame errors in software. We allow
                   1208:                 * a little more than the normal frame size to account for
                   1209:                 * frames with VLAN tags.
                   1210:                 */
                   1211:                if (total_len > XL_MAX_FRAMELEN)
                   1212:                        rxstat |= (XL_RXSTAT_UP_ERROR|XL_RXSTAT_OVERSIZE);
                   1213:
                   1214:                /*
                   1215:                 * If an error occurs, update stats, clear the
                   1216:                 * status word and leave the mbuf cluster in place:
                   1217:                 * it should simply get re-used next time this descriptor
                   1218:                 * comes up in the ring.
                   1219:                 */
                   1220:                if (rxstat & XL_RXSTAT_UP_ERROR) {
                   1221:                        ifp->if_ierrors++;
                   1222:                        cur_rx->xl_ptr->xl_status = htole32(0);
                   1223:                        continue;
                   1224:                }
                   1225:
                   1226:                /*
                   1227:                 * If the error bit was not set, the upload complete
                   1228:                 * bit should be set which means we have a valid packet.
                   1229:                 * If not, something truly strange has happened.
                   1230:                 */
                   1231:                if (!(rxstat & XL_RXSTAT_UP_CMPLT)) {
                   1232:                        printf("%s: bad receive status -- "
                   1233:                            "packet dropped\n", sc->sc_dev.dv_xname);
                   1234:                        ifp->if_ierrors++;
                   1235:                        cur_rx->xl_ptr->xl_status = htole32(0);
                   1236:                        continue;
                   1237:                }
                   1238:
                   1239:                /* No errors; receive the packet. */
                   1240:                m = cur_rx->xl_mbuf;
                   1241:
                   1242:                /*
                   1243:                 * Try to conjure up a new mbuf cluster. If that
                   1244:                 * fails, it means we have an out of memory condition and
                   1245:                 * should leave the buffer in place and continue. This will
                   1246:                 * result in a lost packet, but there's little else we
                   1247:                 * can do in this situation.
                   1248:                 */
                   1249:                if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
                   1250:                        ifp->if_ierrors++;
                   1251:                        cur_rx->xl_ptr->xl_status = htole32(0);
                   1252:                        continue;
                   1253:                }
                   1254:
                   1255:                ifp->if_ipackets++;
                   1256:                m->m_pkthdr.rcvif = ifp;
                   1257:                m->m_pkthdr.len = m->m_len = total_len;
                   1258: #if NBPFILTER > 0
                   1259:                /*
                   1260:                 * Handle BPF listeners. Let the BPF user see the packet.
                   1261:                 */
                   1262:                if (ifp->if_bpf) {
                   1263:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                   1264:                }
                   1265: #endif
                   1266:
                   1267:                if (sc->xl_type == XL_TYPE_905B) {
                   1268:                        if (!(rxstat & XL_RXSTAT_IPCKERR) &&
                   1269:                            (rxstat & XL_RXSTAT_IPCKOK))
                   1270:                                sumflags |= M_IPV4_CSUM_IN_OK;
                   1271:
                   1272:                        if (!(rxstat & XL_RXSTAT_TCPCKERR) &&
                   1273:                            (rxstat & XL_RXSTAT_TCPCKOK))
                   1274:                                sumflags |= M_TCP_CSUM_IN_OK;
                   1275:
                   1276:                        if (!(rxstat & XL_RXSTAT_UDPCKERR) &&
                   1277:                            (rxstat & XL_RXSTAT_UDPCKOK))
                   1278:                                sumflags |= M_UDP_CSUM_IN_OK;
                   1279:
                   1280:                        m->m_pkthdr.csum_flags = sumflags;
                   1281:                }
                   1282:
                   1283:                ether_input_mbuf(ifp, m);
                   1284:        }
                   1285:
                   1286:        /*
                   1287:         * Handle the 'end of channel' condition. When the upload
                   1288:         * engine hits the end of the RX ring, it will stall. This
                   1289:         * is our cue to flush the RX ring, reload the uplist pointer
                   1290:         * register and unstall the engine.
                   1291:         * XXX This is actually a little goofy. With the ThunderLAN
                   1292:         * chip, you get an interrupt when the receiver hits the end
                   1293:         * of the receive ring, which tells you exactly when you
                   1294:         * you need to reload the ring pointer. Here we have to
                   1295:         * fake it. I'm mad at myself for not being clever enough
                   1296:         * to avoid the use of a goto here.
                   1297:         */
                   1298:        if (CSR_READ_4(sc, XL_UPLIST_PTR) == 0 ||
                   1299:                CSR_READ_4(sc, XL_UPLIST_STATUS) & XL_PKTSTAT_UP_STALLED) {
                   1300:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
                   1301:                xl_wait(sc);
                   1302:                CSR_WRITE_4(sc, XL_UPLIST_PTR,
                   1303:                    sc->sc_listmap->dm_segs[0].ds_addr +
                   1304:                    offsetof(struct xl_list_data, xl_rx_list[0]));
                   1305:                sc->xl_cdata.xl_rx_head = &sc->xl_cdata.xl_rx_chain[0];
                   1306:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
                   1307:                goto again;
                   1308:        }
                   1309: }
                   1310:
                   1311: /*
                   1312:  * A frame was downloaded to the chip. It's safe for us to clean up
                   1313:  * the list buffers.
                   1314:  */
                   1315: void
                   1316: xl_txeof(struct xl_softc *sc)
                   1317: {
                   1318:        struct xl_chain         *cur_tx;
                   1319:        struct ifnet            *ifp;
                   1320:
                   1321:        ifp = &sc->sc_arpcom.ac_if;
                   1322:
                   1323:        /* Clear the timeout timer. */
                   1324:        ifp->if_timer = 0;
                   1325:
                   1326:        /*
                   1327:         * Go through our tx list and free mbufs for those
                   1328:         * frames that have been uploaded. Note: the 3c905B
                   1329:         * sets a special bit in the status word to let us
                   1330:         * know that a frame has been downloaded, but the
                   1331:         * original 3c900/3c905 adapters don't do that.
                   1332:         * Consequently, we have to use a different test if
                   1333:         * xl_type != XL_TYPE_905B.
                   1334:         */
                   1335:        while (sc->xl_cdata.xl_tx_head != NULL) {
                   1336:                cur_tx = sc->xl_cdata.xl_tx_head;
                   1337:
                   1338:                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                   1339:                    ((caddr_t)cur_tx->xl_ptr - sc->sc_listkva),
                   1340:                    sizeof(struct xl_list),
                   1341:                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                   1342:
                   1343:                if (CSR_READ_4(sc, XL_DOWNLIST_PTR))
                   1344:                        break;
                   1345:
                   1346:                sc->xl_cdata.xl_tx_head = cur_tx->xl_next;
                   1347:                ifp->if_opackets++;
                   1348:                if (cur_tx->map->dm_nsegs != 0) {
                   1349:                        bus_dmamap_t map = cur_tx->map;
                   1350:
                   1351:                        bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
                   1352:                            BUS_DMASYNC_POSTWRITE);
                   1353:                        bus_dmamap_unload(sc->sc_dmat, map);
                   1354:                }
                   1355:                if (cur_tx->xl_mbuf != NULL) {
                   1356:                        m_freem(cur_tx->xl_mbuf);
                   1357:                        cur_tx->xl_mbuf = NULL;
                   1358:                }
                   1359:                cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
                   1360:                sc->xl_cdata.xl_tx_free = cur_tx;
                   1361:        }
                   1362:
                   1363:        if (sc->xl_cdata.xl_tx_head == NULL) {
                   1364:                ifp->if_flags &= ~IFF_OACTIVE;
                   1365:                sc->xl_cdata.xl_tx_tail = NULL;
                   1366:        } else {
                   1367:                if (CSR_READ_4(sc, XL_DMACTL) & XL_DMACTL_DOWN_STALLED ||
                   1368:                        !CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
                   1369:                        CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
                   1370:                            sc->sc_listmap->dm_segs[0].ds_addr +
                   1371:                            ((caddr_t)sc->xl_cdata.xl_tx_head->xl_ptr -
                   1372:                            sc->sc_listkva));
                   1373:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
                   1374:                }
                   1375:        }
                   1376: }
                   1377:
                   1378: void
                   1379: xl_txeof_90xB(struct xl_softc *sc)
                   1380: {
                   1381:        struct xl_chain *cur_tx = NULL;
                   1382:        struct ifnet *ifp;
                   1383:        int idx;
                   1384:
                   1385:        ifp = &sc->sc_arpcom.ac_if;
                   1386:
                   1387:        idx = sc->xl_cdata.xl_tx_cons;
                   1388:        while (idx != sc->xl_cdata.xl_tx_prod) {
                   1389:
                   1390:                cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
                   1391:
                   1392:                if ((cur_tx->xl_ptr->xl_status &
                   1393:                    htole32(XL_TXSTAT_DL_COMPLETE)) == 0)
                   1394:                        break;
                   1395:
                   1396:                if (cur_tx->xl_mbuf != NULL) {
                   1397:                        m_freem(cur_tx->xl_mbuf);
                   1398:                        cur_tx->xl_mbuf = NULL;
                   1399:                }
                   1400:
                   1401:                if (cur_tx->map->dm_nsegs != 0) {
                   1402:                        bus_dmamap_sync(sc->sc_dmat, cur_tx->map,
                   1403:                            0, cur_tx->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1404:                        bus_dmamap_unload(sc->sc_dmat, cur_tx->map);
                   1405:                }
                   1406:
                   1407:                ifp->if_opackets++;
                   1408:
                   1409:                sc->xl_cdata.xl_tx_cnt--;
                   1410:                XL_INC(idx, XL_TX_LIST_CNT);
                   1411:                ifp->if_timer = 0;
                   1412:        }
                   1413:
                   1414:        sc->xl_cdata.xl_tx_cons = idx;
                   1415:
                   1416:        if (cur_tx != NULL)
                   1417:                ifp->if_flags &= ~IFF_OACTIVE;
                   1418: }
                   1419:
                   1420: /*
                   1421:  * TX 'end of channel' interrupt handler. Actually, we should
                   1422:  * only get a 'TX complete' interrupt if there's a transmit error,
                   1423:  * so this is really TX error handler.
                   1424:  */
                   1425: void
                   1426: xl_txeoc(struct xl_softc *sc)
                   1427: {
                   1428:        u_int8_t        txstat;
                   1429:
                   1430:        while ((txstat = CSR_READ_1(sc, XL_TX_STATUS))) {
                   1431:                if (txstat & XL_TXSTATUS_UNDERRUN ||
                   1432:                        txstat & XL_TXSTATUS_JABBER ||
                   1433:                        txstat & XL_TXSTATUS_RECLAIM) {
                   1434:                        if (txstat != 0x90) {
                   1435:                                printf("%s: transmission error: %x\n",
                   1436:                                    sc->sc_dev.dv_xname, txstat);
                   1437:                        }
                   1438:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
                   1439:                        xl_wait(sc);
                   1440:                        if (sc->xl_type == XL_TYPE_905B) {
                   1441:                                if (sc->xl_cdata.xl_tx_cnt) {
                   1442:                                        int i;
                   1443:                                        struct xl_chain *c;
                   1444:
                   1445:                                        i = sc->xl_cdata.xl_tx_cons;
                   1446:                                        c = &sc->xl_cdata.xl_tx_chain[i];
                   1447:                                        CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
                   1448:                                            c->xl_phys);
                   1449:                                        CSR_WRITE_1(sc, XL_DOWN_POLL, 64);
                   1450:                                }
                   1451:                        } else {
                   1452:                                if (sc->xl_cdata.xl_tx_head != NULL)
                   1453:                                        CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
                   1454:                                            sc->sc_listmap->dm_segs[0].ds_addr +
                   1455:                                            ((caddr_t)sc->xl_cdata.xl_tx_head->xl_ptr -
                   1456:                                            sc->sc_listkva));
                   1457:                        }
                   1458:                        /*
                   1459:                         * Remember to set this for the
                   1460:                         * first generation 3c90X chips.
                   1461:                         */
                   1462:                        CSR_WRITE_1(sc, XL_TX_FREETHRESH, XL_PACKET_SIZE >> 8);
                   1463:                        if (txstat & XL_TXSTATUS_UNDERRUN &&
                   1464:                            sc->xl_tx_thresh < XL_PACKET_SIZE) {
                   1465:                                sc->xl_tx_thresh += XL_MIN_FRAMELEN;
                   1466: #ifdef notdef
                   1467:                                printf("%s: tx underrun, increasing tx start"
                   1468:                                    " threshold to %d\n", sc->sc_dev.dv_xname,
                   1469:                                    sc->xl_tx_thresh);
                   1470: #endif
                   1471:                        }
                   1472:                        CSR_WRITE_2(sc, XL_COMMAND,
                   1473:                            XL_CMD_TX_SET_START|sc->xl_tx_thresh);
                   1474:                        if (sc->xl_type == XL_TYPE_905B) {
                   1475:                                CSR_WRITE_2(sc, XL_COMMAND,
                   1476:                                XL_CMD_SET_TX_RECLAIM|(XL_PACKET_SIZE >> 4));
                   1477:                        }
                   1478:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
                   1479:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
                   1480:                } else {
                   1481:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
                   1482:                        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
                   1483:                }
                   1484:                /*
                   1485:                 * Write an arbitrary byte to the TX_STATUS register
                   1486:                 * to clear this interrupt/error and advance to the next.
                   1487:                 */
                   1488:                CSR_WRITE_1(sc, XL_TX_STATUS, 0x01);
                   1489:        }
                   1490: }
                   1491:
                   1492: int
                   1493: xl_intr(void *arg)
                   1494: {
                   1495:        struct xl_softc         *sc;
                   1496:        struct ifnet            *ifp;
                   1497:        u_int16_t               status;
                   1498:        int                     claimed = 0;
                   1499:
                   1500:        sc = arg;
                   1501:        ifp = &sc->sc_arpcom.ac_if;
                   1502:
                   1503:        while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS && status != 0xFFFF) {
                   1504:
                   1505:                claimed = 1;
                   1506:
                   1507:                CSR_WRITE_2(sc, XL_COMMAND,
                   1508:                    XL_CMD_INTR_ACK|(status & XL_INTRS));
                   1509:
                   1510:                if (sc->intr_ack)
                   1511:                        (*sc->intr_ack)(sc);
                   1512:
                   1513:                if (status & XL_STAT_UP_COMPLETE) {
                   1514:                        int curpkts;
                   1515:
                   1516:                        curpkts = ifp->if_ipackets;
                   1517:                        xl_rxeof(sc);
                   1518:                        if (curpkts == ifp->if_ipackets) {
                   1519:                                while (xl_rx_resync(sc))
                   1520:                                        xl_rxeof(sc);
                   1521:                        }
                   1522:                }
                   1523:
                   1524:                if (status & XL_STAT_DOWN_COMPLETE) {
                   1525:                        if (sc->xl_type == XL_TYPE_905B)
                   1526:                                xl_txeof_90xB(sc);
                   1527:                        else
                   1528:                                xl_txeof(sc);
                   1529:                }
                   1530:
                   1531:                if (status & XL_STAT_TX_COMPLETE) {
                   1532:                        ifp->if_oerrors++;
                   1533:                        xl_txeoc(sc);
                   1534:                }
                   1535:
                   1536:                if (status & XL_STAT_ADFAIL) {
                   1537:                        xl_reset(sc);
                   1538:                        xl_init(sc);
                   1539:                }
                   1540:
                   1541:                if (status & XL_STAT_STATSOFLOW) {
                   1542:                        sc->xl_stats_no_timeout = 1;
                   1543:                        xl_stats_update(sc);
                   1544:                        sc->xl_stats_no_timeout = 0;
                   1545:                }
                   1546:        }
                   1547:
                   1548:        if (!IFQ_IS_EMPTY(&ifp->if_snd))
                   1549:                (*ifp->if_start)(ifp);
                   1550:
                   1551:        return (claimed);
                   1552: }
                   1553:
                   1554: void
                   1555: xl_stats_update(void *xsc)
                   1556: {
                   1557:        struct xl_softc         *sc;
                   1558:        struct ifnet            *ifp;
                   1559:        struct xl_stats         xl_stats;
                   1560:        u_int8_t                *p;
                   1561:        int                     i;
                   1562:        struct mii_data         *mii = NULL;
                   1563:
                   1564:        bzero((char *)&xl_stats, sizeof(struct xl_stats));
                   1565:
                   1566:        sc = xsc;
                   1567:        ifp = &sc->sc_arpcom.ac_if;
                   1568:        if (sc->xl_hasmii)
                   1569:                mii = &sc->sc_mii;
                   1570:
                   1571:        p = (u_int8_t *)&xl_stats;
                   1572:
                   1573:        /* Read all the stats registers. */
                   1574:        XL_SEL_WIN(6);
                   1575:
                   1576:        for (i = 0; i < 16; i++)
                   1577:                *p++ = CSR_READ_1(sc, XL_W6_CARRIER_LOST + i);
                   1578:
                   1579:        ifp->if_ierrors += xl_stats.xl_rx_overrun;
                   1580:
                   1581:        ifp->if_collisions += xl_stats.xl_tx_multi_collision +
                   1582:                                xl_stats.xl_tx_single_collision +
                   1583:                                xl_stats.xl_tx_late_collision;
                   1584:
                   1585:        /*
                   1586:         * Boomerang and cyclone chips have an extra stats counter
                   1587:         * in window 4 (BadSSD). We have to read this too in order
                   1588:         * to clear out all the stats registers and avoid a statsoflow
                   1589:         * interrupt.
                   1590:         */
                   1591:        XL_SEL_WIN(4);
                   1592:        CSR_READ_1(sc, XL_W4_BADSSD);
                   1593:
                   1594:        if (mii != NULL && (!sc->xl_stats_no_timeout))
                   1595:                mii_tick(mii);
                   1596:
                   1597:        XL_SEL_WIN(7);
                   1598:
                   1599:        if (!sc->xl_stats_no_timeout)
                   1600:                timeout_add(&sc->xl_stsup_tmo, hz);
                   1601: }
                   1602:
                   1603: /*
                   1604:  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
                   1605:  * pointers to the fragment pointers.
                   1606:  */
                   1607: int
                   1608: xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf *m_head)
                   1609: {
                   1610:        int             error, frag, total_len;
                   1611:        u_int32_t       status;
                   1612:        bus_dmamap_t    map;
                   1613:
                   1614:        map = sc->sc_tx_sparemap;
                   1615:
                   1616: reload:
                   1617:        error = bus_dmamap_load_mbuf(sc->sc_dmat, map,
                   1618:            m_head, BUS_DMA_NOWAIT);
                   1619:
                   1620:        if (error && error != EFBIG) {
                   1621:                m_freem(m_head);
                   1622:                return (1);
                   1623:        }
                   1624:
                   1625:        /*
                   1626:         * Start packing the mbufs in this chain into
                   1627:         * the fragment pointers. Stop when we run out
                   1628:         * of fragments or hit the end of the mbuf chain.
                   1629:         */
                   1630:        for (frag = 0, total_len = 0; frag < map->dm_nsegs; frag++) {
                   1631:                if (frag == XL_MAXFRAGS)
                   1632:                        break;
                   1633:                total_len += map->dm_segs[frag].ds_len;
                   1634:                c->xl_ptr->xl_frag[frag].xl_addr =
                   1635:                    htole32(map->dm_segs[frag].ds_addr);
                   1636:                c->xl_ptr->xl_frag[frag].xl_len =
                   1637:                    htole32(map->dm_segs[frag].ds_len);
                   1638:        }
                   1639:
                   1640:        /*
                   1641:         * Handle special case: we used up all 63 fragments,
                   1642:         * but we have more mbufs left in the chain. Copy the
                   1643:         * data into an mbuf cluster. Note that we don't
                   1644:         * bother clearing the values in the other fragment
                   1645:         * pointers/counters; it wouldn't gain us anything,
                   1646:         * and would waste cycles.
                   1647:         */
                   1648:        if (error) {
                   1649:                struct mbuf     *m_new = NULL;
                   1650:
                   1651:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
                   1652:                if (m_new == NULL) {
                   1653:                        m_freem(m_head);
                   1654:                        return (1);
                   1655:                }
                   1656:                if (m_head->m_pkthdr.len > MHLEN) {
                   1657:                        MCLGET(m_new, M_DONTWAIT);
                   1658:                        if (!(m_new->m_flags & M_EXT)) {
                   1659:                                m_freem(m_new);
                   1660:                                m_freem(m_head);
                   1661:                                return (1);
                   1662:                        }
                   1663:                }
                   1664:                m_copydata(m_head, 0, m_head->m_pkthdr.len,
                   1665:                    mtod(m_new, caddr_t));
                   1666:                m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
                   1667:                m_freem(m_head);
                   1668:                m_head = m_new;
                   1669:                goto reload;
                   1670:        }
                   1671:
                   1672:        bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
                   1673:            BUS_DMASYNC_PREWRITE);
                   1674:
                   1675:        if (c->map->dm_nsegs != 0) {
                   1676:                bus_dmamap_sync(sc->sc_dmat, c->map,
                   1677:                    0, c->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1678:                bus_dmamap_unload(sc->sc_dmat, c->map);
                   1679:        }
                   1680:
                   1681:        c->xl_mbuf = m_head;
                   1682:        sc->sc_tx_sparemap = c->map;
                   1683:        c->map = map;
                   1684:        c->xl_ptr->xl_frag[frag - 1].xl_len |= htole32(XL_LAST_FRAG);
                   1685:        c->xl_ptr->xl_status = htole32(total_len);
                   1686:        c->xl_ptr->xl_next = 0;
                   1687:
                   1688:        if (sc->xl_type == XL_TYPE_905B) {
                   1689:                status = XL_TXSTAT_RND_DEFEAT;
                   1690:
                   1691: #ifndef XL905B_TXCSUM_BROKEN
                   1692:                if (m_head->m_pkthdr.csum_flags) {
                   1693:                        if (m_head->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
                   1694:                                status |= XL_TXSTAT_IPCKSUM;
                   1695:                        if (m_head->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
                   1696:                                status |= XL_TXSTAT_TCPCKSUM;
                   1697:                        if (m_head->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
                   1698:                                status |= XL_TXSTAT_UDPCKSUM;
                   1699:                }
                   1700: #endif
                   1701:                c->xl_ptr->xl_status = htole32(status);
                   1702:        }
                   1703:
                   1704:        bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                   1705:            offsetof(struct xl_list_data, xl_tx_list[0]),
                   1706:            sizeof(struct xl_list) * XL_TX_LIST_CNT,
                   1707:            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                   1708:
                   1709:        return (0);
                   1710: }
                   1711:
                   1712: /*
                   1713:  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
                   1714:  * to the mbuf data regions directly in the transmit lists. We also save a
                   1715:  * copy of the pointers since the transmit list fragment pointers are
                   1716:  * physical addresses.
                   1717:  */
                   1718: void
                   1719: xl_start(struct ifnet *ifp)
                   1720: {
                   1721:        struct xl_softc         *sc;
                   1722:        struct mbuf             *m_head = NULL;
                   1723:        struct xl_chain         *prev = NULL, *cur_tx = NULL, *start_tx;
                   1724:        struct xl_chain         *prev_tx;
                   1725:        int                     error;
                   1726:
                   1727:        sc = ifp->if_softc;
                   1728:
                   1729:        /*
                   1730:         * Check for an available queue slot. If there are none,
                   1731:         * punt.
                   1732:         */
                   1733:        if (sc->xl_cdata.xl_tx_free == NULL) {
                   1734:                xl_txeoc(sc);
                   1735:                xl_txeof(sc);
                   1736:                if (sc->xl_cdata.xl_tx_free == NULL) {
                   1737:                        ifp->if_flags |= IFF_OACTIVE;
                   1738:                        return;
                   1739:                }
                   1740:        }
                   1741:
                   1742:        start_tx = sc->xl_cdata.xl_tx_free;
                   1743:
                   1744:        while (sc->xl_cdata.xl_tx_free != NULL) {
                   1745:                IFQ_DEQUEUE(&ifp->if_snd, m_head);
                   1746:                if (m_head == NULL)
                   1747:                        break;
                   1748:
                   1749:                /* Pick a descriptor off the free list. */
                   1750:                prev_tx = cur_tx;
                   1751:                cur_tx = sc->xl_cdata.xl_tx_free;
                   1752:
                   1753:                /* Pack the data into the descriptor. */
                   1754:                error = xl_encap(sc, cur_tx, m_head);
                   1755:                if (error) {
                   1756:                        cur_tx = prev_tx;
                   1757:                        continue;
                   1758:                }
                   1759:
                   1760:                sc->xl_cdata.xl_tx_free = cur_tx->xl_next;
                   1761:                cur_tx->xl_next = NULL;
                   1762:
                   1763:                /* Chain it together. */
                   1764:                if (prev != NULL) {
                   1765:                        prev->xl_next = cur_tx;
                   1766:                        prev->xl_ptr->xl_next =
                   1767:                            sc->sc_listmap->dm_segs[0].ds_addr +
                   1768:                            ((caddr_t)cur_tx->xl_ptr - sc->sc_listkva);
                   1769:
                   1770:                }
                   1771:                prev = cur_tx;
                   1772:
                   1773: #if NBPFILTER > 0
                   1774:                /*
                   1775:                 * If there's a BPF listener, bounce a copy of this frame
                   1776:                 * to him.
                   1777:                 */
                   1778:                if (ifp->if_bpf)
                   1779:                        bpf_mtap(ifp->if_bpf, cur_tx->xl_mbuf,
                   1780:                            BPF_DIRECTION_OUT);
                   1781: #endif
                   1782:        }
                   1783:
                   1784:        /*
                   1785:         * If there are no packets queued, bail.
                   1786:         */
                   1787:        if (cur_tx == NULL)
                   1788:                return;
                   1789:
                   1790:        /*
                   1791:         * Place the request for the upload interrupt
                   1792:         * in the last descriptor in the chain. This way, if
                   1793:         * we're chaining several packets at once, we'll only
                   1794:         * get an interrupt once for the whole chain rather than
                   1795:         * once for each packet.
                   1796:         */
                   1797:        cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR);
                   1798:
                   1799:        /*
                   1800:         * Queue the packets. If the TX channel is clear, update
                   1801:         * the downlist pointer register.
                   1802:         */
                   1803:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
                   1804:        xl_wait(sc);
                   1805:
                   1806:        if (sc->xl_cdata.xl_tx_head != NULL) {
                   1807:                sc->xl_cdata.xl_tx_tail->xl_next = start_tx;
                   1808:                sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next =
                   1809:                    sc->sc_listmap->dm_segs[0].ds_addr +
                   1810:                    ((caddr_t)start_tx->xl_ptr - sc->sc_listkva);
                   1811:                sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &=
                   1812:                    htole32(~XL_TXSTAT_DL_INTR);
                   1813:                sc->xl_cdata.xl_tx_tail = cur_tx;
                   1814:        } else {
                   1815:                sc->xl_cdata.xl_tx_head = start_tx;
                   1816:                sc->xl_cdata.xl_tx_tail = cur_tx;
                   1817:        }
                   1818:        if (!CSR_READ_4(sc, XL_DOWNLIST_PTR))
                   1819:                CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
                   1820:                    sc->sc_listmap->dm_segs[0].ds_addr +
                   1821:                    ((caddr_t)start_tx->xl_ptr - sc->sc_listkva));
                   1822:
                   1823:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
                   1824:
                   1825:        XL_SEL_WIN(7);
                   1826:
                   1827:        /*
                   1828:         * Set a timeout in case the chip goes out to lunch.
                   1829:         */
                   1830:        ifp->if_timer = 5;
                   1831:
                   1832:        /*
                   1833:         * XXX Under certain conditions, usually on slower machines
                   1834:         * where interrupts may be dropped, it's possible for the
                   1835:         * adapter to chew up all the buffers in the receive ring
                   1836:         * and stall, without us being able to do anything about it.
                   1837:         * To guard against this, we need to make a pass over the
                   1838:         * RX queue to make sure there aren't any packets pending.
                   1839:         * Doing it here means we can flush the receive ring at the
                   1840:         * same time the chip is DMAing the transmit descriptors we
                   1841:         * just gave it.
                   1842:         *
                   1843:         * 3Com goes to some lengths to emphasize the Parallel Tasking (tm)
                   1844:         * nature of their chips in all their marketing literature;
                   1845:         * we may as well take advantage of it. :)
                   1846:         */
                   1847:        xl_rxeof(sc);
                   1848: }
                   1849:
                   1850: void
                   1851: xl_start_90xB(struct ifnet *ifp)
                   1852: {
                   1853:        struct xl_softc *sc;
                   1854:        struct mbuf     *m_head = NULL;
                   1855:        struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
                   1856:        struct xl_chain *prev_tx;
                   1857:        int             error, idx;
                   1858:
                   1859:        sc = ifp->if_softc;
                   1860:
                   1861:        if (ifp->if_flags & IFF_OACTIVE)
                   1862:                return;
                   1863:
                   1864:        idx = sc->xl_cdata.xl_tx_prod;
                   1865:        start_tx = &sc->xl_cdata.xl_tx_chain[idx];
                   1866:
                   1867:        while (sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL) {
                   1868:
                   1869:                if ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) < 3) {
                   1870:                        ifp->if_flags |= IFF_OACTIVE;
                   1871:                        break;
                   1872:                }
                   1873:
                   1874:                IFQ_DEQUEUE(&ifp->if_snd, m_head);
                   1875:                if (m_head == NULL)
                   1876:                        break;
                   1877:
                   1878:                prev_tx = cur_tx;
                   1879:                cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
                   1880:
                   1881:                /* Pack the data into the descriptor. */
                   1882:                error = xl_encap(sc, cur_tx, m_head);
                   1883:                if (error) {
                   1884:                        cur_tx = prev_tx;
                   1885:                        continue;
                   1886:                }
                   1887:
                   1888:                /* Chain it together. */
                   1889:                if (prev != NULL)
                   1890:                        prev->xl_ptr->xl_next = htole32(cur_tx->xl_phys);
                   1891:                prev = cur_tx;
                   1892:
                   1893: #if NBPFILTER > 0
                   1894:                /*
                   1895:                 * If there's a BPF listener, bounce a copy of this frame
                   1896:                 * to him.
                   1897:                 */
                   1898:                if (ifp->if_bpf)
                   1899:                        bpf_mtap(ifp->if_bpf, cur_tx->xl_mbuf,
                   1900:                            BPF_DIRECTION_OUT);
                   1901: #endif
                   1902:
                   1903:                XL_INC(idx, XL_TX_LIST_CNT);
                   1904:                sc->xl_cdata.xl_tx_cnt++;
                   1905:        }
                   1906:
                   1907:        /*
                   1908:         * If there are no packets queued, bail.
                   1909:         */
                   1910:        if (cur_tx == NULL)
                   1911:                return;
                   1912:
                   1913:        /*
                   1914:         * Place the request for the upload interrupt
                   1915:         * in the last descriptor in the chain. This way, if
                   1916:         * we're chaining several packets at once, we'll only
                   1917:         * get an interrupt once for the whole chain rather than
                   1918:         * once for each packet.
                   1919:         */
                   1920:        cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR);
                   1921:
                   1922:        /* Start transmission */
                   1923:        sc->xl_cdata.xl_tx_prod = idx;
                   1924:        start_tx->xl_prev->xl_ptr->xl_next = htole32(start_tx->xl_phys);
                   1925:
                   1926:        /*
                   1927:         * Set a timeout in case the chip goes out to lunch.
                   1928:         */
                   1929:        ifp->if_timer = 5;
                   1930: }
                   1931:
                   1932: void
                   1933: xl_init(void *xsc)
                   1934: {
                   1935:        struct xl_softc         *sc = xsc;
                   1936:        struct ifnet            *ifp = &sc->sc_arpcom.ac_if;
                   1937:        int                     s, i;
                   1938:        u_int16_t               rxfilt = 0;
                   1939:        struct mii_data         *mii = NULL;
                   1940:
                   1941:        s = splnet();
                   1942:
                   1943:        /*
                   1944:         * Cancel pending I/O and free all RX/TX buffers.
                   1945:         */
                   1946:        xl_stop(sc);
                   1947:
                   1948:        if (sc->xl_hasmii)
                   1949:                mii = &sc->sc_mii;
                   1950:
                   1951:        if (mii == NULL) {
                   1952:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
                   1953:                xl_wait(sc);
                   1954:        }
                   1955:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
                   1956:        xl_wait(sc);
                   1957:        DELAY(10000);
                   1958:
                   1959:        /* Init our MAC address */
                   1960:        XL_SEL_WIN(2);
                   1961:        for (i = 0; i < ETHER_ADDR_LEN; i++) {
                   1962:                CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i,
                   1963:                                sc->sc_arpcom.ac_enaddr[i]);
                   1964:        }
                   1965:
                   1966:        /* Clear the station mask. */
                   1967:        for (i = 0; i < 3; i++)
                   1968:                CSR_WRITE_2(sc, XL_W2_STATION_MASK_LO + (i * 2), 0);
                   1969: #ifdef notdef
                   1970:        /* Reset TX and RX. */
                   1971:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
                   1972:        xl_wait(sc);
                   1973:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
                   1974:        xl_wait(sc);
                   1975: #endif
                   1976:        /* Init circular RX list. */
                   1977:        if (xl_list_rx_init(sc) == ENOBUFS) {
                   1978:                printf("%s: initialization failed: no "
                   1979:                        "memory for rx buffers\n", sc->sc_dev.dv_xname);
                   1980:                xl_stop(sc);
                   1981:                splx(s);
                   1982:                return;
                   1983:        }
                   1984:
                   1985:        /* Init TX descriptors. */
                   1986:        if (sc->xl_type == XL_TYPE_905B)
                   1987:                xl_list_tx_init_90xB(sc);
                   1988:        else
                   1989:                xl_list_tx_init(sc);
                   1990:
                   1991:        /*
                   1992:         * Set the TX freethresh value.
                   1993:         * Note that this has no effect on 3c905B "cyclone"
                   1994:         * cards but is required for 3c900/3c905 "boomerang"
                   1995:         * cards in order to enable the download engine.
                   1996:         */
                   1997:        CSR_WRITE_1(sc, XL_TX_FREETHRESH, XL_PACKET_SIZE >> 8);
                   1998:
                   1999:        /* Set the TX start threshold for best performance. */
                   2000:        sc->xl_tx_thresh = XL_MIN_FRAMELEN;
                   2001:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_SET_START|sc->xl_tx_thresh);
                   2002:
                   2003:        /*
                   2004:         * If this is a 3c905B, also set the tx reclaim threshold.
                   2005:         * This helps cut down on the number of tx reclaim errors
                   2006:         * that could happen on a busy network. The chip multiplies
                   2007:         * the register value by 16 to obtain the actual threshold
                   2008:         * in bytes, so we divide by 16 when setting the value here.
                   2009:         * The existing threshold value can be examined by reading
                   2010:         * the register at offset 9 in window 5.
                   2011:         */
                   2012:        if (sc->xl_type == XL_TYPE_905B) {
                   2013:                CSR_WRITE_2(sc, XL_COMMAND,
                   2014:                    XL_CMD_SET_TX_RECLAIM|(XL_PACKET_SIZE >> 4));
                   2015:        }
                   2016:
                   2017:        /* Set RX filter bits. */
                   2018:        XL_SEL_WIN(5);
                   2019:        rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
                   2020:
                   2021:        /* Set the individual bit to receive frames for this host only. */
                   2022:        rxfilt |= XL_RXFILTER_INDIVIDUAL;
                   2023:
                   2024:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                   2025:
                   2026:        /* Set promiscuous mode. */
                   2027:        xl_setpromisc(sc);
                   2028:
                   2029:        rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
                   2030:
                   2031:        /*
                   2032:         * Set capture broadcast bit to capture broadcast frames.
                   2033:         */
                   2034:        if (ifp->if_flags & IFF_BROADCAST)
                   2035:                rxfilt |= XL_RXFILTER_BROADCAST;
                   2036:        else
                   2037:                rxfilt &= ~XL_RXFILTER_BROADCAST;
                   2038:
                   2039:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
                   2040:
                   2041:        /*
                   2042:         * Program the multicast filter, if necessary.
                   2043:         */
                   2044:        if (sc->xl_type == XL_TYPE_905B)
                   2045:                xl_setmulti_hash(sc);
                   2046:        else
                   2047:                xl_setmulti(sc);
                   2048:
                   2049:        /*
                   2050:         * Load the address of the RX list. We have to
                   2051:         * stall the upload engine before we can manipulate
                   2052:         * the uplist pointer register, then unstall it when
                   2053:         * we're finished. We also have to wait for the
                   2054:         * stall command to complete before proceeding.
                   2055:         * Note that we have to do this after any RX resets
                   2056:         * have completed since the uplist register is cleared
                   2057:         * by a reset.
                   2058:         */
                   2059:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
                   2060:        xl_wait(sc);
                   2061:        CSR_WRITE_4(sc, XL_UPLIST_PTR, sc->sc_listmap->dm_segs[0].ds_addr +
                   2062:            offsetof(struct xl_list_data, xl_rx_list[0]));
                   2063:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
                   2064:        xl_wait(sc);
                   2065:
                   2066:        if (sc->xl_type == XL_TYPE_905B) {
                   2067:                /* Set polling interval */
                   2068:                CSR_WRITE_1(sc, XL_DOWN_POLL, 64);
                   2069:                /* Load the address of the TX list */
                   2070:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
                   2071:                xl_wait(sc);
                   2072:                CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
                   2073:                    sc->sc_listmap->dm_segs[0].ds_addr +
                   2074:                    offsetof(struct xl_list_data, xl_tx_list[0]));
                   2075:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
                   2076:                xl_wait(sc);
                   2077:        }
                   2078:
                   2079:        /*
                   2080:         * If the coax transceiver is on, make sure to enable
                   2081:         * the DC-DC converter.
                   2082:         */
                   2083:        XL_SEL_WIN(3);
                   2084:        if (sc->xl_xcvr == XL_XCVR_COAX)
                   2085:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
                   2086:        else
                   2087:                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
                   2088:
                   2089:        /*
                   2090:         * increase packet size to allow reception of 802.1q or ISL packets.
                   2091:         * For the 3c90x chip, set the 'allow large packets' bit in the MAC
                   2092:         * control register. For 3c90xB/C chips, use the RX packet size
                   2093:         * register.
                   2094:         */
                   2095:
                   2096:        if (sc->xl_type == XL_TYPE_905B)
                   2097:                CSR_WRITE_2(sc, XL_W3_MAXPKTSIZE, XL_PACKET_SIZE);
                   2098:        else {
                   2099:                u_int8_t macctl;
                   2100:                macctl = CSR_READ_1(sc, XL_W3_MAC_CTRL);
                   2101:                macctl |= XL_MACCTRL_ALLOW_LARGE_PACK;
                   2102:                CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl);
                   2103:        }
                   2104:
                   2105:        /* Clear out the stats counters. */
                   2106:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
                   2107:        sc->xl_stats_no_timeout = 1;
                   2108:        xl_stats_update(sc);
                   2109:        sc->xl_stats_no_timeout = 0;
                   2110:        XL_SEL_WIN(4);
                   2111:        CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE);
                   2112:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE);
                   2113:
                   2114:        /*
                   2115:         * Enable interrupts.
                   2116:         */
                   2117:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
                   2118:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
                   2119:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
                   2120:
                   2121:        if (sc->intr_ack)
                   2122:                (*sc->intr_ack)(sc);
                   2123:
                   2124:        /* Set the RX early threshold */
                   2125:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2));
                   2126:        CSR_WRITE_2(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY);
                   2127:
                   2128:        /* Enable receiver and transmitter. */
                   2129:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
                   2130:        xl_wait(sc);
                   2131:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
                   2132:        xl_wait(sc);
                   2133:
                   2134:        /* Restore state of BMCR */
                   2135:        if (mii != NULL)
                   2136:                mii_mediachg(mii);
                   2137:
                   2138:        /* Select window 7 for normal operations. */
                   2139:        XL_SEL_WIN(7);
                   2140:
                   2141:        ifp->if_flags |= IFF_RUNNING;
                   2142:        ifp->if_flags &= ~IFF_OACTIVE;
                   2143:
                   2144:        splx(s);
                   2145:
                   2146:        timeout_add(&sc->xl_stsup_tmo, hz);
                   2147: }
                   2148:
                   2149: /*
                   2150:  * Set media options.
                   2151:  */
                   2152: int
                   2153: xl_ifmedia_upd(struct ifnet *ifp)
                   2154: {
                   2155:        struct xl_softc         *sc;
                   2156:        struct ifmedia          *ifm = NULL;
                   2157:        struct mii_data         *mii = NULL;
                   2158:
                   2159:        sc = ifp->if_softc;
                   2160:
                   2161:        if (sc->xl_hasmii)
                   2162:                mii = &sc->sc_mii;
                   2163:        if (mii == NULL)
                   2164:                ifm = &sc->ifmedia;
                   2165:        else
                   2166:                ifm = &mii->mii_media;
                   2167:
                   2168:        switch(IFM_SUBTYPE(ifm->ifm_media)) {
                   2169:        case IFM_100_FX:
                   2170:        case IFM_10_FL:
                   2171:        case IFM_10_2:
                   2172:        case IFM_10_5:
                   2173:                xl_setmode(sc, ifm->ifm_media);
                   2174:                return (0);
                   2175:                break;
                   2176:        default:
                   2177:                break;
                   2178:        }
                   2179:
                   2180:        if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
                   2181:                || sc->xl_media & XL_MEDIAOPT_BT4) {
                   2182:                xl_init(sc);
                   2183:        } else {
                   2184:                xl_setmode(sc, ifm->ifm_media);
                   2185:        }
                   2186:
                   2187:        return (0);
                   2188: }
                   2189:
                   2190: /*
                   2191:  * Report current media status.
                   2192:  */
                   2193: void
                   2194: xl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
                   2195: {
                   2196:        struct xl_softc         *sc;
                   2197:        u_int32_t               icfg;
                   2198:        u_int16_t               status = 0;
                   2199:        struct mii_data         *mii = NULL;
                   2200:
                   2201:        sc = ifp->if_softc;
                   2202:        if (sc->xl_hasmii != 0)
                   2203:                mii = &sc->sc_mii;
                   2204:
                   2205:        XL_SEL_WIN(4);
                   2206:        status = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
                   2207:
                   2208:        XL_SEL_WIN(3);
                   2209:        icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG) & XL_ICFG_CONNECTOR_MASK;
                   2210:        icfg >>= XL_ICFG_CONNECTOR_BITS;
                   2211:
                   2212:        ifmr->ifm_active = IFM_ETHER;
                   2213:        ifmr->ifm_status = IFM_AVALID;
                   2214:
                   2215:        if ((status & XL_MEDIASTAT_CARRIER) == 0)
                   2216:                ifmr->ifm_status |= IFM_ACTIVE;
                   2217:
                   2218:        switch(icfg) {
                   2219:        case XL_XCVR_10BT:
                   2220:                ifmr->ifm_active = IFM_ETHER|IFM_10_T;
                   2221:                if (CSR_READ_1(sc, XL_W3_MAC_CTRL) & XL_MACCTRL_DUPLEX)
                   2222:                        ifmr->ifm_active |= IFM_FDX;
                   2223:                else
                   2224:                        ifmr->ifm_active |= IFM_HDX;
                   2225:                break;
                   2226:        case XL_XCVR_AUI:
                   2227:                if (sc->xl_type == XL_TYPE_905B &&
                   2228:                    sc->xl_media == XL_MEDIAOPT_10FL) {
                   2229:                        ifmr->ifm_active = IFM_ETHER|IFM_10_FL;
                   2230:                        if (CSR_READ_1(sc, XL_W3_MAC_CTRL) & XL_MACCTRL_DUPLEX)
                   2231:                                ifmr->ifm_active |= IFM_FDX;
                   2232:                        else
                   2233:                                ifmr->ifm_active |= IFM_FDX;
                   2234:                } else
                   2235:                        ifmr->ifm_active = IFM_ETHER|IFM_10_5;
                   2236:                break;
                   2237:        case XL_XCVR_COAX:
                   2238:                ifmr->ifm_active = IFM_ETHER|IFM_10_2;
                   2239:                break;
                   2240:        /*
                   2241:         * XXX MII and BTX/AUTO should be separate cases.
                   2242:         */
                   2243:
                   2244:        case XL_XCVR_100BTX:
                   2245:        case XL_XCVR_AUTO:
                   2246:        case XL_XCVR_MII:
                   2247:                if (mii != NULL) {
                   2248:                        mii_pollstat(mii);
                   2249:                        ifmr->ifm_active = mii->mii_media_active;
                   2250:                        ifmr->ifm_status = mii->mii_media_status;
                   2251:                }
                   2252:                break;
                   2253:        case XL_XCVR_100BFX:
                   2254:                ifmr->ifm_active = IFM_ETHER|IFM_100_FX;
                   2255:                break;
                   2256:        default:
                   2257:                printf("%s: unknown XCVR type: %d\n", sc->sc_dev.dv_xname, icfg);
                   2258:                break;
                   2259:        }
                   2260: }
                   2261:
                   2262: int
                   2263: xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
                   2264: {
                   2265:        struct xl_softc *sc = ifp->if_softc;
                   2266:        struct ifreq *ifr = (struct ifreq *)data;
                   2267:        struct ifaddr *ifa = (struct ifaddr *)data;
                   2268:        int s, error = 0;
                   2269:        struct mii_data *mii = NULL;
                   2270:
                   2271:        s = splnet();
                   2272:
                   2273:        if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command, data)) > 0) {
                   2274:                splx(s);
                   2275:                return error;
                   2276:        }
                   2277:
                   2278:        switch(command) {
                   2279:        case SIOCSIFADDR:
                   2280:                ifp->if_flags |= IFF_UP;
                   2281:                if (!(ifp->if_flags & IFF_RUNNING))
                   2282:                        xl_init(sc);
                   2283: #ifdef INET
                   2284:                if (ifa->ifa_addr->sa_family == AF_INET)
                   2285:                        arp_ifinit(&sc->sc_arpcom, ifa);
                   2286: #endif /* INET */
                   2287:                break;
                   2288:
                   2289:        case SIOCSIFMTU:
                   2290:                if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN)
                   2291:                        error = EINVAL;
                   2292:                else if (ifp->if_mtu != ifr->ifr_mtu)
                   2293:                        ifp->if_mtu = ifr->ifr_mtu;
                   2294:                break;
                   2295:
                   2296:        case SIOCSIFFLAGS:
                   2297:                XL_SEL_WIN(5);
                   2298:                if (ifp->if_flags & IFF_UP) {
                   2299:                        if (ifp->if_flags & IFF_RUNNING &&
                   2300:                            (ifp->if_flags ^ sc->xl_if_flags) &
                   2301:                             IFF_PROMISC) {
                   2302:                                xl_setpromisc(sc);
                   2303:                                XL_SEL_WIN(7);
                   2304:                        } else {
                   2305:                                if (!(ifp->if_flags & IFF_RUNNING))
                   2306:                                        xl_init(sc);
                   2307:                        }
                   2308:                } else {
                   2309:                        if (ifp->if_flags & IFF_RUNNING)
                   2310:                                xl_stop(sc);
                   2311:                }
                   2312:                sc->xl_if_flags = ifp->if_flags;
                   2313:                break;
                   2314:        case SIOCADDMULTI:
                   2315:        case SIOCDELMULTI:
                   2316:                error = (command == SIOCADDMULTI) ?
                   2317:                    ether_addmulti(ifr, &sc->sc_arpcom) :
                   2318:                    ether_delmulti(ifr, &sc->sc_arpcom);
                   2319:
                   2320:                if (error == ENETRESET) {
                   2321:                        /*
                   2322:                         * Multicast list has changed; set the hardware
                   2323:                         * filter accordingly.
                   2324:                         */
                   2325:                        if (ifp->if_flags & IFF_RUNNING) {
                   2326:                                if (sc->xl_type == XL_TYPE_905B)
                   2327:                                        xl_setmulti_hash(sc);
                   2328:                                else
                   2329:                                        xl_setmulti(sc);
                   2330:                        }
                   2331:                        error = 0;
                   2332:                }
                   2333:                break;
                   2334:        case SIOCGIFMEDIA:
                   2335:        case SIOCSIFMEDIA:
                   2336:                if (sc->xl_hasmii != 0)
                   2337:                        mii = &sc->sc_mii;
                   2338:                if (mii == NULL)
                   2339:                        error = ifmedia_ioctl(ifp, ifr,
                   2340:                            &sc->ifmedia, command);
                   2341:                else
                   2342:                        error = ifmedia_ioctl(ifp, ifr,
                   2343:                            &mii->mii_media, command);
                   2344:                break;
                   2345:        default:
                   2346:                error = EINVAL;
                   2347:                break;
                   2348:        }
                   2349:
                   2350:        splx(s);
                   2351:
                   2352:        return (error);
                   2353: }
                   2354:
                   2355: void
                   2356: xl_watchdog(struct ifnet *ifp)
                   2357: {
                   2358:        struct xl_softc         *sc;
                   2359:        u_int16_t               status = 0;
                   2360:
                   2361:        sc = ifp->if_softc;
                   2362:
                   2363:        ifp->if_oerrors++;
                   2364:        XL_SEL_WIN(4);
                   2365:        status = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
                   2366:        printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
                   2367:
                   2368:        if (status & XL_MEDIASTAT_CARRIER)
                   2369:                printf("%s: no carrier - transceiver cable problem?\n",
                   2370:                                                                sc->sc_dev.dv_xname);
                   2371:        xl_txeoc(sc);
                   2372:        xl_txeof(sc);
                   2373:        xl_rxeof(sc);
                   2374:        xl_reset(sc);
                   2375:        xl_init(sc);
                   2376:
                   2377:        if (!IFQ_IS_EMPTY(&ifp->if_snd))
                   2378:                (*ifp->if_start)(ifp);
                   2379: }
                   2380:
                   2381: void
                   2382: xl_freetxrx(struct xl_softc *sc)
                   2383: {
                   2384:        bus_dmamap_t    map;
                   2385:        int             i;
                   2386:
                   2387:        /*
                   2388:         * Free data in the RX lists.
                   2389:         */
                   2390:        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                   2391:                if (sc->xl_cdata.xl_rx_chain[i].map->dm_nsegs != 0) {
                   2392:                        map = sc->xl_cdata.xl_rx_chain[i].map;
                   2393:
                   2394:                        bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
                   2395:                            BUS_DMASYNC_POSTREAD);
                   2396:                        bus_dmamap_unload(sc->sc_dmat, map);
                   2397:                }
                   2398:                if (sc->xl_cdata.xl_rx_chain[i].xl_mbuf != NULL) {
                   2399:                        m_freem(sc->xl_cdata.xl_rx_chain[i].xl_mbuf);
                   2400:                        sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL;
                   2401:                }
                   2402:        }
                   2403:        bzero((char *)&sc->xl_ldata->xl_rx_list,
                   2404:                sizeof(sc->xl_ldata->xl_rx_list));
                   2405:        /*
                   2406:         * Free the TX list buffers.
                   2407:         */
                   2408:        for (i = 0; i < XL_TX_LIST_CNT; i++) {
                   2409:                if (sc->xl_cdata.xl_tx_chain[i].map->dm_nsegs != 0) {
                   2410:                        map = sc->xl_cdata.xl_tx_chain[i].map;
                   2411:
                   2412:                        bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
                   2413:                            BUS_DMASYNC_POSTWRITE);
                   2414:                        bus_dmamap_unload(sc->sc_dmat, map);
                   2415:                }
                   2416:                if (sc->xl_cdata.xl_tx_chain[i].xl_mbuf != NULL) {
                   2417:                        m_freem(sc->xl_cdata.xl_tx_chain[i].xl_mbuf);
                   2418:                        sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL;
                   2419:                }
                   2420:        }
                   2421:        bzero((char *)&sc->xl_ldata->xl_tx_list,
                   2422:                sizeof(sc->xl_ldata->xl_tx_list));
                   2423: }
                   2424:
                   2425: /*
                   2426:  * Stop the adapter and free any mbufs allocated to the
                   2427:  * RX and TX lists.
                   2428:  */
                   2429: void
                   2430: xl_stop(struct xl_softc *sc)
                   2431: {
                   2432:        struct ifnet *ifp;
                   2433:
                   2434:        ifp = &sc->sc_arpcom.ac_if;
                   2435:        ifp->if_timer = 0;
                   2436:
                   2437:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
                   2438:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
                   2439:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB);
                   2440:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISCARD);
                   2441:        xl_wait(sc);
                   2442:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
                   2443:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
                   2444:        DELAY(800);
                   2445:
                   2446: #ifdef foo
                   2447:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
                   2448:        xl_wait(sc);
                   2449:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
                   2450:        xl_wait(sc);
                   2451: #endif
                   2452:
                   2453:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);
                   2454:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);
                   2455:        CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
                   2456:
                   2457:        if (sc->intr_ack)
                   2458:                (*sc->intr_ack)(sc);
                   2459:
                   2460:        /* Stop the stats updater. */
                   2461:        timeout_del(&sc->xl_stsup_tmo);
                   2462:
                   2463:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2464:
                   2465:        xl_freetxrx(sc);
                   2466: }
                   2467:
                   2468: void
                   2469: xl_attach(struct xl_softc *sc)
                   2470: {
                   2471:        u_int8_t enaddr[ETHER_ADDR_LEN];
                   2472:        u_int16_t               xcvr[2];
                   2473:        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
                   2474:        int i, media = IFM_ETHER|IFM_100_TX|IFM_FDX;
                   2475:        struct ifmedia *ifm;
                   2476:
                   2477:        i = splnet();
                   2478:        xl_reset(sc);
                   2479:        splx(i);
                   2480:
                   2481:        /*
                   2482:         * Get station address from the EEPROM.
                   2483:         */
                   2484:        if (xl_read_eeprom(sc, (caddr_t)&enaddr, XL_EE_OEM_ADR0, 3, 1)) {
                   2485:                printf("\n%s: failed to read station address\n",
                   2486:                    sc->sc_dev.dv_xname);
                   2487:                return;
                   2488:        }
                   2489:        bcopy(enaddr, (char *)&sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
                   2490:
                   2491:        if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct xl_list_data),
                   2492:            PAGE_SIZE, 0, sc->sc_listseg, 1, &sc->sc_listnseg,
                   2493:            BUS_DMA_NOWAIT) != 0) {
                   2494:                printf(": can't alloc list mem\n");
                   2495:                return;
                   2496:        }
                   2497:        if (bus_dmamem_map(sc->sc_dmat, sc->sc_listseg, sc->sc_listnseg,
                   2498:            sizeof(struct xl_list_data), &sc->sc_listkva,
                   2499:            BUS_DMA_NOWAIT) != 0) {
                   2500:                printf(": can't map list mem\n");
                   2501:                return;
                   2502:        }
                   2503:        if (bus_dmamap_create(sc->sc_dmat, sizeof(struct xl_list_data), 1,
                   2504:            sizeof(struct xl_list_data), 0, BUS_DMA_NOWAIT,
                   2505:            &sc->sc_listmap) != 0) {
                   2506:                printf(": can't alloc list map\n");
                   2507:                return;
                   2508:        }
                   2509:        if (bus_dmamap_load(sc->sc_dmat, sc->sc_listmap, sc->sc_listkva,
                   2510:            sizeof(struct xl_list_data), NULL, BUS_DMA_NOWAIT) != 0) {
                   2511:                printf(": can't load list map\n");
                   2512:                return;
                   2513:        }
                   2514:        sc->xl_ldata = (struct xl_list_data *)sc->sc_listkva;
                   2515:        bzero(sc->xl_ldata, sizeof(struct xl_list_data));
                   2516:
                   2517:        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                   2518:                if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
                   2519:                    0, BUS_DMA_NOWAIT,
                   2520:                    &sc->xl_cdata.xl_rx_chain[i].map) != 0) {
                   2521:                        printf(": can't create rx map\n");
                   2522:                        return;
                   2523:                }
                   2524:        }
                   2525:        if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
                   2526:            BUS_DMA_NOWAIT, &sc->sc_rx_sparemap) != 0) {
                   2527:                printf(": can't create rx spare map\n");
                   2528:                return;
                   2529:        }
                   2530:
                   2531:        for (i = 0; i < XL_TX_LIST_CNT; i++) {
                   2532:                if (bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                   2533:                    XL_TX_LIST_CNT - 3, MCLBYTES, 0, BUS_DMA_NOWAIT,
                   2534:                    &sc->xl_cdata.xl_tx_chain[i].map) != 0) {
                   2535:                        printf(": can't create tx map\n");
                   2536:                        return;
                   2537:                }
                   2538:        }
                   2539:        if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, XL_TX_LIST_CNT - 3,
                   2540:            MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_tx_sparemap) != 0) {
                   2541:                printf(": can't create tx spare map\n");
                   2542:                return;
                   2543:        }
                   2544:
                   2545:        printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
                   2546:
                   2547:        if (sc->xl_flags & (XL_FLAG_INVERT_LED_PWR|XL_FLAG_INVERT_MII_PWR)) {
                   2548:                u_int16_t n;
                   2549:
                   2550:                XL_SEL_WIN(2);
                   2551:                n = CSR_READ_2(sc, 12);
                   2552:
                   2553:                if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR)
                   2554:                        n |= 0x0010;
                   2555:
                   2556:                if (sc->xl_flags & XL_FLAG_INVERT_MII_PWR)
                   2557:                        n |= 0x4000;
                   2558:
                   2559:                CSR_WRITE_2(sc, 12, n);
                   2560:        }
                   2561:
                   2562:        /*
                   2563:         * Figure out the card type. 3c905B adapters have the
                   2564:         * 'supportsNoTxLength' bit set in the capabilities
                   2565:         * word in the EEPROM.
                   2566:         * Note: my 3c575C cardbus card lies. It returns a value
                   2567:         * of 0x1578 for its capabilities word, which is somewhat
                   2568:         * nonsensical. Another way to distinguish a 3c90x chip
                   2569:         * from a 3c90xB/C chip is to check for the 'supportsLargePackets'
                   2570:         * bit. This will only be set for 3c90x boomerage chips.
                   2571:         */
                   2572:        xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
                   2573:        if (sc->xl_caps & XL_CAPS_NO_TXLENGTH ||
                   2574:            !(sc->xl_caps & XL_CAPS_LARGE_PKTS))
                   2575:                sc->xl_type = XL_TYPE_905B;
                   2576:        else
                   2577:                sc->xl_type = XL_TYPE_90X;
                   2578:
                   2579:        timeout_set(&sc->xl_stsup_tmo, xl_stats_update, sc);
                   2580:
                   2581:        ifp->if_softc = sc;
                   2582:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                   2583:        ifp->if_ioctl = xl_ioctl;
                   2584:        if (sc->xl_type == XL_TYPE_905B)
                   2585:                ifp->if_start = xl_start_90xB;
                   2586:        else
                   2587:                ifp->if_start = xl_start;
                   2588:        ifp->if_watchdog = xl_watchdog;
                   2589:        ifp->if_baudrate = 10000000;
                   2590:        IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1);
                   2591:        IFQ_SET_READY(&ifp->if_snd);
                   2592:        bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                   2593:
                   2594:        ifp->if_capabilities = IFCAP_VLAN_MTU;
                   2595:
                   2596: #ifndef XL905B_TXCSUM_BROKEN
                   2597:        ifp->if_capabilities |= IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|
                   2598:                                IFCAP_CSUM_UDPv4;
                   2599: #endif
                   2600:
                   2601:        XL_SEL_WIN(3);
                   2602:        sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
                   2603:
                   2604:        xl_read_eeprom(sc, (char *)&xcvr, XL_EE_ICFG_0, 2, 0);
                   2605:        sc->xl_xcvr = xcvr[0] | xcvr[1] << 16;
                   2606:        sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
                   2607:        sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
                   2608:
                   2609:        xl_mediacheck(sc);
                   2610:
                   2611:        if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
                   2612:            || sc->xl_media & XL_MEDIAOPT_BT4) {
                   2613:                ifmedia_init(&sc->sc_mii.mii_media, 0,
                   2614:                    xl_ifmedia_upd, xl_ifmedia_sts);
                   2615:                sc->xl_hasmii = 1;
                   2616:                sc->sc_mii.mii_ifp = ifp;
                   2617:                sc->sc_mii.mii_readreg = xl_miibus_readreg;
                   2618:                sc->sc_mii.mii_writereg = xl_miibus_writereg;
                   2619:                sc->sc_mii.mii_statchg = xl_miibus_statchg;
                   2620:                xl_setcfg(sc);
                   2621:                mii_attach((struct device *)sc, &sc->sc_mii, 0xffffffff,
                   2622:                    MII_PHY_ANY, MII_OFFSET_ANY, 0);
                   2623:
                   2624:                if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
                   2625:                        ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,
                   2626:                            0, NULL);
                   2627:                        ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
                   2628:                }
                   2629:                else {
                   2630:                        ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
                   2631:                }
                   2632:                ifm = &sc->sc_mii.mii_media;
                   2633:        }
                   2634:        else {
                   2635:                ifmedia_init(&sc->ifmedia, 0, xl_ifmedia_upd, xl_ifmedia_sts);
                   2636:                sc->xl_hasmii = 0;
                   2637:                ifm = &sc->ifmedia;
                   2638:        }
                   2639:
                   2640:        /*
                   2641:         * Sanity check. If the user has selected "auto" and this isn't
                   2642:         * a 10/100 card of some kind, we need to force the transceiver
                   2643:         * type to something sane.
                   2644:         */
                   2645:        if (sc->xl_xcvr == XL_XCVR_AUTO) {
                   2646:                xl_choose_xcvr(sc, 0);
                   2647:                i = splnet();
                   2648:                xl_reset(sc);
                   2649:                splx(i);
                   2650:        }
                   2651:
                   2652:        if (sc->xl_media & XL_MEDIAOPT_BT) {
                   2653:                ifmedia_add(ifm, IFM_ETHER|IFM_10_T, 0, NULL);
                   2654:                ifmedia_add(ifm, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
                   2655:                if (sc->xl_caps & XL_CAPS_FULL_DUPLEX)
                   2656:                        ifmedia_add(ifm, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
                   2657:        }
                   2658:
                   2659:        if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
                   2660:                /*
                   2661:                 * Check for a 10baseFL board in disguise.
                   2662:                 */
                   2663:                if (sc->xl_type == XL_TYPE_905B &&
                   2664:                    sc->xl_media == XL_MEDIAOPT_10FL) {
                   2665:                        ifmedia_add(ifm, IFM_ETHER|IFM_10_FL, 0, NULL);
                   2666:                        ifmedia_add(ifm, IFM_ETHER|IFM_10_FL|IFM_HDX,
                   2667:                            0, NULL);
                   2668:                        if (sc->xl_caps & XL_CAPS_FULL_DUPLEX)
                   2669:                                ifmedia_add(ifm,
                   2670:                                    IFM_ETHER|IFM_10_FL|IFM_FDX, 0, NULL);
                   2671:                } else {
                   2672:                        ifmedia_add(ifm, IFM_ETHER|IFM_10_5, 0, NULL);
                   2673:                }
                   2674:        }
                   2675:
                   2676:        if (sc->xl_media & XL_MEDIAOPT_BNC) {
                   2677:                ifmedia_add(ifm, IFM_ETHER|IFM_10_2, 0, NULL);
                   2678:        }
                   2679:
                   2680:        if (sc->xl_media & XL_MEDIAOPT_BFX) {
                   2681:                ifp->if_baudrate = 100000000;
                   2682:                ifmedia_add(ifm, IFM_ETHER|IFM_100_FX, 0, NULL);
                   2683:        }
                   2684:
                   2685:        /* Choose a default media. */
                   2686:        switch(sc->xl_xcvr) {
                   2687:        case XL_XCVR_10BT:
                   2688:                media = IFM_ETHER|IFM_10_T;
                   2689:                xl_setmode(sc, media);
                   2690:                break;
                   2691:        case XL_XCVR_AUI:
                   2692:                if (sc->xl_type == XL_TYPE_905B &&
                   2693:                    sc->xl_media == XL_MEDIAOPT_10FL) {
                   2694:                        media = IFM_ETHER|IFM_10_FL;
                   2695:                        xl_setmode(sc, media);
                   2696:                } else {
                   2697:                        media = IFM_ETHER|IFM_10_5;
                   2698:                        xl_setmode(sc, media);
                   2699:                }
                   2700:                break;
                   2701:        case XL_XCVR_COAX:
                   2702:                media = IFM_ETHER|IFM_10_2;
                   2703:                xl_setmode(sc, media);
                   2704:                break;
                   2705:        case XL_XCVR_AUTO:
                   2706:        case XL_XCVR_100BTX:
                   2707:        case XL_XCVR_MII:
                   2708:                /* Chosen by miibus */
                   2709:                break;
                   2710:        case XL_XCVR_100BFX:
                   2711:                media = IFM_ETHER|IFM_100_FX;
                   2712:                xl_setmode(sc, media);
                   2713:                break;
                   2714:        default:
                   2715:                printf("%s: unknown XCVR type: %d\n", sc->sc_dev.dv_xname,
                   2716:                                                        sc->xl_xcvr);
                   2717:                /*
                   2718:                 * This will probably be wrong, but it prevents
                   2719:                 * the ifmedia code from panicking.
                   2720:                 */
                   2721:                media = IFM_ETHER | IFM_10_T;
                   2722:                break;
                   2723:        }
                   2724:
                   2725:        if (sc->xl_hasmii == 0)
                   2726:                ifmedia_set(&sc->ifmedia, media);
                   2727:
                   2728:        if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
                   2729:                XL_SEL_WIN(0);
                   2730:                CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
                   2731:        }
                   2732:
                   2733:        /*
                   2734:         * Call MI attach routines.
                   2735:         */
                   2736:        if_attach(ifp);
                   2737:        ether_ifattach(ifp);
                   2738:
                   2739:        sc->sc_sdhook = shutdownhook_establish(xl_shutdown, sc);
                   2740:        sc->sc_pwrhook = powerhook_establish(xl_power, sc);
                   2741: }
                   2742:
                   2743: void
                   2744: xl_shutdown(void *v)
                   2745: {
                   2746:        struct xl_softc *sc = (struct xl_softc *)v;
                   2747:
                   2748:        xl_reset(sc);
                   2749:        xl_stop(sc);
                   2750: }
                   2751:
                   2752: struct cfdriver xl_cd = {
                   2753:        0, "xl", DV_IFNET
                   2754: };

CVSweb