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

Annotation of sys/dev/pci/if_bge.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: if_bge.c,v 1.213 2007/06/21 01:11:50 dlg Exp $        */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2001 Wind River Systems
        !             5:  * Copyright (c) 1997, 1998, 1999, 2001
        !             6:  *     Bill Paul <wpaul@windriver.com>.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *     This product includes software developed by Bill Paul.
        !            19:  * 4. Neither the name of the author nor the names of any co-contributors
        !            20:  *    may be used to endorse or promote products derived from this software
        !            21:  *    without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
        !            24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            26:  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
        !            27:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            28:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            29:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            30:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            31:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            32:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            33:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            34:  *
        !            35:  * $FreeBSD: if_bge.c,v 1.25 2002/11/14 23:54:49 sam Exp $
        !            36:  */
        !            37:
        !            38: /*
        !            39:  * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
        !            40:  *
        !            41:  * Written by Bill Paul <wpaul@windriver.com>
        !            42:  * Senior Engineer, Wind River Systems
        !            43:  */
        !            44:
        !            45: /*
        !            46:  * The Broadcom BCM5700 is based on technology originally developed by
        !            47:  * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet
        !            48:  * MAC chips. The BCM5700, sometimes refered to as the Tigon III, has
        !            49:  * two on-board MIPS R4000 CPUs and can have as much as 16MB of external
        !            50:  * SSRAM. The BCM5700 supports TCP, UDP and IP checksum offload, Jumbo
        !            51:  * frames, highly configurable RX filtering, and 16 RX and TX queues
        !            52:  * (which, along with RX filter rules, can be used for QOS applications).
        !            53:  * Other features, such as TCP segmentation, may be available as part
        !            54:  * of value-added firmware updates. Unlike the Tigon I and Tigon II,
        !            55:  * firmware images can be stored in hardware and need not be compiled
        !            56:  * into the driver.
        !            57:  *
        !            58:  * The BCM5700 supports the PCI v2.2 and PCI-X v1.0 standards, and will
        !            59:  * function in a 32-bit/64-bit 33/66MHz bus, or a 64-bit/133MHz bus.
        !            60:  *
        !            61:  * The BCM5701 is a single-chip solution incorporating both the BCM5700
        !            62:  * MAC and a BCM5401 10/100/1000 PHY. Unlike the BCM5700, the BCM5701
        !            63:  * does not support external SSRAM.
        !            64:  *
        !            65:  * Broadcom also produces a variation of the BCM5700 under the "Altima"
        !            66:  * brand name, which is functionally similar but lacks PCI-X support.
        !            67:  *
        !            68:  * Without external SSRAM, you can only have at most 4 TX rings,
        !            69:  * and the use of the mini RX ring is disabled. This seems to imply
        !            70:  * that these features are simply not available on the BCM5701. As a
        !            71:  * result, this driver does not implement any support for the mini RX
        !            72:  * ring.
        !            73:  */
        !            74:
        !            75: #include "bpfilter.h"
        !            76: #include "vlan.h"
        !            77:
        !            78: #include <sys/param.h>
        !            79: #include <sys/systm.h>
        !            80: #include <sys/sockio.h>
        !            81: #include <sys/mbuf.h>
        !            82: #include <sys/malloc.h>
        !            83: #include <sys/kernel.h>
        !            84: #include <sys/device.h>
        !            85: #include <sys/timeout.h>
        !            86: #include <sys/socket.h>
        !            87:
        !            88: #include <net/if.h>
        !            89: #include <net/if_dl.h>
        !            90: #include <net/if_media.h>
        !            91:
        !            92: #ifdef INET
        !            93: #include <netinet/in.h>
        !            94: #include <netinet/in_systm.h>
        !            95: #include <netinet/in_var.h>
        !            96: #include <netinet/ip.h>
        !            97: #include <netinet/if_ether.h>
        !            98: #endif
        !            99:
        !           100: #if NVLAN > 0
        !           101: #include <net/if_types.h>
        !           102: #include <net/if_vlan_var.h>
        !           103: #endif
        !           104:
        !           105: #if NBPFILTER > 0
        !           106: #include <net/bpf.h>
        !           107: #endif
        !           108:
        !           109: #ifdef __sparc64__
        !           110: #include <dev/ofw/openfirm.h>
        !           111: #endif
        !           112:
        !           113: #include <dev/pci/pcireg.h>
        !           114: #include <dev/pci/pcivar.h>
        !           115: #include <dev/pci/pcidevs.h>
        !           116:
        !           117: #include <dev/mii/mii.h>
        !           118: #include <dev/mii/miivar.h>
        !           119: #include <dev/mii/miidevs.h>
        !           120: #include <dev/mii/brgphyreg.h>
        !           121:
        !           122: #include <dev/pci/if_bgereg.h>
        !           123:
        !           124: const struct bge_revision * bge_lookup_rev(u_int32_t);
        !           125: int bge_probe(struct device *, void *, void *);
        !           126: void bge_attach(struct device *, struct device *, void *);
        !           127:
        !           128: struct cfattach bge_ca = {
        !           129:        sizeof(struct bge_softc), bge_probe, bge_attach
        !           130: };
        !           131:
        !           132: struct cfdriver bge_cd = {
        !           133:        0, "bge", DV_IFNET
        !           134: };
        !           135:
        !           136: void bge_txeof(struct bge_softc *);
        !           137: void bge_rxeof(struct bge_softc *);
        !           138:
        !           139: void bge_tick(void *);
        !           140: void bge_stats_update(struct bge_softc *);
        !           141: void bge_stats_update_regs(struct bge_softc *);
        !           142: int bge_encap(struct bge_softc *, struct mbuf *, u_int32_t *);
        !           143: int bge_compact_dma_runt(struct mbuf *pkt);
        !           144:
        !           145: int bge_intr(void *);
        !           146: void bge_start(struct ifnet *);
        !           147: int bge_ioctl(struct ifnet *, u_long, caddr_t);
        !           148: void bge_init(void *);
        !           149: void bge_power(int, void *);
        !           150: void bge_stop_block(struct bge_softc *, bus_size_t, u_int32_t);
        !           151: void bge_stop(struct bge_softc *);
        !           152: void bge_watchdog(struct ifnet *);
        !           153: void bge_shutdown(void *);
        !           154: int bge_ifmedia_upd(struct ifnet *);
        !           155: void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
        !           156:
        !           157: u_int8_t bge_eeprom_getbyte(struct bge_softc *, int, u_int8_t *);
        !           158: int bge_read_eeprom(struct bge_softc *, caddr_t, int, int);
        !           159:
        !           160: void bge_iff(struct bge_softc *);
        !           161:
        !           162: int bge_alloc_jumbo_mem(struct bge_softc *);
        !           163: void *bge_jalloc(struct bge_softc *);
        !           164: void bge_jfree(caddr_t, u_int, void *);
        !           165: int bge_newbuf_std(struct bge_softc *, int, struct mbuf *, bus_dmamap_t);
        !           166: int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
        !           167: int bge_init_rx_ring_std(struct bge_softc *);
        !           168: void bge_free_rx_ring_std(struct bge_softc *);
        !           169: int bge_init_rx_ring_jumbo(struct bge_softc *);
        !           170: void bge_free_rx_ring_jumbo(struct bge_softc *);
        !           171: void bge_free_tx_ring(struct bge_softc *);
        !           172: int bge_init_tx_ring(struct bge_softc *);
        !           173:
        !           174: void bge_chipinit(struct bge_softc *);
        !           175: int bge_blockinit(struct bge_softc *);
        !           176:
        !           177: u_int32_t bge_readmem_ind(struct bge_softc *, int);
        !           178: void bge_writemem_ind(struct bge_softc *, int, int);
        !           179: void bge_writereg_ind(struct bge_softc *, int, int);
        !           180:
        !           181: int bge_miibus_readreg(struct device *, int, int);
        !           182: void bge_miibus_writereg(struct device *, int, int, int);
        !           183: void bge_miibus_statchg(struct device *);
        !           184:
        !           185: void bge_reset(struct bge_softc *);
        !           186: void bge_link_upd(struct bge_softc *);
        !           187:
        !           188: #ifdef BGE_DEBUG
        !           189: #define DPRINTF(x)     do { if (bgedebug) printf x; } while (0)
        !           190: #define DPRINTFN(n,x)  do { if (bgedebug >= (n)) printf x; } while (0)
        !           191: int    bgedebug = 0;
        !           192: #else
        !           193: #define DPRINTF(x)
        !           194: #define DPRINTFN(n,x)
        !           195: #endif
        !           196:
        !           197: /*
        !           198:  * Various supported device vendors/types and their names. Note: the
        !           199:  * spec seems to indicate that the hardware still has Alteon's vendor
        !           200:  * ID burned into it, though it will always be overridden by the vendor
        !           201:  * ID in the EEPROM. Just to be safe, we cover all possibilities.
        !           202:  */
        !           203: const struct pci_matchid bge_devices[] = {
        !           204:        { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_BCM5700 },
        !           205:        { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_BCM5701 },
        !           206:
        !           207:        { PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC1000 },
        !           208:        { PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC1001 },
        !           209:        { PCI_VENDOR_ALTIMA, PCI_PRODUCT_ALTIMA_AC9100 },
        !           210:
        !           211:        { PCI_VENDOR_APPLE, PCI_PRODUCT_APPLE_BCM5701 },
        !           212:
        !           213:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5700 },
        !           214:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5701 },
        !           215:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702 },
        !           216:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702_ALT },
        !           217:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5702X },
        !           218:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5703 },
        !           219:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5703_ALT },
        !           220:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5703X },
        !           221:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5704C },
        !           222:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5704S },
        !           223:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5704S_ALT },
        !           224:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705 },
        !           225:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705F },
        !           226:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705K },
        !           227:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705M },
        !           228:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5705M_ALT },
        !           229:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5714 },
        !           230:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5714S },
        !           231:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5715 },
        !           232:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5715S },
        !           233:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5720 },
        !           234:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5721 },
        !           235:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5722 },
        !           236:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5750 },
        !           237:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5750M },
        !           238:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5751 },
        !           239:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5751F },
        !           240:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5751M },
        !           241:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5752 },
        !           242:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5752M },
        !           243:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5753 },
        !           244:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5753F },
        !           245:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5753M },
        !           246:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5754 },
        !           247:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5754M },
        !           248:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5755 },
        !           249:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5755M },
        !           250:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5756 },
        !           251:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5780 },
        !           252:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5780S },
        !           253:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5781 },
        !           254:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5782 },
        !           255:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5786 },
        !           256:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5787 },
        !           257:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5787F },
        !           258:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5787M },
        !           259:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5788 },
        !           260:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5789 },
        !           261:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5901 },
        !           262:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5901A2 },
        !           263:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5903M },
        !           264: #if 0
        !           265:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5906 },
        !           266:        { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5906M },
        !           267: #endif
        !           268:
        !           269:        { PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9D21 },
        !           270:
        !           271:        { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C996 },
        !           272: };
        !           273:
        !           274: #define BGE_IS_5705_OR_BEYOND(sc)  \
        !           275:        (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705    || \
        !           276:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750    || \
        !           277:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 || \
        !           278:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780    || \
        !           279:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714    || \
        !           280:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752    || \
        !           281:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755    || \
        !           282:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787    || \
        !           283:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
        !           284:
        !           285: #define BGE_IS_575X_PLUS(sc)  \
        !           286:        (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750    || \
        !           287:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 || \
        !           288:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780    || \
        !           289:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714    || \
        !           290:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752    || \
        !           291:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755    || \
        !           292:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787    || \
        !           293:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
        !           294:
        !           295: #define BGE_IS_5714_FAMILY(sc)  \
        !           296:        (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 || \
        !           297:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780    || \
        !           298:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714)
        !           299:
        !           300: #define BGE_IS_JUMBO_CAPABLE(sc)  \
        !           301:        (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700    || \
        !           302:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701    || \
        !           303:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703    || \
        !           304:         BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
        !           305:
        !           306:
        !           307: static const struct bge_revision {
        !           308:        u_int32_t               br_chipid;
        !           309:        const char              *br_name;
        !           310: } bge_revisions[] = {
        !           311:        { BGE_CHIPID_BCM5700_A0, "BCM5700 A0" },
        !           312:        { BGE_CHIPID_BCM5700_A1, "BCM5700 A1" },
        !           313:        { BGE_CHIPID_BCM5700_B0, "BCM5700 B0" },
        !           314:        { BGE_CHIPID_BCM5700_B1, "BCM5700 B1" },
        !           315:        { BGE_CHIPID_BCM5700_B2, "BCM5700 B2" },
        !           316:        { BGE_CHIPID_BCM5700_B3, "BCM5700 B3" },
        !           317:        { BGE_CHIPID_BCM5700_ALTIMA, "BCM5700 Altima" },
        !           318:        { BGE_CHIPID_BCM5700_C0, "BCM5700 C0" },
        !           319:        { BGE_CHIPID_BCM5701_A0, "BCM5701 A0" },
        !           320:        { BGE_CHIPID_BCM5701_B0, "BCM5701 B0" },
        !           321:        { BGE_CHIPID_BCM5701_B2, "BCM5701 B2" },
        !           322:        { BGE_CHIPID_BCM5701_B5, "BCM5701 B5" },
        !           323:        { BGE_CHIPID_BCM5703_A0, "BCM5703 A0" },
        !           324:        { BGE_CHIPID_BCM5703_A1, "BCM5703 A1" },
        !           325:        { BGE_CHIPID_BCM5703_A2, "BCM5703 A2" },
        !           326:        { BGE_CHIPID_BCM5703_A3, "BCM5703 A3" },
        !           327:        { BGE_CHIPID_BCM5703_B0, "BCM5703 B0" },
        !           328:        { BGE_CHIPID_BCM5704_A0, "BCM5704 A0" },
        !           329:        { BGE_CHIPID_BCM5704_A1, "BCM5704 A1" },
        !           330:        { BGE_CHIPID_BCM5704_A2, "BCM5704 A2" },
        !           331:        { BGE_CHIPID_BCM5704_A3, "BCM5704 A3" },
        !           332:        { BGE_CHIPID_BCM5704_B0, "BCM5704 B0" },
        !           333:        { BGE_CHIPID_BCM5705_A0, "BCM5705 A0" },
        !           334:        { BGE_CHIPID_BCM5705_A1, "BCM5705 A1" },
        !           335:        { BGE_CHIPID_BCM5705_A2, "BCM5705 A2" },
        !           336:        { BGE_CHIPID_BCM5705_A3, "BCM5705 A3" },
        !           337:        { BGE_CHIPID_BCM5750_A0, "BCM5750 A0" },
        !           338:        { BGE_CHIPID_BCM5750_A1, "BCM5750 A1" },
        !           339:        { BGE_CHIPID_BCM5750_A3, "BCM5750 A3" },
        !           340:        { BGE_CHIPID_BCM5750_B0, "BCM5750 B0" },
        !           341:        { BGE_CHIPID_BCM5750_B1, "BCM5750 B1" },
        !           342:        { BGE_CHIPID_BCM5750_C0, "BCM5750 C0" },
        !           343:        { BGE_CHIPID_BCM5750_C1, "BCM5750 C1" },
        !           344:        { BGE_CHIPID_BCM5750_C2, "BCM5750 C2" },
        !           345:        { BGE_CHIPID_BCM5714_A0, "BCM5714 A0" },
        !           346:        { BGE_CHIPID_BCM5752_A0, "BCM5752 A0" },
        !           347:        { BGE_CHIPID_BCM5752_A1, "BCM5752 A1" },
        !           348:        { BGE_CHIPID_BCM5752_A2, "BCM5752 A2" },
        !           349:        { BGE_CHIPID_BCM5714_B0, "BCM5714 B0" },
        !           350:        { BGE_CHIPID_BCM5714_B3, "BCM5714 B3" },
        !           351:        { BGE_CHIPID_BCM5715_A0, "BCM5715 A0" },
        !           352:        { BGE_CHIPID_BCM5715_A1, "BCM5715 A1" },
        !           353:        { BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },
        !           354:        { BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
        !           355:        { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
        !           356:        { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
        !           357:        /* the 5754 and 5787 share the same ASIC ID */
        !           358:        { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
        !           359:        { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
        !           360:        { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
        !           361:        { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
        !           362:
        !           363:        { 0, NULL }
        !           364: };
        !           365:
        !           366: /*
        !           367:  * Some defaults for major revisions, so that newer steppings
        !           368:  * that we don't know about have a shot at working.
        !           369:  */
        !           370: static const struct bge_revision bge_majorrevs[] = {
        !           371:        { BGE_ASICREV_BCM5700, "unknown BCM5700" },
        !           372:        { BGE_ASICREV_BCM5701, "unknown BCM5701" },
        !           373:        /* 5702 and 5703 share the same ASIC ID */
        !           374:        { BGE_ASICREV_BCM5703, "unknown BCM5703" },
        !           375:        { BGE_ASICREV_BCM5704, "unknown BCM5704" },
        !           376:        { BGE_ASICREV_BCM5705, "unknown BCM5705" },
        !           377:        { BGE_ASICREV_BCM5750, "unknown BCM5750" },
        !           378:        { BGE_ASICREV_BCM5714_A0, "unknown BCM5714" },
        !           379:        { BGE_ASICREV_BCM5752, "unknown BCM5752" },
        !           380:        { BGE_ASICREV_BCM5780, "unknown BCM5780" },
        !           381:        { BGE_ASICREV_BCM5714, "unknown BCM5714" },
        !           382:        { BGE_ASICREV_BCM5755, "unknown BCM5755" },
        !           383:        /* 5754 and 5787 share the same ASIC ID */
        !           384:        { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
        !           385:        { BGE_ASICREV_BCM5906, "unknown BCM5906" },
        !           386:
        !           387:        { 0, NULL }
        !           388: };
        !           389:
        !           390: u_int32_t
        !           391: bge_readmem_ind(struct bge_softc *sc, int off)
        !           392: {
        !           393:        struct pci_attach_args  *pa = &(sc->bge_pa);
        !           394:
        !           395:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_BASEADDR, off);
        !           396:        return (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_DATA));
        !           397: }
        !           398:
        !           399: void
        !           400: bge_writemem_ind(struct bge_softc *sc, int off, int val)
        !           401: {
        !           402:        struct pci_attach_args  *pa = &(sc->bge_pa);
        !           403:
        !           404:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_BASEADDR, off);
        !           405:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_DATA, val);
        !           406: }
        !           407:
        !           408: void
        !           409: bge_writereg_ind(struct bge_softc *sc, int off, int val)
        !           410: {
        !           411:        struct pci_attach_args  *pa = &(sc->bge_pa);
        !           412:
        !           413:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_BASEADDR, off);
        !           414:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_DATA, val);
        !           415: }
        !           416:
        !           417: /*
        !           418:  * Read a byte of data stored in the EEPROM at address 'addr.' The
        !           419:  * BCM570x supports both the traditional bitbang interface and an
        !           420:  * auto access interface for reading the EEPROM. We use the auto
        !           421:  * access method.
        !           422:  */
        !           423: u_int8_t
        !           424: bge_eeprom_getbyte(struct bge_softc *sc, int addr, u_int8_t *dest)
        !           425: {
        !           426:        int i;
        !           427:        u_int32_t byte = 0;
        !           428:
        !           429:        /*
        !           430:         * Enable use of auto EEPROM access so we can avoid
        !           431:         * having to use the bitbang method.
        !           432:         */
        !           433:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_AUTO_EEPROM);
        !           434:
        !           435:        /* Reset the EEPROM, load the clock period. */
        !           436:        CSR_WRITE_4(sc, BGE_EE_ADDR,
        !           437:            BGE_EEADDR_RESET|BGE_EEHALFCLK(BGE_HALFCLK_384SCL));
        !           438:        DELAY(20);
        !           439:
        !           440:        /* Issue the read EEPROM command. */
        !           441:        CSR_WRITE_4(sc, BGE_EE_ADDR, BGE_EE_READCMD | addr);
        !           442:
        !           443:        /* Wait for completion */
        !           444:        for(i = 0; i < BGE_TIMEOUT * 10; i++) {
        !           445:                DELAY(10);
        !           446:                if (CSR_READ_4(sc, BGE_EE_ADDR) & BGE_EEADDR_DONE)
        !           447:                        break;
        !           448:        }
        !           449:
        !           450:        if (i == BGE_TIMEOUT * 10) {
        !           451:                printf("%s: eeprom read timed out\n", sc->bge_dev.dv_xname);
        !           452:                return (1);
        !           453:        }
        !           454:
        !           455:        /* Get result. */
        !           456:        byte = CSR_READ_4(sc, BGE_EE_DATA);
        !           457:
        !           458:        *dest = (byte >> ((addr % 4) * 8)) & 0xFF;
        !           459:
        !           460:        return (0);
        !           461: }
        !           462:
        !           463: /*
        !           464:  * Read a sequence of bytes from the EEPROM.
        !           465:  */
        !           466: int
        !           467: bge_read_eeprom(struct bge_softc *sc, caddr_t dest, int off, int cnt)
        !           468: {
        !           469:        int err = 0, i;
        !           470:        u_int8_t byte = 0;
        !           471:
        !           472:        for (i = 0; i < cnt; i++) {
        !           473:                err = bge_eeprom_getbyte(sc, off + i, &byte);
        !           474:                if (err)
        !           475:                        break;
        !           476:                *(dest + i) = byte;
        !           477:        }
        !           478:
        !           479:        return (err ? 1 : 0);
        !           480: }
        !           481:
        !           482: int
        !           483: bge_miibus_readreg(struct device *dev, int phy, int reg)
        !           484: {
        !           485:        struct bge_softc *sc = (struct bge_softc *)dev;
        !           486:        u_int32_t val, autopoll;
        !           487:        int i;
        !           488:
        !           489:        /*
        !           490:         * Broadcom's own driver always assumes the internal
        !           491:         * PHY is at GMII address 1. On some chips, the PHY responds
        !           492:         * to accesses at all addresses, which could cause us to
        !           493:         * bogusly attach the PHY 32 times at probe type. Always
        !           494:         * restricting the lookup to address 1 is simpler than
        !           495:         * trying to figure out which chips revisions should be
        !           496:         * special-cased.
        !           497:         */
        !           498:        if (phy != 1)
        !           499:                return (0);
        !           500:
        !           501:        /* Reading with autopolling on may trigger PCI errors */
        !           502:        autopoll = CSR_READ_4(sc, BGE_MI_MODE);
        !           503:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
        !           504:                BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
        !           505:                DELAY(40);
        !           506:        }
        !           507:
        !           508:        CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_READ|BGE_MICOMM_BUSY|
        !           509:            BGE_MIPHY(phy)|BGE_MIREG(reg));
        !           510:
        !           511:        for (i = 0; i < 200; i++) {
        !           512:                delay(1);
        !           513:                val = CSR_READ_4(sc, BGE_MI_COMM);
        !           514:                if (!(val & BGE_MICOMM_BUSY))
        !           515:                        break;
        !           516:                delay(10);
        !           517:        }
        !           518:
        !           519:        if (i == 200) {
        !           520:                printf("%s: PHY read timed out\n", sc->bge_dev.dv_xname);
        !           521:                val = 0;
        !           522:                goto done;
        !           523:        }
        !           524:
        !           525:        val = CSR_READ_4(sc, BGE_MI_COMM);
        !           526:
        !           527: done:
        !           528:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
        !           529:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
        !           530:                DELAY(40);
        !           531:        }
        !           532:
        !           533:        if (val & BGE_MICOMM_READFAIL)
        !           534:                return (0);
        !           535:
        !           536:        return (val & 0xFFFF);
        !           537: }
        !           538:
        !           539: void
        !           540: bge_miibus_writereg(struct device *dev, int phy, int reg, int val)
        !           541: {
        !           542:        struct bge_softc *sc = (struct bge_softc *)dev;
        !           543:        u_int32_t autopoll;
        !           544:        int i;
        !           545:
        !           546:        /* Reading with autopolling on may trigger PCI errors */
        !           547:        autopoll = CSR_READ_4(sc, BGE_MI_MODE);
        !           548:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
        !           549:                DELAY(40);
        !           550:                BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
        !           551:                DELAY(10); /* 40 usec is supposed to be adequate */
        !           552:        }
        !           553:
        !           554:        CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_WRITE|BGE_MICOMM_BUSY|
        !           555:            BGE_MIPHY(phy)|BGE_MIREG(reg)|val);
        !           556:
        !           557:        for (i = 0; i < 200; i++) {
        !           558:                delay(1);
        !           559:                if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY))
        !           560:                        break;
        !           561:                delay(10);
        !           562:        }
        !           563:
        !           564:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
        !           565:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
        !           566:                DELAY(40);
        !           567:        }
        !           568:
        !           569:        if (i == 200) {
        !           570:                printf("%s: PHY read timed out\n", sc->bge_dev.dv_xname);
        !           571:        }
        !           572: }
        !           573:
        !           574: void
        !           575: bge_miibus_statchg(struct device *dev)
        !           576: {
        !           577:        struct bge_softc *sc = (struct bge_softc *)dev;
        !           578:        struct mii_data *mii = &sc->bge_mii;
        !           579:
        !           580:        /*
        !           581:         * Get flow control negotiation result.
        !           582:         */
        !           583:        if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
        !           584:            (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) {
        !           585:                sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
        !           586:                mii->mii_media_active &= ~IFM_ETH_FMASK;
        !           587:        }
        !           588:
        !           589:        BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
        !           590:        if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T)
        !           591:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
        !           592:        else
        !           593:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);
        !           594:
        !           595:        if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
        !           596:                BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
        !           597:        else
        !           598:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
        !           599:
        !           600:        /*
        !           601:         * 802.3x flow control
        !           602:         */
        !           603:        if (sc->bge_flowflags & IFM_ETH_RXPAUSE)
        !           604:                BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
        !           605:        else
        !           606:                BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
        !           607:
        !           608:        if (sc->bge_flowflags & IFM_ETH_TXPAUSE)
        !           609:                BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
        !           610:        else
        !           611:                BGE_CLRBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
        !           612: }
        !           613:
        !           614: /*
        !           615:  * Memory management for Jumbo frames.
        !           616:  */
        !           617:
        !           618: int
        !           619: bge_alloc_jumbo_mem(struct bge_softc *sc)
        !           620: {
        !           621:        caddr_t                 ptr, kva;
        !           622:        bus_dma_segment_t       seg;
        !           623:        int             i, rseg, state, error;
        !           624:        struct bge_jpool_entry   *entry;
        !           625:
        !           626:        state = error = 0;
        !           627:
        !           628:        /* Grab a big chunk o' storage. */
        !           629:        if (bus_dmamem_alloc(sc->bge_dmatag, BGE_JMEM, PAGE_SIZE, 0,
        !           630:                             &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
        !           631:                printf("%s: can't alloc rx buffers\n", sc->bge_dev.dv_xname);
        !           632:                return (ENOBUFS);
        !           633:        }
        !           634:
        !           635:        state = 1;
        !           636:        if (bus_dmamem_map(sc->bge_dmatag, &seg, rseg, BGE_JMEM, &kva,
        !           637:                           BUS_DMA_NOWAIT)) {
        !           638:                printf("%s: can't map dma buffers (%d bytes)\n",
        !           639:                    sc->bge_dev.dv_xname, BGE_JMEM);
        !           640:                error = ENOBUFS;
        !           641:                goto out;
        !           642:        }
        !           643:
        !           644:        state = 2;
        !           645:        if (bus_dmamap_create(sc->bge_dmatag, BGE_JMEM, 1, BGE_JMEM, 0,
        !           646:            BUS_DMA_NOWAIT, &sc->bge_cdata.bge_rx_jumbo_map)) {
        !           647:                printf("%s: can't create dma map\n", sc->bge_dev.dv_xname);
        !           648:                error = ENOBUFS;
        !           649:                goto out;
        !           650:        }
        !           651:
        !           652:        state = 3;
        !           653:        if (bus_dmamap_load(sc->bge_dmatag, sc->bge_cdata.bge_rx_jumbo_map,
        !           654:                            kva, BGE_JMEM, NULL, BUS_DMA_NOWAIT)) {
        !           655:                printf("%s: can't load dma map\n", sc->bge_dev.dv_xname);
        !           656:                error = ENOBUFS;
        !           657:                goto out;
        !           658:        }
        !           659:
        !           660:        state = 4;
        !           661:        sc->bge_cdata.bge_jumbo_buf = (caddr_t)kva;
        !           662:        DPRINTFN(1,("bge_jumbo_buf = 0x%08X\n", sc->bge_cdata.bge_jumbo_buf));
        !           663:
        !           664:        SLIST_INIT(&sc->bge_jfree_listhead);
        !           665:        SLIST_INIT(&sc->bge_jinuse_listhead);
        !           666:
        !           667:        /*
        !           668:         * Now divide it up into 9K pieces and save the addresses
        !           669:         * in an array.
        !           670:         */
        !           671:        ptr = sc->bge_cdata.bge_jumbo_buf;
        !           672:        for (i = 0; i < BGE_JSLOTS; i++) {
        !           673:                sc->bge_cdata.bge_jslots[i] = ptr;
        !           674:                ptr += BGE_JLEN;
        !           675:                entry = malloc(sizeof(struct bge_jpool_entry),
        !           676:                    M_DEVBUF, M_NOWAIT);
        !           677:                if (entry == NULL) {
        !           678:                        printf("%s: no memory for jumbo buffer queue!\n",
        !           679:                            sc->bge_dev.dv_xname);
        !           680:                        error = ENOBUFS;
        !           681:                        goto out;
        !           682:                }
        !           683:                entry->slot = i;
        !           684:                SLIST_INSERT_HEAD(&sc->bge_jfree_listhead,
        !           685:                                 entry, jpool_entries);
        !           686:        }
        !           687: out:
        !           688:        if (error != 0) {
        !           689:                switch (state) {
        !           690:                case 4:
        !           691:                        bus_dmamap_unload(sc->bge_dmatag,
        !           692:                            sc->bge_cdata.bge_rx_jumbo_map);
        !           693:                case 3:
        !           694:                        bus_dmamap_destroy(sc->bge_dmatag,
        !           695:                            sc->bge_cdata.bge_rx_jumbo_map);
        !           696:                case 2:
        !           697:                        bus_dmamem_unmap(sc->bge_dmatag, kva, BGE_JMEM);
        !           698:                case 1:
        !           699:                        bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
        !           700:                        break;
        !           701:                default:
        !           702:                        break;
        !           703:                }
        !           704:        }
        !           705:
        !           706:        return (error);
        !           707: }
        !           708:
        !           709: /*
        !           710:  * Allocate a Jumbo buffer.
        !           711:  */
        !           712: void *
        !           713: bge_jalloc(struct bge_softc *sc)
        !           714: {
        !           715:        struct bge_jpool_entry   *entry;
        !           716:
        !           717:        entry = SLIST_FIRST(&sc->bge_jfree_listhead);
        !           718:
        !           719:        if (entry == NULL)
        !           720:                return (NULL);
        !           721:
        !           722:        SLIST_REMOVE_HEAD(&sc->bge_jfree_listhead, jpool_entries);
        !           723:        SLIST_INSERT_HEAD(&sc->bge_jinuse_listhead, entry, jpool_entries);
        !           724:        return (sc->bge_cdata.bge_jslots[entry->slot]);
        !           725: }
        !           726:
        !           727: /*
        !           728:  * Release a Jumbo buffer.
        !           729:  */
        !           730: void
        !           731: bge_jfree(caddr_t buf, u_int size, void *arg)
        !           732: {
        !           733:        struct bge_jpool_entry *entry;
        !           734:        struct bge_softc *sc;
        !           735:        int i;
        !           736:
        !           737:        /* Extract the softc struct pointer. */
        !           738:        sc = (struct bge_softc *)arg;
        !           739:
        !           740:        if (sc == NULL)
        !           741:                panic("bge_jfree: can't find softc pointer!");
        !           742:
        !           743:        /* calculate the slot this buffer belongs to */
        !           744:
        !           745:        i = ((vaddr_t)buf
        !           746:             - (vaddr_t)sc->bge_cdata.bge_jumbo_buf) / BGE_JLEN;
        !           747:
        !           748:        if ((i < 0) || (i >= BGE_JSLOTS))
        !           749:                panic("bge_jfree: asked to free buffer that we don't manage!");
        !           750:
        !           751:        entry = SLIST_FIRST(&sc->bge_jinuse_listhead);
        !           752:        if (entry == NULL)
        !           753:                panic("bge_jfree: buffer not in use!");
        !           754:        entry->slot = i;
        !           755:        SLIST_REMOVE_HEAD(&sc->bge_jinuse_listhead, jpool_entries);
        !           756:        SLIST_INSERT_HEAD(&sc->bge_jfree_listhead, entry, jpool_entries);
        !           757: }
        !           758:
        !           759:
        !           760: /*
        !           761:  * Intialize a standard receive ring descriptor.
        !           762:  */
        !           763: int
        !           764: bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m,
        !           765:     bus_dmamap_t dmamap)
        !           766: {
        !           767:        struct mbuf             *m_new = NULL;
        !           768:        struct bge_rx_bd        *r;
        !           769:        int                     error;
        !           770:
        !           771:        if (dmamap == NULL) {
        !           772:                error = bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1,
        !           773:                    MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap);
        !           774:                if (error != 0)
        !           775:                        return (error);
        !           776:        }
        !           777:
        !           778:        sc->bge_cdata.bge_rx_std_map[i] = dmamap;
        !           779:
        !           780:        if (m == NULL) {
        !           781:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
        !           782:                if (m_new == NULL)
        !           783:                        return (ENOBUFS);
        !           784:
        !           785:                MCLGET(m_new, M_DONTWAIT);
        !           786:                if (!(m_new->m_flags & M_EXT)) {
        !           787:                        m_freem(m_new);
        !           788:                        return (ENOBUFS);
        !           789:                }
        !           790:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
        !           791:        } else {
        !           792:                /*
        !           793:                 * We're re-using a previously allocated mbuf;
        !           794:                 * be sure to re-init pointers and lengths to
        !           795:                 * default values.
        !           796:                 */
        !           797:                m_new = m;
        !           798:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
        !           799:                m_new->m_data = m_new->m_ext.ext_buf;
        !           800:        }
        !           801:
        !           802:        if (!(sc->bge_flags & BGE_RX_ALIGNBUG))
        !           803:            m_adj(m_new, ETHER_ALIGN);
        !           804:
        !           805:        error = bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_new,
        !           806:            BUS_DMA_READ|BUS_DMA_NOWAIT);
        !           807:        if (error) {
        !           808:                if (m == NULL) {
        !           809:                        m_freem(m_new);
        !           810:                        sc->bge_cdata.bge_rx_std_chain[i] = NULL;
        !           811:                }
        !           812:                return (ENOBUFS);
        !           813:        }
        !           814:
        !           815:        sc->bge_cdata.bge_rx_std_chain[i] = m_new;
        !           816:        r = &sc->bge_rdata->bge_rx_std_ring[i];
        !           817:        BGE_HOSTADDR(r->bge_addr, dmamap->dm_segs[0].ds_addr);
        !           818:        r->bge_flags = BGE_RXBDFLAG_END;
        !           819:        r->bge_len = m_new->m_len;
        !           820:        r->bge_idx = i;
        !           821:
        !           822:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !           823:            offsetof(struct bge_ring_data, bge_rx_std_ring) +
        !           824:                i * sizeof (struct bge_rx_bd),
        !           825:            sizeof (struct bge_rx_bd),
        !           826:            BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
        !           827:
        !           828:        return (0);
        !           829: }
        !           830:
        !           831: /*
        !           832:  * Initialize a Jumbo receive ring descriptor. This allocates
        !           833:  * a Jumbo buffer from the pool managed internally by the driver.
        !           834:  */
        !           835: int
        !           836: bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m)
        !           837: {
        !           838:        struct mbuf *m_new = NULL;
        !           839:        struct bge_rx_bd *r;
        !           840:
        !           841:        if (m == NULL) {
        !           842:                caddr_t                 buf = NULL;
        !           843:
        !           844:                /* Allocate the mbuf. */
        !           845:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
        !           846:                if (m_new == NULL)
        !           847:                        return (ENOBUFS);
        !           848:
        !           849:                /* Allocate the Jumbo buffer */
        !           850:                buf = bge_jalloc(sc);
        !           851:                if (buf == NULL) {
        !           852:                        m_freem(m_new);
        !           853:                        return (ENOBUFS);
        !           854:                }
        !           855:
        !           856:                /* Attach the buffer to the mbuf. */
        !           857:                m_new->m_len = m_new->m_pkthdr.len = BGE_JUMBO_FRAMELEN;
        !           858:                MEXTADD(m_new, buf, BGE_JUMBO_FRAMELEN, 0, bge_jfree, sc);
        !           859:        } else {
        !           860:                /*
        !           861:                 * We're re-using a previously allocated mbuf;
        !           862:                 * be sure to re-init pointers and lengths to
        !           863:                 * default values.
        !           864:                 */
        !           865:                m_new = m;
        !           866:                m_new->m_data = m_new->m_ext.ext_buf;
        !           867:                m_new->m_ext.ext_size = BGE_JUMBO_FRAMELEN;
        !           868:        }
        !           869:
        !           870:        if (!(sc->bge_flags & BGE_RX_ALIGNBUG))
        !           871:                m_adj(m_new, ETHER_ALIGN);
        !           872:        /* Set up the descriptor. */
        !           873:        r = &sc->bge_rdata->bge_rx_jumbo_ring[i];
        !           874:        sc->bge_cdata.bge_rx_jumbo_chain[i] = m_new;
        !           875:        BGE_HOSTADDR(r->bge_addr, BGE_JUMBO_DMA_ADDR(sc, m_new));
        !           876:        r->bge_flags = BGE_RXBDFLAG_END|BGE_RXBDFLAG_JUMBO_RING;
        !           877:        r->bge_len = m_new->m_len;
        !           878:        r->bge_idx = i;
        !           879:
        !           880:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !           881:            offsetof(struct bge_ring_data, bge_rx_jumbo_ring) +
        !           882:                i * sizeof (struct bge_rx_bd),
        !           883:            sizeof (struct bge_rx_bd),
        !           884:            BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
        !           885:
        !           886:        return (0);
        !           887: }
        !           888:
        !           889: /*
        !           890:  * The standard receive ring has 512 entries in it. At 2K per mbuf cluster,
        !           891:  * that's 1MB or memory, which is a lot. For now, we fill only the first
        !           892:  * 256 ring entries and hope that our CPU is fast enough to keep up with
        !           893:  * the NIC.
        !           894:  */
        !           895: int
        !           896: bge_init_rx_ring_std(struct bge_softc *sc)
        !           897: {
        !           898:        int i;
        !           899:
        !           900:        if (sc->bge_flags & BGE_RXRING_VALID)
        !           901:                return (0);
        !           902:
        !           903:        for (i = 0; i < BGE_SSLOTS; i++) {
        !           904:                if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS)
        !           905:                        return (ENOBUFS);
        !           906:        }
        !           907:
        !           908:        sc->bge_std = i - 1;
        !           909:        CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
        !           910:
        !           911:        sc->bge_flags |= BGE_RXRING_VALID;
        !           912:
        !           913:        return (0);
        !           914: }
        !           915:
        !           916: void
        !           917: bge_free_rx_ring_std(struct bge_softc *sc)
        !           918: {
        !           919:        int i;
        !           920:
        !           921:        if (!(sc->bge_flags & BGE_RXRING_VALID))
        !           922:                return;
        !           923:
        !           924:        for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
        !           925:                if (sc->bge_cdata.bge_rx_std_chain[i] != NULL) {
        !           926:                        m_freem(sc->bge_cdata.bge_rx_std_chain[i]);
        !           927:                        sc->bge_cdata.bge_rx_std_chain[i] = NULL;
        !           928:                        bus_dmamap_destroy(sc->bge_dmatag,
        !           929:                            sc->bge_cdata.bge_rx_std_map[i]);
        !           930:                }
        !           931:                bzero((char *)&sc->bge_rdata->bge_rx_std_ring[i],
        !           932:                    sizeof(struct bge_rx_bd));
        !           933:        }
        !           934:
        !           935:        sc->bge_flags &= ~BGE_RXRING_VALID;
        !           936: }
        !           937:
        !           938: int
        !           939: bge_init_rx_ring_jumbo(struct bge_softc *sc)
        !           940: {
        !           941:        int i;
        !           942:        volatile struct bge_rcb *rcb;
        !           943:
        !           944:        if (sc->bge_flags & BGE_JUMBO_RXRING_VALID)
        !           945:                return (0);
        !           946:
        !           947:        for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
        !           948:                if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
        !           949:                        return (ENOBUFS);
        !           950:        };
        !           951:
        !           952:        sc->bge_jumbo = i - 1;
        !           953:        sc->bge_flags |= BGE_JUMBO_RXRING_VALID;
        !           954:
        !           955:        rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
        !           956:        rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0, 0);
        !           957:        CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
        !           958:
        !           959:        CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
        !           960:
        !           961:        return (0);
        !           962: }
        !           963:
        !           964: void
        !           965: bge_free_rx_ring_jumbo(struct bge_softc *sc)
        !           966: {
        !           967:        int i;
        !           968:
        !           969:        if (!(sc->bge_flags & BGE_JUMBO_RXRING_VALID))
        !           970:                return;
        !           971:
        !           972:        for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
        !           973:                if (sc->bge_cdata.bge_rx_jumbo_chain[i] != NULL) {
        !           974:                        m_freem(sc->bge_cdata.bge_rx_jumbo_chain[i]);
        !           975:                        sc->bge_cdata.bge_rx_jumbo_chain[i] = NULL;
        !           976:                }
        !           977:                bzero((char *)&sc->bge_rdata->bge_rx_jumbo_ring[i],
        !           978:                    sizeof(struct bge_rx_bd));
        !           979:        }
        !           980:
        !           981:        sc->bge_flags &= ~BGE_JUMBO_RXRING_VALID;
        !           982: }
        !           983:
        !           984: void
        !           985: bge_free_tx_ring(struct bge_softc *sc)
        !           986: {
        !           987:        int i;
        !           988:        struct txdmamap_pool_entry *dma;
        !           989:
        !           990:        if (!(sc->bge_flags & BGE_TXRING_VALID))
        !           991:                return;
        !           992:
        !           993:        for (i = 0; i < BGE_TX_RING_CNT; i++) {
        !           994:                if (sc->bge_cdata.bge_tx_chain[i] != NULL) {
        !           995:                        m_freem(sc->bge_cdata.bge_tx_chain[i]);
        !           996:                        sc->bge_cdata.bge_tx_chain[i] = NULL;
        !           997:                        SLIST_INSERT_HEAD(&sc->txdma_list, sc->txdma[i],
        !           998:                                            link);
        !           999:                        sc->txdma[i] = 0;
        !          1000:                }
        !          1001:                bzero((char *)&sc->bge_rdata->bge_tx_ring[i],
        !          1002:                    sizeof(struct bge_tx_bd));
        !          1003:        }
        !          1004:
        !          1005:        while ((dma = SLIST_FIRST(&sc->txdma_list))) {
        !          1006:                SLIST_REMOVE_HEAD(&sc->txdma_list, link);
        !          1007:                bus_dmamap_destroy(sc->bge_dmatag, dma->dmamap);
        !          1008:                free(dma, M_DEVBUF);
        !          1009:        }
        !          1010:
        !          1011:        sc->bge_flags &= ~BGE_TXRING_VALID;
        !          1012: }
        !          1013:
        !          1014: int
        !          1015: bge_init_tx_ring(struct bge_softc *sc)
        !          1016: {
        !          1017:        int i;
        !          1018:        bus_dmamap_t dmamap;
        !          1019:        struct txdmamap_pool_entry *dma;
        !          1020:
        !          1021:        if (sc->bge_flags & BGE_TXRING_VALID)
        !          1022:                return (0);
        !          1023:
        !          1024:        sc->bge_txcnt = 0;
        !          1025:        sc->bge_tx_saved_considx = 0;
        !          1026:
        !          1027:        /* Initialize transmit producer index for host-memory send ring. */
        !          1028:        sc->bge_tx_prodidx = 0;
        !          1029:        CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
        !          1030:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
        !          1031:                CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
        !          1032:
        !          1033:        /* NIC-memory send ring not used; initialize to zero. */
        !          1034:        CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
        !          1035:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
        !          1036:                CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
        !          1037:
        !          1038:        SLIST_INIT(&sc->txdma_list);
        !          1039:        for (i = 0; i < BGE_TX_RING_CNT; i++) {
        !          1040:                if (bus_dmamap_create(sc->bge_dmatag, BGE_JLEN,
        !          1041:                    BGE_NTXSEG, BGE_JLEN, 0, BUS_DMA_NOWAIT,
        !          1042:                    &dmamap))
        !          1043:                        return (ENOBUFS);
        !          1044:                if (dmamap == NULL)
        !          1045:                        panic("dmamap NULL in bge_init_tx_ring");
        !          1046:                dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT);
        !          1047:                if (dma == NULL) {
        !          1048:                        printf("%s: can't alloc txdmamap_pool_entry\n",
        !          1049:                            sc->bge_dev.dv_xname);
        !          1050:                        bus_dmamap_destroy(sc->bge_dmatag, dmamap);
        !          1051:                        return (ENOMEM);
        !          1052:                }
        !          1053:                dma->dmamap = dmamap;
        !          1054:                SLIST_INSERT_HEAD(&sc->txdma_list, dma, link);
        !          1055:        }
        !          1056:
        !          1057:        sc->bge_flags |= BGE_TXRING_VALID;
        !          1058:
        !          1059:        return (0);
        !          1060: }
        !          1061:
        !          1062: void
        !          1063: bge_iff(struct bge_softc *sc)
        !          1064: {
        !          1065:        struct arpcom           *ac = &sc->arpcom;
        !          1066:        struct ifnet            *ifp = &ac->ac_if;
        !          1067:        struct ether_multi      *enm;
        !          1068:        struct ether_multistep  step;
        !          1069:        u_int8_t                hashes[16];
        !          1070:        u_int32_t               h, rxmode;
        !          1071:
        !          1072:        /* First, zot all the existing filters. */
        !          1073:        rxmode = CSR_READ_4(sc, BGE_RX_MODE) & ~BGE_RXMODE_RX_PROMISC;
        !          1074:        ifp->if_flags &= ~IFF_ALLMULTI;
        !          1075:        memset(hashes, 0x00, sizeof(hashes));
        !          1076:
        !          1077:        if (ifp->if_flags & IFF_PROMISC)
        !          1078:                rxmode |= BGE_RXMODE_RX_PROMISC;
        !          1079:        else if (ac->ac_multirangecnt > 0) {
        !          1080:                ifp->if_flags |= IFF_ALLMULTI;
        !          1081:                memset(hashes, 0xff, sizeof(hashes));
        !          1082:        } else {
        !          1083:                ETHER_FIRST_MULTI(step, ac, enm);
        !          1084:                while (enm != NULL) {
        !          1085:                        h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
        !          1086:                        setbit(hashes, h & 0x7F);
        !          1087:                        ETHER_NEXT_MULTI(step, enm);
        !          1088:                }
        !          1089:        }
        !          1090:
        !          1091:        bus_space_write_raw_region_4(sc->bge_btag, sc->bge_bhandle, BGE_MAR0,
        !          1092:            hashes, sizeof(hashes));
        !          1093:
        !          1094:        CSR_WRITE_4(sc, BGE_RX_MODE, rxmode);
        !          1095: }
        !          1096:
        !          1097: /*
        !          1098:  * Do endian, PCI and DMA initialization.
        !          1099:  */
        !          1100: void
        !          1101: bge_chipinit(struct bge_softc *sc)
        !          1102: {
        !          1103:        struct pci_attach_args  *pa = &(sc->bge_pa);
        !          1104:        u_int32_t dma_rw_ctl;
        !          1105:        int i;
        !          1106:
        !          1107:        /* Set endianness before we access any non-PCI registers. */
        !          1108:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
        !          1109:            BGE_INIT);
        !          1110:
        !          1111:        /* Clear the MAC control register */
        !          1112:        CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
        !          1113:
        !          1114:        /*
        !          1115:         * Clear the MAC statistics block in the NIC's
        !          1116:         * internal memory.
        !          1117:         */
        !          1118:        for (i = BGE_STATS_BLOCK;
        !          1119:            i < BGE_STATS_BLOCK_END + 1; i += sizeof(u_int32_t))
        !          1120:                BGE_MEMWIN_WRITE(pa->pa_pc, pa->pa_tag, i, 0);
        !          1121:
        !          1122:        for (i = BGE_STATUS_BLOCK;
        !          1123:            i < BGE_STATUS_BLOCK_END + 1; i += sizeof(u_int32_t))
        !          1124:                BGE_MEMWIN_WRITE(pa->pa_pc, pa->pa_tag, i, 0);
        !          1125:
        !          1126:        /* Set up the PCI DMA control register. */
        !          1127:        if (sc->bge_flags & BGE_PCIE) {
        !          1128:                /* PCI Express bus */
        !          1129:                u_int32_t device_ctl;
        !          1130:
        !          1131:                /* alternative from Linux driver */
        !          1132: #define DMA_CTRL_WRITE_PCIE_H20MARK_128                0x00180000
        !          1133: #define DMA_CTRL_WRITE_PCIE_H20MARK_256                0x00380000
        !          1134:
        !          1135:                dma_rw_ctl = 0x76000000; /* XXX XXX XXX */;
        !          1136:                device_ctl = pci_conf_read(pa->pa_pc, pa->pa_tag,
        !          1137:                                           BGE_PCI_CONF_DEV_CTRL);
        !          1138:
        !          1139:                if ((device_ctl & 0x00e0) && 0) {
        !          1140:                        /*
        !          1141:                         * This clause is exactly what the Broadcom-supplied
        !          1142:                         * Linux does; but given overall register programming
        !          1143:                         * by bge(4), this larger DMA-write watermark
        !          1144:                         * value causes BCM5721 chips to totally wedge.
        !          1145:                         */
        !          1146:                        dma_rw_ctl |= BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_256;
        !          1147:                } else {
        !          1148:                        dma_rw_ctl |= BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_128;
        !          1149:                }
        !          1150:        } else if (sc->bge_flags & BGE_PCIX) {
        !          1151:                /* PCI-X bus */
        !          1152:                if (BGE_IS_5714_FAMILY(sc)) {
        !          1153:                        dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD;
        !          1154:                        dma_rw_ctl &= ~BGE_PCIDMARWCTL_ONEDMA_ATONCE; /* XXX */
        !          1155:                        /* XXX magic values, Broadcom-supplied Linux driver */
        !          1156:                        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780)
        !          1157:                                dma_rw_ctl |= (1 << 20) | (1 << 18) |
        !          1158:                                    BGE_PCIDMARWCTL_ONEDMA_ATONCE;
        !          1159:                        else
        !          1160:                                dma_rw_ctl |= (1<<20) | (1<<18) | (1 << 15);
        !          1161:                } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
        !          1162:                        /*
        !          1163:                         * The 5704 uses a different encoding of read/write
        !          1164:                         * watermarks.
        !          1165:                         */
        !          1166:                        dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
        !          1167:                            (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
        !          1168:                            (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
        !          1169:                else
        !          1170:                        dma_rw_ctl = BGE_PCI_READ_CMD|BGE_PCI_WRITE_CMD |
        !          1171:                            (0x3 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
        !          1172:                            (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
        !          1173:                            (0x0F);
        !          1174:
        !          1175:                /*
        !          1176:                 * 5703 and 5704 need ONEDMA_AT_ONCE as a workaround
        !          1177:                 * for hardware bugs.
        !          1178:                 */
        !          1179:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||
        !          1180:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
        !          1181:                        u_int32_t tmp;
        !          1182:
        !          1183:                        tmp = CSR_READ_4(sc, BGE_PCI_CLKCTL) & 0x1f;
        !          1184:                        if (tmp == 0x6 || tmp == 0x7)
        !          1185:                                dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE;
        !          1186:                }
        !          1187:        } else {
        !          1188:                /* Conventional PCI bus */
        !          1189:                dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD |
        !          1190:                    (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
        !          1191:                    (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
        !          1192:                    (0x0f);
        !          1193:        }
        !          1194:
        !          1195:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||
        !          1196:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704 ||
        !          1197:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705)
        !          1198:                dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
        !          1199:
        !          1200:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl);
        !          1201:
        !          1202:        /*
        !          1203:         * Set up general mode register.
        !          1204:         */
        !          1205: #ifndef BGE_CHECKSUM
        !          1206:        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
        !          1207:                    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS|
        !          1208:                    BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
        !          1209: #else
        !          1210:        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
        !          1211:                    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS);
        !          1212: #endif
        !          1213:
        !          1214:        /*
        !          1215:         * Disable memory write invalidate.  Apparently it is not supported
        !          1216:         * properly by these devices.
        !          1217:         */
        !          1218:        PCI_CLRBIT(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
        !          1219:            PCI_COMMAND_INVALIDATE_ENABLE);
        !          1220:
        !          1221: #ifdef __brokenalpha__
        !          1222:        /*
        !          1223:         * Must insure that we do not cross an 8K (bytes) boundary
        !          1224:         * for DMA reads.  Our highest limit is 1K bytes.  This is a
        !          1225:         * restriction on some ALPHA platforms with early revision
        !          1226:         * 21174 PCI chipsets, such as the AlphaPC 164lx
        !          1227:         */
        !          1228:        PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
        !          1229:            BGE_PCI_READ_BNDRY_1024);
        !          1230: #endif
        !          1231:
        !          1232:        /* Set the timer prescaler (always 66MHz) */
        !          1233:        CSR_WRITE_4(sc, BGE_MISC_CFG, 65 << 1/*BGE_32BITTIME_66MHZ*/);
        !          1234: }
        !          1235:
        !          1236: int
        !          1237: bge_blockinit(struct bge_softc *sc)
        !          1238: {
        !          1239:        volatile struct bge_rcb         *rcb;
        !          1240:        vaddr_t                 rcb_addr;
        !          1241:        int                     i;
        !          1242:        bge_hostaddr            taddr;
        !          1243:        u_int32_t               val;
        !          1244:
        !          1245:        /*
        !          1246:         * Initialize the memory window pointer register so that
        !          1247:         * we can access the first 32K of internal NIC RAM. This will
        !          1248:         * allow us to set up the TX send ring RCBs and the RX return
        !          1249:         * ring RCBs, plus other things which live in NIC memory.
        !          1250:         */
        !          1251:        CSR_WRITE_4(sc, BGE_PCI_MEMWIN_BASEADDR, 0);
        !          1252:
        !          1253:        /* Configure mbuf memory pool */
        !          1254:        if (!(BGE_IS_5705_OR_BEYOND(sc))) {
        !          1255:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
        !          1256:                    BGE_BUFFPOOL_1);
        !          1257:
        !          1258:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
        !          1259:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x10000);
        !          1260:                else
        !          1261:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x18000);
        !          1262:
        !          1263:                /* Configure DMA resource pool */
        !          1264:                CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_BASEADDR,
        !          1265:                    BGE_DMA_DESCRIPTORS);
        !          1266:                CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);
        !          1267:        }
        !          1268:
        !          1269:        /* Configure mbuf pool watermarks */
        !          1270:        /* new Broadcom docs strongly recommend these: */
        !          1271:        if (!(BGE_IS_5705_OR_BEYOND(sc))) {
        !          1272:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
        !          1273:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
        !          1274:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
        !          1275:        } else {
        !          1276:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
        !          1277:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
        !          1278:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
        !          1279:        }
        !          1280:
        !          1281:        /* Configure DMA resource watermarks */
        !          1282:        CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
        !          1283:        CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
        !          1284:
        !          1285:        /* Enable buffer manager */
        !          1286:        CSR_WRITE_4(sc, BGE_BMAN_MODE,
        !          1287:            BGE_BMANMODE_ENABLE|BGE_BMANMODE_LOMBUF_ATTN);
        !          1288:
        !          1289:        /* Poll for buffer manager start indication */
        !          1290:        for (i = 0; i < 2000; i++) {
        !          1291:                if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
        !          1292:                        break;
        !          1293:                DELAY(10);
        !          1294:        }
        !          1295:
        !          1296:        if (i == 2000) {
        !          1297:                printf("%s: buffer manager failed to start\n",
        !          1298:                    sc->bge_dev.dv_xname);
        !          1299:                return (ENXIO);
        !          1300:        }
        !          1301:
        !          1302:        /* Enable flow-through queues */
        !          1303:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
        !          1304:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
        !          1305:
        !          1306:        /* Wait until queue initialization is complete */
        !          1307:        for (i = 0; i < 2000; i++) {
        !          1308:                if (CSR_READ_4(sc, BGE_FTQ_RESET) == 0)
        !          1309:                        break;
        !          1310:                DELAY(10);
        !          1311:        }
        !          1312:
        !          1313:        if (i == 2000) {
        !          1314:                printf("%s: flow-through queue init failed\n",
        !          1315:                    sc->bge_dev.dv_xname);
        !          1316:                return (ENXIO);
        !          1317:        }
        !          1318:
        !          1319:        /* Initialize the standard RX ring control block */
        !          1320:        rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
        !          1321:        BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));
        !          1322:        if (BGE_IS_5705_OR_BEYOND(sc))
        !          1323:                rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
        !          1324:        else
        !          1325:                rcb->bge_maxlen_flags =
        !          1326:                    BGE_RCB_MAXLEN_FLAGS(ETHER_MAX_DIX_LEN, 0);
        !          1327:        rcb->bge_nicaddr = BGE_STD_RX_RINGS;
        !          1328:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);
        !          1329:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);
        !          1330:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
        !          1331:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);
        !          1332:
        !          1333:        /*
        !          1334:         * Initialize the Jumbo RX ring control block
        !          1335:         * We set the 'ring disabled' bit in the flags
        !          1336:         * field until we're actually ready to start
        !          1337:         * using this ring (i.e. once we set the MTU
        !          1338:         * high enough to require it).
        !          1339:         */
        !          1340:        if (BGE_IS_JUMBO_CAPABLE(sc)) {
        !          1341:                rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
        !          1342:                BGE_HOSTADDR(rcb->bge_hostaddr,
        !          1343:                    BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring));
        !          1344:                rcb->bge_maxlen_flags =
        !          1345:                    BGE_RCB_MAXLEN_FLAGS(BGE_JUMBO_FRAMELEN,
        !          1346:                        BGE_RCB_FLAG_RING_DISABLED);
        !          1347:                rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
        !          1348:
        !          1349:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI,
        !          1350:                    rcb->bge_hostaddr.bge_addr_hi);
        !          1351:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,
        !          1352:                    rcb->bge_hostaddr.bge_addr_lo);
        !          1353:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,
        !          1354:                    rcb->bge_maxlen_flags);
        !          1355:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_NICADDR,
        !          1356:                    rcb->bge_nicaddr);
        !          1357:
        !          1358:                /* Set up dummy disabled mini ring RCB */
        !          1359:                rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;
        !          1360:                rcb->bge_maxlen_flags =
        !          1361:                    BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED);
        !          1362:                CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS,
        !          1363:                    rcb->bge_maxlen_flags);
        !          1364:
        !          1365:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          1366:                    offsetof(struct bge_ring_data, bge_info),
        !          1367:                    sizeof (struct bge_gib),
        !          1368:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
        !          1369:        }
        !          1370:
        !          1371:        /*
        !          1372:         * Set the BD ring replenish thresholds. The recommended
        !          1373:         * values are 1/8th the number of descriptors allocated to
        !          1374:         * each ring.
        !          1375:         */
        !          1376:        i = BGE_STD_RX_RING_CNT / 8;
        !          1377:
        !          1378:        /*
        !          1379:         * Use a value of 8 for the following chips to workaround HW errata.
        !          1380:         * Some of these chips have been added based on empirical
        !          1381:         * evidence (they don't work unless this is done).
        !          1382:         */
        !          1383:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 ||
        !          1384:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
        !          1385:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
        !          1386:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
        !          1387:                i = 8;
        !          1388:
        !          1389:        CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);
        !          1390:        CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT / 8);
        !          1391:
        !          1392:        /*
        !          1393:         * Disable all unused send rings by setting the 'ring disabled'
        !          1394:         * bit in the flags field of all the TX send ring control blocks.
        !          1395:         * These are located in NIC memory.
        !          1396:         */
        !          1397:        rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
        !          1398:        for (i = 0; i < BGE_TX_RINGS_EXTSSRAM_MAX; i++) {
        !          1399:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
        !          1400:                    BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED));
        !          1401:                RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
        !          1402:                rcb_addr += sizeof(struct bge_rcb);
        !          1403:        }
        !          1404:
        !          1405:        /* Configure TX RCB 0 (we use only the first ring) */
        !          1406:        rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
        !          1407:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));
        !          1408:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
        !          1409:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
        !          1410:        RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,
        !          1411:                    BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
        !          1412:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          1413:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
        !          1414:                    BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
        !          1415:
        !          1416:        /* Disable all unused RX return rings */
        !          1417:        rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
        !          1418:        for (i = 0; i < BGE_RX_RINGS_MAX; i++) {
        !          1419:                RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
        !          1420:                RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, 0);
        !          1421:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
        !          1422:                    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
        !          1423:                        BGE_RCB_FLAG_RING_DISABLED));
        !          1424:                RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
        !          1425:                CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
        !          1426:                    (i * (sizeof(u_int64_t))), 0);
        !          1427:                rcb_addr += sizeof(struct bge_rcb);
        !          1428:        }
        !          1429:
        !          1430:        /* Initialize RX ring indexes */
        !          1431:        CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, 0);
        !          1432:        CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
        !          1433:        CSR_WRITE_4(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
        !          1434:
        !          1435:        /*
        !          1436:         * Set up RX return ring 0
        !          1437:         * Note that the NIC address for RX return rings is 0x00000000.
        !          1438:         * The return rings live entirely within the host, so the
        !          1439:         * nicaddr field in the RCB isn't used.
        !          1440:         */
        !          1441:        rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
        !          1442:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
        !          1443:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
        !          1444:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
        !          1445:        RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0x00000000);
        !          1446:        RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
        !          1447:            BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));
        !          1448:
        !          1449:        /* Set random backoff seed for TX */
        !          1450:        CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
        !          1451:            sc->arpcom.ac_enaddr[0] + sc->arpcom.ac_enaddr[1] +
        !          1452:            sc->arpcom.ac_enaddr[2] + sc->arpcom.ac_enaddr[3] +
        !          1453:            sc->arpcom.ac_enaddr[4] + sc->arpcom.ac_enaddr[5] +
        !          1454:            BGE_TX_BACKOFF_SEED_MASK);
        !          1455:
        !          1456:        /* Set inter-packet gap */
        !          1457:        CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);
        !          1458:
        !          1459:        /*
        !          1460:         * Specify which ring to use for packets that don't match
        !          1461:         * any RX rules.
        !          1462:         */
        !          1463:        CSR_WRITE_4(sc, BGE_RX_RULES_CFG, 0x08);
        !          1464:
        !          1465:        /*
        !          1466:         * Configure number of RX lists. One interrupt distribution
        !          1467:         * list, sixteen active lists, one bad frames class.
        !          1468:         */
        !          1469:        CSR_WRITE_4(sc, BGE_RXLP_CFG, 0x181);
        !          1470:
        !          1471:        /* Inialize RX list placement stats mask. */
        !          1472:        CSR_WRITE_4(sc, BGE_RXLP_STATS_ENABLE_MASK, 0x007FFFFF);
        !          1473:        CSR_WRITE_4(sc, BGE_RXLP_STATS_CTL, 0x1);
        !          1474:
        !          1475:        /* Disable host coalescing until we get it set up */
        !          1476:        CSR_WRITE_4(sc, BGE_HCC_MODE, 0x00000000);
        !          1477:
        !          1478:        /* Poll to make sure it's shut down. */
        !          1479:        for (i = 0; i < 2000; i++) {
        !          1480:                if (!(CSR_READ_4(sc, BGE_HCC_MODE) & BGE_HCCMODE_ENABLE))
        !          1481:                        break;
        !          1482:                DELAY(10);
        !          1483:        }
        !          1484:
        !          1485:        if (i == 2000) {
        !          1486:                printf("%s: host coalescing engine failed to idle\n",
        !          1487:                    sc->bge_dev.dv_xname);
        !          1488:                return (ENXIO);
        !          1489:        }
        !          1490:
        !          1491:        /* Set up host coalescing defaults */
        !          1492:        CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS, sc->bge_rx_coal_ticks);
        !          1493:        CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);
        !          1494:        CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);
        !          1495:        CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);
        !          1496:        if (!(BGE_IS_5705_OR_BEYOND(sc))) {
        !          1497:                CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);
        !          1498:                CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);
        !          1499:        }
        !          1500:        CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS_INT, 0);
        !          1501:        CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 0);
        !          1502:
        !          1503:        /* Set up address of statistics block */
        !          1504:        if (!(BGE_IS_5705_OR_BEYOND(sc))) {
        !          1505:                CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI, 0);
        !          1506:                CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO,
        !          1507:                            BGE_RING_DMA_ADDR(sc, bge_info.bge_stats));
        !          1508:
        !          1509:                CSR_WRITE_4(sc, BGE_HCC_STATS_BASEADDR, BGE_STATS_BLOCK);
        !          1510:                CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_BASEADDR, BGE_STATUS_BLOCK);
        !          1511:                CSR_WRITE_4(sc, BGE_HCC_STATS_TICKS, sc->bge_stat_ticks);
        !          1512:        }
        !          1513:
        !          1514:        /* Set up address of status block */
        !          1515:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_status_block));
        !          1516:        CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_HI, taddr.bge_addr_hi);
        !          1517:        CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_LO, taddr.bge_addr_lo);
        !          1518:
        !          1519:        sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx = 0;
        !          1520:        sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx = 0;
        !          1521:
        !          1522:        /* Turn on host coalescing state machine */
        !          1523:        CSR_WRITE_4(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
        !          1524:
        !          1525:        /* Turn on RX BD completion state machine and enable attentions */
        !          1526:        CSR_WRITE_4(sc, BGE_RBDC_MODE,
        !          1527:            BGE_RBDCMODE_ENABLE|BGE_RBDCMODE_ATTN);
        !          1528:
        !          1529:        /* Turn on RX list placement state machine */
        !          1530:        CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
        !          1531:
        !          1532:        /* Turn on RX list selector state machine. */
        !          1533:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          1534:                CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
        !          1535:
        !          1536:        /* Turn on DMA, clear stats */
        !          1537:        CSR_WRITE_4(sc, BGE_MAC_MODE, BGE_MACMODE_TXDMA_ENB|
        !          1538:            BGE_MACMODE_RXDMA_ENB|BGE_MACMODE_RX_STATS_CLEAR|
        !          1539:            BGE_MACMODE_TX_STATS_CLEAR|BGE_MACMODE_RX_STATS_ENB|
        !          1540:            BGE_MACMODE_TX_STATS_ENB|BGE_MACMODE_FRMHDR_DMA_ENB|
        !          1541:            (sc->bge_flags & BGE_TBI ? BGE_PORTMODE_TBI : BGE_PORTMODE_MII));
        !          1542:
        !          1543:        /* Set misc. local control, enable interrupts on attentions */
        !          1544:        CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_ONATTN);
        !          1545:
        !          1546: #ifdef notdef
        !          1547:        /* Assert GPIO pins for PHY reset */
        !          1548:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUT0|
        !          1549:            BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUT2);
        !          1550:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUTEN0|
        !          1551:            BGE_MLC_MISCIO_OUTEN1|BGE_MLC_MISCIO_OUTEN2);
        !          1552: #endif
        !          1553:
        !          1554:        /* Turn on DMA completion state machine */
        !          1555:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          1556:                CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
        !          1557:
        !          1558:        val = BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;
        !          1559:
        !          1560:        /* Enable host coalescing bug fix. */
        !          1561:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
        !          1562:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
        !          1563:                val |= (1 << 29);
        !          1564:
        !          1565:        /* Turn on write DMA state machine */
        !          1566:        CSR_WRITE_4(sc, BGE_WDMA_MODE, val);
        !          1567:
        !          1568:        /* Turn on read DMA state machine */
        !          1569:        {
        !          1570:                uint32_t dma_read_modebits;
        !          1571:
        !          1572:                dma_read_modebits =
        !          1573:                  BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;
        !          1574:
        !          1575:                if (sc->bge_flags & BGE_PCIE && 0)
        !          1576:                        dma_read_modebits |= BGE_RDMA_MODE_FIFO_LONG_BURST;
        !          1577:
        !          1578:                CSR_WRITE_4(sc, BGE_RDMA_MODE, dma_read_modebits);
        !          1579:        }
        !          1580:
        !          1581:        /* Turn on RX data completion state machine */
        !          1582:        CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
        !          1583:
        !          1584:        /* Turn on RX BD initiator state machine */
        !          1585:        CSR_WRITE_4(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
        !          1586:
        !          1587:        /* Turn on RX data and RX BD initiator state machine */
        !          1588:        CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);
        !          1589:
        !          1590:        /* Turn on Mbuf cluster free state machine */
        !          1591:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          1592:                CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
        !          1593:
        !          1594:        /* Turn on send BD completion state machine */
        !          1595:        CSR_WRITE_4(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
        !          1596:
        !          1597:        /* Turn on send data completion state machine */
        !          1598:        CSR_WRITE_4(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE);
        !          1599:
        !          1600:        /* Turn on send data initiator state machine */
        !          1601:        CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
        !          1602:
        !          1603:        /* Turn on send BD initiator state machine */
        !          1604:        CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
        !          1605:
        !          1606:        /* Turn on send BD selector state machine */
        !          1607:        CSR_WRITE_4(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
        !          1608:
        !          1609:        CSR_WRITE_4(sc, BGE_SDI_STATS_ENABLE_MASK, 0x007FFFFF);
        !          1610:        CSR_WRITE_4(sc, BGE_SDI_STATS_CTL,
        !          1611:            BGE_SDISTATSCTL_ENABLE|BGE_SDISTATSCTL_FASTER);
        !          1612:
        !          1613:        /* ack/clear link change events */
        !          1614:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
        !          1615:            BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
        !          1616:            BGE_MACSTAT_LINK_CHANGED);
        !          1617:
        !          1618:        /* Enable PHY auto polling (for MII/GMII only) */
        !          1619:        if (sc->bge_flags & BGE_TBI) {
        !          1620:                CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK);
        !          1621:        } else {
        !          1622:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL|10<<16);
        !          1623:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 &&
        !          1624:                    sc->bge_chipid != BGE_CHIPID_BCM5700_B2)
        !          1625:                        CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
        !          1626:                            BGE_EVTENB_MI_INTERRUPT);
        !          1627:        }
        !          1628:
        !          1629:        /*
        !          1630:         * Clear any pending link state attention.
        !          1631:         * Otherwise some link state change events may be lost until attention
        !          1632:         * is cleared by bge_intr() -> bge_link_upd() sequence.
        !          1633:         * It's not necessary on newer BCM chips - perhaps enabling link
        !          1634:         * state change attentions implies clearing pending attention.
        !          1635:         */
        !          1636:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
        !          1637:            BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
        !          1638:            BGE_MACSTAT_LINK_CHANGED);
        !          1639:
        !          1640:        /* Enable link state change attentions. */
        !          1641:        BGE_SETBIT(sc, BGE_MAC_EVT_ENB, BGE_EVTENB_LINK_CHANGED);
        !          1642:
        !          1643:        return (0);
        !          1644: }
        !          1645:
        !          1646: const struct bge_revision *
        !          1647: bge_lookup_rev(u_int32_t chipid)
        !          1648: {
        !          1649:        const struct bge_revision *br;
        !          1650:
        !          1651:        for (br = bge_revisions; br->br_name != NULL; br++) {
        !          1652:                if (br->br_chipid == chipid)
        !          1653:                        return (br);
        !          1654:        }
        !          1655:
        !          1656:        for (br = bge_majorrevs; br->br_name != NULL; br++) {
        !          1657:                if (br->br_chipid == BGE_ASICREV(chipid))
        !          1658:                        return (br);
        !          1659:        }
        !          1660:
        !          1661:        return (NULL);
        !          1662: }
        !          1663:
        !          1664: /*
        !          1665:  * Probe for a Broadcom chip. Check the PCI vendor and device IDs
        !          1666:  * against our list and return its name if we find a match. Note
        !          1667:  * that since the Broadcom controller contains VPD support, we
        !          1668:  * can get the device name string from the controller itself instead
        !          1669:  * of the compiled-in string. This is a little slow, but it guarantees
        !          1670:  * we'll always announce the right product name.
        !          1671:  */
        !          1672: int
        !          1673: bge_probe(struct device *parent, void *match, void *aux)
        !          1674: {
        !          1675:        return (pci_matchbyid((struct pci_attach_args *)aux, bge_devices,
        !          1676:            sizeof(bge_devices)/sizeof(bge_devices[0])));
        !          1677: }
        !          1678:
        !          1679: void
        !          1680: bge_attach(struct device *parent, struct device *self, void *aux)
        !          1681: {
        !          1682:        struct bge_softc        *sc = (struct bge_softc *)self;
        !          1683:        struct pci_attach_args  *pa = aux;
        !          1684:        pci_chipset_tag_t       pc = pa->pa_pc;
        !          1685:        const struct bge_revision *br;
        !          1686:        pcireg_t                pm_ctl, memtype, subid;
        !          1687:        pci_intr_handle_t       ih;
        !          1688:        const char              *intrstr = NULL;
        !          1689:        bus_size_t              size;
        !          1690:        bus_dma_segment_t       seg;
        !          1691:        int                     rseg, gotenaddr = 0;
        !          1692:        u_int32_t               hwcfg = 0;
        !          1693:        u_int32_t               mac_addr = 0;
        !          1694:        u_int32_t               misccfg;
        !          1695:        struct ifnet            *ifp;
        !          1696:        caddr_t                 kva;
        !          1697: #ifdef __sparc64__
        !          1698:        int                     subvendor;
        !          1699: #endif
        !          1700:
        !          1701:        sc->bge_pa = *pa;
        !          1702:
        !          1703:        subid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
        !          1704:
        !          1705:        /*
        !          1706:         * Map control/status registers.
        !          1707:         */
        !          1708:        DPRINTFN(5, ("Map control/status regs\n"));
        !          1709:
        !          1710:        DPRINTFN(5, ("pci_mapreg_map\n"));
        !          1711:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BGE_PCI_BAR0);
        !          1712:        switch (memtype) {
        !          1713:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
        !          1714:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
        !          1715:                if (pci_mapreg_map(pa, BGE_PCI_BAR0,
        !          1716:                    memtype, 0, &sc->bge_btag, &sc->bge_bhandle,
        !          1717:                    NULL, &size, 0) == 0)
        !          1718:                        break;
        !          1719:        default:
        !          1720:                printf(": can't find mem space\n");
        !          1721:                return;
        !          1722:        }
        !          1723:
        !          1724:        DPRINTFN(5, ("pci_intr_map\n"));
        !          1725:        if (pci_intr_map(pa, &ih)) {
        !          1726:                printf(": couldn't map interrupt\n");
        !          1727:                goto fail_1;
        !          1728:        }
        !          1729:
        !          1730:        DPRINTFN(5, ("pci_intr_string\n"));
        !          1731:        intrstr = pci_intr_string(pc, ih);
        !          1732:
        !          1733:        /*
        !          1734:         * Kludge for 5700 Bx bug: a hardware bug (PCIX byte enable?)
        !          1735:         * can clobber the chip's PCI config-space power control registers,
        !          1736:         * leaving the card in D3 powersave state.
        !          1737:         * We do not have memory-mapped registers in this state,
        !          1738:         * so force device into D0 state before starting initialization.
        !          1739:         */
        !          1740:        pm_ctl = pci_conf_read(pc, pa->pa_tag, BGE_PCI_PWRMGMT_CMD);
        !          1741:        pm_ctl &= ~(PCI_PWR_D0|PCI_PWR_D1|PCI_PWR_D2|PCI_PWR_D3);
        !          1742:        pm_ctl |= (1 << 8) | PCI_PWR_D0 ; /* D0 state */
        !          1743:        pci_conf_write(pc, pa->pa_tag, BGE_PCI_PWRMGMT_CMD, pm_ctl);
        !          1744:        DELAY(1000);    /* 27 usec is allegedly sufficent */
        !          1745:
        !          1746:        /*
        !          1747:         * Save ASIC rev.
        !          1748:         */
        !          1749:
        !          1750:        sc->bge_chipid =
        !          1751:             pci_conf_read(pc, pa->pa_tag, BGE_PCI_MISC_CTL) &
        !          1752:             BGE_PCIMISCCTL_ASICREV;
        !          1753:
        !          1754:        printf(", ");
        !          1755:        br = bge_lookup_rev(sc->bge_chipid);
        !          1756:        if (br == NULL)
        !          1757:                printf("unknown ASIC (0x%04x)", sc->bge_chipid >> 16);
        !          1758:        else
        !          1759:                printf("%s (0x%04x)", br->br_name, sc->bge_chipid >> 16);
        !          1760:
        !          1761:        /*
        !          1762:         * PCI Express check.
        !          1763:         */
        !          1764:        if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
        !          1765:            NULL, NULL) != 0)
        !          1766:                sc->bge_flags |= BGE_PCIE;
        !          1767:
        !          1768:        /*
        !          1769:         * PCI-X check.
        !          1770:         */
        !          1771:        if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) &
        !          1772:            BGE_PCISTATE_PCI_BUSMODE) == 0)
        !          1773:                sc->bge_flags |= BGE_PCIX;
        !          1774:
        !          1775:        /*
        !          1776:         * SEEPROM check.
        !          1777:         */
        !          1778: #ifdef __sparc64__
        !          1779:        if (OF_getprop(PCITAG_NODE(pa->pa_tag), "subsystem-vendor-id",
        !          1780:            &subvendor, sizeof(subvendor)) == sizeof(subvendor)) {
        !          1781:                if (subvendor == PCI_VENDOR_SUN)
        !          1782:                sc->bge_flags |= BGE_NO_EEPROM;
        !          1783:        }
        !          1784: #endif
        !          1785:
        !          1786:        /*
        !          1787:         * When using the BCM5701 in PCI-X mode, data corruption has
        !          1788:         * been observed in the first few bytes of some received packets.
        !          1789:         * Aligning the packet buffer in memory eliminates the corruption.
        !          1790:         * Unfortunately, this misaligns the packet payloads.  On platforms
        !          1791:         * which do not support unaligned accesses, we will realign the
        !          1792:         * payloads by copying the received packets.
        !          1793:         */
        !          1794:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 &&
        !          1795:            sc->bge_flags & BGE_PCIX)
        !          1796:                sc->bge_flags |= BGE_RX_ALIGNBUG;
        !          1797:
        !          1798:        if (BGE_IS_JUMBO_CAPABLE(sc))
        !          1799:                sc->bge_flags |= BGE_JUMBO_CAP;
        !          1800:
        !          1801:        if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
        !          1802:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701) &&
        !          1803:            PCI_VENDOR(subid) == DELL_VENDORID)
        !          1804:                sc->bge_flags |= BGE_NO_3LED;
        !          1805:
        !          1806:        misccfg = CSR_READ_4(sc, BGE_MISC_CFG);
        !          1807:        misccfg &= BGE_MISCCFG_BOARD_ID_MASK;
        !          1808:
        !          1809:        if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 &&
        !          1810:             (misccfg == 0x4000 || misccfg == 0x8000)) ||
        !          1811:            (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
        !          1812:             PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
        !          1813:             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5901 ||
        !          1814:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5901A2 ||
        !          1815:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5705F)) ||
        !          1816:            (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
        !          1817:             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5751F ||
        !          1818:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5753F ||
        !          1819:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5787F)) ||
        !          1820:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
        !          1821:                sc->bge_flags |= BGE_10_100_ONLY;
        !          1822:
        !          1823:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
        !          1824:            (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
        !          1825:             (sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
        !          1826:              sc->bge_chipid != BGE_CHIPID_BCM5705_A1)) ||
        !          1827:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
        !          1828:                sc->bge_flags |= BGE_NO_ETH_WIRE_SPEED;
        !          1829:
        !          1830:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5703_AX ||
        !          1831:            BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_AX)
        !          1832:                sc->bge_flags |= BGE_PHY_ADC_BUG;
        !          1833:        if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0)
        !          1834:                sc->bge_flags |= BGE_PHY_5704_A0_BUG;
        !          1835:
        !          1836:        if (BGE_IS_5705_OR_BEYOND(sc)) {
        !          1837:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
        !          1838:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787) {
        !          1839:                        if (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5722 &&
        !          1840:                            PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5756)
        !          1841:                                sc->bge_flags |= BGE_PHY_JITTER_BUG;
        !          1842:                        if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5755M)
        !          1843:                                sc->bge_flags |= BGE_PHY_ADJUST_TRIM;
        !          1844:                } else if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)
        !          1845:                        sc->bge_flags |= BGE_PHY_BER_BUG;
        !          1846:        }
        !          1847:
        !          1848:        /* Try to reset the chip. */
        !          1849:        DPRINTFN(5, ("bge_reset\n"));
        !          1850:        bge_reset(sc);
        !          1851:
        !          1852:        bge_chipinit(sc);
        !          1853:
        !          1854: #ifdef __sparc64__
        !          1855:        if (!gotenaddr) {
        !          1856:                if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
        !          1857:                    sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) == ETHER_ADDR_LEN)
        !          1858:                        gotenaddr = 1;
        !          1859:        }
        !          1860: #endif
        !          1861:
        !          1862:        /*
        !          1863:         * Get station address from the EEPROM.
        !          1864:         */
        !          1865:        if (!gotenaddr) {
        !          1866:                mac_addr = bge_readmem_ind(sc, 0x0c14);
        !          1867:                if ((mac_addr >> 16) == 0x484b) {
        !          1868:                        sc->arpcom.ac_enaddr[0] = (u_char)(mac_addr >> 8);
        !          1869:                        sc->arpcom.ac_enaddr[1] = (u_char)mac_addr;
        !          1870:                        mac_addr = bge_readmem_ind(sc, 0x0c18);
        !          1871:                        sc->arpcom.ac_enaddr[2] = (u_char)(mac_addr >> 24);
        !          1872:                        sc->arpcom.ac_enaddr[3] = (u_char)(mac_addr >> 16);
        !          1873:                        sc->arpcom.ac_enaddr[4] = (u_char)(mac_addr >> 8);
        !          1874:                        sc->arpcom.ac_enaddr[5] = (u_char)mac_addr;
        !          1875:                        gotenaddr = 1;
        !          1876:                }
        !          1877:        }
        !          1878:        if (!gotenaddr && (!(sc->bge_flags & BGE_NO_EEPROM))) {
        !          1879:                if (bge_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
        !          1880:                    BGE_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN) == 0)
        !          1881:                        gotenaddr = 1;
        !          1882:        }
        !          1883:
        !          1884: #ifdef __sparc64__
        !          1885:        if (!gotenaddr) {
        !          1886:                extern void myetheraddr(u_char *);
        !          1887:
        !          1888:                myetheraddr(sc->arpcom.ac_enaddr);
        !          1889:                gotenaddr = 1;
        !          1890:        }
        !          1891: #endif
        !          1892:
        !          1893:        if (!gotenaddr) {
        !          1894:                printf(": failed to read station address\n");
        !          1895:                goto fail_1;
        !          1896:        }
        !          1897:
        !          1898:        /* Allocate the general information block and ring buffers. */
        !          1899:        sc->bge_dmatag = pa->pa_dmat;
        !          1900:        DPRINTFN(5, ("bus_dmamem_alloc\n"));
        !          1901:        if (bus_dmamem_alloc(sc->bge_dmatag, sizeof(struct bge_ring_data),
        !          1902:                             PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
        !          1903:                printf(": can't alloc rx buffers\n");
        !          1904:                goto fail_1;
        !          1905:        }
        !          1906:        DPRINTFN(5, ("bus_dmamem_map\n"));
        !          1907:        if (bus_dmamem_map(sc->bge_dmatag, &seg, rseg,
        !          1908:                           sizeof(struct bge_ring_data), &kva,
        !          1909:                           BUS_DMA_NOWAIT)) {
        !          1910:                printf(": can't map dma buffers (%d bytes)\n",
        !          1911:                    sizeof(struct bge_ring_data));
        !          1912:                goto fail_2;
        !          1913:        }
        !          1914:        DPRINTFN(5, ("bus_dmamem_create\n"));
        !          1915:        if (bus_dmamap_create(sc->bge_dmatag, sizeof(struct bge_ring_data), 1,
        !          1916:            sizeof(struct bge_ring_data), 0,
        !          1917:            BUS_DMA_NOWAIT, &sc->bge_ring_map)) {
        !          1918:                printf(": can't create dma map\n");
        !          1919:                goto fail_3;
        !          1920:        }
        !          1921:        DPRINTFN(5, ("bus_dmamem_load\n"));
        !          1922:        if (bus_dmamap_load(sc->bge_dmatag, sc->bge_ring_map, kva,
        !          1923:                            sizeof(struct bge_ring_data), NULL,
        !          1924:                            BUS_DMA_NOWAIT)) {
        !          1925:                goto fail_4;
        !          1926:        }
        !          1927:
        !          1928:        DPRINTFN(5, ("bzero\n"));
        !          1929:        sc->bge_rdata = (struct bge_ring_data *)kva;
        !          1930:
        !          1931:        bzero(sc->bge_rdata, sizeof(struct bge_ring_data));
        !          1932:
        !          1933:        /*
        !          1934:         * Try to allocate memory for Jumbo buffers.
        !          1935:         */
        !          1936:        if (BGE_IS_JUMBO_CAPABLE(sc)) {
        !          1937:                if (bge_alloc_jumbo_mem(sc)) {
        !          1938:                        printf(": jumbo buffer allocation failed\n");
        !          1939:                        goto fail_5;
        !          1940:                }
        !          1941:        }
        !          1942:
        !          1943:        /* Set default tuneable values. */
        !          1944:        sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
        !          1945:        sc->bge_rx_coal_ticks = 150;
        !          1946:        sc->bge_rx_max_coal_bds = 64;
        !          1947:        sc->bge_tx_coal_ticks = 300;
        !          1948:        sc->bge_tx_max_coal_bds = 400;
        !          1949:
        !          1950:        /* 5705 limits RX return ring to 512 entries. */
        !          1951:        if (BGE_IS_5705_OR_BEYOND(sc))
        !          1952:                sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
        !          1953:        else
        !          1954:                sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
        !          1955:
        !          1956:        /* Set up ifnet structure */
        !          1957:        ifp = &sc->arpcom.ac_if;
        !          1958:        ifp->if_softc = sc;
        !          1959:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        !          1960:        ifp->if_ioctl = bge_ioctl;
        !          1961:        ifp->if_start = bge_start;
        !          1962:        ifp->if_watchdog = bge_watchdog;
        !          1963:        ifp->if_baudrate = 1000000000;
        !          1964:        IFQ_SET_MAXLEN(&ifp->if_snd, BGE_TX_RING_CNT - 1);
        !          1965:        IFQ_SET_READY(&ifp->if_snd);
        !          1966:        DPRINTFN(5, ("bcopy\n"));
        !          1967:        bcopy(sc->bge_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
        !          1968:
        !          1969:        ifp->if_capabilities = IFCAP_VLAN_MTU;
        !          1970:
        !          1971: #if NVLAN > 0
        !          1972:        ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
        !          1973: #endif
        !          1974:
        !          1975:        if (BGE_IS_JUMBO_CAPABLE(sc))
        !          1976:                ifp->if_hardmtu = BGE_JUMBO_MTU;
        !          1977:
        !          1978:        /*
        !          1979:         * Do MII setup.
        !          1980:         */
        !          1981:        DPRINTFN(5, ("mii setup\n"));
        !          1982:        sc->bge_mii.mii_ifp = ifp;
        !          1983:        sc->bge_mii.mii_readreg = bge_miibus_readreg;
        !          1984:        sc->bge_mii.mii_writereg = bge_miibus_writereg;
        !          1985:        sc->bge_mii.mii_statchg = bge_miibus_statchg;
        !          1986:
        !          1987:        /*
        !          1988:         * Figure out what sort of media we have by checking the hardware
        !          1989:         * config word in the first 32K of internal NIC memory, or fall back to
        !          1990:         * examining the EEPROM if necessary.  Note: on some BCM5700 cards,
        !          1991:         * this value seems to be unset. If that's the case, we have to rely on
        !          1992:         * identifying the NIC by its PCI subsystem ID, as we do below for the
        !          1993:         * SysKonnect SK-9D41.
        !          1994:         */
        !          1995:        if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
        !          1996:                hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
        !          1997:        else if (!(sc->bge_flags & BGE_NO_EEPROM)) {
        !          1998:                if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
        !          1999:                    sizeof(hwcfg))) {
        !          2000:                        printf(": failed to read media type\n");
        !          2001:                        goto fail_5;
        !          2002:                }
        !          2003:                hwcfg = ntohl(hwcfg);
        !          2004:        }
        !          2005:
        !          2006:        if ((hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER)
        !          2007:                sc->bge_flags |= BGE_TBI;
        !          2008:
        !          2009:        /* The SysKonnect SK-9D41 is a 1000baseSX card. */
        !          2010:        if (PCI_PRODUCT(subid) == SK_SUBSYSID_9D41)
        !          2011:                sc->bge_flags |= BGE_TBI;
        !          2012:
        !          2013:        /* Hookup IRQ last. */
        !          2014:        DPRINTFN(5, ("pci_intr_establish\n"));
        !          2015:        sc->bge_intrhand = pci_intr_establish(pc, ih, IPL_NET, bge_intr, sc,
        !          2016:            sc->bge_dev.dv_xname);
        !          2017:        if (sc->bge_intrhand == NULL) {
        !          2018:                printf(": couldn't establish interrupt");
        !          2019:                if (intrstr != NULL)
        !          2020:                        printf(" at %s", intrstr);
        !          2021:                printf("\n");
        !          2022:                goto fail_5;
        !          2023:        }
        !          2024:
        !          2025:        /*
        !          2026:         * A Broadcom chip was detected. Inform the world.
        !          2027:         */
        !          2028:        printf(": %s, address %s\n", intrstr,
        !          2029:            ether_sprintf(sc->arpcom.ac_enaddr));
        !          2030:
        !          2031:        if (sc->bge_flags & BGE_TBI) {
        !          2032:                ifmedia_init(&sc->bge_ifmedia, IFM_IMASK, bge_ifmedia_upd,
        !          2033:                    bge_ifmedia_sts);
        !          2034:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
        !          2035:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_1000_SX|IFM_FDX,
        !          2036:                            0, NULL);
        !          2037:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
        !          2038:                ifmedia_set(&sc->bge_ifmedia, IFM_ETHER|IFM_AUTO);
        !          2039:                sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media;
        !          2040:        } else {
        !          2041:                /*
        !          2042:                 * Do transceiver setup.
        !          2043:                 */
        !          2044:                ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,
        !          2045:                             bge_ifmedia_sts);
        !          2046:                mii_attach(&sc->bge_dev, &sc->bge_mii, 0xffffffff,
        !          2047:                           MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE);
        !          2048:
        !          2049:                if (LIST_FIRST(&sc->bge_mii.mii_phys) == NULL) {
        !          2050:                        printf("%s: no PHY found!\n", sc->bge_dev.dv_xname);
        !          2051:                        ifmedia_add(&sc->bge_mii.mii_media,
        !          2052:                                    IFM_ETHER|IFM_MANUAL, 0, NULL);
        !          2053:                        ifmedia_set(&sc->bge_mii.mii_media,
        !          2054:                                    IFM_ETHER|IFM_MANUAL);
        !          2055:                } else
        !          2056:                        ifmedia_set(&sc->bge_mii.mii_media,
        !          2057:                                    IFM_ETHER|IFM_AUTO);
        !          2058:        }
        !          2059:
        !          2060:        /*
        !          2061:         * Call MI attach routine.
        !          2062:         */
        !          2063:        if_attach(ifp);
        !          2064:        ether_ifattach(ifp);
        !          2065:
        !          2066:        sc->sc_shutdownhook = shutdownhook_establish(bge_shutdown, sc);
        !          2067:        sc->sc_powerhook = powerhook_establish(bge_power, sc);
        !          2068:
        !          2069:        timeout_set(&sc->bge_timeout, bge_tick, sc);
        !          2070:        return;
        !          2071:
        !          2072: fail_5:
        !          2073:        bus_dmamap_unload(sc->bge_dmatag, sc->bge_ring_map);
        !          2074:
        !          2075: fail_4:
        !          2076:        bus_dmamap_destroy(sc->bge_dmatag, sc->bge_ring_map);
        !          2077:
        !          2078: fail_3:
        !          2079:        bus_dmamem_unmap(sc->bge_dmatag, kva,
        !          2080:            sizeof(struct bge_ring_data));
        !          2081:
        !          2082: fail_2:
        !          2083:        bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
        !          2084:
        !          2085: fail_1:
        !          2086:        bus_space_unmap(sc->bge_btag, sc->bge_bhandle, size);
        !          2087: }
        !          2088:
        !          2089: void
        !          2090: bge_reset(struct bge_softc *sc)
        !          2091: {
        !          2092:        struct pci_attach_args *pa = &sc->bge_pa;
        !          2093:        pcireg_t cachesize, command, pcistate, new_pcistate;
        !          2094:        u_int32_t reset;
        !          2095:        int i, val = 0;
        !          2096:
        !          2097:        /* Save some important PCI state. */
        !          2098:        cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ);
        !          2099:        command = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD);
        !          2100:        pcistate = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE);
        !          2101:
        !          2102:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
        !          2103:            BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
        !          2104:            BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);
        !          2105:
        !          2106:        /* Disable fastboot on controllers that support it. */
        !          2107:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
        !          2108:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
        !          2109:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787)
        !          2110:                CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
        !          2111:
        !          2112:        reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1);
        !          2113:
        !          2114:        if (sc->bge_flags & BGE_PCIE) {
        !          2115:                if (CSR_READ_4(sc, 0x7e2c) == 0x60) {
        !          2116:                        /* PCI Express 1.0 system */
        !          2117:                        CSR_WRITE_4(sc, 0x7e2c, 0x20);
        !          2118:                }
        !          2119:                if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
        !          2120:                        /*
        !          2121:                         * Prevent PCI Express link training
        !          2122:                         * during global reset.
        !          2123:                         */
        !          2124:                        CSR_WRITE_4(sc, BGE_MISC_CFG, (1<<29));
        !          2125:                        reset |= (1<<29);
        !          2126:                }
        !          2127:        }
        !          2128:
        !          2129:        /*
        !          2130:         * Set GPHY Power Down Override to leave GPHY
        !          2131:         * powered up in D0 uninitialized.
        !          2132:         */
        !          2133:        if (BGE_IS_5705_OR_BEYOND(sc))
        !          2134:                reset |= BGE_MISCCFG_KEEP_GPHY_POWER;
        !          2135:
        !          2136:        /* Issue global reset */
        !          2137:        bge_writereg_ind(sc, BGE_MISC_CFG, reset);
        !          2138:
        !          2139:        DELAY(1000);
        !          2140:
        !          2141:        if (sc->bge_flags & BGE_PCIE) {
        !          2142:                if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
        !          2143:                        pcireg_t v;
        !          2144:
        !          2145:                        DELAY(500000); /* wait for link training to complete */
        !          2146:                        v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0xc4);
        !          2147:                        pci_conf_write(pa->pa_pc, pa->pa_tag, 0xc4, v | (1<<15));
        !          2148:                }
        !          2149:
        !          2150:                /*
        !          2151:                 * Set PCI Express max payload size to 128 bytes
        !          2152:                 * and clear error status.
        !          2153:                 */
        !          2154:                pci_conf_write(pa->pa_pc, pa->pa_tag,
        !          2155:                    BGE_PCI_CONF_DEV_CTRL, 0xf5000);
        !          2156:        }
        !          2157:
        !          2158:        /* Reset some of the PCI state that got zapped by reset */
        !          2159:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
        !          2160:            BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
        !          2161:            BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);
        !          2162:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ, cachesize);
        !          2163:        pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, command);
        !          2164:        bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));
        !          2165:
        !          2166:        /* Enable memory arbiter. */
        !          2167:        if (BGE_IS_5714_FAMILY(sc)) {
        !          2168:                u_int32_t val;
        !          2169:
        !          2170:                val = CSR_READ_4(sc, BGE_MARB_MODE);
        !          2171:                CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | val);
        !          2172:        } else
        !          2173:                CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
        !          2174:
        !          2175:        /*
        !          2176:         * Prevent PXE restart: write a magic number to the
        !          2177:         * general communications memory at 0xB50.
        !          2178:         */
        !          2179:        bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
        !          2180:
        !          2181:        /*
        !          2182:         * Poll until we see 1's complement of the magic number.
        !          2183:         * This indicates that the firmware initialization
        !          2184:         * is complete.  We expect this to fail if no SEEPROM
        !          2185:         * is fitted.
        !          2186:         */
        !          2187:        for (i = 0; i < BGE_TIMEOUT; i++) {
        !          2188:                val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
        !          2189:                if (val == ~BGE_MAGIC_NUMBER)
        !          2190:                        break;
        !          2191:                DELAY(10);
        !          2192:        }
        !          2193:
        !          2194:        if (i >= BGE_TIMEOUT && (!(sc->bge_flags & BGE_NO_EEPROM)))
        !          2195:                printf("%s: firmware handshake timed out\n",
        !          2196:                    sc->bge_dev.dv_xname);
        !          2197:
        !          2198:        /*
        !          2199:         * XXX Wait for the value of the PCISTATE register to
        !          2200:         * return to its original pre-reset state. This is a
        !          2201:         * fairly good indicator of reset completion. If we don't
        !          2202:         * wait for the reset to fully complete, trying to read
        !          2203:         * from the device's non-PCI registers may yield garbage
        !          2204:         * results.
        !          2205:         */
        !          2206:        for (i = 0; i < BGE_TIMEOUT; i++) {
        !          2207:                new_pcistate = pci_conf_read(pa->pa_pc, pa->pa_tag,
        !          2208:                    BGE_PCI_PCISTATE);
        !          2209:                if ((new_pcistate & ~BGE_PCISTATE_RESERVED) ==
        !          2210:                    (pcistate & ~BGE_PCISTATE_RESERVED))
        !          2211:                        break;
        !          2212:                DELAY(10);
        !          2213:        }
        !          2214:        if ((new_pcistate & ~BGE_PCISTATE_RESERVED) !=
        !          2215:            (pcistate & ~BGE_PCISTATE_RESERVED)) {
        !          2216:                DPRINTFN(5, ("%s: pcistate failed to revert\n",
        !          2217:                    sc->bge_dev.dv_xname));
        !          2218:        }
        !          2219:
        !          2220:        /* Fix up byte swapping */
        !          2221:        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
        !          2222:
        !          2223:        CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
        !          2224:
        !          2225:        /*
        !          2226:         * The 5704 in TBI mode apparently needs some special
        !          2227:         * adjustment to insure the SERDES drive level is set
        !          2228:         * to 1.2V.
        !          2229:         */
        !          2230:        if (sc->bge_flags & BGE_TBI &&
        !          2231:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
        !          2232:                u_int32_t serdescfg;
        !          2233:
        !          2234:                serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);
        !          2235:                serdescfg = (serdescfg & ~0xFFF) | 0x880;
        !          2236:                CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
        !          2237:        }
        !          2238:
        !          2239:        if (sc->bge_flags & BGE_PCIE &&
        !          2240:            sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
        !          2241:                u_int32_t v;
        !          2242:
        !          2243:                /* Enable PCI Express bug fix */
        !          2244:                v = CSR_READ_4(sc, 0x7c00);
        !          2245:                CSR_WRITE_4(sc, 0x7c00, v | (1<<25));
        !          2246:        }
        !          2247:        DELAY(10000);
        !          2248: }
        !          2249:
        !          2250: /*
        !          2251:  * Frame reception handling. This is called if there's a frame
        !          2252:  * on the receive return list.
        !          2253:  *
        !          2254:  * Note: we have to be able to handle two possibilities here:
        !          2255:  * 1) the frame is from the Jumbo receive ring
        !          2256:  * 2) the frame is from the standard receive ring
        !          2257:  */
        !          2258:
        !          2259: void
        !          2260: bge_rxeof(struct bge_softc *sc)
        !          2261: {
        !          2262:        struct ifnet *ifp;
        !          2263:        int stdcnt = 0, jumbocnt = 0;
        !          2264:        bus_dmamap_t dmamap;
        !          2265:        bus_addr_t offset, toff;
        !          2266:        bus_size_t tlen;
        !          2267:        int tosync;
        !          2268:
        !          2269:        /* Nothing to do */
        !          2270:        if (sc->bge_rx_saved_considx ==
        !          2271:            sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx)
        !          2272:                return;
        !          2273:
        !          2274:        ifp = &sc->arpcom.ac_if;
        !          2275:
        !          2276:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2277:            offsetof(struct bge_ring_data, bge_status_block),
        !          2278:            sizeof (struct bge_status_block),
        !          2279:            BUS_DMASYNC_POSTREAD);
        !          2280:
        !          2281:        offset = offsetof(struct bge_ring_data, bge_rx_return_ring);
        !          2282:        tosync = sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx -
        !          2283:            sc->bge_rx_saved_considx;
        !          2284:
        !          2285:        toff = offset + (sc->bge_rx_saved_considx * sizeof (struct bge_rx_bd));
        !          2286:
        !          2287:        if (tosync < 0) {
        !          2288:                tlen = (sc->bge_return_ring_cnt - sc->bge_rx_saved_considx) *
        !          2289:                    sizeof (struct bge_rx_bd);
        !          2290:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2291:                    toff, tlen, BUS_DMASYNC_POSTREAD);
        !          2292:                tosync = -tosync;
        !          2293:        }
        !          2294:
        !          2295:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2296:            offset, tosync * sizeof (struct bge_rx_bd),
        !          2297:            BUS_DMASYNC_POSTREAD);
        !          2298:
        !          2299:        while(sc->bge_rx_saved_considx !=
        !          2300:            sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx) {
        !          2301:                struct bge_rx_bd        *cur_rx;
        !          2302:                u_int32_t               rxidx;
        !          2303:                struct mbuf             *m = NULL;
        !          2304: #ifdef BGE_CHECKSUM
        !          2305:                int                     sumflags = 0;
        !          2306: #endif
        !          2307:
        !          2308:                cur_rx = &sc->bge_rdata->
        !          2309:                        bge_rx_return_ring[sc->bge_rx_saved_considx];
        !          2310:
        !          2311:                rxidx = cur_rx->bge_idx;
        !          2312:                BGE_INC(sc->bge_rx_saved_considx, sc->bge_return_ring_cnt);
        !          2313:
        !          2314:                if (cur_rx->bge_flags & BGE_RXBDFLAG_JUMBO_RING) {
        !          2315:                        BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT);
        !          2316:                        m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx];
        !          2317:                        sc->bge_cdata.bge_rx_jumbo_chain[rxidx] = NULL;
        !          2318:                        jumbocnt++;
        !          2319:                        if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) {
        !          2320:                                ifp->if_ierrors++;
        !          2321:                                bge_newbuf_jumbo(sc, sc->bge_jumbo, m);
        !          2322:                                continue;
        !          2323:                        }
        !          2324:                        if (bge_newbuf_jumbo(sc, sc->bge_jumbo, NULL)
        !          2325:                            == ENOBUFS) {
        !          2326:                                struct mbuf             *m0;
        !          2327:                                m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
        !          2328:                                    cur_rx->bge_len - ETHER_CRC_LEN +
        !          2329:                                    ETHER_ALIGN, 0, ifp, NULL);
        !          2330:                                bge_newbuf_jumbo(sc, sc->bge_jumbo, m);
        !          2331:                                if (m0 == NULL) {
        !          2332:                                        ifp->if_ierrors++;
        !          2333:                                        continue;
        !          2334:                                }
        !          2335:                                m_adj(m0, ETHER_ALIGN);
        !          2336:                                m = m0;
        !          2337:                        }
        !          2338:                } else {
        !          2339:                        BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT);
        !          2340:                        m = sc->bge_cdata.bge_rx_std_chain[rxidx];
        !          2341:                        sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL;
        !          2342:                        stdcnt++;
        !          2343:                        dmamap = sc->bge_cdata.bge_rx_std_map[rxidx];
        !          2344:                        sc->bge_cdata.bge_rx_std_map[rxidx] = 0;
        !          2345:                        bus_dmamap_unload(sc->bge_dmatag, dmamap);
        !          2346:                        if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) {
        !          2347:                                ifp->if_ierrors++;
        !          2348:                                bge_newbuf_std(sc, sc->bge_std, m, dmamap);
        !          2349:                                continue;
        !          2350:                        }
        !          2351:                        if (bge_newbuf_std(sc, sc->bge_std,
        !          2352:                            NULL, dmamap) == ENOBUFS) {
        !          2353:                                ifp->if_ierrors++;
        !          2354:                                bge_newbuf_std(sc, sc->bge_std, m, dmamap);
        !          2355:                                continue;
        !          2356:                        }
        !          2357:                }
        !          2358:
        !          2359:                ifp->if_ipackets++;
        !          2360: #ifdef __STRICT_ALIGNMENT
        !          2361:                /*
        !          2362:                 * The i386 allows unaligned accesses, but for other
        !          2363:                 * platforms we must make sure the payload is aligned.
        !          2364:                 */
        !          2365:                if (sc->bge_flags & BGE_RX_ALIGNBUG) {
        !          2366:                        bcopy(m->m_data, m->m_data + ETHER_ALIGN,
        !          2367:                            cur_rx->bge_len);
        !          2368:                        m->m_data += ETHER_ALIGN;
        !          2369:                }
        !          2370: #endif
        !          2371:                m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
        !          2372:                m->m_pkthdr.rcvif = ifp;
        !          2373:
        !          2374: #if NBPFILTER > 0
        !          2375:                /*
        !          2376:                 * Handle BPF listeners. Let the BPF user see the packet.
        !          2377:                 */
        !          2378:                if (ifp->if_bpf)
        !          2379:                        bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
        !          2380: #endif
        !          2381:
        !          2382: #ifdef BGE_CHECKSUM
        !          2383:                if ((cur_rx->bge_ip_csum ^ 0xffff) == 0)
        !          2384:                        sumflags |= M_IPV4_CSUM_IN_OK;
        !          2385:                else
        !          2386:                        sumflags |= M_IPV4_CSUM_IN_BAD;
        !          2387:
        !          2388:                if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM) {
        !          2389:                        m->m_pkthdr.csum_data =
        !          2390:                                cur_rx->bge_tcp_udp_csum;
        !          2391:                        m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
        !          2392:                }
        !          2393:
        !          2394:                m->m_pkthdr.csum_flags = sumflags;
        !          2395:                sumflags = 0;
        !          2396: #endif
        !          2397:                ether_input_mbuf(ifp, m);
        !          2398:        }
        !          2399:
        !          2400:        CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
        !          2401:        if (stdcnt)
        !          2402:                CSR_WRITE_4(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
        !          2403:        if (jumbocnt)
        !          2404:                CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
        !          2405: }
        !          2406:
        !          2407: void
        !          2408: bge_txeof(struct bge_softc *sc)
        !          2409: {
        !          2410:        struct bge_tx_bd *cur_tx = NULL;
        !          2411:        struct ifnet *ifp;
        !          2412:        struct txdmamap_pool_entry *dma;
        !          2413:        bus_addr_t offset, toff;
        !          2414:        bus_size_t tlen;
        !          2415:        int tosync;
        !          2416:        struct mbuf *m;
        !          2417:
        !          2418:        /* Nothing to do */
        !          2419:        if (sc->bge_tx_saved_considx ==
        !          2420:            sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx)
        !          2421:                return;
        !          2422:
        !          2423:        ifp = &sc->arpcom.ac_if;
        !          2424:
        !          2425:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2426:            offsetof(struct bge_ring_data, bge_status_block),
        !          2427:            sizeof (struct bge_status_block),
        !          2428:            BUS_DMASYNC_POSTREAD);
        !          2429:
        !          2430:        offset = offsetof(struct bge_ring_data, bge_tx_ring);
        !          2431:        tosync = sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx -
        !          2432:            sc->bge_tx_saved_considx;
        !          2433:
        !          2434:        toff = offset + (sc->bge_tx_saved_considx * sizeof (struct bge_tx_bd));
        !          2435:
        !          2436:        if (tosync < 0) {
        !          2437:                tlen = (BGE_TX_RING_CNT - sc->bge_tx_saved_considx) *
        !          2438:                    sizeof (struct bge_tx_bd);
        !          2439:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2440:                    toff, tlen, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          2441:                tosync = -tosync;
        !          2442:        }
        !          2443:
        !          2444:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
        !          2445:            offset, tosync * sizeof (struct bge_tx_bd),
        !          2446:            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
        !          2447:
        !          2448:        /*
        !          2449:         * Go through our tx ring and free mbufs for those
        !          2450:         * frames that have been sent.
        !          2451:         */
        !          2452:        while (sc->bge_tx_saved_considx !=
        !          2453:            sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx) {
        !          2454:                u_int32_t               idx = 0;
        !          2455:
        !          2456:                idx = sc->bge_tx_saved_considx;
        !          2457:                cur_tx = &sc->bge_rdata->bge_tx_ring[idx];
        !          2458:                if (cur_tx->bge_flags & BGE_TXBDFLAG_END)
        !          2459:                        ifp->if_opackets++;
        !          2460:                m = sc->bge_cdata.bge_tx_chain[idx];
        !          2461:                if (m != NULL) {
        !          2462:                        sc->bge_cdata.bge_tx_chain[idx] = NULL;
        !          2463:                        dma = sc->txdma[idx];
        !          2464:                        bus_dmamap_sync(sc->bge_dmatag, dma->dmamap, 0,
        !          2465:                            dma->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !          2466:                        bus_dmamap_unload(sc->bge_dmatag, dma->dmamap);
        !          2467:                        SLIST_INSERT_HEAD(&sc->txdma_list, dma, link);
        !          2468:                        sc->txdma[idx] = NULL;
        !          2469:
        !          2470:                        m_freem(m);
        !          2471:                }
        !          2472:                sc->bge_txcnt--;
        !          2473:                BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT);
        !          2474:                ifp->if_timer = 0;
        !          2475:        }
        !          2476:
        !          2477:        if (cur_tx != NULL)
        !          2478:                ifp->if_flags &= ~IFF_OACTIVE;
        !          2479: }
        !          2480:
        !          2481: int
        !          2482: bge_intr(void *xsc)
        !          2483: {
        !          2484:        struct bge_softc *sc;
        !          2485:        struct ifnet *ifp;
        !          2486:        u_int32_t statusword;
        !          2487:
        !          2488:        sc = xsc;
        !          2489:        ifp = &sc->arpcom.ac_if;
        !          2490:
        !          2491:        /* It is possible for the interrupt to arrive before
        !          2492:         * the status block is updated prior to the interrupt.
        !          2493:         * Reading the PCI State register will confirm whether the
        !          2494:         * interrupt is ours and will flush the status block.
        !          2495:         */
        !          2496:
        !          2497:        /* read status word from status block */
        !          2498:        statusword = sc->bge_rdata->bge_status_block.bge_status;
        !          2499:
        !          2500:        if ((statusword & BGE_STATFLAG_UPDATED) ||
        !          2501:            (!(CSR_READ_4(sc, BGE_PCI_PCISTATE) & BGE_PCISTATE_INTR_NOT_ACTIVE))) {
        !          2502:
        !          2503:                /* Ack interrupt and stop others from occurring. */
        !          2504:                CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
        !          2505:
        !          2506:                /* clear status word */
        !          2507:                sc->bge_rdata->bge_status_block.bge_status = 0;
        !          2508:
        !          2509:                if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 &&
        !          2510:                    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
        !          2511:                    statusword & BGE_STATFLAG_LINKSTATE_CHANGED ||
        !          2512:                    sc->bge_link_evt)
        !          2513:                        bge_link_upd(sc);
        !          2514:
        !          2515:                if (ifp->if_flags & IFF_RUNNING) {
        !          2516:                        /* Check RX return ring producer/consumer */
        !          2517:                        bge_rxeof(sc);
        !          2518:
        !          2519:                        /* Check TX ring producer/consumer */
        !          2520:                        bge_txeof(sc);
        !          2521:                }
        !          2522:
        !          2523:                /* Re-enable interrupts. */
        !          2524:                CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
        !          2525:
        !          2526:                if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
        !          2527:                        bge_start(ifp);
        !          2528:
        !          2529:                return (1);
        !          2530:        } else
        !          2531:                return (0);
        !          2532: }
        !          2533:
        !          2534: void
        !          2535: bge_tick(void *xsc)
        !          2536: {
        !          2537:        struct bge_softc *sc = xsc;
        !          2538:        struct mii_data *mii = &sc->bge_mii;
        !          2539:        int s;
        !          2540:
        !          2541:        s = splnet();
        !          2542:
        !          2543:        if (BGE_IS_5705_OR_BEYOND(sc))
        !          2544:                bge_stats_update_regs(sc);
        !          2545:        else
        !          2546:                bge_stats_update(sc);
        !          2547:
        !          2548:        if (sc->bge_flags & BGE_TBI) {
        !          2549:                /*
        !          2550:                 * Since in TBI mode auto-polling can't be used we should poll
        !          2551:                 * link status manually. Here we register pending link event
        !          2552:                 * and trigger interrupt.
        !          2553:                 */
        !          2554:                sc->bge_link_evt++;
        !          2555:                BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
        !          2556:        } else
        !          2557:                mii_tick(mii);
        !          2558:
        !          2559:        timeout_add(&sc->bge_timeout, hz);
        !          2560:
        !          2561:        splx(s);
        !          2562: }
        !          2563:
        !          2564: void
        !          2565: bge_stats_update_regs(struct bge_softc *sc)
        !          2566: {
        !          2567:        struct ifnet *ifp;
        !          2568:        struct bge_mac_stats_regs stats;
        !          2569:        u_int32_t *s;
        !          2570:        u_long cnt;
        !          2571:        int i;
        !          2572:
        !          2573:        ifp = &sc->arpcom.ac_if;
        !          2574:
        !          2575:        s = (u_int32_t *)&stats;
        !          2576:        for (i = 0; i < sizeof(struct bge_mac_stats_regs); i += 4) {
        !          2577:                *s = CSR_READ_4(sc, BGE_RX_STATS + i);
        !          2578:                s++;
        !          2579:        }
        !          2580:
        !          2581:        cnt = stats.dot3StatsSingleCollisionFrames +
        !          2582:            stats.dot3StatsMultipleCollisionFrames +
        !          2583:            stats.dot3StatsExcessiveCollisions +
        !          2584:            stats.dot3StatsLateCollisions;
        !          2585:        ifp->if_collisions += cnt >= sc->bge_tx_collisions ?
        !          2586:            cnt - sc->bge_tx_collisions : cnt;
        !          2587:        sc->bge_tx_collisions = cnt;
        !          2588: }
        !          2589:
        !          2590: void
        !          2591: bge_stats_update(struct bge_softc *sc)
        !          2592: {
        !          2593:        struct ifnet *ifp = &sc->arpcom.ac_if;
        !          2594:        bus_size_t stats = BGE_MEMWIN_START + BGE_STATS_BLOCK;
        !          2595:        u_long cnt;
        !          2596:
        !          2597: #define READ_STAT(sc, stats, stat) \
        !          2598:          CSR_READ_4(sc, stats + offsetof(struct bge_stats, stat))
        !          2599:
        !          2600:        cnt = READ_STAT(sc, stats,
        !          2601:            txstats.dot3StatsSingleCollisionFrames.bge_addr_lo);
        !          2602:        cnt += READ_STAT(sc, stats,
        !          2603:            txstats.dot3StatsMultipleCollisionFrames.bge_addr_lo);
        !          2604:        cnt += READ_STAT(sc, stats,
        !          2605:            txstats.dot3StatsExcessiveCollisions.bge_addr_lo);
        !          2606:        cnt += READ_STAT(sc, stats,
        !          2607:                txstats.dot3StatsLateCollisions.bge_addr_lo);
        !          2608:        ifp->if_collisions += cnt >= sc->bge_tx_collisions ?
        !          2609:            cnt - sc->bge_tx_collisions : cnt;
        !          2610:        sc->bge_tx_collisions = cnt;
        !          2611:
        !          2612:        cnt = READ_STAT(sc, stats, ifInDiscards.bge_addr_lo);
        !          2613:        ifp->if_ierrors += cnt >= sc->bge_rx_discards ?
        !          2614:            cnt - sc->bge_rx_discards : cnt;
        !          2615:        sc->bge_rx_discards = cnt;
        !          2616:
        !          2617:        cnt = READ_STAT(sc, stats, txstats.ifOutDiscards.bge_addr_lo);
        !          2618:        ifp->if_oerrors += cnt >= sc->bge_tx_discards ?
        !          2619:            cnt - sc->bge_tx_discards : cnt;
        !          2620:        sc->bge_tx_discards = cnt;
        !          2621:
        !          2622: #undef READ_STAT
        !          2623: }
        !          2624:
        !          2625: /*
        !          2626:  * Compact outbound packets to avoid bug with DMA segments less than 8 bytes.
        !          2627:  */
        !          2628: int
        !          2629: bge_compact_dma_runt(struct mbuf *pkt)
        !          2630: {
        !          2631:        struct mbuf     *m, *prev, *n = NULL;
        !          2632:        int             totlen, prevlen, newprevlen;
        !          2633:
        !          2634:        prev = NULL;
        !          2635:        totlen = 0;
        !          2636:        prevlen = -1;
        !          2637:
        !          2638:        for (m = pkt; m != NULL; prev = m,m = m->m_next) {
        !          2639:                int mlen = m->m_len;
        !          2640:                int shortfall = 8 - mlen ;
        !          2641:
        !          2642:                totlen += mlen;
        !          2643:                if (mlen == 0)
        !          2644:                        continue;
        !          2645:                if (mlen >= 8)
        !          2646:                        continue;
        !          2647:
        !          2648:                /* If we get here, mbuf data is too small for DMA engine.
        !          2649:                 * Try to fix by shuffling data to prev or next in chain.
        !          2650:                 * If that fails, do a compacting deep-copy of the whole chain.
        !          2651:                 */
        !          2652:
        !          2653:                /* Internal frag. If fits in prev, copy it there. */
        !          2654:                if (prev && M_TRAILINGSPACE(prev) >= m->m_len) {
        !          2655:                        bcopy(m->m_data,
        !          2656:                              prev->m_data+prev->m_len,
        !          2657:                              mlen);
        !          2658:                        prev->m_len += mlen;
        !          2659:                        m->m_len = 0;
        !          2660:                        /* XXX stitch chain */
        !          2661:                        prev->m_next = m_free(m);
        !          2662:                        m = prev;
        !          2663:                        continue;
        !          2664:                } else if (m->m_next != NULL &&
        !          2665:                           M_TRAILINGSPACE(m) >= shortfall &&
        !          2666:                           m->m_next->m_len >= (8 + shortfall)) {
        !          2667:                        /* m is writable and have enough data in next, pull up. */
        !          2668:
        !          2669:                        bcopy(m->m_next->m_data,
        !          2670:                              m->m_data+m->m_len,
        !          2671:                              shortfall);
        !          2672:                        m->m_len += shortfall;
        !          2673:                        m->m_next->m_len -= shortfall;
        !          2674:                        m->m_next->m_data += shortfall;
        !          2675:                } else if (m->m_next == NULL || 1) {
        !          2676:                        /* Got a runt at the very end of the packet.
        !          2677:                         * borrow data from the tail of the preceding mbuf and
        !          2678:                         * update its length in-place. (The original data is still
        !          2679:                         * valid, so we can do this even if prev is not writable.)
        !          2680:                         */
        !          2681:
        !          2682:                        /* if we'd make prev a runt, just move all of its data. */
        !          2683: #ifdef DEBUG
        !          2684:                        KASSERT(prev != NULL /*, ("runt but null PREV")*/);
        !          2685:                        KASSERT(prev->m_len >= 8 /*, ("runt prev")*/);
        !          2686: #endif
        !          2687:                        if ((prev->m_len - shortfall) < 8)
        !          2688:                                shortfall = prev->m_len;
        !          2689:
        !          2690:                        newprevlen = prev->m_len - shortfall;
        !          2691:
        !          2692:                        MGET(n, M_NOWAIT, MT_DATA);
        !          2693:                        if (n == NULL)
        !          2694:                                return (ENOBUFS);
        !          2695:                        KASSERT(m->m_len + shortfall < MLEN
        !          2696:                                /*,
        !          2697:                                  ("runt %d +prev %d too big\n", m->m_len, shortfall)*/);
        !          2698:
        !          2699:                        /* first copy the data we're stealing from prev */
        !          2700:                        bcopy(prev->m_data + newprevlen, n->m_data, shortfall);
        !          2701:
        !          2702:                        /* update prev->m_len accordingly */
        !          2703:                        prev->m_len -= shortfall;
        !          2704:
        !          2705:                        /* copy data from runt m */
        !          2706:                        bcopy(m->m_data, n->m_data + shortfall, m->m_len);
        !          2707:
        !          2708:                        /* n holds what we stole from prev, plus m */
        !          2709:                        n->m_len = shortfall + m->m_len;
        !          2710:
        !          2711:                        /* stitch n into chain and free m */
        !          2712:                        n->m_next = m->m_next;
        !          2713:                        prev->m_next = n;
        !          2714:                        /* KASSERT(m->m_next == NULL); */
        !          2715:                        m->m_next = NULL;
        !          2716:                        m_free(m);
        !          2717:                        m = n;  /* for continuing loop */
        !          2718:                }
        !          2719:                prevlen = m->m_len;
        !          2720:        }
        !          2721:        return (0);
        !          2722: }
        !          2723:
        !          2724: /*
        !          2725:  * Encapsulate an mbuf chain in the tx ring by coupling the mbuf data
        !          2726:  * pointers to descriptors.
        !          2727:  */
        !          2728: int
        !          2729: bge_encap(struct bge_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
        !          2730: {
        !          2731:        struct bge_tx_bd        *f = NULL;
        !          2732:        u_int32_t               frag, cur;
        !          2733:        u_int16_t               csum_flags = 0;
        !          2734:        struct txdmamap_pool_entry *dma;
        !          2735:        bus_dmamap_t dmamap;
        !          2736:        int                     i = 0;
        !          2737: #if NVLAN > 0
        !          2738:        struct ifvlan           *ifv = NULL;
        !          2739:
        !          2740:        if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
        !          2741:            m_head->m_pkthdr.rcvif != NULL)
        !          2742:                ifv = m_head->m_pkthdr.rcvif->if_softc;
        !          2743: #endif
        !          2744:
        !          2745:        cur = frag = *txidx;
        !          2746:
        !          2747: #ifdef BGE_CHECKSUM
        !          2748:        if (m_head->m_pkthdr.csum_flags) {
        !          2749:                if (m_head->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
        !          2750:                        csum_flags |= BGE_TXBDFLAG_IP_CSUM;
        !          2751:                if (m_head->m_pkthdr.csum_flags & (M_TCPV4_CSUM_OUT |
        !          2752:                                             M_UDPV4_CSUM_OUT))
        !          2753:                        csum_flags |= BGE_TXBDFLAG_TCP_UDP_CSUM;
        !          2754: #ifdef fake
        !          2755:                if (m_head->m_flags & M_LASTFRAG)
        !          2756:                        csum_flags |= BGE_TXBDFLAG_IP_FRAG_END;
        !          2757:                else if (m_head->m_flags & M_FRAG)
        !          2758:                        csum_flags |= BGE_TXBDFLAG_IP_FRAG;
        !          2759: #endif
        !          2760:        }
        !          2761: #endif
        !          2762:        if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX))
        !          2763:                goto doit;
        !          2764:
        !          2765:        /*
        !          2766:         * bcm5700 Revision B silicon cannot handle DMA descriptors with
        !          2767:         * less than eight bytes.  If we encounter a teeny mbuf
        !          2768:         * at the end of a chain, we can pad.  Otherwise, copy.
        !          2769:         */
        !          2770:        if (bge_compact_dma_runt(m_head) != 0)
        !          2771:                return (ENOBUFS);
        !          2772:
        !          2773: doit:
        !          2774:        dma = SLIST_FIRST(&sc->txdma_list);
        !          2775:        if (dma == NULL)
        !          2776:                return (ENOBUFS);
        !          2777:        dmamap = dma->dmamap;
        !          2778:
        !          2779:        /*
        !          2780:         * Start packing the mbufs in this chain into
        !          2781:         * the fragment pointers. Stop when we run out
        !          2782:         * of fragments or hit the end of the mbuf chain.
        !          2783:         */
        !          2784:        if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_head,
        !          2785:            BUS_DMA_NOWAIT))
        !          2786:                return (ENOBUFS);
        !          2787:
        !          2788:        /*
        !          2789:         * Sanity check: avoid coming within 16 descriptors
        !          2790:         * of the end of the ring.
        !          2791:         */
        !          2792:        if (dmamap->dm_nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16))
        !          2793:                goto fail_unload;
        !          2794:
        !          2795:        for (i = 0; i < dmamap->dm_nsegs; i++) {
        !          2796:                f = &sc->bge_rdata->bge_tx_ring[frag];
        !          2797:                if (sc->bge_cdata.bge_tx_chain[frag] != NULL)
        !          2798:                        break;
        !          2799:                BGE_HOSTADDR(f->bge_addr, dmamap->dm_segs[i].ds_addr);
        !          2800:                f->bge_len = dmamap->dm_segs[i].ds_len;
        !          2801:                f->bge_flags = csum_flags;
        !          2802: #if NVLAN > 0
        !          2803:                if (ifv != NULL) {
        !          2804:                        f->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
        !          2805:                        f->bge_vlan_tag = ifv->ifv_tag;
        !          2806:                } else {
        !          2807:                        f->bge_vlan_tag = 0;
        !          2808:                }
        !          2809: #endif
        !          2810:                cur = frag;
        !          2811:                BGE_INC(frag, BGE_TX_RING_CNT);
        !          2812:        }
        !          2813:
        !          2814:        if (i < dmamap->dm_nsegs)
        !          2815:                goto fail_unload;
        !          2816:
        !          2817:        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
        !          2818:            BUS_DMASYNC_PREWRITE);
        !          2819:
        !          2820:        if (frag == sc->bge_tx_saved_considx)
        !          2821:                goto fail_unload;
        !          2822:
        !          2823:        sc->bge_rdata->bge_tx_ring[cur].bge_flags |= BGE_TXBDFLAG_END;
        !          2824:        sc->bge_cdata.bge_tx_chain[cur] = m_head;
        !          2825:        SLIST_REMOVE_HEAD(&sc->txdma_list, link);
        !          2826:        sc->txdma[cur] = dma;
        !          2827:        sc->bge_txcnt += dmamap->dm_nsegs;
        !          2828:
        !          2829:        *txidx = frag;
        !          2830:
        !          2831:        return (0);
        !          2832:
        !          2833: fail_unload:
        !          2834:        bus_dmamap_unload(sc->bge_dmatag, dmamap);
        !          2835:
        !          2836:        return (ENOBUFS);
        !          2837: }
        !          2838:
        !          2839: /*
        !          2840:  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
        !          2841:  * to the mbuf data regions directly in the transmit descriptors.
        !          2842:  */
        !          2843: void
        !          2844: bge_start(struct ifnet *ifp)
        !          2845: {
        !          2846:        struct bge_softc *sc;
        !          2847:        struct mbuf *m_head = NULL;
        !          2848:        u_int32_t prodidx;
        !          2849:        int pkts = 0;
        !          2850:
        !          2851:        sc = ifp->if_softc;
        !          2852:
        !          2853:        if (!sc->bge_link || IFQ_IS_EMPTY(&ifp->if_snd))
        !          2854:                return;
        !          2855:
        !          2856:        prodidx = sc->bge_tx_prodidx;
        !          2857:
        !          2858:        while (sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
        !          2859:                IFQ_POLL(&ifp->if_snd, m_head);
        !          2860:                if (m_head == NULL)
        !          2861:                        break;
        !          2862:
        !          2863:                /*
        !          2864:                 * Pack the data into the transmit ring. If we
        !          2865:                 * don't have room, set the OACTIVE flag and wait
        !          2866:                 * for the NIC to drain the ring.
        !          2867:                 */
        !          2868:                if (bge_encap(sc, m_head, &prodidx)) {
        !          2869:                        ifp->if_flags |= IFF_OACTIVE;
        !          2870:                        break;
        !          2871:                }
        !          2872:
        !          2873:                /* now we are committed to transmit the packet */
        !          2874:                IFQ_DEQUEUE(&ifp->if_snd, m_head);
        !          2875:                pkts++;
        !          2876:
        !          2877: #if NBPFILTER > 0
        !          2878:                /*
        !          2879:                 * If there's a BPF listener, bounce a copy of this frame
        !          2880:                 * to him.
        !          2881:                 */
        !          2882:                if (ifp->if_bpf)
        !          2883:                        bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
        !          2884: #endif
        !          2885:        }
        !          2886:        if (pkts == 0)
        !          2887:                return;
        !          2888:
        !          2889:        /* Transmit */
        !          2890:        CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
        !          2891:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
        !          2892:                CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
        !          2893:
        !          2894:        sc->bge_tx_prodidx = prodidx;
        !          2895:
        !          2896:        /*
        !          2897:         * Set a timeout in case the chip goes out to lunch.
        !          2898:         */
        !          2899:        ifp->if_timer = 5;
        !          2900: }
        !          2901:
        !          2902: void
        !          2903: bge_init(void *xsc)
        !          2904: {
        !          2905:        struct bge_softc *sc = xsc;
        !          2906:        struct ifnet *ifp;
        !          2907:        u_int16_t *m;
        !          2908:        int s;
        !          2909:
        !          2910:        s = splnet();
        !          2911:
        !          2912:        ifp = &sc->arpcom.ac_if;
        !          2913:
        !          2914:        /* Cancel pending I/O and flush buffers. */
        !          2915:        bge_stop(sc);
        !          2916:        bge_reset(sc);
        !          2917:        bge_chipinit(sc);
        !          2918:
        !          2919:        /*
        !          2920:         * Init the various state machines, ring
        !          2921:         * control blocks and firmware.
        !          2922:         */
        !          2923:        if (bge_blockinit(sc)) {
        !          2924:                printf("%s: initialization failure\n", sc->bge_dev.dv_xname);
        !          2925:                splx(s);
        !          2926:                return;
        !          2927:        }
        !          2928:
        !          2929:        ifp = &sc->arpcom.ac_if;
        !          2930:
        !          2931:        /* Specify MRU. */
        !          2932:        if (BGE_IS_JUMBO_CAPABLE(sc))
        !          2933:                CSR_WRITE_4(sc, BGE_RX_MTU,
        !          2934:                        BGE_JUMBO_FRAMELEN + ETHER_VLAN_ENCAP_LEN);
        !          2935:        else
        !          2936:                CSR_WRITE_4(sc, BGE_RX_MTU,
        !          2937:                        ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
        !          2938:
        !          2939:        /* Load our MAC address. */
        !          2940:        m = (u_int16_t *)&sc->arpcom.ac_enaddr[0];
        !          2941:        CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));
        !          2942:        CSR_WRITE_4(sc, BGE_MAC_ADDR1_HI, (htons(m[1]) << 16) | htons(m[2]));
        !          2943:
        !          2944:        /* Disable hardware decapsulation of vlan frames. */
        !          2945:        BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_KEEP_VLAN_DIAG);
        !          2946:
        !          2947:        /* Program promiscuous mode and multicast filters. */
        !          2948:        bge_iff(sc);
        !          2949:
        !          2950:        /* Init RX ring. */
        !          2951:        bge_init_rx_ring_std(sc);
        !          2952:
        !          2953:        /*
        !          2954:         * Workaround for a bug in 5705 ASIC rev A0. Poll the NIC's
        !          2955:         * memory to insure that the chip has in fact read the first
        !          2956:         * entry of the ring.
        !          2957:         */
        !          2958:        if (sc->bge_chipid == BGE_CHIPID_BCM5705_A0) {
        !          2959:                u_int32_t               v, i;
        !          2960:                for (i = 0; i < 10; i++) {
        !          2961:                        DELAY(20);
        !          2962:                        v = bge_readmem_ind(sc, BGE_STD_RX_RINGS + 8);
        !          2963:                        if (v == (MCLBYTES - ETHER_ALIGN))
        !          2964:                                break;
        !          2965:                }
        !          2966:                if (i == 10)
        !          2967:                        printf("%s: 5705 A0 chip failed to load RX ring\n",
        !          2968:                            sc->bge_dev.dv_xname);
        !          2969:        }
        !          2970:
        !          2971:        /* Init Jumbo RX ring. */
        !          2972:        if (BGE_IS_JUMBO_CAPABLE(sc))
        !          2973:                bge_init_rx_ring_jumbo(sc);
        !          2974:
        !          2975:        /* Init our RX return ring index */
        !          2976:        sc->bge_rx_saved_considx = 0;
        !          2977:
        !          2978:        /* Init TX ring. */
        !          2979:        bge_init_tx_ring(sc);
        !          2980:
        !          2981:        /* Turn on transmitter */
        !          2982:        BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);
        !          2983:
        !          2984:        /* Turn on receiver */
        !          2985:        BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
        !          2986:
        !          2987:        CSR_WRITE_4(sc, BGE_MAX_RX_FRAME_LOWAT, 2);
        !          2988:
        !          2989:        /* Tell firmware we're alive. */
        !          2990:        BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
        !          2991:
        !          2992:        /* Enable host interrupts. */
        !          2993:        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
        !          2994:        BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
        !          2995:        CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
        !          2996:
        !          2997:        bge_ifmedia_upd(ifp);
        !          2998:
        !          2999:        ifp->if_flags |= IFF_RUNNING;
        !          3000:        ifp->if_flags &= ~IFF_OACTIVE;
        !          3001:
        !          3002:        splx(s);
        !          3003:
        !          3004:        timeout_add(&sc->bge_timeout, hz);
        !          3005: }
        !          3006:
        !          3007: /*
        !          3008:  * Set media options.
        !          3009:  */
        !          3010: int
        !          3011: bge_ifmedia_upd(struct ifnet *ifp)
        !          3012: {
        !          3013:        struct bge_softc *sc = ifp->if_softc;
        !          3014:        struct mii_data *mii = &sc->bge_mii;
        !          3015:        struct ifmedia *ifm = &sc->bge_ifmedia;
        !          3016:
        !          3017:        /* If this is a 1000baseX NIC, enable the TBI port. */
        !          3018:        if (sc->bge_flags & BGE_TBI) {
        !          3019:                if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
        !          3020:                        return (EINVAL);
        !          3021:                switch(IFM_SUBTYPE(ifm->ifm_media)) {
        !          3022:                case IFM_AUTO:
        !          3023:                        /*
        !          3024:                         * The BCM5704 ASIC appears to have a special
        !          3025:                         * mechanism for programming the autoneg
        !          3026:                         * advertisement registers in TBI mode.
        !          3027:                         */
        !          3028:                        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
        !          3029:                                u_int32_t sgdig;
        !          3030:                                CSR_WRITE_4(sc, BGE_TX_TBI_AUTONEG, 0);
        !          3031:                                sgdig = CSR_READ_4(sc, BGE_SGDIG_CFG);
        !          3032:                                sgdig |= BGE_SGDIGCFG_AUTO|
        !          3033:                                    BGE_SGDIGCFG_PAUSE_CAP|
        !          3034:                                    BGE_SGDIGCFG_ASYM_PAUSE;
        !          3035:                                CSR_WRITE_4(sc, BGE_SGDIG_CFG,
        !          3036:                                    sgdig|BGE_SGDIGCFG_SEND);
        !          3037:                                DELAY(5);
        !          3038:                                CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
        !          3039:                        }
        !          3040:                        break;
        !          3041:                case IFM_1000_SX:
        !          3042:                        if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
        !          3043:                                BGE_CLRBIT(sc, BGE_MAC_MODE,
        !          3044:                                    BGE_MACMODE_HALF_DUPLEX);
        !          3045:                        } else {
        !          3046:                                BGE_SETBIT(sc, BGE_MAC_MODE,
        !          3047:                                    BGE_MACMODE_HALF_DUPLEX);
        !          3048:                        }
        !          3049:                        break;
        !          3050:                default:
        !          3051:                        return (EINVAL);
        !          3052:                }
        !          3053:                /* XXX 802.3x flow control for 1000BASE-SX */
        !          3054:                return (0);
        !          3055:        }
        !          3056:
        !          3057:        sc->bge_link_evt++;
        !          3058:        if (mii->mii_instance) {
        !          3059:                struct mii_softc *miisc;
        !          3060:                LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
        !          3061:                        mii_phy_reset(miisc);
        !          3062:        }
        !          3063:        mii_mediachg(mii);
        !          3064:
        !          3065:        return (0);
        !          3066: }
        !          3067:
        !          3068: /*
        !          3069:  * Report current media status.
        !          3070:  */
        !          3071: void
        !          3072: bge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
        !          3073: {
        !          3074:        struct bge_softc *sc = ifp->if_softc;
        !          3075:        struct mii_data *mii = &sc->bge_mii;
        !          3076:
        !          3077:        if (sc->bge_flags & BGE_TBI) {
        !          3078:                ifmr->ifm_status = IFM_AVALID;
        !          3079:                ifmr->ifm_active = IFM_ETHER;
        !          3080:                if (CSR_READ_4(sc, BGE_MAC_STS) &
        !          3081:                    BGE_MACSTAT_TBI_PCS_SYNCHED) {
        !          3082:                        ifmr->ifm_status |= IFM_ACTIVE;
        !          3083:                } else {
        !          3084:                        ifmr->ifm_active |= IFM_NONE;
        !          3085:                        return;
        !          3086:                }
        !          3087:                ifmr->ifm_active |= IFM_1000_SX;
        !          3088:                if (CSR_READ_4(sc, BGE_MAC_MODE) & BGE_MACMODE_HALF_DUPLEX)
        !          3089:                        ifmr->ifm_active |= IFM_HDX;
        !          3090:                else
        !          3091:                        ifmr->ifm_active |= IFM_FDX;
        !          3092:                return;
        !          3093:        }
        !          3094:
        !          3095:        mii_pollstat(mii);
        !          3096:        ifmr->ifm_status = mii->mii_media_status;
        !          3097:        ifmr->ifm_active = (mii->mii_media_active & ~IFM_ETH_FMASK) |
        !          3098:            sc->bge_flowflags;
        !          3099: }
        !          3100:
        !          3101: int
        !          3102: bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
        !          3103: {
        !          3104:        struct bge_softc *sc = ifp->if_softc;
        !          3105:        struct ifreq *ifr = (struct ifreq *) data;
        !          3106:        struct ifaddr *ifa = (struct ifaddr *)data;
        !          3107:        int s, error = 0;
        !          3108:        struct mii_data *mii;
        !          3109:
        !          3110:        s = splnet();
        !          3111:
        !          3112:        if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {
        !          3113:                splx(s);
        !          3114:                return (error);
        !          3115:        }
        !          3116:
        !          3117:        switch(command) {
        !          3118:        case SIOCSIFADDR:
        !          3119:                ifp->if_flags |= IFF_UP;
        !          3120:                if (!(ifp->if_flags & IFF_RUNNING))
        !          3121:                        bge_init(sc);
        !          3122: #ifdef INET
        !          3123:                if (ifa->ifa_addr->sa_family == AF_INET)
        !          3124:                        arp_ifinit(&sc->arpcom, ifa);
        !          3125: #endif /* INET */
        !          3126:                break;
        !          3127:        case SIOCSIFMTU:
        !          3128:                if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
        !          3129:                        error = EINVAL;
        !          3130:                else if (ifp->if_mtu != ifr->ifr_mtu)
        !          3131:                        ifp->if_mtu = ifr->ifr_mtu;
        !          3132:                break;
        !          3133:        case SIOCSIFFLAGS:
        !          3134:                if (ifp->if_flags & IFF_UP) {
        !          3135:                        if (ifp->if_flags & IFF_RUNNING)
        !          3136:                                bge_iff(sc);
        !          3137:                        else
        !          3138:                                bge_init(sc);
        !          3139:                } else {
        !          3140:                        if (ifp->if_flags & IFF_RUNNING)
        !          3141:                                bge_stop(sc);
        !          3142:                }
        !          3143:                sc->bge_if_flags = ifp->if_flags;
        !          3144:                break;
        !          3145:        case SIOCADDMULTI:
        !          3146:        case SIOCDELMULTI:
        !          3147:                error = (command == SIOCADDMULTI)
        !          3148:                        ? ether_addmulti(ifr, &sc->arpcom)
        !          3149:                        : ether_delmulti(ifr, &sc->arpcom);
        !          3150:
        !          3151:                if (error == ENETRESET) {
        !          3152:                        if (ifp->if_flags & IFF_RUNNING)
        !          3153:                                bge_iff(sc);
        !          3154:                        error = 0;
        !          3155:                }
        !          3156:                break;
        !          3157:        case SIOCSIFMEDIA:
        !          3158:                /* XXX Flow control is not supported for 1000BASE-SX */
        !          3159:                if (sc->bge_flags & BGE_TBI) {
        !          3160:                        ifr->ifr_media &= ~IFM_ETH_FMASK;
        !          3161:                        sc->bge_flowflags = 0;
        !          3162:                }
        !          3163:
        !          3164:                /* Flow control requires full-duplex mode. */
        !          3165:                if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
        !          3166:                    (ifr->ifr_media & IFM_FDX) == 0) {
        !          3167:                        ifr->ifr_media &= ~IFM_ETH_FMASK;
        !          3168:                }
        !          3169:                if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
        !          3170:                        if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
        !          3171:                                /* We can do both TXPAUSE and RXPAUSE. */
        !          3172:                                ifr->ifr_media |=
        !          3173:                                    IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
        !          3174:                        }
        !          3175:                        sc->bge_flowflags = ifr->ifr_media & IFM_ETH_FMASK;
        !          3176:                }
        !          3177:                /* FALLTHROUGH */
        !          3178:        case SIOCGIFMEDIA:
        !          3179:                if (sc->bge_flags & BGE_TBI) {
        !          3180:                        error = ifmedia_ioctl(ifp, ifr, &sc->bge_ifmedia,
        !          3181:                            command);
        !          3182:                } else {
        !          3183:                        mii = &sc->bge_mii;
        !          3184:                        error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
        !          3185:                            command);
        !          3186:                }
        !          3187:                break;
        !          3188:        default:
        !          3189:                error = ENOTTY;
        !          3190:                break;
        !          3191:        }
        !          3192:
        !          3193:        splx(s);
        !          3194:
        !          3195:        return (error);
        !          3196: }
        !          3197:
        !          3198: void
        !          3199: bge_watchdog(struct ifnet *ifp)
        !          3200: {
        !          3201:        struct bge_softc *sc;
        !          3202:
        !          3203:        sc = ifp->if_softc;
        !          3204:
        !          3205:        printf("%s: watchdog timeout -- resetting\n", sc->bge_dev.dv_xname);
        !          3206:
        !          3207:        bge_init(sc);
        !          3208:
        !          3209:        ifp->if_oerrors++;
        !          3210: }
        !          3211:
        !          3212: void
        !          3213: bge_stop_block(struct bge_softc *sc, bus_size_t reg, u_int32_t bit)
        !          3214: {
        !          3215:        int i;
        !          3216:
        !          3217:        BGE_CLRBIT(sc, reg, bit);
        !          3218:
        !          3219:        for (i = 0; i < BGE_TIMEOUT; i++) {
        !          3220:                if ((CSR_READ_4(sc, reg) & bit) == 0)
        !          3221:                        return;
        !          3222:                delay(100);
        !          3223:        }
        !          3224:
        !          3225:        DPRINTFN(5, ("%s: block failed to stop: reg 0x%lx, bit 0x%08x\n",
        !          3226:            sc->bge_dev.dv_xname, (u_long) reg, bit));
        !          3227: }
        !          3228:
        !          3229: /*
        !          3230:  * Stop the adapter and free any mbufs allocated to the
        !          3231:  * RX and TX lists.
        !          3232:  */
        !          3233: void
        !          3234: bge_stop(struct bge_softc *sc)
        !          3235: {
        !          3236:        struct ifnet *ifp = &sc->arpcom.ac_if;
        !          3237:        struct ifmedia_entry *ifm;
        !          3238:        struct mii_data *mii;
        !          3239:        int mtmp, itmp;
        !          3240:
        !          3241:        timeout_del(&sc->bge_timeout);
        !          3242:
        !          3243:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
        !          3244:
        !          3245:        /*
        !          3246:         * Disable all of the receiver blocks
        !          3247:         */
        !          3248:        bge_stop_block(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
        !          3249:        bge_stop_block(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
        !          3250:        bge_stop_block(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
        !          3251:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          3252:                bge_stop_block(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
        !          3253:        bge_stop_block(sc, BGE_RDBDI_MODE, BGE_RBDIMODE_ENABLE);
        !          3254:        bge_stop_block(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
        !          3255:        bge_stop_block(sc, BGE_RBDC_MODE, BGE_RBDCMODE_ENABLE);
        !          3256:
        !          3257:        /*
        !          3258:         * Disable all of the transmit blocks
        !          3259:         */
        !          3260:        bge_stop_block(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
        !          3261:        bge_stop_block(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
        !          3262:        bge_stop_block(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
        !          3263:        bge_stop_block(sc, BGE_RDMA_MODE, BGE_RDMAMODE_ENABLE);
        !          3264:        bge_stop_block(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE);
        !          3265:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          3266:                bge_stop_block(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
        !          3267:        bge_stop_block(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
        !          3268:
        !          3269:        /*
        !          3270:         * Shut down all of the memory managers and related
        !          3271:         * state machines.
        !          3272:         */
        !          3273:        bge_stop_block(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
        !          3274:        bge_stop_block(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);
        !          3275:        if (!(BGE_IS_5705_OR_BEYOND(sc)))
        !          3276:                bge_stop_block(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
        !          3277:
        !          3278:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
        !          3279:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
        !          3280:
        !          3281:        if (!(BGE_IS_5705_OR_BEYOND(sc))) {
        !          3282:                bge_stop_block(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE);
        !          3283:                bge_stop_block(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
        !          3284:        }
        !          3285:
        !          3286:        /* Disable host interrupts. */
        !          3287:        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
        !          3288:        CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
        !          3289:
        !          3290:        /*
        !          3291:         * Tell firmware we're shutting down.
        !          3292:         */
        !          3293:        BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
        !          3294:
        !          3295:        /* Free the RX lists. */
        !          3296:        bge_free_rx_ring_std(sc);
        !          3297:
        !          3298:        /* Free jumbo RX list. */
        !          3299:        if (BGE_IS_JUMBO_CAPABLE(sc))
        !          3300:                bge_free_rx_ring_jumbo(sc);
        !          3301:
        !          3302:        /* Free TX buffers. */
        !          3303:        bge_free_tx_ring(sc);
        !          3304:
        !          3305:        /*
        !          3306:         * Isolate/power down the PHY, but leave the media selection
        !          3307:         * unchanged so that things will be put back to normal when
        !          3308:         * we bring the interface back up.
        !          3309:         */
        !          3310:        if (!(sc->bge_flags & BGE_TBI)) {
        !          3311:                mii = &sc->bge_mii;
        !          3312:                itmp = ifp->if_flags;
        !          3313:                ifp->if_flags |= IFF_UP;
        !          3314:                ifm = mii->mii_media.ifm_cur;
        !          3315:                mtmp = ifm->ifm_media;
        !          3316:                ifm->ifm_media = IFM_ETHER|IFM_NONE;
        !          3317:                mii_mediachg(mii);
        !          3318:                ifm->ifm_media = mtmp;
        !          3319:                ifp->if_flags = itmp;
        !          3320:        }
        !          3321:
        !          3322:        sc->bge_tx_saved_considx = BGE_TXCONS_UNSET;
        !          3323:
        !          3324:        /*
        !          3325:         * We can't just call bge_link_upd() cause chip is almost stopped so
        !          3326:         * bge_link_upd -> bge_tick_locked -> bge_stats_update sequence may
        !          3327:         * lead to hardware deadlock. So we just clearing MAC's link state
        !          3328:         * (PHY may still have link UP).
        !          3329:         */
        !          3330:        sc->bge_link = 0;
        !          3331: }
        !          3332:
        !          3333: /*
        !          3334:  * Stop all chip I/O so that the kernel's probe routines don't
        !          3335:  * get confused by errant DMAs when rebooting.
        !          3336:  */
        !          3337: void
        !          3338: bge_shutdown(void *xsc)
        !          3339: {
        !          3340:        struct bge_softc *sc = (struct bge_softc *)xsc;
        !          3341:
        !          3342:        bge_stop(sc);
        !          3343:        bge_reset(sc);
        !          3344: }
        !          3345:
        !          3346: void
        !          3347: bge_link_upd(struct bge_softc *sc)
        !          3348: {
        !          3349:        struct ifnet *ifp = &sc->arpcom.ac_if;
        !          3350:        struct mii_data *mii = &sc->bge_mii;
        !          3351:        u_int32_t link, status;
        !          3352:
        !          3353:        /* Clear 'pending link event' flag */
        !          3354:        sc->bge_link_evt = 0;
        !          3355:
        !          3356:        /*
        !          3357:         * Process link state changes.
        !          3358:         * Grrr. The link status word in the status block does
        !          3359:         * not work correctly on the BCM5700 rev AX and BX chips,
        !          3360:         * according to all available information. Hence, we have
        !          3361:         * to enable MII interrupts in order to properly obtain
        !          3362:         * async link changes. Unfortunately, this also means that
        !          3363:         * we have to read the MAC status register to detect link
        !          3364:         * changes, thereby adding an additional register access to
        !          3365:         * the interrupt handler.
        !          3366:         *
        !          3367:         * XXX: perhaps link state detection procedure used for
        !          3368:         * BGE_CHIPID_BCM5700_B2 can be used for other BCM5700 revisions.
        !          3369:         */
        !          3370:
        !          3371:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 &&
        !          3372:            sc->bge_chipid != BGE_CHIPID_BCM5700_B2) {
        !          3373:                status = CSR_READ_4(sc, BGE_MAC_STS);
        !          3374:                if (status & BGE_MACSTAT_MI_INTERRUPT) {
        !          3375:                        timeout_del(&sc->bge_timeout);
        !          3376:                        bge_tick(sc);
        !          3377:
        !          3378:                        if (!sc->bge_link &&
        !          3379:                            mii->mii_media_status & IFM_ACTIVE &&
        !          3380:                            IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
        !          3381:                                sc->bge_link++;
        !          3382:                        } else if (sc->bge_link &&
        !          3383:                            (!(mii->mii_media_status & IFM_ACTIVE) ||
        !          3384:                            IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE)) {
        !          3385:                                sc->bge_link = 0;
        !          3386:                        }
        !          3387:
        !          3388:                        /* Clear the interrupt */
        !          3389:                        CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
        !          3390:                            BGE_EVTENB_MI_INTERRUPT);
        !          3391:                        bge_miibus_readreg(&sc->bge_dev, 1, BRGPHY_MII_ISR);
        !          3392:                        bge_miibus_writereg(&sc->bge_dev, 1, BRGPHY_MII_IMR,
        !          3393:                            BRGPHY_INTRS);
        !          3394:                }
        !          3395:                return;
        !          3396:        }
        !          3397:
        !          3398:        if (sc->bge_flags & BGE_TBI) {
        !          3399:                status = CSR_READ_4(sc, BGE_MAC_STS);
        !          3400:                if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {
        !          3401:                        if (!sc->bge_link) {
        !          3402:                                sc->bge_link++;
        !          3403:                                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
        !          3404:                                        BGE_CLRBIT(sc, BGE_MAC_MODE,
        !          3405:                                            BGE_MACMODE_TBI_SEND_CFGS);
        !          3406:                                CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
        !          3407:                                status = CSR_READ_4(sc, BGE_MAC_MODE);
        !          3408:                                ifp->if_link_state =
        !          3409:                                    (status & BGE_MACMODE_HALF_DUPLEX) ?
        !          3410:                                    LINK_STATE_HALF_DUPLEX :
        !          3411:                                    LINK_STATE_FULL_DUPLEX;
        !          3412:                                if_link_state_change(ifp);
        !          3413:                        }
        !          3414:                } else if (sc->bge_link) {
        !          3415:                        sc->bge_link = 0;
        !          3416:                        ifp->if_link_state = LINK_STATE_DOWN;
        !          3417:                        if_link_state_change(ifp);
        !          3418:                }
        !          3419:        /* Discard link events for MII/GMII cards if MI auto-polling disabled */
        !          3420:        } else if (CSR_READ_4(sc, BGE_MI_MODE) & BGE_MIMODE_AUTOPOLL) {
        !          3421:                /*
        !          3422:                 * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED bit
        !          3423:                 * in status word always set. Workaround this bug by reading
        !          3424:                 * PHY link status directly.
        !          3425:                 */
        !          3426:                link = (CSR_READ_4(sc, BGE_MI_STS) & BGE_MISTS_LINK) ? 1 : 0;
        !          3427:
        !          3428:                if (link != sc->bge_link ||
        !          3429:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700) {
        !          3430:                        timeout_del(&sc->bge_timeout);
        !          3431:                        bge_tick(sc);
        !          3432:
        !          3433:                        if (!sc->bge_link &&
        !          3434:                            mii->mii_media_status & IFM_ACTIVE &&
        !          3435:                            IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
        !          3436:                                sc->bge_link++;
        !          3437:                        else if (sc->bge_link &&
        !          3438:                            (!(mii->mii_media_status & IFM_ACTIVE) ||
        !          3439:                            IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
        !          3440:                                sc->bge_link = 0;
        !          3441:                }
        !          3442:        }
        !          3443:
        !          3444:        /* Clear the attention */
        !          3445:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
        !          3446:            BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
        !          3447:            BGE_MACSTAT_LINK_CHANGED);
        !          3448: }
        !          3449:
        !          3450: void
        !          3451: bge_power(int why, void *xsc)
        !          3452: {
        !          3453:        struct bge_softc *sc = (struct bge_softc *)xsc;
        !          3454:        struct ifnet *ifp;
        !          3455:
        !          3456:        if (why == PWR_RESUME) {
        !          3457:                ifp = &sc->arpcom.ac_if;
        !          3458:                if (ifp->if_flags & IFF_UP) {
        !          3459:                        bge_init(xsc);
        !          3460:                        if (ifp->if_flags & IFF_RUNNING)
        !          3461:                                bge_start(ifp);
        !          3462:                }
        !          3463:        }
        !          3464: }

CVSweb