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

Annotation of src/sys/dev/pci/if_bge.c, Revision 1.186

1.186   ! msaitoh     1: /*     $NetBSD: if_bge.c,v 1.185 2010/06/03 00:05:36 msaitoh Exp $     */
1.8       thorpej     2:
1.1       fvdl        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.13 2002/04/04 06:01:31 wpaul Exp $
                     36:  */
                     37:
                     38: /*
1.12      thorpej    39:  * Broadcom BCM570x family gigabit ethernet driver for NetBSD.
1.1       fvdl       40:  *
1.12      thorpej    41:  * NetBSD version by:
                     42:  *
                     43:  *     Frank van der Linden <fvdl@wasabisystems.com>
                     44:  *     Jason Thorpe <thorpej@wasabisystems.com>
1.32      tron       45:  *     Jonathan Stone <jonathan@dsg.stanford.edu>
1.12      thorpej    46:  *
                     47:  * Originally written for FreeBSD by Bill Paul <wpaul@windriver.com>
1.1       fvdl       48:  * Senior Engineer, Wind River Systems
                     49:  */
                     50:
                     51: /*
                     52:  * The Broadcom BCM5700 is based on technology originally developed by
                     53:  * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet
                     54:  * MAC chips. The BCM5700, sometimes refered to as the Tigon III, has
                     55:  * two on-board MIPS R4000 CPUs and can have as much as 16MB of external
                     56:  * SSRAM. The BCM5700 supports TCP, UDP and IP checksum offload, jumbo
                     57:  * frames, highly configurable RX filtering, and 16 RX and TX queues
                     58:  * (which, along with RX filter rules, can be used for QOS applications).
                     59:  * Other features, such as TCP segmentation, may be available as part
                     60:  * of value-added firmware updates. Unlike the Tigon I and Tigon II,
                     61:  * firmware images can be stored in hardware and need not be compiled
                     62:  * into the driver.
                     63:  *
                     64:  * The BCM5700 supports the PCI v2.2 and PCI-X v1.0 standards, and will
1.33      tsutsui    65:  * function in a 32-bit/64-bit 33/66MHz bus, or a 64-bit/133MHz bus.
1.1       fvdl       66:  *
                     67:  * The BCM5701 is a single-chip solution incorporating both the BCM5700
1.25      jonathan   68:  * MAC and a BCM5401 10/100/1000 PHY. Unlike the BCM5700, the BCM5701
1.1       fvdl       69:  * does not support external SSRAM.
                     70:  *
                     71:  * Broadcom also produces a variation of the BCM5700 under the "Altima"
                     72:  * brand name, which is functionally similar but lacks PCI-X support.
                     73:  *
                     74:  * Without external SSRAM, you can only have at most 4 TX rings,
                     75:  * and the use of the mini RX ring is disabled. This seems to imply
                     76:  * that these features are simply not available on the BCM5701. As a
                     77:  * result, this driver does not implement any support for the mini RX
                     78:  * ring.
                     79:  */
1.43      lukem      80:
                     81: #include <sys/cdefs.h>
1.186   ! msaitoh    82: __KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.185 2010/06/03 00:05:36 msaitoh Exp $");
1.1       fvdl       83:
                     84: #include "vlan.h"
1.148     mlelstv    85: #include "rnd.h"
1.1       fvdl       86:
                     87: #include <sys/param.h>
                     88: #include <sys/systm.h>
                     89: #include <sys/callout.h>
                     90: #include <sys/sockio.h>
                     91: #include <sys/mbuf.h>
                     92: #include <sys/malloc.h>
                     93: #include <sys/kernel.h>
                     94: #include <sys/device.h>
                     95: #include <sys/socket.h>
1.64      jonathan   96: #include <sys/sysctl.h>
1.1       fvdl       97:
                     98: #include <net/if.h>
                     99: #include <net/if_dl.h>
                    100: #include <net/if_media.h>
                    101: #include <net/if_ether.h>
                    102:
1.148     mlelstv   103: #if NRND > 0
                    104: #include <sys/rnd.h>
                    105: #endif
                    106:
1.1       fvdl      107: #ifdef INET
                    108: #include <netinet/in.h>
                    109: #include <netinet/in_systm.h>
                    110: #include <netinet/in_var.h>
                    111: #include <netinet/ip.h>
                    112: #endif
                    113:
1.95      jonathan  114: /* Headers for TCP  Segmentation Offload (TSO) */
                    115: #include <netinet/in_systm.h>          /* n_time for <netinet/ip.h>... */
                    116: #include <netinet/in.h>                        /* ip_{src,dst}, for <netinet/ip.h> */
                    117: #include <netinet/ip.h>                        /* for struct ip */
                    118: #include <netinet/tcp.h>               /* for struct tcphdr */
                    119:
                    120:
1.1       fvdl      121: #include <net/bpf.h>
                    122:
                    123: #include <dev/pci/pcireg.h>
                    124: #include <dev/pci/pcivar.h>
                    125: #include <dev/pci/pcidevs.h>
                    126:
                    127: #include <dev/mii/mii.h>
                    128: #include <dev/mii/miivar.h>
                    129: #include <dev/mii/miidevs.h>
                    130: #include <dev/mii/brgphyreg.h>
                    131:
                    132: #include <dev/pci/if_bgereg.h>
1.164     msaitoh   133: #include <dev/pci/if_bgevar.h>
1.1       fvdl      134:
                    135: #include <uvm/uvm_extern.h>
1.164     msaitoh   136: #include <prop/proplib.h>
1.1       fvdl      137:
1.46      jonathan  138: #define ETHER_MIN_NOPAD (ETHER_MIN_LEN - ETHER_CRC_LEN) /* i.e., 60 */
                    139:
1.63      jonathan  140:
                    141: /*
                    142:  * Tunable thresholds for rx-side bge interrupt mitigation.
                    143:  */
                    144:
                    145: /*
                    146:  * The pairs of values below were obtained from empirical measurement
                    147:  * on bcm5700 rev B2; they ar designed to give roughly 1 receive
                    148:  * interrupt for every N packets received, where N is, approximately,
                    149:  * the second value (rx_max_bds) in each pair.  The values are chosen
                    150:  * such that moving from one pair to the succeeding pair was observed
                    151:  * to roughly halve interrupt rate under sustained input packet load.
                    152:  * The values were empirically chosen to avoid overflowing internal
1.184     njoly     153:  * limits on the  bcm5700: increasing rx_ticks much beyond 600
1.63      jonathan  154:  * results in internal wrapping and higher interrupt rates.
                    155:  * The limit of 46 frames was chosen to match NFS workloads.
1.87      perry     156:  *
1.63      jonathan  157:  * These values also work well on bcm5701, bcm5704C, and (less
                    158:  * tested) bcm5703.  On other chipsets, (including the Altima chip
                    159:  * family), the larger values may overflow internal chip limits,
                    160:  * leading to increasing interrupt rates rather than lower interrupt
                    161:  * rates.
                    162:  *
                    163:  * Applications using heavy interrupt mitigation (interrupting every
                    164:  * 32 or 46 frames) in both directions may need to increase the TCP
                    165:  * windowsize to above 131072 bytes (e.g., to 199608 bytes) to sustain
1.87      perry     166:  * full link bandwidth, due to ACKs and window updates lingering
1.63      jonathan  167:  * in the RX queue during the 30-to-40-frame interrupt-mitigation window.
                    168:  */
1.104     thorpej   169: static const struct bge_load_rx_thresh {
1.63      jonathan  170:        int rx_ticks;
                    171:        int rx_max_bds; }
                    172: bge_rx_threshes[] = {
                    173:        { 32,   2 },
                    174:        { 50,   4 },
                    175:        { 100,  8 },
                    176:        { 192, 16 },
                    177:        { 416, 32 },
                    178:        { 598, 46 }
                    179: };
                    180: #define NBGE_RX_THRESH (sizeof(bge_rx_threshes) / sizeof(bge_rx_threshes[0]))
                    181:
                    182: /* XXX patchable; should be sysctl'able */
1.177     msaitoh   183: static int bge_auto_thresh = 1;
                    184: static int bge_rx_thresh_lvl;
1.64      jonathan  185:
1.177     msaitoh   186: static int bge_rxthresh_nodenum;
1.1       fvdl      187:
1.170     msaitoh   188: typedef int (*bge_eaddr_fcn_t)(struct bge_softc *, uint8_t[]);
1.151     cegger    189:
1.177     msaitoh   190: static int bge_probe(device_t, cfdata_t, void *);
                    191: static void bge_attach(device_t, device_t, void *);
                    192: static void bge_release_resources(struct bge_softc *);
                    193:
                    194: static int bge_get_eaddr_fw(struct bge_softc *, uint8_t[]);
                    195: static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
                    196: static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
                    197: static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
                    198: static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
                    199:
                    200: static void bge_txeof(struct bge_softc *);
                    201: static void bge_rxeof(struct bge_softc *);
                    202:
                    203: static void bge_asf_driver_up (struct bge_softc *);
                    204: static void bge_tick(void *);
                    205: static void bge_stats_update(struct bge_softc *);
                    206: static void bge_stats_update_regs(struct bge_softc *);
                    207: static int bge_encap(struct bge_softc *, struct mbuf *, uint32_t *);
                    208:
                    209: static int bge_intr(void *);
                    210: static void bge_start(struct ifnet *);
1.186   ! msaitoh   211: static int bge_ifflags_cb(struct ethercom *);
1.177     msaitoh   212: static int bge_ioctl(struct ifnet *, u_long, void *);
                    213: static int bge_init(struct ifnet *);
                    214: static void bge_stop(struct ifnet *, int);
                    215: static void bge_watchdog(struct ifnet *);
                    216: static int bge_ifmedia_upd(struct ifnet *);
                    217: static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
                    218:
                    219: static uint8_t bge_nvram_getbyte(struct bge_softc *, int, uint8_t *);
                    220: static int bge_read_nvram(struct bge_softc *, uint8_t *, int, int);
                    221:
                    222: static uint8_t bge_eeprom_getbyte(struct bge_softc *, int, uint8_t *);
                    223: static int bge_read_eeprom(struct bge_softc *, void *, int, int);
                    224: static void bge_setmulti(struct bge_softc *);
1.104     thorpej   225:
1.177     msaitoh   226: static void bge_handle_events(struct bge_softc *);
                    227: static int bge_alloc_jumbo_mem(struct bge_softc *);
1.104     thorpej   228: #if 0 /* XXX */
1.177     msaitoh   229: static void bge_free_jumbo_mem(struct bge_softc *);
1.1       fvdl      230: #endif
1.177     msaitoh   231: static void *bge_jalloc(struct bge_softc *);
                    232: static void bge_jfree(struct mbuf *, void *, size_t, void *);
                    233: static int bge_newbuf_std(struct bge_softc *, int, struct mbuf *,
1.104     thorpej   234:                               bus_dmamap_t);
1.177     msaitoh   235: static int bge_newbuf_jumbo(struct bge_softc *, int, struct mbuf *);
                    236: static int bge_init_rx_ring_std(struct bge_softc *);
                    237: static void bge_free_rx_ring_std(struct bge_softc *);
                    238: static int bge_init_rx_ring_jumbo(struct bge_softc *);
                    239: static void bge_free_rx_ring_jumbo(struct bge_softc *);
                    240: static void bge_free_tx_ring(struct bge_softc *);
                    241: static int bge_init_tx_ring(struct bge_softc *);
                    242:
                    243: static int bge_chipinit(struct bge_softc *);
                    244: static int bge_blockinit(struct bge_softc *);
                    245: static int bge_setpowerstate(struct bge_softc *, int);
                    246: static uint32_t bge_readmem_ind(struct bge_softc *, int);
                    247: static void bge_writemem_ind(struct bge_softc *, int, int);
                    248: static void bge_writembx(struct bge_softc *, int, int);
                    249: static void bge_writemem_direct(struct bge_softc *, int, int);
                    250: static void bge_writereg_ind(struct bge_softc *, int, int);
                    251: static void bge_set_max_readrq(struct bge_softc *);
                    252:
                    253: static int bge_miibus_readreg(device_t, int, int);
                    254: static void bge_miibus_writereg(device_t, int, int, int);
                    255: static void bge_miibus_statchg(device_t);
                    256:
                    257: #define        BGE_RESET_START 1
                    258: #define        BGE_RESET_STOP  2
                    259: static void bge_sig_post_reset(struct bge_softc *, int);
                    260: static void bge_sig_legacy(struct bge_softc *, int);
                    261: static void bge_sig_pre_reset(struct bge_softc *, int);
                    262: static void bge_stop_fw(struct bge_softc *);
                    263: static int bge_reset(struct bge_softc *);
                    264: static void bge_link_upd(struct bge_softc *);
1.95      jonathan  265:
1.1       fvdl      266: #ifdef BGE_DEBUG
                    267: #define DPRINTF(x)     if (bgedebug) printf x
                    268: #define DPRINTFN(n,x)  if (bgedebug >= (n)) printf x
1.95      jonathan  269: #define BGE_TSO_PRINTF(x)  do { if (bge_tso_debug) printf x ;} while (0)
1.1       fvdl      270: int    bgedebug = 0;
1.95      jonathan  271: int    bge_tso_debug = 0;
1.172     msaitoh   272: void           bge_debug_info(struct bge_softc *);
1.1       fvdl      273: #else
                    274: #define DPRINTF(x)
                    275: #define DPRINTFN(n,x)
1.95      jonathan  276: #define BGE_TSO_PRINTF(x)
1.1       fvdl      277: #endif
                    278:
1.72      thorpej   279: #ifdef BGE_EVENT_COUNTERS
                    280: #define        BGE_EVCNT_INCR(ev)      (ev).ev_count++
                    281: #define        BGE_EVCNT_ADD(ev, val)  (ev).ev_count += (val)
                    282: #define        BGE_EVCNT_UPD(ev, val)  (ev).ev_count = (val)
                    283: #else
                    284: #define        BGE_EVCNT_INCR(ev)      /* nothing */
                    285: #define        BGE_EVCNT_ADD(ev, val)  /* nothing */
                    286: #define        BGE_EVCNT_UPD(ev, val)  /* nothing */
                    287: #endif
                    288:
1.158     msaitoh   289: static const struct bge_product {
                    290:        pci_vendor_id_t         bp_vendor;
                    291:        pci_product_id_t        bp_product;
                    292:        const char              *bp_name;
                    293: } bge_products[] = {
                    294:        /*
                    295:         * The BCM5700 documentation seems to indicate that the hardware
                    296:         * still has the Alteon vendor ID burned into it, though it
                    297:         * should always be overridden by the value in the EEPROM.  We'll
                    298:         * check for it anyway.
                    299:         */
                    300:        { PCI_VENDOR_ALTEON,
                    301:          PCI_PRODUCT_ALTEON_BCM5700,
                    302:          "Broadcom BCM5700 Gigabit Ethernet",
                    303:          },
                    304:        { PCI_VENDOR_ALTEON,
                    305:          PCI_PRODUCT_ALTEON_BCM5701,
                    306:          "Broadcom BCM5701 Gigabit Ethernet",
                    307:          },
                    308:        { PCI_VENDOR_ALTIMA,
                    309:          PCI_PRODUCT_ALTIMA_AC1000,
                    310:          "Altima AC1000 Gigabit Ethernet",
                    311:          },
                    312:        { PCI_VENDOR_ALTIMA,
                    313:          PCI_PRODUCT_ALTIMA_AC1001,
                    314:          "Altima AC1001 Gigabit Ethernet",
                    315:           },
                    316:        { PCI_VENDOR_ALTIMA,
                    317:          PCI_PRODUCT_ALTIMA_AC9100,
                    318:          "Altima AC9100 Gigabit Ethernet",
                    319:          },
                    320:        { PCI_VENDOR_BROADCOM,
                    321:          PCI_PRODUCT_BROADCOM_BCM5700,
                    322:          "Broadcom BCM5700 Gigabit Ethernet",
                    323:          },
                    324:        { PCI_VENDOR_BROADCOM,
                    325:          PCI_PRODUCT_BROADCOM_BCM5701,
                    326:          "Broadcom BCM5701 Gigabit Ethernet",
                    327:          },
                    328:        { PCI_VENDOR_BROADCOM,
                    329:          PCI_PRODUCT_BROADCOM_BCM5702,
                    330:          "Broadcom BCM5702 Gigabit Ethernet",
                    331:          },
                    332:        { PCI_VENDOR_BROADCOM,
                    333:          PCI_PRODUCT_BROADCOM_BCM5702X,
                    334:          "Broadcom BCM5702X Gigabit Ethernet" },
                    335:        { PCI_VENDOR_BROADCOM,
                    336:          PCI_PRODUCT_BROADCOM_BCM5703,
                    337:          "Broadcom BCM5703 Gigabit Ethernet",
                    338:          },
                    339:        { PCI_VENDOR_BROADCOM,
                    340:          PCI_PRODUCT_BROADCOM_BCM5703X,
                    341:          "Broadcom BCM5703X Gigabit Ethernet",
                    342:          },
                    343:        { PCI_VENDOR_BROADCOM,
                    344:          PCI_PRODUCT_BROADCOM_BCM5703_ALT,
                    345:          "Broadcom BCM5703 Gigabit Ethernet",
                    346:          },
1.178     msaitoh   347:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   348:          PCI_PRODUCT_BROADCOM_BCM5704C,
                    349:          "Broadcom BCM5704C Dual Gigabit Ethernet",
                    350:          },
1.178     msaitoh   351:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   352:          PCI_PRODUCT_BROADCOM_BCM5704S,
                    353:          "Broadcom BCM5704S Dual Gigabit Ethernet",
                    354:          },
1.178     msaitoh   355:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   356:          PCI_PRODUCT_BROADCOM_BCM5705,
                    357:          "Broadcom BCM5705 Gigabit Ethernet",
                    358:          },
1.178     msaitoh   359:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   360:          PCI_PRODUCT_BROADCOM_BCM5705F,
                    361:          "Broadcom BCM5705F Gigabit Ethernet",
                    362:          },
1.178     msaitoh   363:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   364:          PCI_PRODUCT_BROADCOM_BCM5705K,
                    365:          "Broadcom BCM5705K Gigabit Ethernet",
                    366:          },
1.178     msaitoh   367:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   368:          PCI_PRODUCT_BROADCOM_BCM5705M,
                    369:          "Broadcom BCM5705M Gigabit Ethernet",
                    370:          },
1.178     msaitoh   371:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   372:          PCI_PRODUCT_BROADCOM_BCM5705M_ALT,
                    373:          "Broadcom BCM5705M Gigabit Ethernet",
                    374:          },
                    375:        { PCI_VENDOR_BROADCOM,
                    376:          PCI_PRODUCT_BROADCOM_BCM5714,
1.172     msaitoh   377:          "Broadcom BCM5714 Gigabit Ethernet",
                    378:          },
                    379:        { PCI_VENDOR_BROADCOM,
                    380:          PCI_PRODUCT_BROADCOM_BCM5714S,
                    381:          "Broadcom BCM5714S Gigabit Ethernet",
1.158     msaitoh   382:          },
                    383:        { PCI_VENDOR_BROADCOM,
                    384:          PCI_PRODUCT_BROADCOM_BCM5715,
1.172     msaitoh   385:          "Broadcom BCM5715 Gigabit Ethernet",
1.158     msaitoh   386:          },
                    387:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   388:          PCI_PRODUCT_BROADCOM_BCM5715S,
                    389:          "Broadcom BCM5715S Gigabit Ethernet",
                    390:          },
                    391:        { PCI_VENDOR_BROADCOM,
                    392:          PCI_PRODUCT_BROADCOM_BCM5717,
                    393:          "Broadcom BCM5717 Gigabit Ethernet",
                    394:          },
                    395:        { PCI_VENDOR_BROADCOM,
                    396:          PCI_PRODUCT_BROADCOM_BCM5718,
                    397:          "Broadcom BCM5718 Gigabit Ethernet",
                    398:          },
                    399:        { PCI_VENDOR_BROADCOM,
                    400:          PCI_PRODUCT_BROADCOM_BCM5720,
                    401:          "Broadcom BCM5720 Gigabit Ethernet",
1.158     msaitoh   402:          },
                    403:        { PCI_VENDOR_BROADCOM,
                    404:          PCI_PRODUCT_BROADCOM_BCM5721,
                    405:          "Broadcom BCM5721 Gigabit Ethernet",
                    406:          },
                    407:        { PCI_VENDOR_BROADCOM,
                    408:          PCI_PRODUCT_BROADCOM_BCM5722,
                    409:          "Broadcom BCM5722 Gigabit Ethernet",
                    410:          },
                    411:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   412:          PCI_PRODUCT_BROADCOM_BCM5723,
                    413:          "Broadcom BCM5723 Gigabit Ethernet",
                    414:          },
                    415:        { PCI_VENDOR_BROADCOM,
                    416:          PCI_PRODUCT_BROADCOM_BCM5724,
                    417:          "Broadcom BCM5724 Gigabit Ethernet",
                    418:          },
                    419:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   420:          PCI_PRODUCT_BROADCOM_BCM5750,
                    421:          "Broadcom BCM5750 Gigabit Ethernet",
                    422:          },
                    423:        { PCI_VENDOR_BROADCOM,
                    424:          PCI_PRODUCT_BROADCOM_BCM5750M,
                    425:          "Broadcom BCM5750M Gigabit Ethernet",
                    426:          },
                    427:        { PCI_VENDOR_BROADCOM,
                    428:          PCI_PRODUCT_BROADCOM_BCM5751,
                    429:          "Broadcom BCM5751 Gigabit Ethernet",
                    430:          },
                    431:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   432:          PCI_PRODUCT_BROADCOM_BCM5751F,
                    433:          "Broadcom BCM5751F Gigabit Ethernet",
                    434:          },
                    435:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   436:          PCI_PRODUCT_BROADCOM_BCM5751M,
                    437:          "Broadcom BCM5751M Gigabit Ethernet",
                    438:          },
                    439:        { PCI_VENDOR_BROADCOM,
                    440:          PCI_PRODUCT_BROADCOM_BCM5752,
                    441:          "Broadcom BCM5752 Gigabit Ethernet",
                    442:          },
                    443:        { PCI_VENDOR_BROADCOM,
                    444:          PCI_PRODUCT_BROADCOM_BCM5752M,
                    445:          "Broadcom BCM5752M Gigabit Ethernet",
                    446:          },
                    447:        { PCI_VENDOR_BROADCOM,
                    448:          PCI_PRODUCT_BROADCOM_BCM5753,
                    449:          "Broadcom BCM5753 Gigabit Ethernet",
                    450:          },
                    451:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   452:          PCI_PRODUCT_BROADCOM_BCM5753F,
                    453:          "Broadcom BCM5753F Gigabit Ethernet",
                    454:          },
                    455:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   456:          PCI_PRODUCT_BROADCOM_BCM5753M,
                    457:          "Broadcom BCM5753M Gigabit Ethernet",
                    458:          },
                    459:        { PCI_VENDOR_BROADCOM,
                    460:          PCI_PRODUCT_BROADCOM_BCM5754,
                    461:          "Broadcom BCM5754 Gigabit Ethernet",
                    462:        },
                    463:        { PCI_VENDOR_BROADCOM,
                    464:          PCI_PRODUCT_BROADCOM_BCM5754M,
                    465:          "Broadcom BCM5754M Gigabit Ethernet",
                    466:        },
                    467:        { PCI_VENDOR_BROADCOM,
                    468:          PCI_PRODUCT_BROADCOM_BCM5755,
                    469:          "Broadcom BCM5755 Gigabit Ethernet",
                    470:        },
                    471:        { PCI_VENDOR_BROADCOM,
                    472:          PCI_PRODUCT_BROADCOM_BCM5755M,
                    473:          "Broadcom BCM5755M Gigabit Ethernet",
                    474:        },
1.172     msaitoh   475:        { PCI_VENDOR_BROADCOM,
                    476:          PCI_PRODUCT_BROADCOM_BCM5756,
                    477:          "Broadcom BCM5756 Gigabit Ethernet",
                    478:        },
                    479:        { PCI_VENDOR_BROADCOM,
                    480:          PCI_PRODUCT_BROADCOM_BCM5761,
                    481:          "Broadcom BCM5761 Gigabit Ethernet",
                    482:        },
                    483:        { PCI_VENDOR_BROADCOM,
                    484:          PCI_PRODUCT_BROADCOM_BCM5761E,
                    485:          "Broadcom BCM5761E Gigabit Ethernet",
                    486:        },
                    487:        { PCI_VENDOR_BROADCOM,
                    488:          PCI_PRODUCT_BROADCOM_BCM5761S,
                    489:          "Broadcom BCM5761S Gigabit Ethernet",
                    490:        },
                    491:        { PCI_VENDOR_BROADCOM,
                    492:          PCI_PRODUCT_BROADCOM_BCM5761SE,
                    493:          "Broadcom BCM5761SE Gigabit Ethernet",
                    494:        },
1.178     msaitoh   495:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   496:          PCI_PRODUCT_BROADCOM_BCM5764,
                    497:          "Broadcom BCM5764 Gigabit Ethernet",
                    498:          },
1.178     msaitoh   499:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   500:          PCI_PRODUCT_BROADCOM_BCM5780,
                    501:          "Broadcom BCM5780 Gigabit Ethernet",
                    502:          },
1.178     msaitoh   503:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   504:          PCI_PRODUCT_BROADCOM_BCM5780S,
                    505:          "Broadcom BCM5780S Gigabit Ethernet",
                    506:          },
1.178     msaitoh   507:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   508:          PCI_PRODUCT_BROADCOM_BCM5781,
                    509:          "Broadcom BCM5781 Gigabit Ethernet",
                    510:          },
1.178     msaitoh   511:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   512:          PCI_PRODUCT_BROADCOM_BCM5782,
                    513:          "Broadcom BCM5782 Gigabit Ethernet",
                    514:        },
                    515:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   516:          PCI_PRODUCT_BROADCOM_BCM5784M,
                    517:          "BCM5784M NetLink 1000baseT Ethernet",
                    518:        },
                    519:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   520:          PCI_PRODUCT_BROADCOM_BCM5786,
                    521:          "Broadcom BCM5786 Gigabit Ethernet",
                    522:        },
                    523:        { PCI_VENDOR_BROADCOM,
                    524:          PCI_PRODUCT_BROADCOM_BCM5787,
                    525:          "Broadcom BCM5787 Gigabit Ethernet",
                    526:        },
                    527:        { PCI_VENDOR_BROADCOM,
                    528:          PCI_PRODUCT_BROADCOM_BCM5787M,
                    529:          "Broadcom BCM5787M Gigabit Ethernet",
                    530:        },
1.178     msaitoh   531:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   532:          PCI_PRODUCT_BROADCOM_BCM5788,
                    533:          "Broadcom BCM5788 Gigabit Ethernet",
                    534:          },
1.178     msaitoh   535:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   536:          PCI_PRODUCT_BROADCOM_BCM5789,
                    537:          "Broadcom BCM5789 Gigabit Ethernet",
                    538:          },
1.178     msaitoh   539:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   540:          PCI_PRODUCT_BROADCOM_BCM5901,
                    541:          "Broadcom BCM5901 Fast Ethernet",
                    542:          },
1.178     msaitoh   543:        { PCI_VENDOR_BROADCOM,
1.158     msaitoh   544:          PCI_PRODUCT_BROADCOM_BCM5901A2,
                    545:          "Broadcom BCM5901A2 Fast Ethernet",
                    546:          },
1.178     msaitoh   547:        { PCI_VENDOR_BROADCOM,
1.172     msaitoh   548:          PCI_PRODUCT_BROADCOM_BCM5903M,
                    549:          "Broadcom BCM5903M Fast Ethernet",
1.158     msaitoh   550:          },
                    551:        { PCI_VENDOR_BROADCOM,
                    552:          PCI_PRODUCT_BROADCOM_BCM5906,
                    553:          "Broadcom BCM5906 Fast Ethernet",
                    554:          },
                    555:        { PCI_VENDOR_BROADCOM,
                    556:          PCI_PRODUCT_BROADCOM_BCM5906M,
                    557:          "Broadcom BCM5906M Fast Ethernet",
                    558:          },
1.172     msaitoh   559:        { PCI_VENDOR_BROADCOM,
                    560:          PCI_PRODUCT_BROADCOM_BCM57760,
                    561:          "Broadcom BCM57760 Fast Ethernet",
                    562:          },
                    563:        { PCI_VENDOR_BROADCOM,
                    564:          PCI_PRODUCT_BROADCOM_BCM57761,
                    565:          "Broadcom BCM57761 Fast Ethernet",
                    566:          },
                    567:        { PCI_VENDOR_BROADCOM,
                    568:          PCI_PRODUCT_BROADCOM_BCM57765,
                    569:          "Broadcom BCM57765 Fast Ethernet",
                    570:          },
                    571:        { PCI_VENDOR_BROADCOM,
                    572:          PCI_PRODUCT_BROADCOM_BCM57780,
                    573:          "Broadcom BCM57780 Fast Ethernet",
                    574:          },
                    575:        { PCI_VENDOR_BROADCOM,
                    576:          PCI_PRODUCT_BROADCOM_BCM57781,
                    577:          "Broadcom BCM57781 Fast Ethernet",
                    578:          },
                    579:        { PCI_VENDOR_BROADCOM,
                    580:          PCI_PRODUCT_BROADCOM_BCM57785,
                    581:          "Broadcom BCM57785 Fast Ethernet",
                    582:          },
                    583:        { PCI_VENDOR_BROADCOM,
                    584:          PCI_PRODUCT_BROADCOM_BCM57788,
                    585:          "Broadcom BCM57788 Fast Ethernet",
                    586:          },
                    587:        { PCI_VENDOR_BROADCOM,
                    588:          PCI_PRODUCT_BROADCOM_BCM57790,
                    589:          "Broadcom BCM57790 Fast Ethernet",
                    590:          },
                    591:        { PCI_VENDOR_BROADCOM,
                    592:          PCI_PRODUCT_BROADCOM_BCM57791,
                    593:          "Broadcom BCM57791 Fast Ethernet",
                    594:          },
                    595:        { PCI_VENDOR_BROADCOM,
                    596:          PCI_PRODUCT_BROADCOM_BCM57795,
                    597:          "Broadcom BCM57795 Fast Ethernet",
                    598:          },
                    599:        { PCI_VENDOR_SCHNEIDERKOCH,
                    600:          PCI_PRODUCT_SCHNEIDERKOCH_SK_9DX1,
                    601:          "SysKonnect SK-9Dx1 Gigabit Ethernet",
                    602:          },
                    603:        { PCI_VENDOR_3COM,
                    604:          PCI_PRODUCT_3COM_3C996,
                    605:          "3Com 3c996 Gigabit Ethernet",
                    606:          },
1.158     msaitoh   607:        { 0,
                    608:          0,
                    609:          NULL },
                    610: };
                    611:
1.95      jonathan  612: /*
                    613:  * XXX: how to handle variants based on 5750 and derivatives:
1.107     blymn     614:  * 5750 5751, 5721, possibly 5714, 5752, and 5708?, which
1.95      jonathan  615:  * in general behave like a 5705, except with additional quirks.
                    616:  * This driver's current handling of the 5721 is wrong;
                    617:  * how we map ASIC revision to "quirks" needs more thought.
                    618:  * (defined here until the thought is done).
                    619:  */
1.172     msaitoh   620: #define BGE_IS_5700_FAMILY(sc)         ((sc)->bge_flags & BGE_5700_FAMILY)
                    621: #define BGE_IS_5714_FAMILY(sc)         ((sc)->bge_flags & BGE_5714_FAMILY)
                    622: #define BGE_IS_5705_PLUS(sc)   ((sc)->bge_flags & BGE_5705_PLUS)
                    623: #define BGE_IS_5750_OR_BEYOND(sc)      ((sc)->bge_flags & BGE_5750_PLUS)
                    624: #define BGE_IS_5755_PLUS(sc)   ((sc)->bge_flags & BGE_5755_PLUS)
                    625: #define BGE_IS_JUMBO_CAPABLE(sc)       ((sc)->bge_flags & BGE_JUMBO_CAPABLE)
1.166     msaitoh   626:
1.158     msaitoh   627: static const struct bge_revision {
                    628:        uint32_t                br_chipid;
                    629:        const char              *br_name;
                    630: } bge_revisions[] = {
                    631:        { BGE_CHIPID_BCM5700_A0, "BCM5700 A0" },
                    632:        { BGE_CHIPID_BCM5700_A1, "BCM5700 A1" },
                    633:        { BGE_CHIPID_BCM5700_B0, "BCM5700 B0" },
                    634:        { BGE_CHIPID_BCM5700_B1, "BCM5700 B1" },
                    635:        { BGE_CHIPID_BCM5700_B2, "BCM5700 B2" },
                    636:        { BGE_CHIPID_BCM5700_B3, "BCM5700 B3" },
                    637:        /* This is treated like a BCM5700 Bx */
                    638:        { BGE_CHIPID_BCM5700_ALTIMA, "BCM5700 Altima" },
                    639:        { BGE_CHIPID_BCM5700_C0, "BCM5700 C0" },
                    640:        { BGE_CHIPID_BCM5701_A0, "BCM5701 A0" },
                    641:        { BGE_CHIPID_BCM5701_B0, "BCM5701 B0" },
                    642:        { BGE_CHIPID_BCM5701_B2, "BCM5701 B2" },
                    643:        { BGE_CHIPID_BCM5701_B5, "BCM5701 B5" },
1.172     msaitoh   644:        { BGE_CHIPID_BCM5703_A0, "BCM5702/5703 A0" },
                    645:        { BGE_CHIPID_BCM5703_A1, "BCM5702/5703 A1" },
                    646:        { BGE_CHIPID_BCM5703_A2, "BCM5702/5703 A2" },
                    647:        { BGE_CHIPID_BCM5703_A3, "BCM5702/5703 A3" },
                    648:        { BGE_CHIPID_BCM5703_B0, "BCM5702/5703 B0" },
1.158     msaitoh   649:        { BGE_CHIPID_BCM5704_A0, "BCM5704 A0" },
                    650:        { BGE_CHIPID_BCM5704_A1, "BCM5704 A1" },
                    651:        { BGE_CHIPID_BCM5704_A2, "BCM5704 A2" },
                    652:        { BGE_CHIPID_BCM5704_A3, "BCM5704 A3" },
1.159     msaitoh   653:        { BGE_CHIPID_BCM5704_B0, "BCM5704 B0" },
1.158     msaitoh   654:        { BGE_CHIPID_BCM5705_A0, "BCM5705 A0" },
                    655:        { BGE_CHIPID_BCM5705_A1, "BCM5705 A1" },
                    656:        { BGE_CHIPID_BCM5705_A2, "BCM5705 A2" },
                    657:        { BGE_CHIPID_BCM5705_A3, "BCM5705 A3" },
                    658:        { BGE_CHIPID_BCM5750_A0, "BCM5750 A0" },
                    659:        { BGE_CHIPID_BCM5750_A1, "BCM5750 A1" },
1.161     msaitoh   660:        { BGE_CHIPID_BCM5750_A3, "BCM5750 A3" },
                    661:        { BGE_CHIPID_BCM5750_B0, "BCM5750 B0" },
                    662:        { BGE_CHIPID_BCM5750_B1, "BCM5750 B1" },
                    663:        { BGE_CHIPID_BCM5750_C0, "BCM5750 C0" },
                    664:        { BGE_CHIPID_BCM5750_C1, "BCM5750 C1" },
                    665:        { BGE_CHIPID_BCM5750_C2, "BCM5750 C2" },
1.158     msaitoh   666:        { BGE_CHIPID_BCM5752_A0, "BCM5752 A0" },
                    667:        { BGE_CHIPID_BCM5752_A1, "BCM5752 A1" },
                    668:        { BGE_CHIPID_BCM5752_A2, "BCM5752 A2" },
1.159     msaitoh   669:        { BGE_CHIPID_BCM5714_A0, "BCM5714 A0" },
                    670:        { BGE_CHIPID_BCM5714_B0, "BCM5714 B0" },
                    671:        { BGE_CHIPID_BCM5714_B3, "BCM5714 B3" },
                    672:        { BGE_CHIPID_BCM5715_A0, "BCM5715 A0" },
                    673:        { BGE_CHIPID_BCM5715_A1, "BCM5715 A1" },
                    674:        { BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },
1.158     msaitoh   675:        { BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
                    676:        { BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
                    677:        { BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
                    678:        { BGE_CHIPID_BCM5755_C0, "BCM5755 C0" },
1.172     msaitoh   679:        { BGE_CHIPID_BCM5761_A0, "BCM5761 A0" },
                    680:        { BGE_CHIPID_BCM5761_A1, "BCM5761 A1" },
                    681:        { BGE_CHIPID_BCM5784_A0, "BCM5784 A0" },
                    682:        { BGE_CHIPID_BCM5784_A1, "BCM5784 A1" },
                    683:        /* 5754 and 5787 share the same ASIC ID */
1.158     msaitoh   684:        { BGE_CHIPID_BCM5787_A0, "BCM5754/5787 A0" },
                    685:        { BGE_CHIPID_BCM5787_A1, "BCM5754/5787 A1" },
                    686:        { BGE_CHIPID_BCM5787_A2, "BCM5754/5787 A2" },
1.161     msaitoh   687:        { BGE_CHIPID_BCM5906_A1, "BCM5906 A1" },
                    688:        { BGE_CHIPID_BCM5906_A2, "BCM5906 A2" },
1.172     msaitoh   689:        { BGE_CHIPID_BCM57780_A0, "BCM57780 A0" },
                    690:        { BGE_CHIPID_BCM57780_A1, "BCM57780 A1" },
                    691:
1.158     msaitoh   692:        { 0, NULL }
                    693: };
                    694:
                    695: /*
                    696:  * Some defaults for major revisions, so that newer steppings
                    697:  * that we don't know about have a shot at working.
                    698:  */
                    699: static const struct bge_revision bge_majorrevs[] = {
                    700:        { BGE_ASICREV_BCM5700, "unknown BCM5700" },
                    701:        { BGE_ASICREV_BCM5701, "unknown BCM5701" },
                    702:        { BGE_ASICREV_BCM5703, "unknown BCM5703" },
                    703:        { BGE_ASICREV_BCM5704, "unknown BCM5704" },
                    704:        { BGE_ASICREV_BCM5705, "unknown BCM5705" },
1.162     msaitoh   705:        { BGE_ASICREV_BCM5750, "unknown BCM5750" },
1.158     msaitoh   706:        { BGE_ASICREV_BCM5714_A0, "unknown BCM5714" },
1.172     msaitoh   707:        { BGE_ASICREV_BCM5752, "unknown BCM5752" },
                    708:        { BGE_ASICREV_BCM5780, "unknown BCM5780" },
1.158     msaitoh   709:        { BGE_ASICREV_BCM5714, "unknown BCM5714" },
                    710:        { BGE_ASICREV_BCM5755, "unknown BCM5755" },
1.172     msaitoh   711:        { BGE_ASICREV_BCM5761, "unknown BCM5761" },
                    712:        { BGE_ASICREV_BCM5784, "unknown BCM5784" },
                    713:        { BGE_ASICREV_BCM5785, "unknown BCM5785" },
1.162     msaitoh   714:        /* 5754 and 5787 share the same ASIC ID */
1.166     msaitoh   715:        { BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
1.172     msaitoh   716:        { BGE_ASICREV_BCM5906, "unknown BCM5906" },
                    717:        { BGE_ASICREV_BCM57780, "unknown BCM57780" },
                    718:        { BGE_ASICREV_BCM5717, "unknown BCM5717" },
                    719:        { BGE_ASICREV_BCM57765, "unknown BCM57765" },
                    720:
1.158     msaitoh   721:        { 0, NULL }
                    722: };
1.17      thorpej   723:
1.177     msaitoh   724: static int bge_allow_asf = 1;
                    725:
1.138     joerg     726: CFATTACH_DECL_NEW(bge, sizeof(struct bge_softc),
1.22      thorpej   727:     bge_probe, bge_attach, NULL, NULL);
1.1       fvdl      728:
1.170     msaitoh   729: static uint32_t
1.104     thorpej   730: bge_readmem_ind(struct bge_softc *sc, int off)
1.1       fvdl      731: {
                    732:        pcireg_t val;
                    733:
1.141     jmcneill  734:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
                    735:        val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA);
1.1       fvdl      736:        return val;
                    737: }
                    738:
1.104     thorpej   739: static void
                    740: bge_writemem_ind(struct bge_softc *sc, int off, int val)
1.1       fvdl      741: {
1.141     jmcneill  742:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
                    743:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA, val);
1.1       fvdl      744: }
                    745:
1.177     msaitoh   746: /*
                    747:  * PCI Express only
                    748:  */
                    749: static void
                    750: bge_set_max_readrq(struct bge_softc *sc)
                    751: {
                    752:        device_t dev;
                    753:        pcireg_t val;
                    754:
                    755:        dev = sc->bge_dev;
                    756:
1.180     msaitoh   757:        val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
1.177     msaitoh   758:            + PCI_PCIE_DCSR);
                    759:        if ((val & PCI_PCIE_DCSR_MAX_READ_REQ) !=
                    760:            BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
1.183     ad        761:                aprint_verbose("adjust device control 0x%04x ", val);
1.177     msaitoh   762:                val &= ~PCI_PCIE_DCSR_MAX_READ_REQ;
                    763:                val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
1.180     msaitoh   764:                pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pciecap
1.177     msaitoh   765:                    + PCI_PCIE_DCSR, val);
1.183     ad        766:                aprint_verbose("-> 0x%04x\n", val);
1.177     msaitoh   767:        }
                    768: }
                    769:
1.1       fvdl      770: #ifdef notdef
1.170     msaitoh   771: static uint32_t
1.104     thorpej   772: bge_readreg_ind(struct bge_softc *sc, int off)
1.1       fvdl      773: {
1.141     jmcneill  774:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_BASEADDR, off);
1.158     msaitoh   775:        return (pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_DATA));
1.1       fvdl      776: }
                    777: #endif
                    778:
1.104     thorpej   779: static void
                    780: bge_writereg_ind(struct bge_softc *sc, int off, int val)
1.1       fvdl      781: {
1.141     jmcneill  782:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_BASEADDR, off);
                    783:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_DATA, val);
1.1       fvdl      784: }
                    785:
1.151     cegger    786: static void
                    787: bge_writemem_direct(struct bge_softc *sc, int off, int val)
                    788: {
                    789:        CSR_WRITE_4(sc, off, val);
                    790: }
                    791:
                    792: static void
                    793: bge_writembx(struct bge_softc *sc, int off, int val)
                    794: {
                    795:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                    796:                off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
                    797:
                    798:        CSR_WRITE_4(sc, off, val);
                    799: }
                    800:
1.170     msaitoh   801: static uint8_t
                    802: bge_nvram_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
1.151     cegger    803: {
1.170     msaitoh   804:        uint32_t access, byte = 0;
1.151     cegger    805:        int i;
                    806:
                    807:        /* Lock. */
                    808:        CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_SET1);
                    809:        for (i = 0; i < 8000; i++) {
                    810:                if (CSR_READ_4(sc, BGE_NVRAM_SWARB) & BGE_NVRAMSWARB_GNT1)
                    811:                        break;
                    812:                DELAY(20);
                    813:        }
                    814:        if (i == 8000)
1.170     msaitoh   815:                return 1;
1.151     cegger    816:
                    817:        /* Enable access. */
                    818:        access = CSR_READ_4(sc, BGE_NVRAM_ACCESS);
                    819:        CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access | BGE_NVRAMACC_ENABLE);
                    820:
                    821:        CSR_WRITE_4(sc, BGE_NVRAM_ADDR, addr & 0xfffffffc);
                    822:        CSR_WRITE_4(sc, BGE_NVRAM_CMD, BGE_NVRAM_READCMD);
                    823:        for (i = 0; i < BGE_TIMEOUT * 10; i++) {
                    824:                DELAY(10);
                    825:                if (CSR_READ_4(sc, BGE_NVRAM_CMD) & BGE_NVRAMCMD_DONE) {
                    826:                        DELAY(10);
                    827:                        break;
                    828:                }
                    829:        }
                    830:
                    831:        if (i == BGE_TIMEOUT * 10) {
                    832:                aprint_error_dev(sc->bge_dev, "nvram read timed out\n");
1.170     msaitoh   833:                return 1;
1.151     cegger    834:        }
                    835:
                    836:        /* Get result. */
                    837:        byte = CSR_READ_4(sc, BGE_NVRAM_RDDATA);
                    838:
                    839:        *dest = (bswap32(byte) >> ((addr % 4) * 8)) & 0xFF;
                    840:
                    841:        /* Disable access. */
                    842:        CSR_WRITE_4(sc, BGE_NVRAM_ACCESS, access);
                    843:
                    844:        /* Unlock. */
                    845:        CSR_WRITE_4(sc, BGE_NVRAM_SWARB, BGE_NVRAMSWARB_CLR1);
                    846:        CSR_READ_4(sc, BGE_NVRAM_SWARB);
                    847:
1.170     msaitoh   848:        return 0;
1.151     cegger    849: }
                    850:
                    851: /*
                    852:  * Read a sequence of bytes from NVRAM.
                    853:  */
                    854: static int
1.170     msaitoh   855: bge_read_nvram(struct bge_softc *sc, uint8_t *dest, int off, int cnt)
1.151     cegger    856: {
                    857:        int err = 0, i;
1.170     msaitoh   858:        uint8_t byte = 0;
1.151     cegger    859:
                    860:        if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)
1.170     msaitoh   861:                return 1;
1.151     cegger    862:
                    863:        for (i = 0; i < cnt; i++) {
                    864:                err = bge_nvram_getbyte(sc, off + i, &byte);
                    865:                if (err)
                    866:                        break;
                    867:                *(dest + i) = byte;
                    868:        }
                    869:
                    870:        return (err ? 1 : 0);
                    871: }
                    872:
1.1       fvdl      873: /*
                    874:  * Read a byte of data stored in the EEPROM at address 'addr.' The
                    875:  * BCM570x supports both the traditional bitbang interface and an
                    876:  * auto access interface for reading the EEPROM. We use the auto
                    877:  * access method.
                    878:  */
1.170     msaitoh   879: static uint8_t
                    880: bge_eeprom_getbyte(struct bge_softc *sc, int addr, uint8_t *dest)
1.1       fvdl      881: {
                    882:        int i;
1.170     msaitoh   883:        uint32_t byte = 0;
1.1       fvdl      884:
                    885:        /*
                    886:         * Enable use of auto EEPROM access so we can avoid
                    887:         * having to use the bitbang method.
                    888:         */
                    889:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_AUTO_EEPROM);
                    890:
                    891:        /* Reset the EEPROM, load the clock period. */
                    892:        CSR_WRITE_4(sc, BGE_EE_ADDR,
1.161     msaitoh   893:            BGE_EEADDR_RESET | BGE_EEHALFCLK(BGE_HALFCLK_384SCL));
1.1       fvdl      894:        DELAY(20);
                    895:
                    896:        /* Issue the read EEPROM command. */
                    897:        CSR_WRITE_4(sc, BGE_EE_ADDR, BGE_EE_READCMD | addr);
                    898:
                    899:        /* Wait for completion */
1.170     msaitoh   900:        for (i = 0; i < BGE_TIMEOUT * 10; i++) {
1.1       fvdl      901:                DELAY(10);
                    902:                if (CSR_READ_4(sc, BGE_EE_ADDR) & BGE_EEADDR_DONE)
                    903:                        break;
                    904:        }
                    905:
1.172     msaitoh   906:        if (i == BGE_TIMEOUT * 10) {
1.138     joerg     907:                aprint_error_dev(sc->bge_dev, "eeprom read timed out\n");
1.177     msaitoh   908:                return 1;
1.1       fvdl      909:        }
                    910:
                    911:        /* Get result. */
                    912:        byte = CSR_READ_4(sc, BGE_EE_DATA);
                    913:
                    914:        *dest = (byte >> ((addr % 4) * 8)) & 0xFF;
                    915:
1.170     msaitoh   916:        return 0;
1.1       fvdl      917: }
                    918:
                    919: /*
                    920:  * Read a sequence of bytes from the EEPROM.
                    921:  */
1.104     thorpej   922: static int
1.126     christos  923: bge_read_eeprom(struct bge_softc *sc, void *destv, int off, int cnt)
1.1       fvdl      924: {
                    925:        int err = 0, i;
1.170     msaitoh   926:        uint8_t byte = 0;
1.126     christos  927:        char *dest = destv;
1.1       fvdl      928:
                    929:        for (i = 0; i < cnt; i++) {
                    930:                err = bge_eeprom_getbyte(sc, off + i, &byte);
                    931:                if (err)
                    932:                        break;
                    933:                *(dest + i) = byte;
                    934:        }
                    935:
1.158     msaitoh   936:        return (err ? 1 : 0);
1.1       fvdl      937: }
                    938:
1.104     thorpej   939: static int
                    940: bge_miibus_readreg(device_t dev, int phy, int reg)
1.1       fvdl      941: {
1.138     joerg     942:        struct bge_softc *sc = device_private(dev);
1.170     msaitoh   943:        uint32_t val;
1.172     msaitoh   944:        uint32_t autopoll;
1.1       fvdl      945:        int i;
                    946:
1.25      jonathan  947:        /*
1.156     msaitoh   948:         * Broadcom's own driver always assumes the internal
                    949:         * PHY is at GMII address 1. On some chips, the PHY responds
                    950:         * to accesses at all addresses, which could cause us to
                    951:         * bogusly attach the PHY 32 times at probe type. Always
                    952:         * restricting the lookup to address 1 is simpler than
                    953:         * trying to figure out which chips revisions should be
                    954:         * special-cased.
1.25      jonathan  955:         */
1.156     msaitoh   956:        if (phy != 1)
1.170     msaitoh   957:                return 0;
1.1       fvdl      958:
1.25      jonathan  959:        /* Reading with autopolling on may trigger PCI errors */
1.172     msaitoh   960:        autopoll = CSR_READ_4(sc, BGE_MI_MODE);
                    961:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
1.161     msaitoh   962:                BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
1.172     msaitoh   963:                BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
1.25      jonathan  964:                DELAY(40);
                    965:        }
                    966:
1.172     msaitoh   967:        CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_READ | BGE_MICOMM_BUSY |
                    968:            BGE_MIPHY(phy) | BGE_MIREG(reg));
1.1       fvdl      969:
                    970:        for (i = 0; i < BGE_TIMEOUT; i++) {
                    971:                val = CSR_READ_4(sc, BGE_MI_COMM);
                    972:                if (!(val & BGE_MICOMM_BUSY))
                    973:                        break;
1.9       thorpej   974:                delay(10);
1.1       fvdl      975:        }
                    976:
                    977:        if (i == BGE_TIMEOUT) {
1.138     joerg     978:                aprint_error_dev(sc->bge_dev, "PHY read timed out\n");
1.29      itojun    979:                val = 0;
1.25      jonathan  980:                goto done;
1.1       fvdl      981:        }
                    982:
                    983:        val = CSR_READ_4(sc, BGE_MI_COMM);
                    984:
1.25      jonathan  985: done:
1.172     msaitoh   986:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
1.161     msaitoh   987:                BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
1.172     msaitoh   988:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
1.25      jonathan  989:                DELAY(40);
                    990:        }
1.29      itojun    991:
1.1       fvdl      992:        if (val & BGE_MICOMM_READFAIL)
1.170     msaitoh   993:                return 0;
1.1       fvdl      994:
1.158     msaitoh   995:        return (val & 0xFFFF);
1.1       fvdl      996: }
                    997:
1.104     thorpej   998: static void
                    999: bge_miibus_writereg(device_t dev, int phy, int reg, int val)
1.1       fvdl     1000: {
1.138     joerg    1001:        struct bge_softc *sc = device_private(dev);
1.172     msaitoh  1002:        uint32_t autopoll;
1.29      itojun   1003:        int i;
1.1       fvdl     1004:
1.151     cegger   1005:        if (phy!=1) {
                   1006:                return;
                   1007:        }
                   1008:
                   1009:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 &&
                   1010:            (reg == BRGPHY_MII_1000CTL || reg == BRGPHY_MII_AUXCTL)) {
                   1011:                return;
                   1012:        }
                   1013:
1.161     msaitoh  1014:        /* Reading with autopolling on may trigger PCI errors */
1.172     msaitoh  1015:        autopoll = CSR_READ_4(sc, BGE_MI_MODE);
                   1016:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
1.25      jonathan 1017:                delay(40);
1.161     msaitoh  1018:                BGE_STS_CLRBIT(sc, BGE_STS_AUTOPOLL);
1.172     msaitoh  1019:                BGE_CLRBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
1.25      jonathan 1020:                delay(10); /* 40 usec is supposed to be adequate */
                   1021:        }
1.29      itojun   1022:
1.161     msaitoh  1023:        CSR_WRITE_4(sc, BGE_MI_COMM, BGE_MICMD_WRITE | BGE_MICOMM_BUSY |
1.177     msaitoh  1024:            BGE_MIPHY(phy) | BGE_MIREG(reg) | val);
1.1       fvdl     1025:
                   1026:        for (i = 0; i < BGE_TIMEOUT; i++) {
1.151     cegger   1027:                delay(10);
                   1028:                if (!(CSR_READ_4(sc, BGE_MI_COMM) & BGE_MICOMM_BUSY)) {
                   1029:                        delay(5);
                   1030:                        CSR_READ_4(sc, BGE_MI_COMM);
1.1       fvdl     1031:                        break;
1.151     cegger   1032:                }
1.1       fvdl     1033:        }
                   1034:
1.172     msaitoh  1035:        if (autopoll & BGE_MIMODE_AUTOPOLL) {
1.161     msaitoh  1036:                BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
1.172     msaitoh  1037:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL);
1.25      jonathan 1038:                delay(40);
                   1039:        }
1.29      itojun   1040:
1.138     joerg    1041:        if (i == BGE_TIMEOUT)
                   1042:                aprint_error_dev(sc->bge_dev, "PHY read timed out\n");
1.1       fvdl     1043: }
                   1044:
1.104     thorpej  1045: static void
                   1046: bge_miibus_statchg(device_t dev)
1.1       fvdl     1047: {
1.138     joerg    1048:        struct bge_softc *sc = device_private(dev);
1.1       fvdl     1049:        struct mii_data *mii = &sc->bge_mii;
                   1050:
1.69      thorpej  1051:        /*
                   1052:         * Get flow control negotiation result.
                   1053:         */
                   1054:        if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
                   1055:            (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) {
                   1056:                sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
                   1057:                mii->mii_media_active &= ~IFM_ETH_FMASK;
                   1058:        }
                   1059:
1.1       fvdl     1060:        BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
1.161     msaitoh  1061:        if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
                   1062:            IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
1.1       fvdl     1063:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
1.161     msaitoh  1064:        else
1.1       fvdl     1065:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_MII);
                   1066:
1.158     msaitoh  1067:        if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
1.1       fvdl     1068:                BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
1.158     msaitoh  1069:        else
1.1       fvdl     1070:                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
1.69      thorpej  1071:
                   1072:        /*
                   1073:         * 802.3x flow control
                   1074:         */
1.158     msaitoh  1075:        if (sc->bge_flowflags & IFM_ETH_RXPAUSE)
1.69      thorpej  1076:                BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
1.158     msaitoh  1077:        else
1.69      thorpej  1078:                BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
1.158     msaitoh  1079:
                   1080:        if (sc->bge_flowflags & IFM_ETH_TXPAUSE)
1.69      thorpej  1081:                BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
1.158     msaitoh  1082:        else
1.69      thorpej  1083:                BGE_CLRBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
1.1       fvdl     1084: }
                   1085:
                   1086: /*
1.63      jonathan 1087:  * Update rx threshold levels to values in a particular slot
                   1088:  * of the interrupt-mitigation table bge_rx_threshes.
                   1089:  */
1.104     thorpej  1090: static void
1.63      jonathan 1091: bge_set_thresh(struct ifnet *ifp, int lvl)
                   1092: {
                   1093:        struct bge_softc *sc = ifp->if_softc;
                   1094:        int s;
                   1095:
                   1096:        /* For now, just save the new Rx-intr thresholds and record
                   1097:         * that a threshold update is pending.  Updating the hardware
                   1098:         * registers here (even at splhigh()) is observed to
                   1099:         * occasionaly cause glitches where Rx-interrupts are not
1.68      keihan   1100:         * honoured for up to 10 seconds. jonathan@NetBSD.org, 2003-04-05
1.63      jonathan 1101:         */
                   1102:        s = splnet();
                   1103:        sc->bge_rx_coal_ticks = bge_rx_threshes[lvl].rx_ticks;
                   1104:        sc->bge_rx_max_coal_bds = bge_rx_threshes[lvl].rx_max_bds;
                   1105:        sc->bge_pending_rxintr_change = 1;
                   1106:        splx(s);
                   1107:
                   1108:         return;
                   1109: }
                   1110:
                   1111:
                   1112: /*
                   1113:  * Update Rx thresholds of all bge devices
                   1114:  */
1.104     thorpej  1115: static void
1.63      jonathan 1116: bge_update_all_threshes(int lvl)
                   1117: {
                   1118:        struct ifnet *ifp;
                   1119:        const char * const namebuf = "bge";
                   1120:        int namelen;
                   1121:
                   1122:        if (lvl < 0)
                   1123:                lvl = 0;
1.170     msaitoh  1124:        else if (lvl >= NBGE_RX_THRESH)
1.63      jonathan 1125:                lvl = NBGE_RX_THRESH - 1;
1.87      perry    1126:
1.63      jonathan 1127:        namelen = strlen(namebuf);
                   1128:        /*
                   1129:         * Now search all the interfaces for this name/number
                   1130:         */
1.81      matt     1131:        IFNET_FOREACH(ifp) {
1.67      jonathan 1132:                if (strncmp(ifp->if_xname, namebuf, namelen) != 0)
1.63      jonathan 1133:                      continue;
                   1134:                /* We got a match: update if doing auto-threshold-tuning */
                   1135:                if (bge_auto_thresh)
1.67      jonathan 1136:                        bge_set_thresh(ifp, lvl);
1.63      jonathan 1137:        }
                   1138: }
                   1139:
                   1140: /*
1.1       fvdl     1141:  * Handle events that have triggered interrupts.
                   1142:  */
1.104     thorpej  1143: static void
1.116     christos 1144: bge_handle_events(struct bge_softc *sc)
1.1       fvdl     1145: {
                   1146:
                   1147:        return;
                   1148: }
                   1149:
                   1150: /*
                   1151:  * Memory management for jumbo frames.
                   1152:  */
                   1153:
1.104     thorpej  1154: static int
                   1155: bge_alloc_jumbo_mem(struct bge_softc *sc)
1.1       fvdl     1156: {
1.126     christos 1157:        char *ptr, *kva;
1.1       fvdl     1158:        bus_dma_segment_t       seg;
                   1159:        int             i, rseg, state, error;
                   1160:        struct bge_jpool_entry   *entry;
                   1161:
                   1162:        state = error = 0;
                   1163:
                   1164:        /* Grab a big chunk o' storage. */
                   1165:        if (bus_dmamem_alloc(sc->bge_dmatag, BGE_JMEM, PAGE_SIZE, 0,
                   1166:             &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1.138     joerg    1167:                aprint_error_dev(sc->bge_dev, "can't alloc rx buffers\n");
1.1       fvdl     1168:                return ENOBUFS;
                   1169:        }
                   1170:
                   1171:        state = 1;
1.126     christos 1172:        if (bus_dmamem_map(sc->bge_dmatag, &seg, rseg, BGE_JMEM, (void **)&kva,
1.1       fvdl     1173:            BUS_DMA_NOWAIT)) {
1.138     joerg    1174:                aprint_error_dev(sc->bge_dev,
                   1175:                    "can't map DMA buffers (%d bytes)\n", (int)BGE_JMEM);
1.1       fvdl     1176:                error = ENOBUFS;
                   1177:                goto out;
                   1178:        }
                   1179:
                   1180:        state = 2;
                   1181:        if (bus_dmamap_create(sc->bge_dmatag, BGE_JMEM, 1, BGE_JMEM, 0,
                   1182:            BUS_DMA_NOWAIT, &sc->bge_cdata.bge_rx_jumbo_map)) {
1.138     joerg    1183:                aprint_error_dev(sc->bge_dev, "can't create DMA map\n");
1.1       fvdl     1184:                error = ENOBUFS;
                   1185:                goto out;
                   1186:        }
                   1187:
                   1188:        state = 3;
                   1189:        if (bus_dmamap_load(sc->bge_dmatag, sc->bge_cdata.bge_rx_jumbo_map,
                   1190:            kva, BGE_JMEM, NULL, BUS_DMA_NOWAIT)) {
1.138     joerg    1191:                aprint_error_dev(sc->bge_dev, "can't load DMA map\n");
1.1       fvdl     1192:                error = ENOBUFS;
                   1193:                goto out;
                   1194:        }
                   1195:
                   1196:        state = 4;
1.126     christos 1197:        sc->bge_cdata.bge_jumbo_buf = (void *)kva;
1.89      christos 1198:        DPRINTFN(1,("bge_jumbo_buf = %p\n", sc->bge_cdata.bge_jumbo_buf));
1.1       fvdl     1199:
                   1200:        SLIST_INIT(&sc->bge_jfree_listhead);
                   1201:        SLIST_INIT(&sc->bge_jinuse_listhead);
                   1202:
                   1203:        /*
                   1204:         * Now divide it up into 9K pieces and save the addresses
                   1205:         * in an array.
                   1206:         */
                   1207:        ptr = sc->bge_cdata.bge_jumbo_buf;
                   1208:        for (i = 0; i < BGE_JSLOTS; i++) {
                   1209:                sc->bge_cdata.bge_jslots[i] = ptr;
                   1210:                ptr += BGE_JLEN;
                   1211:                entry = malloc(sizeof(struct bge_jpool_entry),
                   1212:                    M_DEVBUF, M_NOWAIT);
                   1213:                if (entry == NULL) {
1.138     joerg    1214:                        aprint_error_dev(sc->bge_dev,
                   1215:                            "no memory for jumbo buffer queue!\n");
1.1       fvdl     1216:                        error = ENOBUFS;
                   1217:                        goto out;
                   1218:                }
                   1219:                entry->slot = i;
                   1220:                SLIST_INSERT_HEAD(&sc->bge_jfree_listhead,
                   1221:                                 entry, jpool_entries);
                   1222:        }
                   1223: out:
                   1224:        if (error != 0) {
                   1225:                switch (state) {
                   1226:                case 4:
                   1227:                        bus_dmamap_unload(sc->bge_dmatag,
                   1228:                            sc->bge_cdata.bge_rx_jumbo_map);
                   1229:                case 3:
                   1230:                        bus_dmamap_destroy(sc->bge_dmatag,
                   1231:                            sc->bge_cdata.bge_rx_jumbo_map);
                   1232:                case 2:
                   1233:                        bus_dmamem_unmap(sc->bge_dmatag, kva, BGE_JMEM);
                   1234:                case 1:
                   1235:                        bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
                   1236:                        break;
                   1237:                default:
                   1238:                        break;
                   1239:                }
                   1240:        }
                   1241:
                   1242:        return error;
                   1243: }
                   1244:
                   1245: /*
                   1246:  * Allocate a jumbo buffer.
                   1247:  */
1.104     thorpej  1248: static void *
                   1249: bge_jalloc(struct bge_softc *sc)
1.1       fvdl     1250: {
                   1251:        struct bge_jpool_entry   *entry;
                   1252:
                   1253:        entry = SLIST_FIRST(&sc->bge_jfree_listhead);
                   1254:
                   1255:        if (entry == NULL) {
1.138     joerg    1256:                aprint_error_dev(sc->bge_dev, "no free jumbo buffers\n");
1.170     msaitoh  1257:                return NULL;
1.1       fvdl     1258:        }
                   1259:
                   1260:        SLIST_REMOVE_HEAD(&sc->bge_jfree_listhead, jpool_entries);
                   1261:        SLIST_INSERT_HEAD(&sc->bge_jinuse_listhead, entry, jpool_entries);
1.158     msaitoh  1262:        return (sc->bge_cdata.bge_jslots[entry->slot]);
1.1       fvdl     1263: }
                   1264:
                   1265: /*
                   1266:  * Release a jumbo buffer.
                   1267:  */
1.104     thorpej  1268: static void
1.126     christos 1269: bge_jfree(struct mbuf *m, void *buf, size_t size, void *arg)
1.1       fvdl     1270: {
                   1271:        struct bge_jpool_entry *entry;
                   1272:        struct bge_softc *sc;
                   1273:        int i, s;
                   1274:
                   1275:        /* Extract the softc struct pointer. */
                   1276:        sc = (struct bge_softc *)arg;
                   1277:
                   1278:        if (sc == NULL)
                   1279:                panic("bge_jfree: can't find softc pointer!");
                   1280:
                   1281:        /* calculate the slot this buffer belongs to */
                   1282:
1.126     christos 1283:        i = ((char *)buf
                   1284:             - (char *)sc->bge_cdata.bge_jumbo_buf) / BGE_JLEN;
1.1       fvdl     1285:
                   1286:        if ((i < 0) || (i >= BGE_JSLOTS))
                   1287:                panic("bge_jfree: asked to free buffer that we don't manage!");
                   1288:
                   1289:        s = splvm();
                   1290:        entry = SLIST_FIRST(&sc->bge_jinuse_listhead);
                   1291:        if (entry == NULL)
                   1292:                panic("bge_jfree: buffer not in use!");
                   1293:        entry->slot = i;
                   1294:        SLIST_REMOVE_HEAD(&sc->bge_jinuse_listhead, jpool_entries);
                   1295:        SLIST_INSERT_HEAD(&sc->bge_jfree_listhead, entry, jpool_entries);
                   1296:
                   1297:        if (__predict_true(m != NULL))
1.140     ad       1298:                pool_cache_put(mb_cache, m);
1.1       fvdl     1299:        splx(s);
                   1300: }
                   1301:
                   1302:
                   1303: /*
1.184     njoly    1304:  * Initialize a standard receive ring descriptor.
1.1       fvdl     1305:  */
1.104     thorpej  1306: static int
1.178     msaitoh  1307: bge_newbuf_std(struct bge_softc *sc, int i, struct mbuf *m,
                   1308:     bus_dmamap_t dmamap)
1.1       fvdl     1309: {
                   1310:        struct mbuf             *m_new = NULL;
                   1311:        struct bge_rx_bd        *r;
                   1312:        int                     error;
                   1313:
                   1314:        if (dmamap == NULL) {
                   1315:                error = bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1,
                   1316:                    MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap);
                   1317:                if (error != 0)
                   1318:                        return error;
                   1319:        }
                   1320:
                   1321:        sc->bge_cdata.bge_rx_std_map[i] = dmamap;
                   1322:
                   1323:        if (m == NULL) {
                   1324:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1.158     msaitoh  1325:                if (m_new == NULL)
1.170     msaitoh  1326:                        return ENOBUFS;
1.1       fvdl     1327:
                   1328:                MCLGET(m_new, M_DONTWAIT);
                   1329:                if (!(m_new->m_flags & M_EXT)) {
                   1330:                        m_freem(m_new);
1.170     msaitoh  1331:                        return ENOBUFS;
1.1       fvdl     1332:                }
                   1333:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                   1334:
                   1335:        } else {
                   1336:                m_new = m;
                   1337:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                   1338:                m_new->m_data = m_new->m_ext.ext_buf;
                   1339:        }
1.157     msaitoh  1340:        if (!(sc->bge_flags & BGE_RX_ALIGNBUG))
1.125     bouyer   1341:            m_adj(m_new, ETHER_ALIGN);
1.124     bouyer   1342:        if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_new,
                   1343:            BUS_DMA_READ|BUS_DMA_NOWAIT))
1.170     msaitoh  1344:                return ENOBUFS;
1.178     msaitoh  1345:        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
1.124     bouyer   1346:            BUS_DMASYNC_PREREAD);
1.1       fvdl     1347:
                   1348:        sc->bge_cdata.bge_rx_std_chain[i] = m_new;
                   1349:        r = &sc->bge_rdata->bge_rx_std_ring[i];
1.172     msaitoh  1350:        BGE_HOSTADDR(r->bge_addr, dmamap->dm_segs[0].ds_addr);
1.1       fvdl     1351:        r->bge_flags = BGE_RXBDFLAG_END;
                   1352:        r->bge_len = m_new->m_len;
                   1353:        r->bge_idx = i;
                   1354:
                   1355:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   1356:            offsetof(struct bge_ring_data, bge_rx_std_ring) +
                   1357:                i * sizeof (struct bge_rx_bd),
                   1358:            sizeof (struct bge_rx_bd),
                   1359:            BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
                   1360:
1.170     msaitoh  1361:        return 0;
1.1       fvdl     1362: }
                   1363:
                   1364: /*
                   1365:  * Initialize a jumbo receive ring descriptor. This allocates
                   1366:  * a jumbo buffer from the pool managed internally by the driver.
                   1367:  */
1.104     thorpej  1368: static int
                   1369: bge_newbuf_jumbo(struct bge_softc *sc, int i, struct mbuf *m)
1.1       fvdl     1370: {
                   1371:        struct mbuf *m_new = NULL;
                   1372:        struct bge_rx_bd *r;
1.126     christos 1373:        void *buf = NULL;
1.1       fvdl     1374:
                   1375:        if (m == NULL) {
                   1376:
                   1377:                /* Allocate the mbuf. */
                   1378:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1.158     msaitoh  1379:                if (m_new == NULL)
1.170     msaitoh  1380:                        return ENOBUFS;
1.1       fvdl     1381:
                   1382:                /* Allocate the jumbo buffer */
                   1383:                buf = bge_jalloc(sc);
                   1384:                if (buf == NULL) {
                   1385:                        m_freem(m_new);
1.138     joerg    1386:                        aprint_error_dev(sc->bge_dev,
                   1387:                            "jumbo allocation failed -- packet dropped!\n");
1.170     msaitoh  1388:                        return ENOBUFS;
1.1       fvdl     1389:                }
                   1390:
                   1391:                /* Attach the buffer to the mbuf. */
                   1392:                m_new->m_len = m_new->m_pkthdr.len = BGE_JUMBO_FRAMELEN;
                   1393:                MEXTADD(m_new, buf, BGE_JUMBO_FRAMELEN, M_DEVBUF,
                   1394:                    bge_jfree, sc);
1.74      yamt     1395:                m_new->m_flags |= M_EXT_RW;
1.1       fvdl     1396:        } else {
                   1397:                m_new = m;
1.124     bouyer   1398:                buf = m_new->m_data = m_new->m_ext.ext_buf;
1.1       fvdl     1399:                m_new->m_ext.ext_size = BGE_JUMBO_FRAMELEN;
                   1400:        }
1.157     msaitoh  1401:        if (!(sc->bge_flags & BGE_RX_ALIGNBUG))
1.125     bouyer   1402:            m_adj(m_new, ETHER_ALIGN);
1.124     bouyer   1403:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_cdata.bge_rx_jumbo_map,
1.126     christos 1404:            mtod(m_new, char *) - (char *)sc->bge_cdata.bge_jumbo_buf, BGE_JLEN,
1.124     bouyer   1405:            BUS_DMASYNC_PREREAD);
1.1       fvdl     1406:        /* Set up the descriptor. */
                   1407:        r = &sc->bge_rdata->bge_rx_jumbo_ring[i];
                   1408:        sc->bge_cdata.bge_rx_jumbo_chain[i] = m_new;
1.172     msaitoh  1409:        BGE_HOSTADDR(r->bge_addr, BGE_JUMBO_DMA_ADDR(sc, m_new));
1.1       fvdl     1410:        r->bge_flags = BGE_RXBDFLAG_END|BGE_RXBDFLAG_JUMBO_RING;
                   1411:        r->bge_len = m_new->m_len;
                   1412:        r->bge_idx = i;
                   1413:
                   1414:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   1415:            offsetof(struct bge_ring_data, bge_rx_jumbo_ring) +
                   1416:                i * sizeof (struct bge_rx_bd),
                   1417:            sizeof (struct bge_rx_bd),
                   1418:            BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
                   1419:
1.170     msaitoh  1420:        return 0;
1.1       fvdl     1421: }
                   1422:
                   1423: /*
                   1424:  * The standard receive ring has 512 entries in it. At 2K per mbuf cluster,
                   1425:  * that's 1MB or memory, which is a lot. For now, we fill only the first
                   1426:  * 256 ring entries and hope that our CPU is fast enough to keep up with
                   1427:  * the NIC.
                   1428:  */
1.104     thorpej  1429: static int
                   1430: bge_init_rx_ring_std(struct bge_softc *sc)
1.1       fvdl     1431: {
                   1432:        int i;
                   1433:
                   1434:        if (sc->bge_flags & BGE_RXRING_VALID)
                   1435:                return 0;
                   1436:
                   1437:        for (i = 0; i < BGE_SSLOTS; i++) {
                   1438:                if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS)
1.170     msaitoh  1439:                        return ENOBUFS;
1.1       fvdl     1440:        }
                   1441:
                   1442:        sc->bge_std = i - 1;
1.151     cegger   1443:        bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
1.1       fvdl     1444:
                   1445:        sc->bge_flags |= BGE_RXRING_VALID;
                   1446:
1.170     msaitoh  1447:        return 0;
1.1       fvdl     1448: }
                   1449:
1.104     thorpej  1450: static void
                   1451: bge_free_rx_ring_std(struct bge_softc *sc)
1.1       fvdl     1452: {
                   1453:        int i;
                   1454:
                   1455:        if (!(sc->bge_flags & BGE_RXRING_VALID))
                   1456:                return;
                   1457:
                   1458:        for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
                   1459:                if (sc->bge_cdata.bge_rx_std_chain[i] != NULL) {
                   1460:                        m_freem(sc->bge_cdata.bge_rx_std_chain[i]);
                   1461:                        sc->bge_cdata.bge_rx_std_chain[i] = NULL;
1.87      perry    1462:                        bus_dmamap_destroy(sc->bge_dmatag,
1.1       fvdl     1463:                            sc->bge_cdata.bge_rx_std_map[i]);
                   1464:                }
                   1465:                memset((char *)&sc->bge_rdata->bge_rx_std_ring[i], 0,
                   1466:                    sizeof(struct bge_rx_bd));
                   1467:        }
                   1468:
                   1469:        sc->bge_flags &= ~BGE_RXRING_VALID;
                   1470: }
                   1471:
1.104     thorpej  1472: static int
                   1473: bge_init_rx_ring_jumbo(struct bge_softc *sc)
1.1       fvdl     1474: {
                   1475:        int i;
1.34      jonathan 1476:        volatile struct bge_rcb *rcb;
1.1       fvdl     1477:
1.59      martin   1478:        if (sc->bge_flags & BGE_JUMBO_RXRING_VALID)
                   1479:                return 0;
                   1480:
1.1       fvdl     1481:        for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
                   1482:                if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
1.170     msaitoh  1483:                        return ENOBUFS;
1.1       fvdl     1484:        };
                   1485:
                   1486:        sc->bge_jumbo = i - 1;
1.59      martin   1487:        sc->bge_flags |= BGE_JUMBO_RXRING_VALID;
1.1       fvdl     1488:
                   1489:        rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
1.34      jonathan 1490:        rcb->bge_maxlen_flags = 0;
                   1491:        CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
1.1       fvdl     1492:
1.151     cegger   1493:        bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
1.1       fvdl     1494:
1.170     msaitoh  1495:        return 0;
1.1       fvdl     1496: }
                   1497:
1.104     thorpej  1498: static void
                   1499: bge_free_rx_ring_jumbo(struct bge_softc *sc)
1.1       fvdl     1500: {
                   1501:        int i;
                   1502:
                   1503:        if (!(sc->bge_flags & BGE_JUMBO_RXRING_VALID))
                   1504:                return;
                   1505:
                   1506:        for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
                   1507:                if (sc->bge_cdata.bge_rx_jumbo_chain[i] != NULL) {
                   1508:                        m_freem(sc->bge_cdata.bge_rx_jumbo_chain[i]);
                   1509:                        sc->bge_cdata.bge_rx_jumbo_chain[i] = NULL;
                   1510:                }
                   1511:                memset((char *)&sc->bge_rdata->bge_rx_jumbo_ring[i], 0,
                   1512:                    sizeof(struct bge_rx_bd));
                   1513:        }
                   1514:
                   1515:        sc->bge_flags &= ~BGE_JUMBO_RXRING_VALID;
                   1516: }
                   1517:
1.104     thorpej  1518: static void
                   1519: bge_free_tx_ring(struct bge_softc *sc)
1.1       fvdl     1520: {
                   1521:        int i, freed;
                   1522:        struct txdmamap_pool_entry *dma;
                   1523:
                   1524:        if (!(sc->bge_flags & BGE_TXRING_VALID))
                   1525:                return;
                   1526:
                   1527:        freed = 0;
                   1528:
                   1529:        for (i = 0; i < BGE_TX_RING_CNT; i++) {
                   1530:                if (sc->bge_cdata.bge_tx_chain[i] != NULL) {
                   1531:                        freed++;
                   1532:                        m_freem(sc->bge_cdata.bge_tx_chain[i]);
                   1533:                        sc->bge_cdata.bge_tx_chain[i] = NULL;
                   1534:                        SLIST_INSERT_HEAD(&sc->txdma_list, sc->txdma[i],
                   1535:                                            link);
                   1536:                        sc->txdma[i] = 0;
                   1537:                }
                   1538:                memset((char *)&sc->bge_rdata->bge_tx_ring[i], 0,
                   1539:                    sizeof(struct bge_tx_bd));
                   1540:        }
                   1541:
                   1542:        while ((dma = SLIST_FIRST(&sc->txdma_list))) {
                   1543:                SLIST_REMOVE_HEAD(&sc->txdma_list, link);
                   1544:                bus_dmamap_destroy(sc->bge_dmatag, dma->dmamap);
                   1545:                free(dma, M_DEVBUF);
                   1546:        }
                   1547:
                   1548:        sc->bge_flags &= ~BGE_TXRING_VALID;
                   1549: }
                   1550:
1.104     thorpej  1551: static int
                   1552: bge_init_tx_ring(struct bge_softc *sc)
1.1       fvdl     1553: {
                   1554:        int i;
                   1555:        bus_dmamap_t dmamap;
                   1556:        struct txdmamap_pool_entry *dma;
                   1557:
                   1558:        if (sc->bge_flags & BGE_TXRING_VALID)
                   1559:                return 0;
                   1560:
                   1561:        sc->bge_txcnt = 0;
                   1562:        sc->bge_tx_saved_considx = 0;
1.94      jonathan 1563:
                   1564:        /* Initialize transmit producer index for host-memory send ring. */
                   1565:        sc->bge_tx_prodidx = 0;
1.151     cegger   1566:        bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
1.158     msaitoh  1567:        /* 5700 b2 errata */
                   1568:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
1.151     cegger   1569:                bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
1.25      jonathan 1570:
1.158     msaitoh  1571:        /* NIC-memory send ring not used; initialize to zero. */
1.151     cegger   1572:        bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
1.158     msaitoh  1573:        /* 5700 b2 errata */
                   1574:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
1.151     cegger   1575:                bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
1.1       fvdl     1576:
                   1577:        SLIST_INIT(&sc->txdma_list);
                   1578:        for (i = 0; i < BGE_RSLOTS; i++) {
1.95      jonathan 1579:                if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX,
1.1       fvdl     1580:                    BGE_NTXSEG, ETHER_MAX_LEN_JUMBO, 0, BUS_DMA_NOWAIT,
                   1581:                    &dmamap))
1.170     msaitoh  1582:                        return ENOBUFS;
1.1       fvdl     1583:                if (dmamap == NULL)
                   1584:                        panic("dmamap NULL in bge_init_tx_ring");
                   1585:                dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT);
                   1586:                if (dma == NULL) {
1.138     joerg    1587:                        aprint_error_dev(sc->bge_dev,
                   1588:                            "can't alloc txdmamap_pool_entry\n");
1.1       fvdl     1589:                        bus_dmamap_destroy(sc->bge_dmatag, dmamap);
1.170     msaitoh  1590:                        return ENOMEM;
1.1       fvdl     1591:                }
                   1592:                dma->dmamap = dmamap;
                   1593:                SLIST_INSERT_HEAD(&sc->txdma_list, dma, link);
                   1594:        }
                   1595:
                   1596:        sc->bge_flags |= BGE_TXRING_VALID;
                   1597:
1.170     msaitoh  1598:        return 0;
1.1       fvdl     1599: }
                   1600:
1.104     thorpej  1601: static void
                   1602: bge_setmulti(struct bge_softc *sc)
1.1       fvdl     1603: {
                   1604:        struct ethercom         *ac = &sc->ethercom;
                   1605:        struct ifnet            *ifp = &ac->ec_if;
                   1606:        struct ether_multi      *enm;
                   1607:        struct ether_multistep  step;
1.170     msaitoh  1608:        uint32_t                hashes[4] = { 0, 0, 0, 0 };
                   1609:        uint32_t                h;
1.1       fvdl     1610:        int                     i;
                   1611:
1.13      thorpej  1612:        if (ifp->if_flags & IFF_PROMISC)
                   1613:                goto allmulti;
1.1       fvdl     1614:
                   1615:        /* Now program new ones. */
                   1616:        ETHER_FIRST_MULTI(step, ac, enm);
                   1617:        while (enm != NULL) {
1.13      thorpej  1618:                if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
                   1619:                        /*
                   1620:                         * We must listen to a range of multicast addresses.
                   1621:                         * For now, just accept all multicasts, rather than
                   1622:                         * trying to set only those filter bits needed to match
                   1623:                         * the range.  (At this time, the only use of address
                   1624:                         * ranges is for IP multicast routing, for which the
                   1625:                         * range is big enough to require all bits set.)
                   1626:                         */
                   1627:                        goto allmulti;
                   1628:                }
                   1629:
1.158     msaitoh  1630:                h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
1.1       fvdl     1631:
1.158     msaitoh  1632:                /* Just want the 7 least-significant bits. */
                   1633:                h &= 0x7f;
1.1       fvdl     1634:
1.158     msaitoh  1635:                hashes[(h & 0x60) >> 5] |= 1 << (h & 0x1F);
                   1636:                ETHER_NEXT_MULTI(step, enm);
1.25      jonathan 1637:        }
                   1638:
1.158     msaitoh  1639:        ifp->if_flags &= ~IFF_ALLMULTI;
                   1640:        goto setit;
1.1       fvdl     1641:
1.158     msaitoh  1642:  allmulti:
                   1643:        ifp->if_flags |= IFF_ALLMULTI;
                   1644:        hashes[0] = hashes[1] = hashes[2] = hashes[3] = 0xffffffff;
1.133     markd    1645:
1.158     msaitoh  1646:  setit:
                   1647:        for (i = 0; i < 4; i++)
                   1648:                CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]);
                   1649: }
1.133     markd    1650:
1.177     msaitoh  1651: static void
1.178     msaitoh  1652: bge_sig_pre_reset(struct bge_softc *sc, int type)
1.177     msaitoh  1653: {
                   1654:        /*
                   1655:         * Some chips don't like this so only do this if ASF is enabled
                   1656:         */
                   1657:        if (sc->bge_asf_mode)
                   1658:                bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
1.1       fvdl     1659:
1.177     msaitoh  1660:        if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                   1661:                switch (type) {
                   1662:                case BGE_RESET_START:
                   1663:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
                   1664:                        break;
                   1665:                case BGE_RESET_STOP:
                   1666:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
                   1667:                        break;
                   1668:                }
                   1669:        }
                   1670: }
                   1671:
                   1672: static void
1.178     msaitoh  1673: bge_sig_post_reset(struct bge_softc *sc, int type)
1.177     msaitoh  1674: {
1.178     msaitoh  1675:
1.177     msaitoh  1676:        if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
                   1677:                switch (type) {
                   1678:                case BGE_RESET_START:
                   1679:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);
                   1680:                        /* START DONE */
                   1681:                        break;
                   1682:                case BGE_RESET_STOP:
                   1683:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);
                   1684:                        break;
                   1685:                }
                   1686:        }
                   1687: }
                   1688:
                   1689: static void
1.178     msaitoh  1690: bge_sig_legacy(struct bge_softc *sc, int type)
1.177     msaitoh  1691: {
1.178     msaitoh  1692:
1.177     msaitoh  1693:        if (sc->bge_asf_mode) {
                   1694:                switch (type) {
                   1695:                case BGE_RESET_START:
                   1696:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
                   1697:                        break;
                   1698:                case BGE_RESET_STOP:
                   1699:                        bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
                   1700:                        break;
                   1701:                }
                   1702:        }
                   1703: }
                   1704:
                   1705: static void
1.178     msaitoh  1706: bge_stop_fw(struct bge_softc *sc)
1.177     msaitoh  1707: {
                   1708:        int i;
1.1       fvdl     1709:
1.177     msaitoh  1710:        if (sc->bge_asf_mode) {
                   1711:                bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
                   1712:                CSR_WRITE_4(sc, BGE_CPU_EVENT,
                   1713:                    CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
                   1714:
1.178     msaitoh  1715:                for (i = 0; i < 100; i++) {
1.177     msaitoh  1716:                        if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
                   1717:                                break;
                   1718:                        DELAY(10);
                   1719:                }
                   1720:        }
                   1721: }
1.1       fvdl     1722:
1.180     msaitoh  1723: static int
                   1724: bge_poll_fw(struct bge_softc *sc)
                   1725: {
                   1726:        uint32_t val;
                   1727:        int i;
                   1728:
                   1729:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   1730:                for (i = 0; i < BGE_TIMEOUT; i++) {
                   1731:                        val = CSR_READ_4(sc, BGE_VCPU_STATUS);
                   1732:                        if (val & BGE_VCPU_STATUS_INIT_DONE)
                   1733:                                break;
                   1734:                        DELAY(100);
                   1735:                }
                   1736:                if (i >= BGE_TIMEOUT) {
                   1737:                        aprint_error_dev(sc->bge_dev, "reset timed out\n");
                   1738:                        return -1;
                   1739:                }
                   1740:        } else if ((sc->bge_flags & BGE_NO_EEPROM) == 0) {
                   1741:                /*
                   1742:                 * Poll the value location we just wrote until
                   1743:                 * we see the 1's complement of the magic number.
                   1744:                 * This indicates that the firmware initialization
                   1745:                 * is complete.
                   1746:                 * XXX 1000ms for Flash and 10000ms for SEEPROM.
                   1747:                 */
                   1748:                for (i = 0; i < BGE_TIMEOUT; i++) {
                   1749:                        val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
                   1750:                        if (val == ~BGE_MAGIC_NUMBER)
                   1751:                                break;
                   1752:                        DELAY(10);
                   1753:                }
                   1754:
                   1755:                if (i >= BGE_TIMEOUT) {
                   1756:                        aprint_error_dev(sc->bge_dev,
                   1757:                            "firmware handshake timed out, val = %x\n", val);
                   1758:                        return -1;
                   1759:                }
                   1760:        }
                   1761:
                   1762:        return 0;
                   1763: }
                   1764:
1.158     msaitoh  1765: /*
                   1766:  * Do endian, PCI and DMA initialization. Also check the on-board ROM
                   1767:  * self-test results.
                   1768:  */
                   1769: static int
                   1770: bge_chipinit(struct bge_softc *sc)
                   1771: {
1.178     msaitoh  1772:        int i;
                   1773:        uint32_t dma_rw_ctl;
1.1       fvdl     1774:
1.158     msaitoh  1775:        /* Set endianness before we access any non-PCI registers. */
                   1776:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
                   1777:            BGE_INIT);
1.1       fvdl     1778:
1.158     msaitoh  1779:        /* Set power state to D0. */
                   1780:        bge_setpowerstate(sc, 0);
1.1       fvdl     1781:
1.158     msaitoh  1782:        /* Clear the MAC control register */
                   1783:        CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
1.1       fvdl     1784:
1.158     msaitoh  1785:        /*
                   1786:         * Clear the MAC statistics block in the NIC's
                   1787:         * internal memory.
                   1788:         */
                   1789:        for (i = BGE_STATS_BLOCK;
1.170     msaitoh  1790:            i < BGE_STATS_BLOCK_END + 1; i += sizeof(uint32_t))
1.158     msaitoh  1791:                BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
1.1       fvdl     1792:
1.158     msaitoh  1793:        for (i = BGE_STATUS_BLOCK;
1.170     msaitoh  1794:            i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
1.158     msaitoh  1795:                BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
1.1       fvdl     1796:
1.158     msaitoh  1797:        /* Set up the PCI DMA control register. */
1.166     msaitoh  1798:        dma_rw_ctl = BGE_PCI_READ_CMD | BGE_PCI_WRITE_CMD;
1.158     msaitoh  1799:        if (sc->bge_flags & BGE_PCIE) {
1.166     msaitoh  1800:                /* Read watermark not used, 128 bytes for write. */
1.158     msaitoh  1801:                DPRINTFN(4, ("(%s: PCI-Express DMA setting)\n",
                   1802:                    device_xname(sc->bge_dev)));
1.166     msaitoh  1803:                dma_rw_ctl |= (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
1.170     msaitoh  1804:        } else if (sc->bge_flags & BGE_PCIX) {
1.158     msaitoh  1805:                DPRINTFN(4, ("(:%s: PCI-X DMA setting)\n",
                   1806:                    device_xname(sc->bge_dev)));
                   1807:                /* PCI-X bus */
1.172     msaitoh  1808:                if (BGE_IS_5714_FAMILY(sc)) {
                   1809:                        /* 256 bytes for read and write. */
                   1810:                        dma_rw_ctl |= (0x02 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
                   1811:                            (0x02 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
                   1812:
                   1813:                        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780)
                   1814:                                dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL;
                   1815:                        else
                   1816:                                dma_rw_ctl |= BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;
                   1817:                } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
                   1818:                        /* 1536 bytes for read, 384 bytes for write. */
                   1819:                        dma_rw_ctl |=
1.158     msaitoh  1820:                          (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
                   1821:                          (0x3 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
1.172     msaitoh  1822:                } else {
                   1823:                        /* 384 bytes for read and write. */
                   1824:                        dma_rw_ctl |= (0x03 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
                   1825:                            (0x03 << BGE_PCIDMARWCTL_WR_WAT_SHIFT) |
                   1826:                            (0x0F);
                   1827:                }
                   1828:
                   1829:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||
                   1830:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
                   1831:                        uint32_t tmp;
                   1832:
                   1833:                        /* Set ONEDMA_ATONCE for hardware workaround. */
                   1834:                        tmp = CSR_READ_4(sc, BGE_PCI_CLKCTL) & 0x1f;
                   1835:                        if (tmp == 6 || tmp == 7)
                   1836:                                dma_rw_ctl |=
                   1837:                                    BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL;
                   1838:
                   1839:                        /* Set PCI-X DMA write workaround. */
                   1840:                        dma_rw_ctl |= BGE_PCIDMARWCTL_ASRT_ALL_BE;
1.158     msaitoh  1841:                }
                   1842:        } else {
1.172     msaitoh  1843:                /* Conventional PCI bus: 256 bytes for read and write. */
1.158     msaitoh  1844:                DPRINTFN(4, ("(%s: PCI 2.2 DMA setting)\n",
                   1845:                    device_xname(sc->bge_dev)));
1.185     msaitoh  1846:                dma_rw_ctl |= (0x7 << BGE_PCIDMARWCTL_RD_WAT_SHIFT) |
1.166     msaitoh  1847:                   (0x7 << BGE_PCIDMARWCTL_WR_WAT_SHIFT);
1.160     msaitoh  1848:                if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5705 &&
                   1849:                    BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5750)
1.158     msaitoh  1850:                        dma_rw_ctl |= 0x0F;
                   1851:        }
1.157     msaitoh  1852:
1.161     msaitoh  1853:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   1854:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701)
                   1855:                dma_rw_ctl |= BGE_PCIDMARWCTL_USE_MRM |
                   1856:                    BGE_PCIDMARWCTL_ASRT_ALL_BE;
1.178     msaitoh  1857:
1.161     msaitoh  1858:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||
                   1859:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                   1860:                dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
                   1861:
1.177     msaitoh  1862:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
                   1863:            dma_rw_ctl);
1.120     tsutsui  1864:
1.158     msaitoh  1865:        /*
                   1866:         * Set up general mode register.
                   1867:         */
1.161     msaitoh  1868:        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
1.177     msaitoh  1869:            BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
                   1870:            BGE_MODECTL_TX_NO_PHDR_CSUM | BGE_MODECTL_RX_NO_PHDR_CSUM);
1.16      thorpej  1871:
1.158     msaitoh  1872:        /*
1.172     msaitoh  1873:         * BCM5701 B5 have a bug causing data corruption when using
                   1874:         * 64-bit DMA reads, which can be terminated early and then
                   1875:         * completed later as 32-bit accesses, in combination with
                   1876:         * certain bridges.
                   1877:         */
                   1878:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 &&
                   1879:            sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
                   1880:                BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
                   1881:
                   1882:        /*
1.177     msaitoh  1883:         * Tell the firmware the driver is running
                   1884:         */
                   1885:        if (sc->bge_asf_mode & ASF_STACKUP)
                   1886:                BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
                   1887:
                   1888:        /*
1.158     msaitoh  1889:         * Disable memory write invalidate.  Apparently it is not supported
                   1890:         * properly by these devices.
                   1891:         */
1.172     msaitoh  1892:        PCI_CLRBIT(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG,
                   1893:                   PCI_COMMAND_INVALIDATE_ENABLE);
1.16      thorpej  1894:
1.158     msaitoh  1895: #ifdef __brokenalpha__
                   1896:        /*
                   1897:         * Must insure that we do not cross an 8K (bytes) boundary
                   1898:         * for DMA reads.  Our highest limit is 1K bytes.  This is a
                   1899:         * restriction on some ALPHA platforms with early revision
                   1900:         * 21174 PCI chipsets, such as the AlphaPC 164lx
                   1901:         */
                   1902:        PCI_SETBIT(sc, BGE_PCI_DMA_RW_CTL, BGE_PCI_READ_BNDRY_1024, 4);
                   1903: #endif
1.16      thorpej  1904:
1.158     msaitoh  1905:        /* Set the timer prescaler (always 66MHz) */
                   1906:        CSR_WRITE_4(sc, BGE_MISC_CFG, 65 << 1/*BGE_32BITTIME_66MHZ*/);
1.16      thorpej  1907:
1.159     msaitoh  1908:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   1909:                DELAY(40);      /* XXX */
                   1910:
                   1911:                /* Put PHY into ready state */
                   1912:                BGE_CLRBIT(sc, BGE_MISC_CFG, BGE_MISCCFG_EPHY_IDDQ);
                   1913:                CSR_READ_4(sc, BGE_MISC_CFG); /* Flush */
                   1914:                DELAY(40);
                   1915:        }
                   1916:
1.170     msaitoh  1917:        return 0;
1.158     msaitoh  1918: }
1.16      thorpej  1919:
1.158     msaitoh  1920: static int
                   1921: bge_blockinit(struct bge_softc *sc)
                   1922: {
1.177     msaitoh  1923:        volatile struct bge_rcb  *rcb;
                   1924:        bus_size_t rcb_addr;
                   1925:        int i;
                   1926:        struct ifnet *ifp = &sc->ethercom.ec_if;
                   1927:        bge_hostaddr taddr;
                   1928:        uint32_t val;
1.16      thorpej  1929:
1.158     msaitoh  1930:        /*
                   1931:         * Initialize the memory window pointer register so that
                   1932:         * we can access the first 32K of internal NIC RAM. This will
                   1933:         * allow us to set up the TX send ring RCBs and the RX return
                   1934:         * ring RCBs, plus other things which live in NIC memory.
                   1935:         */
1.55      pooka    1936:
1.158     msaitoh  1937:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
1.120     tsutsui  1938:
1.180     msaitoh  1939:        /* Step 33: Configure mbuf memory pool */
1.172     msaitoh  1940:        if (BGE_IS_5700_FAMILY(sc)) {
                   1941:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_BASEADDR,
                   1942:                    BGE_BUFFPOOL_1);
                   1943:
                   1944:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                   1945:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x10000);
                   1946:                else
                   1947:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_LEN, 0x18000);
1.40      fvdl     1948:
1.158     msaitoh  1949:                /* Configure DMA resource pool */
                   1950:                CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_BASEADDR,
                   1951:                    BGE_DMA_DESCRIPTORS);
                   1952:                CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LEN, 0x2000);
                   1953:        }
1.40      fvdl     1954:
1.180     msaitoh  1955:        /* Step 35: Configure mbuf pool watermarks */
1.158     msaitoh  1956: #ifdef ORIG_WPAUL_VALUES
                   1957:        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 24);
                   1958:        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 24);
                   1959:        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 48);
                   1960: #else
1.49      fvdl     1961:
1.158     msaitoh  1962:        /* new broadcom docs strongly recommend these: */
1.172     msaitoh  1963:        if (!BGE_IS_5705_PLUS(sc)) {
1.158     msaitoh  1964:                if (ifp->if_mtu > ETHER_MAX_LEN) {
                   1965:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
                   1966:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
                   1967:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
                   1968:                } else {
                   1969:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 304);
                   1970:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 152);
                   1971:                        CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 380);
                   1972:                }
                   1973:        } else if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   1974:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
                   1975:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x04);
                   1976:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x10);
                   1977:        } else {
                   1978:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
                   1979:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x10);
                   1980:                CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
                   1981:        }
                   1982: #endif
1.25      jonathan 1983:
1.180     msaitoh  1984:        /* Step 36: Configure DMA resource watermarks */
1.158     msaitoh  1985:        CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_LOWAT, 5);
                   1986:        CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
1.51      fvdl     1987:
1.180     msaitoh  1988:        /* Step 38: Enable buffer manager */
1.172     msaitoh  1989:        CSR_WRITE_4(sc, BGE_BMAN_MODE,
                   1990:            BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);
1.44      hannken  1991:
1.180     msaitoh  1992:        /* Step 39: Poll for buffer manager start indication */
1.172     msaitoh  1993:        for (i = 0; i < BGE_TIMEOUT * 2; i++) {
                   1994:                if (CSR_READ_4(sc, BGE_BMAN_MODE) & BGE_BMANMODE_ENABLE)
                   1995:                        break;
                   1996:                DELAY(10);
                   1997:        }
1.51      fvdl     1998:
1.172     msaitoh  1999:        if (i == BGE_TIMEOUT * 2) {
                   2000:                aprint_error_dev(sc->bge_dev,
                   2001:                    "buffer manager failed to start\n");
                   2002:                return ENXIO;
1.158     msaitoh  2003:        }
1.51      fvdl     2004:
1.180     msaitoh  2005:        /* Step 40: Enable flow-through queues */
1.158     msaitoh  2006:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
                   2007:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
1.76      cube     2008:
1.158     msaitoh  2009:        /* Wait until queue initialization is complete */
1.172     msaitoh  2010:        for (i = 0; i < BGE_TIMEOUT * 2; i++) {
1.158     msaitoh  2011:                if (CSR_READ_4(sc, BGE_FTQ_RESET) == 0)
                   2012:                        break;
                   2013:                DELAY(10);
                   2014:        }
1.76      cube     2015:
1.172     msaitoh  2016:        if (i == BGE_TIMEOUT * 2) {
1.158     msaitoh  2017:                aprint_error_dev(sc->bge_dev,
                   2018:                    "flow-through queue init failed\n");
1.170     msaitoh  2019:                return ENXIO;
1.158     msaitoh  2020:        }
1.92      gavan    2021:
1.180     msaitoh  2022:        /* Step 41: Initialize the standard RX ring control block */
1.158     msaitoh  2023:        rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
1.172     msaitoh  2024:        BGE_HOSTADDR(rcb->bge_hostaddr, BGE_RING_DMA_ADDR(sc, bge_rx_std_ring));
                   2025:        if (BGE_IS_5705_PLUS(sc))
1.158     msaitoh  2026:                rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(512, 0);
                   2027:        else
                   2028:                rcb->bge_maxlen_flags =
                   2029:                    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
1.172     msaitoh  2030:        rcb->bge_nicaddr = BGE_STD_RX_RINGS;
1.158     msaitoh  2031:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);
                   2032:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);
                   2033:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
                   2034:        CSR_WRITE_4(sc, BGE_RX_STD_RCB_NICADDR, rcb->bge_nicaddr);
1.119     tsutsui  2035:
1.158     msaitoh  2036:        /*
1.180     msaitoh  2037:         * Step 42: Initialize the jumbo RX ring control block
1.158     msaitoh  2038:         * We set the 'ring disabled' bit in the flags
                   2039:         * field until we're actually ready to start
                   2040:         * using this ring (i.e. once we set the MTU
                   2041:         * high enough to require it).
                   2042:         */
1.166     msaitoh  2043:        if (BGE_IS_JUMBO_CAPABLE(sc)) {
1.158     msaitoh  2044:                rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
1.172     msaitoh  2045:                BGE_HOSTADDR(rcb->bge_hostaddr,
1.158     msaitoh  2046:                    BGE_RING_DMA_ADDR(sc, bge_rx_jumbo_ring));
                   2047:                rcb->bge_maxlen_flags =
                   2048:                    BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN,
                   2049:                        BGE_RCB_FLAG_RING_DISABLED);
1.172     msaitoh  2050:                rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
1.158     msaitoh  2051:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI,
                   2052:                    rcb->bge_hostaddr.bge_addr_hi);
                   2053:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,
                   2054:                    rcb->bge_hostaddr.bge_addr_lo);
                   2055:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,
                   2056:                    rcb->bge_maxlen_flags);
                   2057:                CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_NICADDR, rcb->bge_nicaddr);
1.149     sborrill 2058:
1.158     msaitoh  2059:                /* Set up dummy disabled mini ring RCB */
                   2060:                rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;
                   2061:                rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
                   2062:                    BGE_RCB_FLAG_RING_DISABLED);
                   2063:                CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS,
                   2064:                    rcb->bge_maxlen_flags);
1.133     markd    2065:
1.158     msaitoh  2066:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   2067:                    offsetof(struct bge_ring_data, bge_info),
                   2068:                    sizeof (struct bge_gib),
                   2069:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   2070:        }
1.133     markd    2071:
1.158     msaitoh  2072:        /*
                   2073:         * Set the BD ring replenish thresholds. The recommended
                   2074:         * values are 1/8th the number of descriptors allocated to
                   2075:         * each ring.
                   2076:         */
                   2077:        i = BGE_STD_RX_RING_CNT / 8;
1.133     markd    2078:
1.158     msaitoh  2079:        /*
                   2080:         * Use a value of 8 for the following chips to workaround HW errata.
                   2081:         * Some of these chips have been added based on empirical
                   2082:         * evidence (they don't work unless this is done).
                   2083:         */
1.172     msaitoh  2084:        if (BGE_IS_5705_PLUS(sc))
1.158     msaitoh  2085:                i = 8;
1.16      thorpej  2086:
1.158     msaitoh  2087:        CSR_WRITE_4(sc, BGE_RBDI_STD_REPL_THRESH, i);
1.161     msaitoh  2088:        CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH, BGE_JUMBO_RX_RING_CNT / 8);
1.157     msaitoh  2089:
1.172     msaitoh  2090:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
                   2091:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765) {
                   2092:                CSR_WRITE_4(sc, BGE_STD_REPL_LWM, 4);
                   2093:                CSR_WRITE_4(sc, BGE_JUMBO_REPL_LWM, 4);
                   2094:        }
                   2095:
1.158     msaitoh  2096:        /*
                   2097:         * Disable all unused send rings by setting the 'ring disabled'
                   2098:         * bit in the flags field of all the TX send ring control blocks.
                   2099:         * These are located in NIC memory.
                   2100:         */
                   2101:        rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
                   2102:        for (i = 0; i < BGE_TX_RINGS_EXTSSRAM_MAX; i++) {
                   2103:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
                   2104:                    BGE_RCB_MAXLEN_FLAGS(0, BGE_RCB_FLAG_RING_DISABLED));
                   2105:                RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
                   2106:                rcb_addr += sizeof(struct bge_rcb);
                   2107:        }
1.157     msaitoh  2108:
1.158     msaitoh  2109:        /* Configure TX RCB 0 (we use only the first ring) */
                   2110:        rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
1.172     msaitoh  2111:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));
1.158     msaitoh  2112:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
                   2113:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
                   2114:        RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,
                   2115:                    BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
1.172     msaitoh  2116:        if (BGE_IS_5700_FAMILY(sc))
1.158     msaitoh  2117:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
                   2118:                    BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
1.157     msaitoh  2119:
1.158     msaitoh  2120:        /* Disable all unused RX return rings */
                   2121:        rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
                   2122:        for (i = 0; i < BGE_RX_RINGS_MAX; i++) {
                   2123:                RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
                   2124:                RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, 0);
                   2125:                RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
1.172     msaitoh  2126:                    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt,
                   2127:                        BGE_RCB_FLAG_RING_DISABLED));
1.158     msaitoh  2128:                RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0);
                   2129:                bge_writembx(sc, BGE_MBX_RX_CONS0_LO +
1.170     msaitoh  2130:                    (i * (sizeof(uint64_t))), 0);
1.158     msaitoh  2131:                rcb_addr += sizeof(struct bge_rcb);
                   2132:        }
1.157     msaitoh  2133:
1.158     msaitoh  2134:        /* Initialize RX ring indexes */
                   2135:        bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, 0);
                   2136:        bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, 0);
                   2137:        bge_writembx(sc, BGE_MBX_RX_MINI_PROD_LO, 0);
1.157     msaitoh  2138:
1.158     msaitoh  2139:        /*
                   2140:         * Set up RX return ring 0
                   2141:         * Note that the NIC address for RX return rings is 0x00000000.
                   2142:         * The return rings live entirely within the host, so the
                   2143:         * nicaddr field in the RCB isn't used.
                   2144:         */
                   2145:        rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
1.172     msaitoh  2146:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
1.158     msaitoh  2147:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
                   2148:        RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
                   2149:        RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0x00000000);
                   2150:        RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
                   2151:            BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));
1.157     msaitoh  2152:
1.158     msaitoh  2153:        /* Set random backoff seed for TX */
                   2154:        CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
                   2155:            CLLADDR(ifp->if_sadl)[0] + CLLADDR(ifp->if_sadl)[1] +
                   2156:            CLLADDR(ifp->if_sadl)[2] + CLLADDR(ifp->if_sadl)[3] +
                   2157:            CLLADDR(ifp->if_sadl)[4] + CLLADDR(ifp->if_sadl)[5] +
                   2158:            BGE_TX_BACKOFF_SEED_MASK);
1.157     msaitoh  2159:
1.158     msaitoh  2160:        /* Set inter-packet gap */
                   2161:        CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);
1.51      fvdl     2162:
1.158     msaitoh  2163:        /*
                   2164:         * Specify which ring to use for packets that don't match
                   2165:         * any RX rules.
                   2166:         */
                   2167:        CSR_WRITE_4(sc, BGE_RX_RULES_CFG, 0x08);
1.157     msaitoh  2168:
1.158     msaitoh  2169:        /*
                   2170:         * Configure number of RX lists. One interrupt distribution
                   2171:         * list, sixteen active lists, one bad frames class.
                   2172:         */
                   2173:        CSR_WRITE_4(sc, BGE_RXLP_CFG, 0x181);
1.157     msaitoh  2174:
1.158     msaitoh  2175:        /* Inialize RX list placement stats mask. */
                   2176:        CSR_WRITE_4(sc, BGE_RXLP_STATS_ENABLE_MASK, 0x007FFFFF);
                   2177:        CSR_WRITE_4(sc, BGE_RXLP_STATS_CTL, 0x1);
1.157     msaitoh  2178:
1.158     msaitoh  2179:        /* Disable host coalescing until we get it set up */
                   2180:        CSR_WRITE_4(sc, BGE_HCC_MODE, 0x00000000);
1.51      fvdl     2181:
1.158     msaitoh  2182:        /* Poll to make sure it's shut down. */
1.172     msaitoh  2183:        for (i = 0; i < BGE_TIMEOUT * 2; i++) {
1.158     msaitoh  2184:                if (!(CSR_READ_4(sc, BGE_HCC_MODE) & BGE_HCCMODE_ENABLE))
                   2185:                        break;
                   2186:                DELAY(10);
                   2187:        }
1.151     cegger   2188:
1.172     msaitoh  2189:        if (i == BGE_TIMEOUT * 2) {
1.158     msaitoh  2190:                aprint_error_dev(sc->bge_dev,
                   2191:                    "host coalescing engine failed to idle\n");
1.170     msaitoh  2192:                return ENXIO;
1.158     msaitoh  2193:        }
1.51      fvdl     2194:
1.158     msaitoh  2195:        /* Set up host coalescing defaults */
                   2196:        CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS, sc->bge_rx_coal_ticks);
                   2197:        CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS, sc->bge_tx_coal_ticks);
                   2198:        CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, sc->bge_rx_max_coal_bds);
                   2199:        CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS, sc->bge_tx_max_coal_bds);
1.172     msaitoh  2200:        if (BGE_IS_5700_FAMILY(sc)) {
1.158     msaitoh  2201:                CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS_INT, 0);
                   2202:                CSR_WRITE_4(sc, BGE_HCC_TX_COAL_TICKS_INT, 0);
1.51      fvdl     2203:        }
1.158     msaitoh  2204:        CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS_INT, 0);
                   2205:        CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 0);
1.51      fvdl     2206:
1.158     msaitoh  2207:        /* Set up address of statistics block */
1.172     msaitoh  2208:        if (BGE_IS_5700_FAMILY(sc)) {
                   2209:                BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_info.bge_stats));
1.158     msaitoh  2210:                CSR_WRITE_4(sc, BGE_HCC_STATS_TICKS, sc->bge_stat_ticks);
                   2211:                CSR_WRITE_4(sc, BGE_HCC_STATS_BASEADDR, BGE_STATS_BLOCK);
                   2212:                CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI, taddr.bge_addr_hi);
                   2213:                CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO, taddr.bge_addr_lo);
1.16      thorpej  2214:        }
                   2215:
1.158     msaitoh  2216:        /* Set up address of status block */
1.172     msaitoh  2217:        BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_status_block));
1.158     msaitoh  2218:        CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_BASEADDR, BGE_STATUS_BLOCK);
                   2219:        CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_HI, taddr.bge_addr_hi);
                   2220:        CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_LO, taddr.bge_addr_lo);
                   2221:        sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx = 0;
                   2222:        sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx = 0;
1.16      thorpej  2223:
1.158     msaitoh  2224:        /* Turn on host coalescing state machine */
                   2225:        CSR_WRITE_4(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
1.7       thorpej  2226:
1.158     msaitoh  2227:        /* Turn on RX BD completion state machine and enable attentions */
                   2228:        CSR_WRITE_4(sc, BGE_RBDC_MODE,
1.161     msaitoh  2229:            BGE_RBDCMODE_ENABLE | BGE_RBDCMODE_ATTN);
1.7       thorpej  2230:
1.158     msaitoh  2231:        /* Turn on RX list placement state machine */
                   2232:        CSR_WRITE_4(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
1.51      fvdl     2233:
1.158     msaitoh  2234:        /* Turn on RX list selector state machine. */
1.172     msaitoh  2235:        if (BGE_IS_5700_FAMILY(sc))
1.158     msaitoh  2236:                CSR_WRITE_4(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
1.51      fvdl     2237:
1.161     msaitoh  2238:        val = BGE_MACMODE_TXDMA_ENB | BGE_MACMODE_RXDMA_ENB |
                   2239:            BGE_MACMODE_RX_STATS_CLEAR | BGE_MACMODE_TX_STATS_CLEAR |
                   2240:            BGE_MACMODE_RX_STATS_ENB | BGE_MACMODE_TX_STATS_ENB |
                   2241:            BGE_MACMODE_FRMHDR_DMA_ENB;
                   2242:
                   2243:        if (sc->bge_flags & BGE_PHY_FIBER_TBI)
1.177     msaitoh  2244:                val |= BGE_PORTMODE_TBI;
1.161     msaitoh  2245:        else if (sc->bge_flags & BGE_PHY_FIBER_MII)
1.177     msaitoh  2246:                val |= BGE_PORTMODE_GMII;
1.161     msaitoh  2247:        else
1.177     msaitoh  2248:                val |= BGE_PORTMODE_MII;
1.161     msaitoh  2249:
1.158     msaitoh  2250:        /* Turn on DMA, clear stats */
1.161     msaitoh  2251:        CSR_WRITE_4(sc, BGE_MAC_MODE, val);
                   2252:
1.158     msaitoh  2253:        /* Set misc. local control, enable interrupts on attentions */
                   2254:        sc->bge_local_ctrl_reg = BGE_MLC_INTR_ONATTN | BGE_MLC_AUTO_EEPROM;
1.51      fvdl     2255:
1.158     msaitoh  2256: #ifdef notdef
                   2257:        /* Assert GPIO pins for PHY reset */
                   2258:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUT0|
                   2259:            BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUT2);
                   2260:        BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_MISCIO_OUTEN0|
                   2261:            BGE_MLC_MISCIO_OUTEN1|BGE_MLC_MISCIO_OUTEN2);
                   2262: #endif
1.98      jonathan 2263:
1.158     msaitoh  2264: #if defined(not_quite_yet)
                   2265:        /* Linux driver enables enable gpio pin #1 on 5700s */
                   2266:        if (sc->bge_chipid == BGE_CHIPID_BCM5700) {
                   2267:                sc->bge_local_ctrl_reg |=
                   2268:                  (BGE_MLC_MISCIO_OUT1|BGE_MLC_MISCIO_OUTEN1);
                   2269:        }
                   2270: #endif
                   2271:        CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, sc->bge_local_ctrl_reg);
1.80      fredb    2272:
1.158     msaitoh  2273:        /* Turn on DMA completion state machine */
1.172     msaitoh  2274:        if (BGE_IS_5700_FAMILY(sc))
1.158     msaitoh  2275:                CSR_WRITE_4(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
1.149     sborrill 2276:
1.158     msaitoh  2277:        /* Turn on write DMA state machine */
                   2278:        {
                   2279:                uint32_t bge_wdma_mode =
                   2280:                        BGE_WDMAMODE_ENABLE|BGE_WDMAMODE_ALL_ATTNS;
1.76      cube     2281:
1.158     msaitoh  2282:                /* Enable host coalescing bug fix; see Linux tg3.c */
1.172     msaitoh  2283:                if (BGE_IS_5755_PLUS(sc))
                   2284:                        bge_wdma_mode |= BGE_WDMAMODE_STATUS_TAG_FIX;
1.76      cube     2285:
1.158     msaitoh  2286:                CSR_WRITE_4(sc, BGE_WDMA_MODE, bge_wdma_mode);
1.178     msaitoh  2287:        }
1.76      cube     2288:
1.158     msaitoh  2289:        /* Turn on read DMA state machine */
                   2290:        {
                   2291:                uint32_t dma_read_modebits;
1.91      gavan    2292:
1.158     msaitoh  2293:                dma_read_modebits =
                   2294:                  BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;
1.98      jonathan 2295:
1.172     msaitoh  2296:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
                   2297:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
                   2298:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)
                   2299:                        dma_read_modebits |= BGE_RDMAMODE_BD_SBD_CRPT_ATTN |
                   2300:                            BGE_RDMAMODE_MBUF_RBD_CRPT_ATTN |
                   2301:                            BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN;
                   2302:
                   2303:                if (sc->bge_flags & BGE_PCIE)
1.158     msaitoh  2304:                        dma_read_modebits |= BGE_RDMA_MODE_FIFO_LONG_BURST;
1.172     msaitoh  2305:                if (sc->bge_flags & BGE_TSO)
                   2306:                        dma_read_modebits |= BGE_RDMAMODE_TSO4_ENABLE;
1.158     msaitoh  2307:                CSR_WRITE_4(sc, BGE_RDMA_MODE, dma_read_modebits);
1.172     msaitoh  2308:                delay(40);
1.158     msaitoh  2309:        }
1.128     tron     2310:
1.158     msaitoh  2311:        /* Turn on RX data completion state machine */
                   2312:        CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
1.128     tron     2313:
1.158     msaitoh  2314:        /* Turn on RX BD initiator state machine */
                   2315:        CSR_WRITE_4(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
1.133     markd    2316:
1.158     msaitoh  2317:        /* Turn on RX data and RX BD initiator state machine */
                   2318:        CSR_WRITE_4(sc, BGE_RDBDI_MODE, BGE_RDBDIMODE_ENABLE);
1.133     markd    2319:
1.158     msaitoh  2320:        /* Turn on Mbuf cluster free state machine */
1.172     msaitoh  2321:        if (BGE_IS_5700_FAMILY(sc))
1.158     msaitoh  2322:                CSR_WRITE_4(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
1.133     markd    2323:
1.158     msaitoh  2324:        /* Turn on send BD completion state machine */
                   2325:        CSR_WRITE_4(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
1.133     markd    2326:
1.158     msaitoh  2327:        /* Turn on send data completion state machine */
1.172     msaitoh  2328:        val = BGE_SDCMODE_ENABLE;
                   2329:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761)
                   2330:                val |= BGE_SDCMODE_CDELAY;
                   2331:        CSR_WRITE_4(sc, BGE_SDC_MODE, val);
1.106     jonathan 2332:
1.158     msaitoh  2333:        /* Turn on send data initiator state machine */
1.172     msaitoh  2334:        if (sc->bge_flags & BGE_TSO) {
1.158     msaitoh  2335:                /* XXX: magic value from Linux driver */
                   2336:                CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
1.177     msaitoh  2337:        } else
1.158     msaitoh  2338:                CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
1.106     jonathan 2339:
1.158     msaitoh  2340:        /* Turn on send BD initiator state machine */
                   2341:        CSR_WRITE_4(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
1.133     markd    2342:
1.158     msaitoh  2343:        /* Turn on send BD selector state machine */
                   2344:        CSR_WRITE_4(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
1.135     taca     2345:
1.158     msaitoh  2346:        CSR_WRITE_4(sc, BGE_SDI_STATS_ENABLE_MASK, 0x007FFFFF);
                   2347:        CSR_WRITE_4(sc, BGE_SDI_STATS_CTL,
1.161     msaitoh  2348:            BGE_SDISTATSCTL_ENABLE | BGE_SDISTATSCTL_FASTER);
1.133     markd    2349:
1.158     msaitoh  2350:        /* ack/clear link change events */
1.161     msaitoh  2351:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED |
                   2352:            BGE_MACSTAT_CFG_CHANGED | BGE_MACSTAT_MI_COMPLETE |
1.172     msaitoh  2353:            BGE_MACSTAT_LINK_CHANGED);
1.158     msaitoh  2354:        CSR_WRITE_4(sc, BGE_MI_STS, 0);
1.106     jonathan 2355:
1.158     msaitoh  2356:        /* Enable PHY auto polling (for MII/GMII only) */
                   2357:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
                   2358:                CSR_WRITE_4(sc, BGE_MI_STS, BGE_MISTS_LINK);
1.178     msaitoh  2359:        } else {
1.161     msaitoh  2360:                BGE_STS_SETBIT(sc, BGE_STS_AUTOPOLL);
                   2361:                BGE_SETBIT(sc, BGE_MI_MODE, BGE_MIMODE_AUTOPOLL | (10 << 16));
1.158     msaitoh  2362:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700)
                   2363:                        CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
                   2364:                            BGE_EVTENB_MI_INTERRUPT);
                   2365:        }
1.70      tron     2366:
1.161     msaitoh  2367:        /*
                   2368:         * Clear any pending link state attention.
                   2369:         * Otherwise some link state change events may be lost until attention
                   2370:         * is cleared by bge_intr() -> bge_link_upd() sequence.
                   2371:         * It's not necessary on newer BCM chips - perhaps enabling link
                   2372:         * state change attentions implies clearing pending attention.
                   2373:         */
                   2374:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED |
                   2375:            BGE_MACSTAT_CFG_CHANGED | BGE_MACSTAT_MI_COMPLETE |
                   2376:            BGE_MACSTAT_LINK_CHANGED);
                   2377:
1.158     msaitoh  2378:        /* Enable link state change attentions. */
                   2379:        BGE_SETBIT(sc, BGE_MAC_EVT_ENB, BGE_EVTENB_LINK_CHANGED);
1.51      fvdl     2380:
1.170     msaitoh  2381:        return 0;
1.158     msaitoh  2382: }
1.7       thorpej  2383:
1.158     msaitoh  2384: static const struct bge_revision *
                   2385: bge_lookup_rev(uint32_t chipid)
                   2386: {
                   2387:        const struct bge_revision *br;
1.7       thorpej  2388:
1.158     msaitoh  2389:        for (br = bge_revisions; br->br_name != NULL; br++) {
                   2390:                if (br->br_chipid == chipid)
1.170     msaitoh  2391:                        return br;
1.158     msaitoh  2392:        }
1.151     cegger   2393:
1.158     msaitoh  2394:        for (br = bge_majorrevs; br->br_name != NULL; br++) {
                   2395:                if (br->br_chipid == BGE_ASICREV(chipid))
1.170     msaitoh  2396:                        return br;
1.158     msaitoh  2397:        }
1.151     cegger   2398:
1.170     msaitoh  2399:        return NULL;
1.158     msaitoh  2400: }
1.7       thorpej  2401:
                   2402: static const struct bge_product *
                   2403: bge_lookup(const struct pci_attach_args *pa)
                   2404: {
                   2405:        const struct bge_product *bp;
                   2406:
                   2407:        for (bp = bge_products; bp->bp_name != NULL; bp++) {
                   2408:                if (PCI_VENDOR(pa->pa_id) == bp->bp_vendor &&
                   2409:                    PCI_PRODUCT(pa->pa_id) == bp->bp_product)
1.170     msaitoh  2410:                        return bp;
1.7       thorpej  2411:        }
                   2412:
1.170     msaitoh  2413:        return NULL;
1.7       thorpej  2414: }
                   2415:
1.104     thorpej  2416: static int
1.116     christos 2417: bge_setpowerstate(struct bge_softc *sc, int powerlevel)
1.25      jonathan 2418: {
                   2419: #ifdef NOTYET
1.170     msaitoh  2420:        uint32_t pm_ctl = 0;
1.25      jonathan 2421:
                   2422:        /* XXX FIXME: make sure indirect accesses enabled? */
                   2423:        pm_ctl = pci_conf_read(sc->bge_dev, BGE_PCI_MISC_CTL, 4);
                   2424:        pm_ctl |= BGE_PCIMISCCTL_INDIRECT_ACCESS;
                   2425:        pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, pm_ctl, 4);
                   2426:
                   2427:        /* clear the PME_assert bit and power state bits, enable PME */
                   2428:        pm_ctl = pci_conf_read(sc->bge_dev, BGE_PCI_PWRMGMT_CMD, 2);
                   2429:        pm_ctl &= ~PCIM_PSTAT_DMASK;
                   2430:        pm_ctl |= (1 << 8);
                   2431:
                   2432:        if (powerlevel == 0) {
                   2433:                pm_ctl |= PCIM_PSTAT_D0;
                   2434:                pci_write_config(sc->bge_dev, BGE_PCI_PWRMGMT_CMD,
                   2435:                    pm_ctl, 2);
                   2436:                DELAY(10000);
1.27      jonathan 2437:                CSR_WRITE_4(sc, BGE_MISC_LOCAL_CTL, sc->bge_local_ctrl_reg);
1.25      jonathan 2438:                DELAY(10000);
                   2439:
                   2440: #ifdef NOTYET
                   2441:                /* XXX FIXME: write 0x02 to phy aux_Ctrl reg */
                   2442:                bge_miibus_writereg(sc->bge_dev, 1, 0x18, 0x02);
                   2443: #endif
                   2444:                DELAY(40); DELAY(40); DELAY(40);
                   2445:                DELAY(10000);   /* above not quite adequate on 5700 */
                   2446:                return 0;
                   2447:        }
                   2448:
                   2449:
                   2450:        /*
                   2451:         * Entering ACPI power states D1-D3 is achieved by wiggling
                   2452:         * GMII gpio pins. Example code assumes all hardware vendors
1.184     njoly    2453:         * followed Broadcom's sample pcb layout. Until we verify that
1.25      jonathan 2454:         * for all supported OEM cards, states D1-D3 are  unsupported.
                   2455:         */
1.138     joerg    2456:        aprint_error_dev(sc->bge_dev,
                   2457:            "power state %d unimplemented; check GPIO pins\n",
                   2458:            powerlevel);
1.25      jonathan 2459: #endif
                   2460:        return EOPNOTSUPP;
                   2461: }
                   2462:
                   2463:
1.1       fvdl     2464: /*
                   2465:  * Probe for a Broadcom chip. Check the PCI vendor and device IDs
                   2466:  * against our list and return its name if we find a match. Note
                   2467:  * that since the Broadcom controller contains VPD support, we
                   2468:  * can get the device name string from the controller itself instead
                   2469:  * of the compiled-in string. This is a little slow, but it guarantees
                   2470:  * we'll always announce the right product name.
                   2471:  */
1.104     thorpej  2472: static int
1.116     christos 2473: bge_probe(device_t parent, cfdata_t match, void *aux)
1.1       fvdl     2474: {
                   2475:        struct pci_attach_args *pa = (struct pci_attach_args *)aux;
                   2476:
1.7       thorpej  2477:        if (bge_lookup(pa) != NULL)
1.170     msaitoh  2478:                return 1;
1.1       fvdl     2479:
1.170     msaitoh  2480:        return 0;
1.1       fvdl     2481: }
                   2482:
1.104     thorpej  2483: static void
1.116     christos 2484: bge_attach(device_t parent, device_t self, void *aux)
1.1       fvdl     2485: {
1.138     joerg    2486:        struct bge_softc        *sc = device_private(self);
1.1       fvdl     2487:        struct pci_attach_args  *pa = aux;
1.164     msaitoh  2488:        prop_dictionary_t dict;
1.7       thorpej  2489:        const struct bge_product *bp;
1.16      thorpej  2490:        const struct bge_revision *br;
1.143     tron     2491:        pci_chipset_tag_t       pc;
1.1       fvdl     2492:        pci_intr_handle_t       ih;
                   2493:        const char              *intrstr = NULL;
                   2494:        bus_dma_segment_t       seg;
                   2495:        int                     rseg;
1.170     msaitoh  2496:        uint32_t                hwcfg = 0;
                   2497:        uint32_t                command;
1.1       fvdl     2498:        struct ifnet            *ifp;
1.170     msaitoh  2499:        uint32_t                misccfg;
1.126     christos 2500:        void *                  kva;
1.1       fvdl     2501:        u_char                  eaddr[ETHER_ADDR_LEN];
1.172     msaitoh  2502:        pcireg_t                memtype, subid;
1.1       fvdl     2503:        bus_addr_t              memaddr;
                   2504:        bus_size_t              memsize;
1.170     msaitoh  2505:        uint32_t                pm_ctl;
1.174     martin   2506:        bool                    no_seeprom;
1.87      perry    2507:
1.7       thorpej  2508:        bp = bge_lookup(pa);
                   2509:        KASSERT(bp != NULL);
                   2510:
1.141     jmcneill 2511:        sc->sc_pc = pa->pa_pc;
                   2512:        sc->sc_pcitag = pa->pa_tag;
1.138     joerg    2513:        sc->bge_dev = self;
1.1       fvdl     2514:
1.172     msaitoh  2515:        pc = sc->sc_pc;
                   2516:        subid = pci_conf_read(pc, sc->sc_pcitag, PCI_SUBSYS_ID_REG);
                   2517:
1.30      thorpej  2518:        aprint_naive(": Ethernet controller\n");
                   2519:        aprint_normal(": %s\n", bp->bp_name);
1.1       fvdl     2520:
                   2521:        /*
                   2522:         * Map control/status registers.
                   2523:         */
                   2524:        DPRINTFN(5, ("Map control/status regs\n"));
1.141     jmcneill 2525:        command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
1.1       fvdl     2526:        command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
1.141     jmcneill 2527:        pci_conf_write(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, command);
                   2528:        command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
1.1       fvdl     2529:
                   2530:        if (!(command & PCI_COMMAND_MEM_ENABLE)) {
1.138     joerg    2531:                aprint_error_dev(sc->bge_dev,
                   2532:                    "failed to enable memory mapping!\n");
1.1       fvdl     2533:                return;
                   2534:        }
                   2535:
                   2536:        DPRINTFN(5, ("pci_mem_find\n"));
1.141     jmcneill 2537:        memtype = pci_mapreg_type(sc->sc_pc, sc->sc_pcitag, BGE_PCI_BAR0);
1.178     msaitoh  2538:        switch (memtype) {
1.29      itojun   2539:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                   2540:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
1.1       fvdl     2541:                if (pci_mapreg_map(pa, BGE_PCI_BAR0,
1.29      itojun   2542:                    memtype, 0, &sc->bge_btag, &sc->bge_bhandle,
1.1       fvdl     2543:                    &memaddr, &memsize) == 0)
                   2544:                        break;
                   2545:        default:
1.138     joerg    2546:                aprint_error_dev(sc->bge_dev, "can't find mem space\n");
1.1       fvdl     2547:                return;
                   2548:        }
                   2549:
                   2550:        DPRINTFN(5, ("pci_intr_map\n"));
                   2551:        if (pci_intr_map(pa, &ih)) {
1.138     joerg    2552:                aprint_error_dev(sc->bge_dev, "couldn't map interrupt\n");
1.1       fvdl     2553:                return;
                   2554:        }
                   2555:
                   2556:        DPRINTFN(5, ("pci_intr_string\n"));
                   2557:        intrstr = pci_intr_string(pc, ih);
                   2558:
                   2559:        DPRINTFN(5, ("pci_intr_establish\n"));
                   2560:        sc->bge_intrhand = pci_intr_establish(pc, ih, IPL_NET, bge_intr, sc);
                   2561:
                   2562:        if (sc->bge_intrhand == NULL) {
1.138     joerg    2563:                aprint_error_dev(sc->bge_dev,
                   2564:                    "couldn't establish interrupt%s%s\n",
                   2565:                    intrstr ? " at " : "", intrstr ? intrstr : "");
1.1       fvdl     2566:                return;
                   2567:        }
1.138     joerg    2568:        aprint_normal_dev(sc->bge_dev, "interrupting at %s\n", intrstr);
1.1       fvdl     2569:
1.25      jonathan 2570:        /*
                   2571:         * Kludge for 5700 Bx bug: a hardware bug (PCIX byte enable?)
                   2572:         * can clobber the chip's PCI config-space power control registers,
                   2573:         * leaving the card in D3 powersave state.
                   2574:         * We do not have memory-mapped registers in this state,
                   2575:         * so force device into D0 state before starting initialization.
                   2576:         */
1.141     jmcneill 2577:        pm_ctl = pci_conf_read(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD);
1.25      jonathan 2578:        pm_ctl &= ~(PCI_PWR_D0|PCI_PWR_D1|PCI_PWR_D2|PCI_PWR_D3);
                   2579:        pm_ctl |= (1 << 8) | PCI_PWR_D0 ; /* D0 state */
1.141     jmcneill 2580:        pci_conf_write(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD, pm_ctl);
1.25      jonathan 2581:        DELAY(1000);    /* 27 usec is allegedly sufficent */
                   2582:
1.76      cube     2583:        /*
1.162     msaitoh  2584:         * Save ASIC rev.
1.76      cube     2585:         */
                   2586:        sc->bge_chipid =
1.172     msaitoh  2587:            pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL)
                   2588:                >> BGE_PCIMISCCTL_ASICREV_SHIFT;
                   2589:
                   2590:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG) {
                   2591:                if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5717 ||
                   2592:                    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5718 ||
                   2593:                    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5724)
                   2594:                        sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,
                   2595:                            BGE_PCI_GEN2_PRODID_ASICREV);
                   2596:                else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57761 ||
                   2597:                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57765 ||
                   2598:                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57781 ||
                   2599:                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57785 ||
                   2600:                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57791 ||
                   2601:                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57795)
                   2602:                        sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,
                   2603:                            BGE_PCI_GEN15_PRODID_ASICREV);
                   2604:                else
                   2605:                        sc->bge_chipid = pci_conf_read(pc, pa->pa_tag,
                   2606:                            BGE_PCI_PRODID_ASICREV);
                   2607:        }
1.76      cube     2608:
1.141     jmcneill 2609:        if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,
1.180     msaitoh  2610:                &sc->bge_pciecap, NULL) != 0) {
1.171     msaitoh  2611:                /* PCIe */
1.157     msaitoh  2612:                sc->bge_flags |= BGE_PCIE;
1.177     msaitoh  2613:                bge_set_max_readrq(sc);
1.171     msaitoh  2614:        } else if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &
                   2615:                BGE_PCISTATE_PCI_BUSMODE) == 0) {
                   2616:                /* PCI-X */
1.157     msaitoh  2617:                sc->bge_flags |= BGE_PCIX;
1.180     msaitoh  2618:                if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
                   2619:                        &sc->bge_pcixcap, NULL) == 0)
                   2620:                        aprint_error_dev(sc->bge_dev,
                   2621:                            "unable to find PCIX capability\n");
1.171     msaitoh  2622:        }
1.76      cube     2623:
1.172     msaitoh  2624:        /* chipid */
                   2625:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   2626:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 ||
                   2627:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 ||
                   2628:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                   2629:                sc->bge_flags |= BGE_5700_FAMILY;
                   2630:
                   2631:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714_A0 ||
                   2632:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5780 ||
                   2633:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5714)
                   2634:                sc->bge_flags |= BGE_5714_FAMILY;
                   2635:
                   2636:        /* Intentionally exclude BGE_ASICREV_BCM5906 */
                   2637:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5717 ||
                   2638:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
                   2639:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
                   2640:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
                   2641:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785 ||
                   2642:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787 ||
                   2643:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57765 ||
                   2644:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM57780)
                   2645:                sc->bge_flags |= BGE_5755_PLUS;
                   2646:
                   2647:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750 ||
                   2648:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
                   2649:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906 ||
                   2650:            BGE_IS_5755_PLUS(sc) ||
                   2651:            BGE_IS_5714_FAMILY(sc))
                   2652:                sc->bge_flags |= BGE_5750_PLUS;
                   2653:
                   2654:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 ||
                   2655:            BGE_IS_5750_OR_BEYOND(sc))
                   2656:                sc->bge_flags |= BGE_5705_PLUS;
                   2657:
                   2658:        /*
                   2659:         * When using the BCM5701 in PCI-X mode, data corruption has
                   2660:         * been observed in the first few bytes of some received packets.
                   2661:         * Aligning the packet buffer in memory eliminates the corruption.
                   2662:         * Unfortunately, this misaligns the packet payloads.  On platforms
                   2663:         * which do not support unaligned accesses, we will realign the
                   2664:         * payloads by copying the received packets.
                   2665:         */
                   2666:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701 &&
                   2667:            sc->bge_flags & BGE_PCIX)
                   2668:                sc->bge_flags |= BGE_RX_ALIGNBUG;
                   2669:
                   2670:        if (BGE_IS_5700_FAMILY(sc))
                   2671:                sc->bge_flags |= BGE_JUMBO_CAPABLE;
                   2672:
                   2673:        if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   2674:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5701) &&
                   2675:            PCI_VENDOR(subid) == PCI_VENDOR_DELL)
                   2676:                sc->bge_flags |= BGE_NO_3LED;
                   2677:
                   2678:        misccfg = CSR_READ_4(sc, BGE_MISC_CFG);
                   2679:        misccfg &= BGE_MISCCFG_BOARD_ID_MASK;
                   2680:
                   2681:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
                   2682:            (misccfg == BGE_MISCCFG_BOARD_ID_5788 ||
                   2683:             misccfg == BGE_MISCCFG_BOARD_ID_5788M))
                   2684:                sc->bge_flags |= BGE_IS_5788;
                   2685:
                   2686:        /*
                   2687:         * Some controllers seem to require a special firmware to use
                   2688:         * TSO. But the firmware is not available to FreeBSD and Linux
                   2689:         * claims that the TSO performed by the firmware is slower than
                   2690:         * hardware based TSO. Moreover the firmware based TSO has one
                   2691:         * known bug which can't handle TSO if ethernet header + IP/TCP
                   2692:         * header is greater than 80 bytes. The workaround for the TSO
                   2693:         * bug exist but it seems it's too expensive than not using
                   2694:         * TSO at all. Some hardwares also have the TSO bug so limit
                   2695:         * the TSO to the controllers that are not affected TSO issues
                   2696:         * (e.g. 5755 or higher).
                   2697:         */
                   2698:        if (BGE_IS_5755_PLUS(sc)) {
                   2699:                /*
                   2700:                 * BCM5754 and BCM5787 shares the same ASIC id so
                   2701:                 * explicit device id check is required.
                   2702:                 */
                   2703:                if ((PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5754) &&
                   2704:                    (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5754M))
                   2705:                        sc->bge_flags |= BGE_TSO;
                   2706:        }
                   2707:
                   2708:        if ((BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5703 &&
                   2709:             (misccfg == 0x4000 || misccfg == 0x8000)) ||
                   2710:            (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
                   2711:             PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
                   2712:             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5901 ||
                   2713:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5901A2 ||
                   2714:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5705F)) ||
                   2715:            (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
                   2716:             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5751F ||
                   2717:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5753F ||
                   2718:              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5787F)) ||
                   2719:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM57790 ||
                   2720:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   2721:                sc->bge_flags |= BGE_10_100_ONLY;
                   2722:
                   2723:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   2724:            (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5705 &&
                   2725:             (sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
                   2726:              sc->bge_chipid != BGE_CHIPID_BCM5705_A1)) ||
                   2727:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   2728:                sc->bge_flags |= BGE_NO_ETH_WIRE_SPEED;
                   2729:
1.162     msaitoh  2730:        if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||
                   2731:            sc->bge_chipid == BGE_CHIPID_BCM5701_B0)
                   2732:                sc->bge_flags |= BGE_PHY_CRC_BUG;
                   2733:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5703_AX ||
                   2734:            BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_AX)
                   2735:                sc->bge_flags |= BGE_PHY_ADC_BUG;
                   2736:        if (sc->bge_chipid == BGE_CHIPID_BCM5704_A0)
                   2737:                sc->bge_flags |= BGE_PHY_5704_A0_BUG;
                   2738:
1.172     msaitoh  2739:        if (BGE_IS_5705_PLUS(sc) &&
                   2740:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906 &&
                   2741:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&
                   2742:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&
                   2743:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765 &&
                   2744:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57780) {
1.162     msaitoh  2745:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5755 ||
1.172     msaitoh  2746:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5761 ||
                   2747:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5784 ||
1.162     msaitoh  2748:                    BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5787) {
                   2749:                        if (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5722 &&
                   2750:                            PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BROADCOM_BCM5756)
                   2751:                                sc->bge_flags |= BGE_PHY_JITTER_BUG;
                   2752:                        if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM5755M)
                   2753:                                sc->bge_flags |= BGE_PHY_ADJUST_TRIM;
                   2754:                } else if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)
                   2755:                        sc->bge_flags |= BGE_PHY_BER_BUG;
                   2756:        }
                   2757:
1.174     martin   2758:        /*
                   2759:         * SEEPROM check.
                   2760:         * First check if firmware knows we do not have SEEPROM.
                   2761:         */
1.180     msaitoh  2762:        if (prop_dictionary_get_bool(device_properties(self),
1.174     martin   2763:             "without-seeprom", &no_seeprom) && no_seeprom)
                   2764:                sc->bge_flags |= BGE_NO_EEPROM;
                   2765:
                   2766:        /* Now check the 'ROM failed' bit on the RX CPU */
                   2767:        else if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL)
1.172     msaitoh  2768:                sc->bge_flags |= BGE_NO_EEPROM;
                   2769:
1.1       fvdl     2770:        /* Try to reset the chip. */
                   2771:        DPRINTFN(5, ("bge_reset\n"));
                   2772:        bge_reset(sc);
                   2773:
1.177     msaitoh  2774:        sc->bge_asf_mode = 0;
                   2775:        if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG)
                   2776:            == BGE_MAGIC_NUMBER)) {
                   2777:                if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)
                   2778:                    & BGE_HWCFG_ASF) {
                   2779:                        sc->bge_asf_mode |= ASF_ENABLE;
                   2780:                        sc->bge_asf_mode |= ASF_STACKUP;
1.180     msaitoh  2781:                        if (BGE_IS_5750_OR_BEYOND(sc)) {
1.177     msaitoh  2782:                                sc->bge_asf_mode |= ASF_NEW_HANDSHAKE;
                   2783:                        }
                   2784:                }
                   2785:        }
                   2786:
                   2787:        /* Try to reset the chip again the nice way. */
                   2788:        bge_stop_fw(sc);
                   2789:        bge_sig_pre_reset(sc, BGE_RESET_STOP);
1.178     msaitoh  2790:        if (bge_reset(sc))
1.177     msaitoh  2791:                aprint_error_dev(sc->bge_dev, "chip reset failed\n");
                   2792:
                   2793:        bge_sig_legacy(sc, BGE_RESET_STOP);
                   2794:        bge_sig_post_reset(sc, BGE_RESET_STOP);
                   2795:
1.1       fvdl     2796:        if (bge_chipinit(sc)) {
1.138     joerg    2797:                aprint_error_dev(sc->bge_dev, "chip initialization failed\n");
1.1       fvdl     2798:                bge_release_resources(sc);
                   2799:                return;
                   2800:        }
                   2801:
                   2802:        /*
1.176     martin   2803:         * Get station address from the EEPROM
1.1       fvdl     2804:         */
1.151     cegger   2805:        if (bge_get_eaddr(sc, eaddr)) {
1.178     msaitoh  2806:                aprint_error_dev(sc->bge_dev,
                   2807:                    "failed to read station address\n");
1.1       fvdl     2808:                bge_release_resources(sc);
                   2809:                return;
                   2810:        }
                   2811:
1.51      fvdl     2812:        br = bge_lookup_rev(sc->bge_chipid);
                   2813:
1.16      thorpej  2814:        if (br == NULL) {
1.172     msaitoh  2815:                aprint_normal_dev(sc->bge_dev, "unknown ASIC (0x%x)",
                   2816:                    sc->bge_chipid);
1.16      thorpej  2817:        } else {
1.172     msaitoh  2818:                aprint_normal_dev(sc->bge_dev, "ASIC %s (0x%x)",
                   2819:                    br->br_name, sc->bge_chipid);
1.16      thorpej  2820:        }
1.30      thorpej  2821:        aprint_normal(", Ethernet address %s\n", ether_sprintf(eaddr));
1.1       fvdl     2822:
                   2823:        /* Allocate the general information block and ring buffers. */
1.41      fvdl     2824:        if (pci_dma64_available(pa))
                   2825:                sc->bge_dmatag = pa->pa_dmat64;
                   2826:        else
                   2827:                sc->bge_dmatag = pa->pa_dmat;
1.1       fvdl     2828:        DPRINTFN(5, ("bus_dmamem_alloc\n"));
                   2829:        if (bus_dmamem_alloc(sc->bge_dmatag, sizeof(struct bge_ring_data),
                   2830:                             PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1.138     joerg    2831:                aprint_error_dev(sc->bge_dev, "can't alloc rx buffers\n");
1.1       fvdl     2832:                return;
                   2833:        }
                   2834:        DPRINTFN(5, ("bus_dmamem_map\n"));
                   2835:        if (bus_dmamem_map(sc->bge_dmatag, &seg, rseg,
                   2836:                           sizeof(struct bge_ring_data), &kva,
                   2837:                           BUS_DMA_NOWAIT)) {
1.138     joerg    2838:                aprint_error_dev(sc->bge_dev,
                   2839:                    "can't map DMA buffers (%zu bytes)\n",
                   2840:                    sizeof(struct bge_ring_data));
1.1       fvdl     2841:                bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
                   2842:                return;
                   2843:        }
                   2844:        DPRINTFN(5, ("bus_dmamem_create\n"));
                   2845:        if (bus_dmamap_create(sc->bge_dmatag, sizeof(struct bge_ring_data), 1,
                   2846:            sizeof(struct bge_ring_data), 0,
                   2847:            BUS_DMA_NOWAIT, &sc->bge_ring_map)) {
1.138     joerg    2848:                aprint_error_dev(sc->bge_dev, "can't create DMA map\n");
1.1       fvdl     2849:                bus_dmamem_unmap(sc->bge_dmatag, kva,
                   2850:                                 sizeof(struct bge_ring_data));
                   2851:                bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
                   2852:                return;
                   2853:        }
                   2854:        DPRINTFN(5, ("bus_dmamem_load\n"));
                   2855:        if (bus_dmamap_load(sc->bge_dmatag, sc->bge_ring_map, kva,
                   2856:                            sizeof(struct bge_ring_data), NULL,
                   2857:                            BUS_DMA_NOWAIT)) {
                   2858:                bus_dmamap_destroy(sc->bge_dmatag, sc->bge_ring_map);
                   2859:                bus_dmamem_unmap(sc->bge_dmatag, kva,
                   2860:                                 sizeof(struct bge_ring_data));
                   2861:                bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
                   2862:                return;
                   2863:        }
                   2864:
                   2865:        DPRINTFN(5, ("bzero\n"));
                   2866:        sc->bge_rdata = (struct bge_ring_data *)kva;
                   2867:
1.19      mjl      2868:        memset(sc->bge_rdata, 0, sizeof(struct bge_ring_data));
1.1       fvdl     2869:
                   2870:        /* Try to allocate memory for jumbo buffers. */
1.166     msaitoh  2871:        if (BGE_IS_JUMBO_CAPABLE(sc)) {
1.44      hannken  2872:                if (bge_alloc_jumbo_mem(sc)) {
1.138     joerg    2873:                        aprint_error_dev(sc->bge_dev,
                   2874:                            "jumbo buffer allocation failed\n");
1.44      hannken  2875:                } else
                   2876:                        sc->ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
                   2877:        }
1.1       fvdl     2878:
                   2879:        /* Set default tuneable values. */
                   2880:        sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
                   2881:        sc->bge_rx_coal_ticks = 150;
1.25      jonathan 2882:        sc->bge_rx_max_coal_bds = 64;
                   2883: #ifdef ORIG_WPAUL_VALUES
1.1       fvdl     2884:        sc->bge_tx_coal_ticks = 150;
                   2885:        sc->bge_tx_max_coal_bds = 128;
1.25      jonathan 2886: #else
                   2887:        sc->bge_tx_coal_ticks = 300;
                   2888:        sc->bge_tx_max_coal_bds = 400;
                   2889: #endif
1.172     msaitoh  2890:        if (BGE_IS_5705_PLUS(sc)) {
1.95      jonathan 2891:                sc->bge_tx_coal_ticks = (12 * 5);
1.146     mlelstv  2892:                sc->bge_tx_max_coal_bds = (12 * 5);
1.138     joerg    2893:                        aprint_verbose_dev(sc->bge_dev,
                   2894:                            "setting short Tx thresholds\n");
1.95      jonathan 2895:        }
1.1       fvdl     2896:
1.172     msaitoh  2897:        if (BGE_IS_5705_PLUS(sc))
                   2898:                sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
                   2899:        else
                   2900:                sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
                   2901:
1.1       fvdl     2902:        /* Set up ifnet structure */
                   2903:        ifp = &sc->ethercom.ec_if;
                   2904:        ifp->if_softc = sc;
                   2905:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                   2906:        ifp->if_ioctl = bge_ioctl;
1.141     jmcneill 2907:        ifp->if_stop = bge_stop;
1.1       fvdl     2908:        ifp->if_start = bge_start;
                   2909:        ifp->if_init = bge_init;
                   2910:        ifp->if_watchdog = bge_watchdog;
1.42      ragge    2911:        IFQ_SET_MAXLEN(&ifp->if_snd, max(BGE_TX_RING_CNT - 1, IFQ_MAXLEN));
1.1       fvdl     2912:        IFQ_SET_READY(&ifp->if_snd);
1.115     tsutsui  2913:        DPRINTFN(5, ("strcpy if_xname\n"));
1.138     joerg    2914:        strcpy(ifp->if_xname, device_xname(sc->bge_dev));
1.1       fvdl     2915:
1.157     msaitoh  2916:        if (sc->bge_chipid != BGE_CHIPID_BCM5700_B0)
1.18      thorpej  2917:                sc->ethercom.ec_if.if_capabilities |=
1.172     msaitoh  2918:                    IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx;
                   2919: #if 1  /* XXX TCP/UDP checksum offload breaks with pf(4) */
                   2920:                sc->ethercom.ec_if.if_capabilities |=
1.88      yamt     2921:                    IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
                   2922:                    IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx;
1.172     msaitoh  2923: #endif
1.87      perry    2924:        sc->ethercom.ec_capabilities |=
1.1       fvdl     2925:            ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_MTU;
                   2926:
1.172     msaitoh  2927:        if (sc->bge_flags & BGE_TSO)
1.95      jonathan 2928:                sc->ethercom.ec_if.if_capabilities |= IFCAP_TSOv4;
                   2929:
1.1       fvdl     2930:        /*
                   2931:         * Do MII setup.
                   2932:         */
                   2933:        DPRINTFN(5, ("mii setup\n"));
                   2934:        sc->bge_mii.mii_ifp = ifp;
                   2935:        sc->bge_mii.mii_readreg = bge_miibus_readreg;
                   2936:        sc->bge_mii.mii_writereg = bge_miibus_writereg;
                   2937:        sc->bge_mii.mii_statchg = bge_miibus_statchg;
                   2938:
                   2939:        /*
                   2940:         * Figure out what sort of media we have by checking the
1.35      jonathan 2941:         * hardware config word in the first 32k of NIC internal memory,
                   2942:         * or fall back to the config word in the EEPROM. Note: on some BCM5700
1.1       fvdl     2943:         * cards, this value appears to be unset. If that's the
                   2944:         * case, we have to rely on identifying the NIC by its PCI
                   2945:         * subsystem ID, as we do below for the SysKonnect SK-9D41.
                   2946:         */
1.35      jonathan 2947:        if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER) {
                   2948:                hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
1.175     martin   2949:        } else if (!(sc->bge_flags & BGE_NO_EEPROM)) {
1.126     christos 2950:                bge_read_eeprom(sc, (void *)&hwcfg,
1.1       fvdl     2951:                    BGE_EE_HWCFG_OFFSET, sizeof(hwcfg));
1.35      jonathan 2952:                hwcfg = be32toh(hwcfg);
                   2953:        }
1.1       fvdl     2954:        /* The SysKonnect SK-9D41 is a 1000baseSX card. */
1.161     msaitoh  2955:        if (PCI_PRODUCT(pa->pa_id) == SK_SUBSYSID_9D41 ||
                   2956:            (hwcfg & BGE_HWCFG_MEDIA) == BGE_MEDIA_FIBER) {
                   2957:                if (BGE_IS_5714_FAMILY(sc))
                   2958:                    sc->bge_flags |= BGE_PHY_FIBER_MII;
                   2959:                else
                   2960:                    sc->bge_flags |= BGE_PHY_FIBER_TBI;
                   2961:        }
1.1       fvdl     2962:
1.167     msaitoh  2963:        /* set phyflags before mii_attach() */
                   2964:        dict = device_properties(self);
                   2965:        prop_dictionary_set_uint32(dict, "phyflags", sc->bge_flags);
                   2966:
1.157     msaitoh  2967:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.1       fvdl     2968:                ifmedia_init(&sc->bge_ifmedia, IFM_IMASK, bge_ifmedia_upd,
                   2969:                    bge_ifmedia_sts);
1.177     msaitoh  2970:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER |IFM_1000_SX, 0, NULL);
                   2971:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER | IFM_1000_SX|IFM_FDX,
1.1       fvdl     2972:                            0, NULL);
1.177     msaitoh  2973:                ifmedia_add(&sc->bge_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
                   2974:                ifmedia_set(&sc->bge_ifmedia, IFM_ETHER | IFM_AUTO);
1.155     he       2975:                /* Pretend the user requested this setting */
1.162     msaitoh  2976:                sc->bge_ifmedia.ifm_media = sc->bge_ifmedia.ifm_cur->ifm_media;
1.1       fvdl     2977:        } else {
                   2978:                /*
1.177     msaitoh  2979:                 * Do transceiver setup and tell the firmware the
                   2980:                 * driver is down so we can try to get access the
                   2981:                 * probe if ASF is running.  Retry a couple of times
                   2982:                 * if we get a conflict with the ASF firmware accessing
                   2983:                 * the PHY.
1.1       fvdl     2984:                 */
1.177     msaitoh  2985:                BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
                   2986:                bge_asf_driver_up(sc);
                   2987:
1.1       fvdl     2988:                ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,
                   2989:                             bge_ifmedia_sts);
1.138     joerg    2990:                mii_attach(sc->bge_dev, &sc->bge_mii, 0xffffffff,
1.69      thorpej  2991:                           MII_PHY_ANY, MII_OFFSET_ANY,
                   2992:                           MIIF_FORCEANEG|MIIF_DOPAUSE);
1.87      perry    2993:
1.142     dyoung   2994:                if (LIST_EMPTY(&sc->bge_mii.mii_phys)) {
1.138     joerg    2995:                        aprint_error_dev(sc->bge_dev, "no PHY found!\n");
1.1       fvdl     2996:                        ifmedia_add(&sc->bge_mii.mii_media,
                   2997:                                    IFM_ETHER|IFM_MANUAL, 0, NULL);
                   2998:                        ifmedia_set(&sc->bge_mii.mii_media,
                   2999:                                    IFM_ETHER|IFM_MANUAL);
                   3000:                } else
                   3001:                        ifmedia_set(&sc->bge_mii.mii_media,
                   3002:                                    IFM_ETHER|IFM_AUTO);
1.177     msaitoh  3003:
                   3004:                /*
                   3005:                 * Now tell the firmware we are going up after probing the PHY
                   3006:                 */
                   3007:                if (sc->bge_asf_mode & ASF_STACKUP)
                   3008:                        BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
1.1       fvdl     3009:        }
                   3010:
                   3011:        /*
                   3012:         * Call MI attach routine.
                   3013:         */
                   3014:        DPRINTFN(5, ("if_attach\n"));
                   3015:        if_attach(ifp);
                   3016:        DPRINTFN(5, ("ether_ifattach\n"));
                   3017:        ether_ifattach(ifp, eaddr);
1.186   ! msaitoh  3018:        ether_set_ifflags_cb(&sc->ethercom, bge_ifflags_cb);
1.148     mlelstv  3019: #if NRND > 0
                   3020:        rnd_attach_source(&sc->rnd_source, device_xname(sc->bge_dev),
                   3021:                RND_TYPE_NET, 0);
                   3022: #endif
1.72      thorpej  3023: #ifdef BGE_EVENT_COUNTERS
                   3024:        /*
                   3025:         * Attach event counters.
                   3026:         */
                   3027:        evcnt_attach_dynamic(&sc->bge_ev_intr, EVCNT_TYPE_INTR,
1.138     joerg    3028:            NULL, device_xname(sc->bge_dev), "intr");
1.72      thorpej  3029:        evcnt_attach_dynamic(&sc->bge_ev_tx_xoff, EVCNT_TYPE_MISC,
1.138     joerg    3030:            NULL, device_xname(sc->bge_dev), "tx_xoff");
1.72      thorpej  3031:        evcnt_attach_dynamic(&sc->bge_ev_tx_xon, EVCNT_TYPE_MISC,
1.138     joerg    3032:            NULL, device_xname(sc->bge_dev), "tx_xon");
1.72      thorpej  3033:        evcnt_attach_dynamic(&sc->bge_ev_rx_xoff, EVCNT_TYPE_MISC,
1.138     joerg    3034:            NULL, device_xname(sc->bge_dev), "rx_xoff");
1.72      thorpej  3035:        evcnt_attach_dynamic(&sc->bge_ev_rx_xon, EVCNT_TYPE_MISC,
1.138     joerg    3036:            NULL, device_xname(sc->bge_dev), "rx_xon");
1.72      thorpej  3037:        evcnt_attach_dynamic(&sc->bge_ev_rx_macctl, EVCNT_TYPE_MISC,
1.138     joerg    3038:            NULL, device_xname(sc->bge_dev), "rx_macctl");
1.72      thorpej  3039:        evcnt_attach_dynamic(&sc->bge_ev_xoffentered, EVCNT_TYPE_MISC,
1.138     joerg    3040:            NULL, device_xname(sc->bge_dev), "xoffentered");
1.72      thorpej  3041: #endif /* BGE_EVENT_COUNTERS */
1.1       fvdl     3042:        DPRINTFN(5, ("callout_init\n"));
1.132     ad       3043:        callout_init(&sc->bge_timeout, 0);
1.82      jmcneill 3044:
1.168     tsutsui  3045:        if (pmf_device_register(self, NULL, NULL))
                   3046:                pmf_class_network_register(self, ifp);
                   3047:        else
1.141     jmcneill 3048:                aprint_error_dev(self, "couldn't establish power handler\n");
1.172     msaitoh  3049:
                   3050: #ifdef BGE_DEBUG
                   3051:        bge_debug_info(sc);
                   3052: #endif
1.1       fvdl     3053: }
                   3054:
1.104     thorpej  3055: static void
                   3056: bge_release_resources(struct bge_softc *sc)
1.1       fvdl     3057: {
                   3058:        if (sc->bge_vpd_prodname != NULL)
                   3059:                free(sc->bge_vpd_prodname, M_DEVBUF);
                   3060:
                   3061:        if (sc->bge_vpd_readonly != NULL)
                   3062:                free(sc->bge_vpd_readonly, M_DEVBUF);
                   3063: }
                   3064:
1.177     msaitoh  3065: static int
1.104     thorpej  3066: bge_reset(struct bge_softc *sc)
1.1       fvdl     3067: {
1.180     msaitoh  3068:        uint32_t cachesize, command, pcistate, marbmode;
                   3069: #if 0
                   3070:        uint32_t new_pcistate;
                   3071: #endif
                   3072:        pcireg_t devctl, reg;
1.76      cube     3073:        int i, val;
1.151     cegger   3074:        void (*write_op)(struct bge_softc *, int, int);
                   3075:
1.178     msaitoh  3076:        if (BGE_IS_5750_OR_BEYOND(sc) && !BGE_IS_5714_FAMILY(sc)
                   3077:            && (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5906)) {
                   3078:                if (sc->bge_flags & BGE_PCIE)
1.151     cegger   3079:                        write_op = bge_writemem_direct;
1.178     msaitoh  3080:                else
1.151     cegger   3081:                        write_op = bge_writemem_ind;
1.178     msaitoh  3082:        } else
1.151     cegger   3083:                write_op = bge_writereg_ind;
1.1       fvdl     3084:
                   3085:        /* Save some important PCI state. */
1.141     jmcneill 3086:        cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);
                   3087:        command = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
                   3088:        pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE);
1.1       fvdl     3089:
1.180     msaitoh  3090:        /* Step 5a: Enable memory arbiter. */
                   3091:        marbmode = 0;
                   3092:        if (BGE_IS_5714_FAMILY(sc))
                   3093:                marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
                   3094:        CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
                   3095:
                   3096:        /* Step 5b-5d: */
1.141     jmcneill 3097:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
1.172     msaitoh  3098:            BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
                   3099:            BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW);
1.1       fvdl     3100:
1.180     msaitoh  3101:        /* XXX ???: Disable fastboot on controllers that support it. */
1.134     markd    3102:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5752 ||
1.172     msaitoh  3103:            BGE_IS_5755_PLUS(sc))
1.119     tsutsui  3104:                CSR_WRITE_4(sc, BGE_FASTBOOT_PC, 0);
                   3105:
1.177     msaitoh  3106:        /*
1.180     msaitoh  3107:         * Step 6: Write the magic number to SRAM at offset 0xB50.
1.177     msaitoh  3108:         * When firmware finishes its initialization it will
                   3109:         * write ~BGE_MAGIC_NUMBER to the same location.
                   3110:         */
                   3111:        bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
                   3112:
1.180     msaitoh  3113:        /* Step 7: */
1.76      cube     3114:        val = BGE_MISCCFG_RESET_CORE_CLOCKS | (65<<1);
                   3115:        /*
                   3116:         * XXX: from FreeBSD/Linux; no documentation
                   3117:         */
1.157     msaitoh  3118:        if (sc->bge_flags & BGE_PCIE) {
1.76      cube     3119:                if (CSR_READ_4(sc, BGE_PCIE_CTL1) == 0x60)
1.157     msaitoh  3120:                        /* PCI Express 1.0 system */
1.76      cube     3121:                        CSR_WRITE_4(sc, BGE_PCIE_CTL1, 0x20);
                   3122:                if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {
1.157     msaitoh  3123:                        /*
                   3124:                         * Prevent PCI Express link training
                   3125:                         * during global reset.
                   3126:                         */
1.76      cube     3127:                        CSR_WRITE_4(sc, BGE_MISC_CFG, 1 << 29);
                   3128:                        val |= (1<<29);
                   3129:                }
                   3130:        }
                   3131:
1.180     msaitoh  3132:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906) {
                   3133:                i = CSR_READ_4(sc, BGE_VCPU_STATUS);
                   3134:                CSR_WRITE_4(sc, BGE_VCPU_STATUS,
                   3135:                    i | BGE_VCPU_STATUS_DRV_RESET);
                   3136:                i = CSR_READ_4(sc, BGE_VCPU_EXT_CTRL);
                   3137:                CSR_WRITE_4(sc, BGE_VCPU_EXT_CTRL,
                   3138:                    i & ~BGE_VCPU_EXT_CTRL_HALT_CPU);
                   3139:        }
                   3140:
1.161     msaitoh  3141:        /*
                   3142:         * Set GPHY Power Down Override to leave GPHY
                   3143:         * powered up in D0 uninitialized.
                   3144:         */
1.172     msaitoh  3145:        if (BGE_IS_5705_PLUS(sc))
1.161     msaitoh  3146:                val |= BGE_MISCCFG_KEEP_GPHY_POWER;
                   3147:
1.180     msaitoh  3148:        /* XXX 5721, 5751 and 5752 */
                   3149:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750)
                   3150:                val |= BGE_MISCCFG_GRC_RESET_DISABLE;
                   3151:
1.1       fvdl     3152:        /* Issue global reset */
1.151     cegger   3153:        write_op(sc, BGE_MISC_CFG, val);
                   3154:
1.180     msaitoh  3155:        /* Step 8: wait for complete */
                   3156:        if (sc->bge_flags & BGE_PCIE)
                   3157:                delay(100*1000); /* too big */
                   3158:        else
                   3159:                delay(100);
                   3160:
                   3161:        /* From Linux: dummy read to flush PCI posted writes */
                   3162:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
                   3163:
                   3164:        /* Step 9-10: Reset some of the PCI state that got zapped by reset */
                   3165:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
                   3166:            BGE_PCIMISCCTL_INDIRECT_ACCESS | BGE_PCIMISCCTL_MASK_PCI_INTR |
                   3167:            BGE_HIF_SWAP_OPTIONS | BGE_PCIMISCCTL_PCISTATE_RW
                   3168:                | BGE_PCIMISCCTL_CLOCKCTL_RW);
                   3169:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);
                   3170:        write_op(sc, BGE_MISC_CFG, (65 << 1));
                   3171:
                   3172:        /* Step 11: disable PCI-X Relaxed Ordering. */
                   3173:        if (sc->bge_flags & BGE_PCIX) {
                   3174:                reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
                   3175:                    + PCI_PCIX_CMD);
                   3176:                pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->bge_pcixcap
                   3177:                    + PCI_PCIX_CMD, reg & ~PCI_PCIX_CMD_RELAXED_ORDER);
1.151     cegger   3178:        }
                   3179:
1.157     msaitoh  3180:        if (sc->bge_flags & BGE_PCIE) {
1.76      cube     3181:                if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {
                   3182:                        DELAY(500000);
                   3183:                        /* XXX: Magic Numbers */
1.170     msaitoh  3184:                        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                   3185:                            BGE_PCI_UNKNOWN0);
                   3186:                        pci_conf_write(sc->sc_pc, sc->sc_pcitag,
                   3187:                            BGE_PCI_UNKNOWN0,
1.76      cube     3188:                            reg | (1 << 15));
                   3189:                }
1.177     msaitoh  3190:                devctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
1.180     msaitoh  3191:                    sc->bge_pciecap + PCI_PCIE_DCSR);
1.177     msaitoh  3192:                /* Clear enable no snoop and disable relaxed ordering. */
                   3193:                devctl &= ~(0x0010 | PCI_PCIE_DCSR_ENA_NO_SNOOP);
                   3194:                /* Set PCIE max payload size to 128. */
                   3195:                devctl &= ~(0x00e0);
1.179     msaitoh  3196:                /* Clear device status register. Write 1b to clear */
                   3197:                devctl |= PCI_PCIE_DCSR_URD | PCI_PCIE_DCSR_FED
                   3198:                    | PCI_PCIE_DCSR_NFED | PCI_PCIE_DCSR_CED;
1.177     msaitoh  3199:                pci_conf_write(sc->sc_pc, sc->sc_pcitag,
1.180     msaitoh  3200:                    sc->bge_pciecap + PCI_PCIE_DCSR, devctl);
1.76      cube     3201:        }
                   3202:
1.180     msaitoh  3203:        /* Step 12: Enable memory arbiter. */
                   3204:        marbmode = 0;
                   3205:        if (BGE_IS_5714_FAMILY(sc))
                   3206:                marbmode = CSR_READ_4(sc, BGE_MARB_MODE);
                   3207:        CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE | marbmode);
                   3208:
1.184     njoly    3209:        /* Step 17: Poll until the firmware initialization is complete */
1.180     msaitoh  3210:        bge_poll_fw(sc);
1.1       fvdl     3211:
1.180     msaitoh  3212:        /* XXX 5721, 5751 and 5752 */
                   3213:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5750) {
                   3214:                /* Step 19: */
                   3215:                BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, 1 << 29 | 1 << 25);
                   3216:                /* Step 20: */
                   3217:                BGE_SETBIT(sc, BGE_TLP_CONTROL_REG, BGE_TLP_DATA_FIFO_PROTECT);
1.44      hannken  3218:        }
1.1       fvdl     3219:
1.180     msaitoh  3220:        /*
                   3221:         * Step 18: wirte mac mode
                   3222:         * XXX Write 0x0c for 5703S and 5704S
                   3223:         */
                   3224:        CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
                   3225:
                   3226:
                   3227:        /* Step 21: 5822 B0 errata */
1.181     msaitoh  3228:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5704_BX) {
                   3229:                pcireg_t msidata;
                   3230:
                   3231:                msidata = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                   3232:                    BGE_PCI_MSI_DATA);
                   3233:                msidata |= ((1 << 13 | 1 << 12 | 1 << 10) << 16);
                   3234:                pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MSI_DATA,
                   3235:                    msidata);
                   3236:        }
1.151     cegger   3237:
1.180     msaitoh  3238:        /* Step 23: restore cache line size */
                   3239:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);
1.1       fvdl     3240:
1.180     msaitoh  3241: #if 0
1.1       fvdl     3242:        /*
                   3243:         * XXX Wait for the value of the PCISTATE register to
                   3244:         * return to its original pre-reset state. This is a
                   3245:         * fairly good indicator of reset completion. If we don't
                   3246:         * wait for the reset to fully complete, trying to read
                   3247:         * from the device's non-PCI registers may yield garbage
                   3248:         * results.
                   3249:         */
1.172     msaitoh  3250:        for (i = 0; i < BGE_TIMEOUT; i++) {
1.141     jmcneill 3251:                new_pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
1.61      jonathan 3252:                    BGE_PCI_PCISTATE);
1.87      perry    3253:                if ((new_pcistate & ~BGE_PCISTATE_RESERVED) ==
1.62      jonathan 3254:                    (pcistate & ~BGE_PCISTATE_RESERVED))
1.1       fvdl     3255:                        break;
                   3256:                DELAY(10);
                   3257:        }
1.87      perry    3258:        if ((new_pcistate & ~BGE_PCISTATE_RESERVED) !=
1.62      jonathan 3259:            (pcistate & ~BGE_PCISTATE_RESERVED)) {
1.138     joerg    3260:                aprint_error_dev(sc->bge_dev, "pcistate failed to revert\n");
1.61      jonathan 3261:        }
1.172     msaitoh  3262: #endif
1.1       fvdl     3263:
1.180     msaitoh  3264:        /* Step 28: Fix up byte swapping */
1.1       fvdl     3265:        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
                   3266:
1.177     msaitoh  3267:        /* Tell the ASF firmware we are up */
                   3268:        if (sc->bge_asf_mode & ASF_STACKUP)
                   3269:                BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
                   3270:
1.161     msaitoh  3271:        /*
                   3272:         * The 5704 in TBI mode apparently needs some special
                   3273:         * adjustment to insure the SERDES drive level is set
                   3274:         * to 1.2V.
                   3275:         */
                   3276:        if (sc->bge_flags & BGE_PHY_FIBER_TBI &&
                   3277:            BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
1.170     msaitoh  3278:                uint32_t serdescfg;
1.161     msaitoh  3279:
                   3280:                serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);
                   3281:                serdescfg = (serdescfg & ~0xFFF) | 0x880;
                   3282:                CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);
                   3283:        }
                   3284:
                   3285:        if (sc->bge_flags & BGE_PCIE &&
1.172     msaitoh  3286:            sc->bge_chipid != BGE_CHIPID_BCM5750_A0 &&
                   3287:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 &&
                   3288:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5785 &&
                   3289:            BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM57765) {
                   3290:                uint32_t v;
                   3291:
                   3292:                /* Enable PCI Express bug fix */
                   3293:                v = CSR_READ_4(sc, 0x7c00);
                   3294:                CSR_WRITE_4(sc, 0x7c00, v | (1<<25));
                   3295:        }
1.1       fvdl     3296:        DELAY(10000);
1.177     msaitoh  3297:
                   3298:        return 0;
1.1       fvdl     3299: }
                   3300:
                   3301: /*
                   3302:  * Frame reception handling. This is called if there's a frame
                   3303:  * on the receive return list.
                   3304:  *
                   3305:  * Note: we have to be able to handle two possibilities here:
1.184     njoly    3306:  * 1) the frame is from the jumbo receive ring
1.1       fvdl     3307:  * 2) the frame is from the standard receive ring
                   3308:  */
                   3309:
1.104     thorpej  3310: static void
                   3311: bge_rxeof(struct bge_softc *sc)
1.1       fvdl     3312: {
                   3313:        struct ifnet *ifp;
1.172     msaitoh  3314:        uint16_t rx_prod, rx_cons;
1.1       fvdl     3315:        int stdcnt = 0, jumbocnt = 0;
                   3316:        bus_dmamap_t dmamap;
                   3317:        bus_addr_t offset, toff;
                   3318:        bus_size_t tlen;
                   3319:        int tosync;
                   3320:
1.172     msaitoh  3321:        rx_cons = sc->bge_rx_saved_considx;
                   3322:        rx_prod = sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx;
                   3323:
                   3324:        /* Nothing to do */
                   3325:        if (rx_cons == rx_prod)
                   3326:                return;
                   3327:
1.1       fvdl     3328:        ifp = &sc->ethercom.ec_if;
                   3329:
                   3330:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3331:            offsetof(struct bge_ring_data, bge_status_block),
                   3332:            sizeof (struct bge_status_block),
                   3333:            BUS_DMASYNC_POSTREAD);
                   3334:
                   3335:        offset = offsetof(struct bge_ring_data, bge_rx_return_ring);
1.172     msaitoh  3336:        tosync = rx_prod - rx_cons;
1.1       fvdl     3337:
1.148     mlelstv  3338: #if NRND > 0
                   3339:        if (tosync != 0 && RND_ENABLED(&sc->rnd_source))
                   3340:                rnd_add_uint32(&sc->rnd_source, tosync);
                   3341: #endif
                   3342:
1.172     msaitoh  3343:        toff = offset + (rx_cons * sizeof (struct bge_rx_bd));
1.1       fvdl     3344:
                   3345:        if (tosync < 0) {
1.172     msaitoh  3346:                tlen = (sc->bge_return_ring_cnt - rx_cons) *
1.1       fvdl     3347:                    sizeof (struct bge_rx_bd);
                   3348:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3349:                    toff, tlen, BUS_DMASYNC_POSTREAD);
                   3350:                tosync = -tosync;
                   3351:        }
                   3352:
                   3353:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3354:            offset, tosync * sizeof (struct bge_rx_bd),
                   3355:            BUS_DMASYNC_POSTREAD);
                   3356:
1.172     msaitoh  3357:        while (rx_cons != rx_prod) {
1.1       fvdl     3358:                struct bge_rx_bd        *cur_rx;
1.170     msaitoh  3359:                uint32_t                rxidx;
1.1       fvdl     3360:                struct mbuf             *m = NULL;
                   3361:
1.172     msaitoh  3362:                cur_rx = &sc->bge_rdata->bge_rx_return_ring[rx_cons];
1.1       fvdl     3363:
                   3364:                rxidx = cur_rx->bge_idx;
1.172     msaitoh  3365:                BGE_INC(rx_cons, sc->bge_return_ring_cnt);
1.1       fvdl     3366:
                   3367:                if (cur_rx->bge_flags & BGE_RXBDFLAG_JUMBO_RING) {
                   3368:                        BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT);
                   3369:                        m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx];
                   3370:                        sc->bge_cdata.bge_rx_jumbo_chain[rxidx] = NULL;
                   3371:                        jumbocnt++;
1.124     bouyer   3372:                        bus_dmamap_sync(sc->bge_dmatag,
                   3373:                            sc->bge_cdata.bge_rx_jumbo_map,
1.126     christos 3374:                            mtod(m, char *) - (char *)sc->bge_cdata.bge_jumbo_buf,
1.125     bouyer   3375:                            BGE_JLEN, BUS_DMASYNC_POSTREAD);
1.1       fvdl     3376:                        if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) {
                   3377:                                ifp->if_ierrors++;
                   3378:                                bge_newbuf_jumbo(sc, sc->bge_jumbo, m);
                   3379:                                continue;
                   3380:                        }
                   3381:                        if (bge_newbuf_jumbo(sc, sc->bge_jumbo,
                   3382:                                             NULL)== ENOBUFS) {
                   3383:                                ifp->if_ierrors++;
                   3384:                                bge_newbuf_jumbo(sc, sc->bge_jumbo, m);
                   3385:                                continue;
                   3386:                        }
                   3387:                } else {
                   3388:                        BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT);
                   3389:                        m = sc->bge_cdata.bge_rx_std_chain[rxidx];
1.124     bouyer   3390:
1.1       fvdl     3391:                        sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL;
                   3392:                        stdcnt++;
                   3393:                        dmamap = sc->bge_cdata.bge_rx_std_map[rxidx];
                   3394:                        sc->bge_cdata.bge_rx_std_map[rxidx] = 0;
1.125     bouyer   3395:                        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0,
                   3396:                            dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   3397:                        bus_dmamap_unload(sc->bge_dmatag, dmamap);
1.1       fvdl     3398:                        if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) {
                   3399:                                ifp->if_ierrors++;
                   3400:                                bge_newbuf_std(sc, sc->bge_std, m, dmamap);
                   3401:                                continue;
                   3402:                        }
                   3403:                        if (bge_newbuf_std(sc, sc->bge_std,
                   3404:                            NULL, dmamap) == ENOBUFS) {
                   3405:                                ifp->if_ierrors++;
                   3406:                                bge_newbuf_std(sc, sc->bge_std, m, dmamap);
                   3407:                                continue;
                   3408:                        }
                   3409:                }
                   3410:
                   3411:                ifp->if_ipackets++;
1.37      jonathan 3412: #ifndef __NO_STRICT_ALIGNMENT
1.178     msaitoh  3413:                /*
                   3414:                 * XXX: if the 5701 PCIX-Rx-DMA workaround is in effect,
                   3415:                 * the Rx buffer has the layer-2 header unaligned.
                   3416:                 * If our CPU requires alignment, re-align by copying.
                   3417:                 */
1.157     msaitoh  3418:                if (sc->bge_flags & BGE_RX_ALIGNBUG) {
1.127     tsutsui  3419:                        memmove(mtod(m, char *) + ETHER_ALIGN, m->m_data,
1.178     msaitoh  3420:                                cur_rx->bge_len);
1.37      jonathan 3421:                        m->m_data += ETHER_ALIGN;
                   3422:                }
                   3423: #endif
1.87      perry    3424:
1.54      fvdl     3425:                m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
1.1       fvdl     3426:                m->m_pkthdr.rcvif = ifp;
                   3427:
                   3428:                /*
                   3429:                 * Handle BPF listeners. Let the BPF user see the packet.
                   3430:                 */
1.182     joerg    3431:                bpf_mtap(ifp, m);
1.1       fvdl     3432:
1.60      drochner 3433:                m->m_pkthdr.csum_flags = M_CSUM_IPv4;
1.46      jonathan 3434:
                   3435:                if ((cur_rx->bge_ip_csum ^ 0xffff) != 0)
                   3436:                        m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
                   3437:                /*
                   3438:                 * Rx transport checksum-offload may also
                   3439:                 * have bugs with packets which, when transmitted,
                   3440:                 * were `runts' requiring padding.
                   3441:                 */
                   3442:                if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM &&
                   3443:                    (/* (sc->_bge_quirks & BGE_QUIRK_SHORT_CKSUM_BUG) == 0 ||*/
                   3444:                     m->m_pkthdr.len >= ETHER_MIN_NOPAD)) {
                   3445:                        m->m_pkthdr.csum_data =
                   3446:                            cur_rx->bge_tcp_udp_csum;
                   3447:                        m->m_pkthdr.csum_flags |=
                   3448:                            (M_CSUM_TCPv4|M_CSUM_UDPv4|
                   3449:                             M_CSUM_DATA|M_CSUM_NO_PSEUDOHDR);
1.1       fvdl     3450:                }
                   3451:
                   3452:                /*
                   3453:                 * If we received a packet with a vlan tag, pass it
                   3454:                 * to vlan_input() instead of ether_input().
                   3455:                 */
1.150     dsl      3456:                if (cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) {
1.85      jdolecek 3457:                        VLAN_INPUT_TAG(ifp, m, cur_rx->bge_vlan_tag, continue);
1.150     dsl      3458:                }
1.1       fvdl     3459:
                   3460:                (*ifp->if_input)(ifp, m);
                   3461:        }
                   3462:
1.172     msaitoh  3463:        sc->bge_rx_saved_considx = rx_cons;
1.151     cegger   3464:        bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
1.1       fvdl     3465:        if (stdcnt)
1.151     cegger   3466:                bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
1.1       fvdl     3467:        if (jumbocnt)
1.151     cegger   3468:                bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
1.1       fvdl     3469: }
                   3470:
1.104     thorpej  3471: static void
                   3472: bge_txeof(struct bge_softc *sc)
1.1       fvdl     3473: {
                   3474:        struct bge_tx_bd *cur_tx = NULL;
                   3475:        struct ifnet *ifp;
                   3476:        struct txdmamap_pool_entry *dma;
                   3477:        bus_addr_t offset, toff;
                   3478:        bus_size_t tlen;
                   3479:        int tosync;
                   3480:        struct mbuf *m;
                   3481:
                   3482:        ifp = &sc->ethercom.ec_if;
                   3483:
                   3484:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3485:            offsetof(struct bge_ring_data, bge_status_block),
                   3486:            sizeof (struct bge_status_block),
                   3487:            BUS_DMASYNC_POSTREAD);
                   3488:
                   3489:        offset = offsetof(struct bge_ring_data, bge_tx_ring);
1.87      perry    3490:        tosync = sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx -
1.1       fvdl     3491:            sc->bge_tx_saved_considx;
                   3492:
1.148     mlelstv  3493: #if NRND > 0
                   3494:        if (tosync != 0 && RND_ENABLED(&sc->rnd_source))
                   3495:                rnd_add_uint32(&sc->rnd_source, tosync);
                   3496: #endif
                   3497:
1.1       fvdl     3498:        toff = offset + (sc->bge_tx_saved_considx * sizeof (struct bge_tx_bd));
                   3499:
                   3500:        if (tosync < 0) {
                   3501:                tlen = (BGE_TX_RING_CNT - sc->bge_tx_saved_considx) *
                   3502:                    sizeof (struct bge_tx_bd);
                   3503:                bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3504:                    toff, tlen, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   3505:                tosync = -tosync;
                   3506:        }
                   3507:
                   3508:        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
                   3509:            offset, tosync * sizeof (struct bge_tx_bd),
                   3510:            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   3511:
                   3512:        /*
                   3513:         * Go through our tx ring and free mbufs for those
                   3514:         * frames that have been sent.
                   3515:         */
                   3516:        while (sc->bge_tx_saved_considx !=
                   3517:            sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx) {
1.170     msaitoh  3518:                uint32_t                idx = 0;
1.1       fvdl     3519:
                   3520:                idx = sc->bge_tx_saved_considx;
                   3521:                cur_tx = &sc->bge_rdata->bge_tx_ring[idx];
                   3522:                if (cur_tx->bge_flags & BGE_TXBDFLAG_END)
                   3523:                        ifp->if_opackets++;
                   3524:                m = sc->bge_cdata.bge_tx_chain[idx];
                   3525:                if (m != NULL) {
                   3526:                        sc->bge_cdata.bge_tx_chain[idx] = NULL;
                   3527:                        dma = sc->txdma[idx];
                   3528:                        bus_dmamap_sync(sc->bge_dmatag, dma->dmamap, 0,
                   3529:                            dma->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   3530:                        bus_dmamap_unload(sc->bge_dmatag, dma->dmamap);
                   3531:                        SLIST_INSERT_HEAD(&sc->txdma_list, dma, link);
                   3532:                        sc->txdma[idx] = NULL;
                   3533:
                   3534:                        m_freem(m);
                   3535:                }
                   3536:                sc->bge_txcnt--;
                   3537:                BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT);
                   3538:                ifp->if_timer = 0;
                   3539:        }
                   3540:
                   3541:        if (cur_tx != NULL)
                   3542:                ifp->if_flags &= ~IFF_OACTIVE;
                   3543: }
                   3544:
1.104     thorpej  3545: static int
                   3546: bge_intr(void *xsc)
1.1       fvdl     3547: {
                   3548:        struct bge_softc *sc;
                   3549:        struct ifnet *ifp;
1.161     msaitoh  3550:        uint32_t statusword;
1.1       fvdl     3551:
                   3552:        sc = xsc;
                   3553:        ifp = &sc->ethercom.ec_if;
                   3554:
1.161     msaitoh  3555:        /* It is possible for the interrupt to arrive before
                   3556:         * the status block is updated prior to the interrupt.
                   3557:         * Reading the PCI State register will confirm whether the
                   3558:         * interrupt is ours and will flush the status block.
                   3559:         */
1.144     mlelstv  3560:
1.161     msaitoh  3561:        /* read status word from status block */
                   3562:        statusword = sc->bge_rdata->bge_status_block.bge_status;
1.144     mlelstv  3563:
1.161     msaitoh  3564:        if ((statusword & BGE_STATFLAG_UPDATED) ||
                   3565:            (!(CSR_READ_4(sc, BGE_PCI_PCISTATE) & BGE_PCISTATE_INTR_NOT_ACTIVE))) {
                   3566:                /* Ack interrupt and stop others from occuring. */
                   3567:                bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
1.144     mlelstv  3568:
1.161     msaitoh  3569:                BGE_EVCNT_INCR(sc->bge_ev_intr);
1.1       fvdl     3570:
1.161     msaitoh  3571:                /* clear status word */
                   3572:                sc->bge_rdata->bge_status_block.bge_status = 0;
1.72      thorpej  3573:
1.161     msaitoh  3574:                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   3575:                    statusword & BGE_STATFLAG_LINKSTATE_CHANGED ||
                   3576:                    BGE_STS_BIT(sc, BGE_STS_LINK_EVT))
                   3577:                        bge_link_upd(sc);
1.1       fvdl     3578:
1.161     msaitoh  3579:                if (ifp->if_flags & IFF_RUNNING) {
                   3580:                        /* Check RX return ring producer/consumer */
                   3581:                        bge_rxeof(sc);
1.144     mlelstv  3582:
1.161     msaitoh  3583:                        /* Check TX ring producer/consumer */
                   3584:                        bge_txeof(sc);
1.1       fvdl     3585:                }
                   3586:
1.161     msaitoh  3587:                if (sc->bge_pending_rxintr_change) {
                   3588:                        uint32_t rx_ticks = sc->bge_rx_coal_ticks;
                   3589:                        uint32_t rx_bds = sc->bge_rx_max_coal_bds;
                   3590:                        uint32_t junk;
1.1       fvdl     3591:
1.161     msaitoh  3592:                        CSR_WRITE_4(sc, BGE_HCC_RX_COAL_TICKS, rx_ticks);
                   3593:                        DELAY(10);
                   3594:                        junk = CSR_READ_4(sc, BGE_HCC_RX_COAL_TICKS);
1.1       fvdl     3595:
1.161     msaitoh  3596:                        CSR_WRITE_4(sc, BGE_HCC_RX_MAX_COAL_BDS, rx_bds);
                   3597:                        DELAY(10);
                   3598:                        junk = CSR_READ_4(sc, BGE_HCC_RX_MAX_COAL_BDS);
1.58      jonathan 3599:
1.161     msaitoh  3600:                        sc->bge_pending_rxintr_change = 0;
                   3601:                }
                   3602:                bge_handle_events(sc);
1.87      perry    3603:
1.161     msaitoh  3604:                /* Re-enable interrupts. */
                   3605:                bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
1.58      jonathan 3606:
1.161     msaitoh  3607:                if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
                   3608:                        bge_start(ifp);
1.1       fvdl     3609:
1.170     msaitoh  3610:                return 1;
1.161     msaitoh  3611:        } else
1.170     msaitoh  3612:                return 0;
1.1       fvdl     3613: }
                   3614:
1.104     thorpej  3615: static void
1.177     msaitoh  3616: bge_asf_driver_up(struct bge_softc *sc)
                   3617: {
                   3618:        if (sc->bge_asf_mode & ASF_STACKUP) {
                   3619:                /* Send ASF heartbeat aprox. every 2s */
                   3620:                if (sc->bge_asf_count)
                   3621:                        sc->bge_asf_count --;
                   3622:                else {
1.180     msaitoh  3623:                        sc->bge_asf_count = 2;
1.177     msaitoh  3624:                        bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,
                   3625:                            BGE_FW_DRV_ALIVE);
                   3626:                        bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
                   3627:                        bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);
                   3628:                        CSR_WRITE_4(sc, BGE_CPU_EVENT,
                   3629:                            CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
                   3630:                }
                   3631:        }
                   3632: }
                   3633:
                   3634: static void
1.104     thorpej  3635: bge_tick(void *xsc)
1.1       fvdl     3636: {
                   3637:        struct bge_softc *sc = xsc;
                   3638:        struct mii_data *mii = &sc->bge_mii;
                   3639:        int s;
                   3640:
                   3641:        s = splnet();
                   3642:
1.172     msaitoh  3643:        if (BGE_IS_5705_PLUS(sc))
                   3644:                bge_stats_update_regs(sc);
                   3645:        else
                   3646:                bge_stats_update(sc);
1.1       fvdl     3647:
1.157     msaitoh  3648:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.161     msaitoh  3649:                /*
                   3650:                 * Since in TBI mode auto-polling can't be used we should poll
                   3651:                 * link status manually. Here we register pending link event
                   3652:                 * and trigger interrupt.
                   3653:                 */
                   3654:                BGE_STS_SETBIT(sc, BGE_STS_LINK_EVT);
                   3655:                BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
                   3656:        } else {
                   3657:                /*
                   3658:                 * Do not touch PHY if we have link up. This could break
                   3659:                 * IPMI/ASF mode or produce extra input errors.
                   3660:                 * (extra input errors was reported for bcm5701 & bcm5704).
                   3661:                 */
                   3662:                if (!BGE_STS_BIT(sc, BGE_STS_LINK))
                   3663:                        mii_tick(mii);
                   3664:        }
                   3665:
                   3666:        callout_reset(&sc->bge_timeout, hz, bge_tick, sc);
1.1       fvdl     3667:
                   3668:        splx(s);
                   3669: }
                   3670:
1.104     thorpej  3671: static void
1.172     msaitoh  3672: bge_stats_update_regs(struct bge_softc *sc)
                   3673: {
                   3674:        struct ifnet *ifp = &sc->ethercom.ec_if;
                   3675:
                   3676:        ifp->if_collisions += CSR_READ_4(sc, BGE_MAC_STATS +
                   3677:            offsetof(struct bge_mac_stats_regs, etherStatsCollisions));
                   3678:
                   3679:        ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS);
                   3680:        ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS);
                   3681:        ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_OUT_OF_BDS);
                   3682: }
                   3683:
                   3684: static void
1.104     thorpej  3685: bge_stats_update(struct bge_softc *sc)
1.1       fvdl     3686: {
                   3687:        struct ifnet *ifp = &sc->ethercom.ec_if;
                   3688:        bus_size_t stats = BGE_MEMWIN_START + BGE_STATS_BLOCK;
1.44      hannken  3689:
1.1       fvdl     3690: #define READ_STAT(sc, stats, stat) \
                   3691:          CSR_READ_4(sc, stats + offsetof(struct bge_stats, stat))
                   3692:
                   3693:        ifp->if_collisions +=
                   3694:          (READ_STAT(sc, stats, dot3StatsSingleCollisionFrames.bge_addr_lo) +
                   3695:           READ_STAT(sc, stats, dot3StatsMultipleCollisionFrames.bge_addr_lo) +
                   3696:           READ_STAT(sc, stats, dot3StatsExcessiveCollisions.bge_addr_lo) +
                   3697:           READ_STAT(sc, stats, dot3StatsLateCollisions.bge_addr_lo)) -
                   3698:          ifp->if_collisions;
                   3699:
1.72      thorpej  3700:        BGE_EVCNT_UPD(sc->bge_ev_tx_xoff,
                   3701:                      READ_STAT(sc, stats, outXoffSent.bge_addr_lo));
                   3702:        BGE_EVCNT_UPD(sc->bge_ev_tx_xon,
                   3703:                      READ_STAT(sc, stats, outXonSent.bge_addr_lo));
                   3704:        BGE_EVCNT_UPD(sc->bge_ev_rx_xoff,
                   3705:                      READ_STAT(sc, stats,
                   3706:                                xoffPauseFramesReceived.bge_addr_lo));
                   3707:        BGE_EVCNT_UPD(sc->bge_ev_rx_xon,
                   3708:                      READ_STAT(sc, stats, xonPauseFramesReceived.bge_addr_lo));
                   3709:        BGE_EVCNT_UPD(sc->bge_ev_rx_macctl,
                   3710:                      READ_STAT(sc, stats,
                   3711:                                macControlFramesReceived.bge_addr_lo));
                   3712:        BGE_EVCNT_UPD(sc->bge_ev_xoffentered,
                   3713:                      READ_STAT(sc, stats, xoffStateEntered.bge_addr_lo));
                   3714:
1.1       fvdl     3715: #undef READ_STAT
                   3716:
                   3717: #ifdef notdef
                   3718:        ifp->if_collisions +=
                   3719:           (sc->bge_rdata->bge_info.bge_stats.dot3StatsSingleCollisionFrames +
                   3720:           sc->bge_rdata->bge_info.bge_stats.dot3StatsMultipleCollisionFrames +
                   3721:           sc->bge_rdata->bge_info.bge_stats.dot3StatsExcessiveCollisions +
                   3722:           sc->bge_rdata->bge_info.bge_stats.dot3StatsLateCollisions) -
                   3723:           ifp->if_collisions;
                   3724: #endif
                   3725: }
                   3726:
1.46      jonathan 3727: /*
                   3728:  * Pad outbound frame to ETHER_MIN_NOPAD for an unusual reason.
                   3729:  * The bge hardware will pad out Tx runts to ETHER_MIN_NOPAD,
                   3730:  * but when such padded frames employ the  bge IP/TCP checksum offload,
                   3731:  * the hardware checksum assist gives incorrect results (possibly
                   3732:  * from incorporating its own padding into the UDP/TCP checksum; who knows).
                   3733:  * If we pad such runts with zeros, the onboard checksum comes out correct.
                   3734:  */
1.102     perry    3735: static inline int
1.46      jonathan 3736: bge_cksum_pad(struct mbuf *pkt)
                   3737: {
                   3738:        struct mbuf *last = NULL;
                   3739:        int padlen;
                   3740:
                   3741:        padlen = ETHER_MIN_NOPAD - pkt->m_pkthdr.len;
                   3742:
                   3743:        /* if there's only the packet-header and we can pad there, use it. */
                   3744:        if (pkt->m_pkthdr.len == pkt->m_len &&
1.113     tsutsui  3745:            M_TRAILINGSPACE(pkt) >= padlen) {
1.46      jonathan 3746:                last = pkt;
                   3747:        } else {
                   3748:                /*
                   3749:                 * Walk packet chain to find last mbuf. We will either
1.87      perry    3750:                 * pad there, or append a new mbuf and pad it
1.46      jonathan 3751:                 * (thus perhaps avoiding the bcm5700 dma-min bug).
                   3752:                 */
                   3753:                for (last = pkt; last->m_next != NULL; last = last->m_next) {
1.114     tsutsui  3754:                       continue; /* do nothing */
1.46      jonathan 3755:                }
                   3756:
                   3757:                /* `last' now points to last in chain. */
1.114     tsutsui  3758:                if (M_TRAILINGSPACE(last) < padlen) {
1.46      jonathan 3759:                        /* Allocate new empty mbuf, pad it. Compact later. */
                   3760:                        struct mbuf *n;
                   3761:                        MGET(n, M_DONTWAIT, MT_DATA);
1.129     joerg    3762:                        if (n == NULL)
                   3763:                                return ENOBUFS;
1.46      jonathan 3764:                        n->m_len = 0;
                   3765:                        last->m_next = n;
                   3766:                        last = n;
                   3767:                }
                   3768:        }
                   3769:
1.114     tsutsui  3770:        KDASSERT(!M_READONLY(last));
                   3771:        KDASSERT(M_TRAILINGSPACE(last) >= padlen);
                   3772:
1.46      jonathan 3773:        /* Now zero the pad area, to avoid the bge cksum-assist bug */
1.126     christos 3774:        memset(mtod(last, char *) + last->m_len, 0, padlen);
1.46      jonathan 3775:        last->m_len += padlen;
                   3776:        pkt->m_pkthdr.len += padlen;
                   3777:        return 0;
                   3778: }
1.45      jonathan 3779:
                   3780: /*
                   3781:  * Compact outbound packets to avoid bug with DMA segments less than 8 bytes.
                   3782:  */
1.102     perry    3783: static inline int
1.45      jonathan 3784: bge_compact_dma_runt(struct mbuf *pkt)
                   3785: {
                   3786:        struct mbuf     *m, *prev;
                   3787:        int             totlen, prevlen;
                   3788:
                   3789:        prev = NULL;
                   3790:        totlen = 0;
                   3791:        prevlen = -1;
                   3792:
                   3793:        for (m = pkt; m != NULL; prev = m,m = m->m_next) {
                   3794:                int mlen = m->m_len;
                   3795:                int shortfall = 8 - mlen ;
                   3796:
                   3797:                totlen += mlen;
                   3798:                if (mlen == 0) {
                   3799:                        continue;
                   3800:                }
                   3801:                if (mlen >= 8)
                   3802:                        continue;
                   3803:
                   3804:                /* If we get here, mbuf data is too small for DMA engine.
                   3805:                 * Try to fix by shuffling data to prev or next in chain.
                   3806:                 * If that fails, do a compacting deep-copy of the whole chain.
                   3807:                 */
                   3808:
                   3809:                /* Internal frag. If fits in prev, copy it there. */
1.113     tsutsui  3810:                if (prev && M_TRAILINGSPACE(prev) >= m->m_len) {
1.115     tsutsui  3811:                        memcpy(prev->m_data + prev->m_len, m->m_data, mlen);
1.45      jonathan 3812:                        prev->m_len += mlen;
                   3813:                        m->m_len = 0;
                   3814:                        /* XXX stitch chain */
                   3815:                        prev->m_next = m_free(m);
                   3816:                        m = prev;
                   3817:                        continue;
                   3818:                }
1.113     tsutsui  3819:                else if (m->m_next != NULL &&
1.45      jonathan 3820:                             M_TRAILINGSPACE(m) >= shortfall &&
                   3821:                             m->m_next->m_len >= (8 + shortfall)) {
                   3822:                    /* m is writable and have enough data in next, pull up. */
                   3823:
1.115     tsutsui  3824:                        memcpy(m->m_data + m->m_len, m->m_next->m_data,
                   3825:                            shortfall);
1.45      jonathan 3826:                        m->m_len += shortfall;
                   3827:                        m->m_next->m_len -= shortfall;
                   3828:                        m->m_next->m_data += shortfall;
                   3829:                }
                   3830:                else if (m->m_next == NULL || 1) {
                   3831:                        /* Got a runt at the very end of the packet.
                   3832:                         * borrow data from the tail of the preceding mbuf and
                   3833:                         * update its length in-place. (The original data is still
                   3834:                         * valid, so we can do this even if prev is not writable.)
                   3835:                         */
                   3836:
                   3837:                        /* if we'd make prev a runt, just move all of its data. */
                   3838:                        KASSERT(prev != NULL /*, ("runt but null PREV")*/);
                   3839:                        KASSERT(prev->m_len >= 8 /*, ("runt prev")*/);
1.111     christos 3840:
1.45      jonathan 3841:                        if ((prev->m_len - shortfall) < 8)
                   3842:                                shortfall = prev->m_len;
1.87      perry    3843:
1.45      jonathan 3844: #ifdef notyet  /* just do the safe slow thing for now */
                   3845:                        if (!M_READONLY(m)) {
                   3846:                                if (M_LEADINGSPACE(m) < shorfall) {
                   3847:                                        void *m_dat;
                   3848:                                        m_dat = (m->m_flags & M_PKTHDR) ?
                   3849:                                          m->m_pktdat : m->dat;
                   3850:                                        memmove(m_dat, mtod(m, void*), m->m_len);
                   3851:                                        m->m_data = m_dat;
                   3852:                                    }
                   3853:                        } else
                   3854: #endif /* just do the safe slow thing */
                   3855:                        {
                   3856:                                struct mbuf * n = NULL;
                   3857:                                int newprevlen = prev->m_len - shortfall;
                   3858:
                   3859:                                MGET(n, M_NOWAIT, MT_DATA);
                   3860:                                if (n == NULL)
                   3861:                                   return ENOBUFS;
                   3862:                                KASSERT(m->m_len + shortfall < MLEN
                   3863:                                        /*,
                   3864:                                          ("runt %d +prev %d too big\n", m->m_len, shortfall)*/);
                   3865:
                   3866:                                /* first copy the data we're stealing from prev */
1.115     tsutsui  3867:                                memcpy(n->m_data, prev->m_data + newprevlen,
                   3868:                                    shortfall);
1.45      jonathan 3869:
                   3870:                                /* update prev->m_len accordingly */
                   3871:                                prev->m_len -= shortfall;
                   3872:
                   3873:                                /* copy data from runt m */
1.115     tsutsui  3874:                                memcpy(n->m_data + shortfall, m->m_data,
                   3875:                                    m->m_len);
1.45      jonathan 3876:
                   3877:                                /* n holds what we stole from prev, plus m */
                   3878:                                n->m_len = shortfall + m->m_len;
                   3879:
                   3880:                                /* stitch n into chain and free m */
                   3881:                                n->m_next = m->m_next;
                   3882:                                prev->m_next = n;
                   3883:                                /* KASSERT(m->m_next == NULL); */
                   3884:                                m->m_next = NULL;
                   3885:                                m_free(m);
                   3886:                                m = n;  /* for continuing loop */
                   3887:                        }
                   3888:                }
                   3889:                prevlen = m->m_len;
                   3890:        }
                   3891:        return 0;
                   3892: }
                   3893:
1.1       fvdl     3894: /*
                   3895:  * Encapsulate an mbuf chain in the tx ring  by coupling the mbuf data
                   3896:  * pointers to descriptors.
                   3897:  */
1.104     thorpej  3898: static int
1.170     msaitoh  3899: bge_encap(struct bge_softc *sc, struct mbuf *m_head, uint32_t *txidx)
1.1       fvdl     3900: {
                   3901:        struct bge_tx_bd        *f = NULL;
1.170     msaitoh  3902:        uint32_t                frag, cur;
                   3903:        uint16_t                csum_flags = 0;
                   3904:        uint16_t                txbd_tso_flags = 0;
1.1       fvdl     3905:        struct txdmamap_pool_entry *dma;
                   3906:        bus_dmamap_t dmamap;
                   3907:        int                     i = 0;
1.29      itojun   3908:        struct m_tag            *mtag;
1.95      jonathan 3909:        int                     use_tso, maxsegsize, error;
1.107     blymn    3910:
1.1       fvdl     3911:        cur = frag = *txidx;
                   3912:
                   3913:        if (m_head->m_pkthdr.csum_flags) {
                   3914:                if (m_head->m_pkthdr.csum_flags & M_CSUM_IPv4)
                   3915:                        csum_flags |= BGE_TXBDFLAG_IP_CSUM;
1.8       thorpej  3916:                if (m_head->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4))
1.1       fvdl     3917:                        csum_flags |= BGE_TXBDFLAG_TCP_UDP_CSUM;
                   3918:        }
                   3919:
1.87      perry    3920:        /*
1.46      jonathan 3921:         * If we were asked to do an outboard checksum, and the NIC
                   3922:         * has the bug where it sometimes adds in the Ethernet padding,
                   3923:         * explicitly pad with zeros so the cksum will be correct either way.
                   3924:         * (For now, do this for all chip versions, until newer
                   3925:         * are confirmed to not require the workaround.)
                   3926:         */
                   3927:        if ((csum_flags & BGE_TXBDFLAG_TCP_UDP_CSUM) == 0 ||
                   3928: #ifdef notyet
                   3929:            (sc->bge_quirks & BGE_QUIRK_SHORT_CKSUM_BUG) == 0 ||
1.87      perry    3930: #endif
1.46      jonathan 3931:            m_head->m_pkthdr.len >= ETHER_MIN_NOPAD)
                   3932:                goto check_dma_bug;
                   3933:
1.170     msaitoh  3934:        if (bge_cksum_pad(m_head) != 0)
1.46      jonathan 3935:            return ENOBUFS;
                   3936:
                   3937: check_dma_bug:
1.157     msaitoh  3938:        if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX))
1.29      itojun   3939:                goto doit;
1.157     msaitoh  3940:
1.25      jonathan 3941:        /*
                   3942:         * bcm5700 Revision B silicon cannot handle DMA descriptors with
1.87      perry    3943:         * less than eight bytes.  If we encounter a teeny mbuf
1.25      jonathan 3944:         * at the end of a chain, we can pad.  Otherwise, copy.
                   3945:         */
1.45      jonathan 3946:        if (bge_compact_dma_runt(m_head) != 0)
                   3947:                return ENOBUFS;
1.25      jonathan 3948:
                   3949: doit:
1.1       fvdl     3950:        dma = SLIST_FIRST(&sc->txdma_list);
                   3951:        if (dma == NULL)
                   3952:                return ENOBUFS;
                   3953:        dmamap = dma->dmamap;
                   3954:
                   3955:        /*
1.95      jonathan 3956:         * Set up any necessary TSO state before we start packing...
                   3957:         */
                   3958:        use_tso = (m_head->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0;
                   3959:        if (!use_tso) {
                   3960:                maxsegsize = 0;
                   3961:        } else {        /* TSO setup */
                   3962:                unsigned  mss;
                   3963:                struct ether_header *eh;
                   3964:                unsigned ip_tcp_hlen, iptcp_opt_words, tcp_seg_flags, offset;
                   3965:                struct mbuf * m0 = m_head;
                   3966:                struct ip *ip;
                   3967:                struct tcphdr *th;
                   3968:                int iphl, hlen;
                   3969:
                   3970:                /*
                   3971:                 * XXX It would be nice if the mbuf pkthdr had offset
                   3972:                 * fields for the protocol headers.
                   3973:                 */
                   3974:
                   3975:                eh = mtod(m0, struct ether_header *);
                   3976:                switch (htons(eh->ether_type)) {
                   3977:                case ETHERTYPE_IP:
                   3978:                        offset = ETHER_HDR_LEN;
                   3979:                        break;
                   3980:
                   3981:                case ETHERTYPE_VLAN:
                   3982:                        offset = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
                   3983:                        break;
                   3984:
                   3985:                default:
                   3986:                        /*
                   3987:                         * Don't support this protocol or encapsulation.
                   3988:                         */
1.170     msaitoh  3989:                        return ENOBUFS;
1.95      jonathan 3990:                }
                   3991:
                   3992:                /*
                   3993:                 * TCP/IP headers are in the first mbuf; we can do
                   3994:                 * this the easy way.
                   3995:                 */
                   3996:                iphl = M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
                   3997:                hlen = iphl + offset;
                   3998:                if (__predict_false(m0->m_len <
                   3999:                                    (hlen + sizeof(struct tcphdr)))) {
                   4000:
1.138     joerg    4001:                        aprint_debug_dev(sc->bge_dev,
                   4002:                            "TSO: hard case m0->m_len == %d < ip/tcp hlen %zd,"
                   4003:                            "not handled yet\n",
                   4004:                             m0->m_len, hlen+ sizeof(struct tcphdr));
1.95      jonathan 4005: #ifdef NOTYET
                   4006:                        /*
                   4007:                         * XXX jonathan@NetBSD.org: untested.
                   4008:                         * how to force  this branch to be taken?
                   4009:                         */
                   4010:                        BGE_EVCNT_INCR(&sc->sc_ev_txtsopain);
                   4011:
                   4012:                        m_copydata(m0, offset, sizeof(ip), &ip);
                   4013:                        m_copydata(m0, hlen, sizeof(th), &th);
                   4014:
                   4015:                        ip.ip_len = 0;
                   4016:
                   4017:                        m_copyback(m0, hlen + offsetof(struct ip, ip_len),
                   4018:                            sizeof(ip.ip_len), &ip.ip_len);
                   4019:
                   4020:                        th.th_sum = in_cksum_phdr(ip.ip_src.s_addr,
                   4021:                            ip.ip_dst.s_addr, htons(IPPROTO_TCP));
                   4022:
                   4023:                        m_copyback(m0, hlen + offsetof(struct tcphdr, th_sum),
                   4024:                            sizeof(th.th_sum), &th.th_sum);
                   4025:
                   4026:                        hlen += th.th_off << 2;
                   4027:                        iptcp_opt_words = hlen;
                   4028: #else
                   4029:                        /*
                   4030:                         * if_wm "hard" case not yet supported, can we not
                   4031:                         * mandate it out of existence?
                   4032:                         */
                   4033:                        (void) ip; (void)th; (void) ip_tcp_hlen;
                   4034:
                   4035:                        return ENOBUFS;
                   4036: #endif
                   4037:                } else {
1.126     christos 4038:                        ip = (struct ip *) (mtod(m0, char *) + offset);
                   4039:                        th = (struct tcphdr *) (mtod(m0, char *) + hlen);
1.95      jonathan 4040:                        ip_tcp_hlen = iphl +  (th->th_off << 2);
                   4041:
                   4042:                        /* Total IP/TCP options, in 32-bit words */
                   4043:                        iptcp_opt_words = (ip_tcp_hlen
                   4044:                                           - sizeof(struct tcphdr)
                   4045:                                           - sizeof(struct ip)) >> 2;
                   4046:                }
                   4047:                if (BGE_IS_5750_OR_BEYOND(sc)) {
                   4048:                        th->th_sum = 0;
                   4049:                        csum_flags &= ~(BGE_TXBDFLAG_TCP_UDP_CSUM);
                   4050:                } else {
                   4051:                        /*
1.107     blymn    4052:                         * XXX jonathan@NetBSD.org: 5705 untested.
1.95      jonathan 4053:                         * Requires TSO firmware patch for 5701/5703/5704.
                   4054:                         */
                   4055:                        th->th_sum = in_cksum_phdr(ip->ip_src.s_addr,
                   4056:                            ip->ip_dst.s_addr, htons(IPPROTO_TCP));
                   4057:                }
                   4058:
                   4059:                mss = m_head->m_pkthdr.segsz;
1.107     blymn    4060:                txbd_tso_flags |=
1.95      jonathan 4061:                    BGE_TXBDFLAG_CPU_PRE_DMA |
                   4062:                    BGE_TXBDFLAG_CPU_POST_DMA;
                   4063:
                   4064:                /*
                   4065:                 * Our NIC TSO-assist assumes TSO has standard, optionless
                   4066:                 * IPv4 and TCP headers, which total 40 bytes. By default,
                   4067:                 * the NIC copies 40 bytes of IP/TCP header from the
                   4068:                 * supplied header into the IP/TCP header portion of
                   4069:                 * each post-TSO-segment. If the supplied packet has IP or
                   4070:                 * TCP options, we need to tell the NIC to copy those extra
                   4071:                 * bytes into each  post-TSO header, in addition to the normal
                   4072:                 * 40-byte IP/TCP header (and to leave space accordingly).
                   4073:                 * Unfortunately, the driver encoding of option length
                   4074:                 * varies across different ASIC families.
                   4075:                 */
                   4076:                tcp_seg_flags = 0;
                   4077:                if (iptcp_opt_words) {
1.172     msaitoh  4078:                        if (BGE_IS_5705_PLUS(sc)) {
1.95      jonathan 4079:                                tcp_seg_flags =
                   4080:                                        iptcp_opt_words << 11;
                   4081:                        } else {
                   4082:                                txbd_tso_flags |=
                   4083:                                        iptcp_opt_words << 12;
                   4084:                        }
                   4085:                }
                   4086:                maxsegsize = mss | tcp_seg_flags;
                   4087:                ip->ip_len = htons(mss + ip_tcp_hlen);
                   4088:
                   4089:        }       /* TSO setup */
                   4090:
                   4091:        /*
1.1       fvdl     4092:         * Start packing the mbufs in this chain into
                   4093:         * the fragment pointers. Stop when we run out
                   4094:         * of fragments or hit the end of the mbuf chain.
                   4095:         */
1.95      jonathan 4096:        error = bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_head,
                   4097:            BUS_DMA_NOWAIT);
1.170     msaitoh  4098:        if (error)
                   4099:                return ENOBUFS;
1.118     tsutsui  4100:        /*
                   4101:         * Sanity check: avoid coming within 16 descriptors
                   4102:         * of the end of the ring.
                   4103:         */
                   4104:        if (dmamap->dm_nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
                   4105:                BGE_TSO_PRINTF(("%s: "
                   4106:                    " dmamap_load_mbuf too close to ring wrap\n",
1.138     joerg    4107:                    device_xname(sc->bge_dev)));
1.118     tsutsui  4108:                goto fail_unload;
                   4109:        }
1.95      jonathan 4110:
                   4111:        mtag = sc->ethercom.ec_nvlans ?
                   4112:            m_tag_find(m_head, PACKET_TAG_VLAN, NULL) : NULL;
1.1       fvdl     4113:
1.6       thorpej  4114:
1.95      jonathan 4115:        /* Iterate over dmap-map fragments. */
1.1       fvdl     4116:        for (i = 0; i < dmamap->dm_nsegs; i++) {
                   4117:                f = &sc->bge_rdata->bge_tx_ring[frag];
                   4118:                if (sc->bge_cdata.bge_tx_chain[frag] != NULL)
                   4119:                        break;
1.107     blymn    4120:
1.172     msaitoh  4121:                BGE_HOSTADDR(f->bge_addr, dmamap->dm_segs[i].ds_addr);
1.1       fvdl     4122:                f->bge_len = dmamap->dm_segs[i].ds_len;
1.95      jonathan 4123:
                   4124:                /*
                   4125:                 * For 5751 and follow-ons, for TSO we must turn
                   4126:                 * off checksum-assist flag in the tx-descr, and
                   4127:                 * supply the ASIC-revision-specific encoding
                   4128:                 * of TSO flags and segsize.
                   4129:                 */
                   4130:                if (use_tso) {
                   4131:                        if (BGE_IS_5750_OR_BEYOND(sc) || i == 0) {
                   4132:                                f->bge_rsvd = maxsegsize;
                   4133:                                f->bge_flags = csum_flags | txbd_tso_flags;
                   4134:                        } else {
                   4135:                                f->bge_rsvd = 0;
                   4136:                                f->bge_flags =
                   4137:                                  (csum_flags | txbd_tso_flags) & 0x0fff;
                   4138:                        }
                   4139:                } else {
                   4140:                        f->bge_rsvd = 0;
                   4141:                        f->bge_flags = csum_flags;
                   4142:                }
1.1       fvdl     4143:
1.28      itojun   4144:                if (mtag != NULL) {
1.1       fvdl     4145:                        f->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
1.85      jdolecek 4146:                        f->bge_vlan_tag = VLAN_TAG_VALUE(mtag);
1.1       fvdl     4147:                } else {
                   4148:                        f->bge_vlan_tag = 0;
                   4149:                }
                   4150:                cur = frag;
                   4151:                BGE_INC(frag, BGE_TX_RING_CNT);
                   4152:        }
                   4153:
1.95      jonathan 4154:        if (i < dmamap->dm_nsegs) {
                   4155:                BGE_TSO_PRINTF(("%s: reached %d < dm_nsegs %d\n",
1.138     joerg    4156:                    device_xname(sc->bge_dev), i, dmamap->dm_nsegs));
1.118     tsutsui  4157:                goto fail_unload;
1.95      jonathan 4158:        }
1.1       fvdl     4159:
                   4160:        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
                   4161:            BUS_DMASYNC_PREWRITE);
                   4162:
1.95      jonathan 4163:        if (frag == sc->bge_tx_saved_considx) {
                   4164:                BGE_TSO_PRINTF(("%s: frag %d = wrapped id %d?\n",
1.138     joerg    4165:                    device_xname(sc->bge_dev), frag, sc->bge_tx_saved_considx));
1.95      jonathan 4166:
1.118     tsutsui  4167:                goto fail_unload;
1.95      jonathan 4168:        }
1.1       fvdl     4169:
                   4170:        sc->bge_rdata->bge_tx_ring[cur].bge_flags |= BGE_TXBDFLAG_END;
                   4171:        sc->bge_cdata.bge_tx_chain[cur] = m_head;
                   4172:        SLIST_REMOVE_HEAD(&sc->txdma_list, link);
                   4173:        sc->txdma[cur] = dma;
1.118     tsutsui  4174:        sc->bge_txcnt += dmamap->dm_nsegs;
1.1       fvdl     4175:
                   4176:        *txidx = frag;
                   4177:
1.170     msaitoh  4178:        return 0;
1.118     tsutsui  4179:
1.158     msaitoh  4180: fail_unload:
1.118     tsutsui  4181:        bus_dmamap_unload(sc->bge_dmatag, dmamap);
                   4182:
                   4183:        return ENOBUFS;
1.1       fvdl     4184: }
                   4185:
                   4186: /*
                   4187:  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
                   4188:  * to the mbuf data regions directly in the transmit descriptors.
                   4189:  */
1.104     thorpej  4190: static void
                   4191: bge_start(struct ifnet *ifp)
1.1       fvdl     4192: {
                   4193:        struct bge_softc *sc;
                   4194:        struct mbuf *m_head = NULL;
1.170     msaitoh  4195:        uint32_t prodidx;
1.1       fvdl     4196:        int pkts = 0;
                   4197:
                   4198:        sc = ifp->if_softc;
                   4199:
1.131     mlelstv  4200:        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
1.1       fvdl     4201:                return;
                   4202:
1.94      jonathan 4203:        prodidx = sc->bge_tx_prodidx;
1.1       fvdl     4204:
1.170     msaitoh  4205:        while (sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
1.1       fvdl     4206:                IFQ_POLL(&ifp->if_snd, m_head);
                   4207:                if (m_head == NULL)
                   4208:                        break;
                   4209:
                   4210: #if 0
                   4211:                /*
                   4212:                 * XXX
                   4213:                 * safety overkill.  If this is a fragmented packet chain
                   4214:                 * with delayed TCP/UDP checksums, then only encapsulate
                   4215:                 * it if we have enough descriptors to handle the entire
                   4216:                 * chain at once.
                   4217:                 * (paranoia -- may not actually be needed)
                   4218:                 */
                   4219:                if (m_head->m_flags & M_FIRSTFRAG &&
                   4220:                    m_head->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) {
                   4221:                        if ((BGE_TX_RING_CNT - sc->bge_txcnt) <
1.86      thorpej  4222:                            M_CSUM_DATA_IPv4_OFFSET(m_head->m_pkthdr.csum_data) + 16) {
1.1       fvdl     4223:                                ifp->if_flags |= IFF_OACTIVE;
                   4224:                                break;
                   4225:                        }
                   4226:                }
                   4227: #endif
                   4228:
                   4229:                /*
                   4230:                 * Pack the data into the transmit ring. If we
                   4231:                 * don't have room, set the OACTIVE flag and wait
                   4232:                 * for the NIC to drain the ring.
                   4233:                 */
                   4234:                if (bge_encap(sc, m_head, &prodidx)) {
                   4235:                        ifp->if_flags |= IFF_OACTIVE;
                   4236:                        break;
                   4237:                }
                   4238:
                   4239:                /* now we are committed to transmit the packet */
                   4240:                IFQ_DEQUEUE(&ifp->if_snd, m_head);
                   4241:                pkts++;
                   4242:
                   4243:                /*
                   4244:                 * If there's a BPF listener, bounce a copy of this frame
                   4245:                 * to him.
                   4246:                 */
1.182     joerg    4247:                bpf_mtap(ifp, m_head);
1.1       fvdl     4248:        }
                   4249:        if (pkts == 0)
                   4250:                return;
                   4251:
                   4252:        /* Transmit */
1.151     cegger   4253:        bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
1.158     msaitoh  4254:        /* 5700 b2 errata */
                   4255:        if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
1.151     cegger   4256:                bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
1.1       fvdl     4257:
1.94      jonathan 4258:        sc->bge_tx_prodidx = prodidx;
                   4259:
1.1       fvdl     4260:        /*
                   4261:         * Set a timeout in case the chip goes out to lunch.
                   4262:         */
                   4263:        ifp->if_timer = 5;
                   4264: }
                   4265:
1.104     thorpej  4266: static int
                   4267: bge_init(struct ifnet *ifp)
1.1       fvdl     4268: {
                   4269:        struct bge_softc *sc = ifp->if_softc;
1.170     msaitoh  4270:        const uint16_t *m;
1.142     dyoung   4271:        int s, error = 0;
1.1       fvdl     4272:
                   4273:        s = splnet();
                   4274:
                   4275:        ifp = &sc->ethercom.ec_if;
                   4276:
                   4277:        /* Cancel pending I/O and flush buffers. */
1.141     jmcneill 4278:        bge_stop(ifp, 0);
1.177     msaitoh  4279:
                   4280:        bge_stop_fw(sc);
                   4281:        bge_sig_pre_reset(sc, BGE_RESET_START);
1.1       fvdl     4282:        bge_reset(sc);
1.177     msaitoh  4283:        bge_sig_legacy(sc, BGE_RESET_START);
                   4284:        bge_sig_post_reset(sc, BGE_RESET_START);
                   4285:
1.1       fvdl     4286:        bge_chipinit(sc);
                   4287:
                   4288:        /*
                   4289:         * Init the various state machines, ring
                   4290:         * control blocks and firmware.
                   4291:         */
                   4292:        error = bge_blockinit(sc);
                   4293:        if (error != 0) {
1.138     joerg    4294:                aprint_error_dev(sc->bge_dev, "initialization error %d\n",
1.1       fvdl     4295:                    error);
                   4296:                splx(s);
                   4297:                return error;
                   4298:        }
                   4299:
                   4300:        ifp = &sc->ethercom.ec_if;
                   4301:
                   4302:        /* Specify MTU. */
                   4303:        CSR_WRITE_4(sc, BGE_RX_MTU, ifp->if_mtu +
1.107     blymn    4304:            ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN);
1.1       fvdl     4305:
                   4306:        /* Load our MAC address. */
1.170     msaitoh  4307:        m = (const uint16_t *)&(CLLADDR(ifp->if_sadl)[0]);
1.1       fvdl     4308:        CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));
                   4309:        CSR_WRITE_4(sc, BGE_MAC_ADDR1_HI, (htons(m[1]) << 16) | htons(m[2]));
                   4310:
                   4311:        /* Enable or disable promiscuous mode as needed. */
1.178     msaitoh  4312:        if (ifp->if_flags & IFF_PROMISC)
1.1       fvdl     4313:                BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
1.178     msaitoh  4314:        else
1.1       fvdl     4315:                BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
                   4316:
                   4317:        /* Program multicast filter. */
                   4318:        bge_setmulti(sc);
                   4319:
                   4320:        /* Init RX ring. */
                   4321:        bge_init_rx_ring_std(sc);
                   4322:
1.161     msaitoh  4323:        /*
                   4324:         * Workaround for a bug in 5705 ASIC rev A0. Poll the NIC's
                   4325:         * memory to insure that the chip has in fact read the first
                   4326:         * entry of the ring.
                   4327:         */
                   4328:        if (sc->bge_chipid == BGE_CHIPID_BCM5705_A0) {
1.170     msaitoh  4329:                uint32_t                v, i;
1.161     msaitoh  4330:                for (i = 0; i < 10; i++) {
                   4331:                        DELAY(20);
                   4332:                        v = bge_readmem_ind(sc, BGE_STD_RX_RINGS + 8);
                   4333:                        if (v == (MCLBYTES - ETHER_ALIGN))
                   4334:                                break;
                   4335:                }
                   4336:                if (i == 10)
                   4337:                        aprint_error_dev(sc->bge_dev,
                   4338:                            "5705 A0 chip failed to load RX ring\n");
                   4339:        }
                   4340:
1.1       fvdl     4341:        /* Init jumbo RX ring. */
                   4342:        if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN))
                   4343:                bge_init_rx_ring_jumbo(sc);
                   4344:
                   4345:        /* Init our RX return ring index */
                   4346:        sc->bge_rx_saved_considx = 0;
                   4347:
                   4348:        /* Init TX ring. */
                   4349:        bge_init_tx_ring(sc);
                   4350:
                   4351:        /* Turn on transmitter */
                   4352:        BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_ENABLE);
                   4353:
                   4354:        /* Turn on receiver */
                   4355:        BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
                   4356:
1.71      thorpej  4357:        CSR_WRITE_4(sc, BGE_MAX_RX_FRAME_LOWAT, 2);
                   4358:
1.1       fvdl     4359:        /* Tell firmware we're alive. */
                   4360:        BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
                   4361:
                   4362:        /* Enable host interrupts. */
                   4363:        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
                   4364:        BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
1.151     cegger   4365:        bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
1.1       fvdl     4366:
1.142     dyoung   4367:        if ((error = bge_ifmedia_upd(ifp)) != 0)
                   4368:                goto out;
1.1       fvdl     4369:
                   4370:        ifp->if_flags |= IFF_RUNNING;
                   4371:        ifp->if_flags &= ~IFF_OACTIVE;
                   4372:
1.142     dyoung   4373:        callout_reset(&sc->bge_timeout, hz, bge_tick, sc);
                   4374:
                   4375: out:
1.186   ! msaitoh  4376:        sc->bge_if_flags = ifp->if_flags;
1.1       fvdl     4377:        splx(s);
                   4378:
1.142     dyoung   4379:        return error;
1.1       fvdl     4380: }
                   4381:
                   4382: /*
                   4383:  * Set media options.
                   4384:  */
1.104     thorpej  4385: static int
                   4386: bge_ifmedia_upd(struct ifnet *ifp)
1.1       fvdl     4387: {
                   4388:        struct bge_softc *sc = ifp->if_softc;
                   4389:        struct mii_data *mii = &sc->bge_mii;
                   4390:        struct ifmedia *ifm = &sc->bge_ifmedia;
1.142     dyoung   4391:        int rc;
1.1       fvdl     4392:
                   4393:        /* If this is a 1000baseX NIC, enable the TBI port. */
1.157     msaitoh  4394:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.1       fvdl     4395:                if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1.170     msaitoh  4396:                        return EINVAL;
                   4397:                switch (IFM_SUBTYPE(ifm->ifm_media)) {
1.1       fvdl     4398:                case IFM_AUTO:
1.161     msaitoh  4399:                        /*
                   4400:                         * The BCM5704 ASIC appears to have a special
                   4401:                         * mechanism for programming the autoneg
                   4402:                         * advertisement registers in TBI mode.
                   4403:                         */
                   4404:                        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704) {
1.170     msaitoh  4405:                                uint32_t sgdig;
1.161     msaitoh  4406:                                sgdig = CSR_READ_4(sc, BGE_SGDIG_STS);
                   4407:                                if (sgdig & BGE_SGDIGSTS_DONE) {
                   4408:                                        CSR_WRITE_4(sc, BGE_TX_TBI_AUTONEG, 0);
                   4409:                                        sgdig = CSR_READ_4(sc, BGE_SGDIG_CFG);
                   4410:                                        sgdig |= BGE_SGDIGCFG_AUTO |
                   4411:                                            BGE_SGDIGCFG_PAUSE_CAP |
                   4412:                                            BGE_SGDIGCFG_ASYM_PAUSE;
                   4413:                                        CSR_WRITE_4(sc, BGE_SGDIG_CFG,
                   4414:                                            sgdig | BGE_SGDIGCFG_SEND);
                   4415:                                        DELAY(5);
                   4416:                                        CSR_WRITE_4(sc, BGE_SGDIG_CFG, sgdig);
                   4417:                                }
                   4418:                        }
1.1       fvdl     4419:                        break;
                   4420:                case IFM_1000_SX:
                   4421:                        if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
                   4422:                                BGE_CLRBIT(sc, BGE_MAC_MODE,
                   4423:                                    BGE_MACMODE_HALF_DUPLEX);
                   4424:                        } else {
                   4425:                                BGE_SETBIT(sc, BGE_MAC_MODE,
                   4426:                                    BGE_MACMODE_HALF_DUPLEX);
                   4427:                        }
                   4428:                        break;
                   4429:                default:
1.170     msaitoh  4430:                        return EINVAL;
1.1       fvdl     4431:                }
1.69      thorpej  4432:                /* XXX 802.3x flow control for 1000BASE-SX */
1.170     msaitoh  4433:                return 0;
1.1       fvdl     4434:        }
                   4435:
1.161     msaitoh  4436:        BGE_STS_SETBIT(sc, BGE_STS_LINK_EVT);
1.142     dyoung   4437:        if ((rc = mii_mediachg(mii)) == ENXIO)
                   4438:                return 0;
1.161     msaitoh  4439:
                   4440:        /*
                   4441:         * Force an interrupt so that we will call bge_link_upd
                   4442:         * if needed and clear any pending link state attention.
                   4443:         * Without this we are not getting any further interrupts
                   4444:         * for link state changes and thus will not UP the link and
                   4445:         * not be able to send in bge_start. The only way to get
                   4446:         * things working was to receive a packet and get a RX intr.
                   4447:         */
                   4448:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700 ||
                   4449:            sc->bge_flags & BGE_IS_5788)
                   4450:                BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
                   4451:        else
                   4452:                BGE_SETBIT(sc, BGE_HCC_MODE, BGE_HCCMODE_COAL_NOW);
                   4453:
1.142     dyoung   4454:        return rc;
1.1       fvdl     4455: }
                   4456:
                   4457: /*
                   4458:  * Report current media status.
                   4459:  */
1.104     thorpej  4460: static void
                   4461: bge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1       fvdl     4462: {
                   4463:        struct bge_softc *sc = ifp->if_softc;
                   4464:        struct mii_data *mii = &sc->bge_mii;
                   4465:
1.157     msaitoh  4466:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.1       fvdl     4467:                ifmr->ifm_status = IFM_AVALID;
                   4468:                ifmr->ifm_active = IFM_ETHER;
                   4469:                if (CSR_READ_4(sc, BGE_MAC_STS) &
                   4470:                    BGE_MACSTAT_TBI_PCS_SYNCHED)
                   4471:                        ifmr->ifm_status |= IFM_ACTIVE;
                   4472:                ifmr->ifm_active |= IFM_1000_SX;
                   4473:                if (CSR_READ_4(sc, BGE_MAC_MODE) & BGE_MACMODE_HALF_DUPLEX)
                   4474:                        ifmr->ifm_active |= IFM_HDX;
                   4475:                else
                   4476:                        ifmr->ifm_active |= IFM_FDX;
                   4477:                return;
                   4478:        }
                   4479:
                   4480:        mii_pollstat(mii);
                   4481:        ifmr->ifm_status = mii->mii_media_status;
1.69      thorpej  4482:        ifmr->ifm_active = (mii->mii_media_active & ~IFM_ETH_FMASK) |
                   4483:            sc->bge_flowflags;
1.1       fvdl     4484: }
                   4485:
1.104     thorpej  4486: static int
1.186   ! msaitoh  4487: bge_ifflags_cb(struct ethercom *ec)
        !          4488: {
        !          4489:        struct ifnet *ifp = &ec->ec_if;
        !          4490:        struct bge_softc *sc = ifp->if_softc;
        !          4491:        int change = ifp->if_flags ^ sc->bge_if_flags;
        !          4492:
        !          4493:        if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0)
        !          4494:                return ENETRESET;
        !          4495:        else if ((change & (IFF_PROMISC | IFF_ALLMULTI)) == 0)
        !          4496:                return 0;
        !          4497:
        !          4498:        if ((ifp->if_flags & IFF_PROMISC) == 0)
        !          4499:                BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
        !          4500:        else
        !          4501:                BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
        !          4502:
        !          4503:        bge_setmulti(sc);
        !          4504:
        !          4505:        sc->bge_if_flags = ifp->if_flags;
        !          4506:        return 0;
        !          4507: }
        !          4508:
        !          4509: static int
1.126     christos 4510: bge_ioctl(struct ifnet *ifp, u_long command, void *data)
1.1       fvdl     4511: {
                   4512:        struct bge_softc *sc = ifp->if_softc;
                   4513:        struct ifreq *ifr = (struct ifreq *) data;
                   4514:        int s, error = 0;
                   4515:        struct mii_data *mii;
                   4516:
                   4517:        s = splnet();
                   4518:
1.170     msaitoh  4519:        switch (command) {
1.1       fvdl     4520:        case SIOCSIFMEDIA:
1.69      thorpej  4521:                /* XXX Flow control is not supported for 1000BASE-SX */
1.157     msaitoh  4522:                if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.69      thorpej  4523:                        ifr->ifr_media &= ~IFM_ETH_FMASK;
                   4524:                        sc->bge_flowflags = 0;
                   4525:                }
                   4526:
                   4527:                /* Flow control requires full-duplex mode. */
                   4528:                if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
                   4529:                    (ifr->ifr_media & IFM_FDX) == 0) {
                   4530:                        ifr->ifr_media &= ~IFM_ETH_FMASK;
                   4531:                }
                   4532:                if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
                   4533:                        if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
1.157     msaitoh  4534:                                /* We can do both TXPAUSE and RXPAUSE. */
1.69      thorpej  4535:                                ifr->ifr_media |=
                   4536:                                    IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
                   4537:                        }
                   4538:                        sc->bge_flowflags = ifr->ifr_media & IFM_ETH_FMASK;
                   4539:                }
                   4540:                /* FALLTHROUGH */
1.1       fvdl     4541:        case SIOCGIFMEDIA:
1.157     msaitoh  4542:                if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
1.1       fvdl     4543:                        error = ifmedia_ioctl(ifp, ifr, &sc->bge_ifmedia,
                   4544:                            command);
                   4545:                } else {
                   4546:                        mii = &sc->bge_mii;
                   4547:                        error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
                   4548:                            command);
                   4549:                }
                   4550:                break;
                   4551:        default:
1.152     tron     4552:                if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
                   4553:                        break;
                   4554:
                   4555:                error = 0;
                   4556:
                   4557:                if (command != SIOCADDMULTI && command != SIOCDELMULTI)
                   4558:                        ;
                   4559:                else if (ifp->if_flags & IFF_RUNNING)
                   4560:                        bge_setmulti(sc);
1.1       fvdl     4561:                break;
                   4562:        }
                   4563:
                   4564:        splx(s);
                   4565:
1.170     msaitoh  4566:        return error;
1.1       fvdl     4567: }
                   4568:
1.104     thorpej  4569: static void
                   4570: bge_watchdog(struct ifnet *ifp)
1.1       fvdl     4571: {
                   4572:        struct bge_softc *sc;
                   4573:
                   4574:        sc = ifp->if_softc;
                   4575:
1.138     joerg    4576:        aprint_error_dev(sc->bge_dev, "watchdog timeout -- resetting\n");
1.1       fvdl     4577:
                   4578:        ifp->if_flags &= ~IFF_RUNNING;
                   4579:        bge_init(ifp);
                   4580:
                   4581:        ifp->if_oerrors++;
                   4582: }
                   4583:
1.11      thorpej  4584: static void
                   4585: bge_stop_block(struct bge_softc *sc, bus_addr_t reg, uint32_t bit)
                   4586: {
                   4587:        int i;
                   4588:
                   4589:        BGE_CLRBIT(sc, reg, bit);
                   4590:
1.180     msaitoh  4591:        for (i = 0; i < 1000; i++) {
1.11      thorpej  4592:                if ((CSR_READ_4(sc, reg) & bit) == 0)
                   4593:                        return;
                   4594:                delay(100);
                   4595:        }
                   4596:
1.165     msaitoh  4597:        /*
                   4598:         * Doesn't print only when the register is BGE_SRS_MODE. It occurs
                   4599:         * on some environment (and once after boot?)
                   4600:         */
                   4601:        if (reg != BGE_SRS_MODE)
                   4602:                aprint_error_dev(sc->bge_dev,
                   4603:                    "block failed to stop: reg 0x%lx, bit 0x%08x\n",
                   4604:                    (u_long)reg, bit);
1.11      thorpej  4605: }
                   4606:
1.1       fvdl     4607: /*
                   4608:  * Stop the adapter and free any mbufs allocated to the
                   4609:  * RX and TX lists.
                   4610:  */
1.104     thorpej  4611: static void
1.141     jmcneill 4612: bge_stop(struct ifnet *ifp, int disable)
1.1       fvdl     4613: {
1.141     jmcneill 4614:        struct bge_softc *sc = ifp->if_softc;
1.1       fvdl     4615:
                   4616:        callout_stop(&sc->bge_timeout);
                   4617:
                   4618:        /*
1.177     msaitoh  4619:         * Tell firmware we're shutting down.
                   4620:         */
                   4621:        bge_stop_fw(sc);
                   4622:        bge_sig_pre_reset(sc, BGE_RESET_STOP);
                   4623:
                   4624:        /* Disable host interrupts. */
                   4625:        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
                   4626:        bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
                   4627:
                   4628:        /*
1.1       fvdl     4629:         * Disable all of the receiver blocks
                   4630:         */
1.11      thorpej  4631:        bge_stop_block(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
                   4632:        bge_stop_block(sc, BGE_RBDI_MODE, BGE_RBDIMODE_ENABLE);
                   4633:        bge_stop_block(sc, BGE_RXLP_MODE, BGE_RXLPMODE_ENABLE);
1.172     msaitoh  4634:        if (BGE_IS_5700_FAMILY(sc))
1.44      hannken  4635:                bge_stop_block(sc, BGE_RXLS_MODE, BGE_RXLSMODE_ENABLE);
1.11      thorpej  4636:        bge_stop_block(sc, BGE_RDBDI_MODE, BGE_RBDIMODE_ENABLE);
                   4637:        bge_stop_block(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
                   4638:        bge_stop_block(sc, BGE_RBDC_MODE, BGE_RBDCMODE_ENABLE);
1.1       fvdl     4639:
                   4640:        /*
                   4641:         * Disable all of the transmit blocks
                   4642:         */
1.11      thorpej  4643:        bge_stop_block(sc, BGE_SRS_MODE, BGE_SRSMODE_ENABLE);
                   4644:        bge_stop_block(sc, BGE_SBDI_MODE, BGE_SBDIMODE_ENABLE);
                   4645:        bge_stop_block(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
                   4646:        bge_stop_block(sc, BGE_RDMA_MODE, BGE_RDMAMODE_ENABLE);
                   4647:        bge_stop_block(sc, BGE_SDC_MODE, BGE_SDCMODE_ENABLE);
1.172     msaitoh  4648:        if (BGE_IS_5700_FAMILY(sc))
1.44      hannken  4649:                bge_stop_block(sc, BGE_DMAC_MODE, BGE_DMACMODE_ENABLE);
1.11      thorpej  4650:        bge_stop_block(sc, BGE_SBDC_MODE, BGE_SBDCMODE_ENABLE);
1.1       fvdl     4651:
                   4652:        /*
                   4653:         * Shut down all of the memory managers and related
                   4654:         * state machines.
                   4655:         */
1.11      thorpej  4656:        bge_stop_block(sc, BGE_HCC_MODE, BGE_HCCMODE_ENABLE);
                   4657:        bge_stop_block(sc, BGE_WDMA_MODE, BGE_WDMAMODE_ENABLE);
1.172     msaitoh  4658:        if (BGE_IS_5700_FAMILY(sc))
1.44      hannken  4659:                bge_stop_block(sc, BGE_MBCF_MODE, BGE_MBCFMODE_ENABLE);
1.11      thorpej  4660:
1.1       fvdl     4661:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0xFFFFFFFF);
                   4662:        CSR_WRITE_4(sc, BGE_FTQ_RESET, 0);
1.11      thorpej  4663:
1.172     msaitoh  4664:        if (BGE_IS_5700_FAMILY(sc)) {
1.44      hannken  4665:                bge_stop_block(sc, BGE_BMAN_MODE, BGE_BMANMODE_ENABLE);
                   4666:                bge_stop_block(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);
                   4667:        }
1.1       fvdl     4668:
1.177     msaitoh  4669:        bge_reset(sc);
                   4670:        bge_sig_legacy(sc, BGE_RESET_STOP);
                   4671:        bge_sig_post_reset(sc, BGE_RESET_STOP);
1.1       fvdl     4672:
                   4673:        /*
1.177     msaitoh  4674:         * Keep the ASF firmware running if up.
1.1       fvdl     4675:         */
1.177     msaitoh  4676:        if (sc->bge_asf_mode & ASF_STACKUP)
                   4677:                BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
                   4678:        else
                   4679:                BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
1.1       fvdl     4680:
                   4681:        /* Free the RX lists. */
                   4682:        bge_free_rx_ring_std(sc);
                   4683:
                   4684:        /* Free jumbo RX list. */
1.172     msaitoh  4685:        if (BGE_IS_JUMBO_CAPABLE(sc))
                   4686:                bge_free_rx_ring_jumbo(sc);
1.1       fvdl     4687:
                   4688:        /* Free TX buffers. */
                   4689:        bge_free_tx_ring(sc);
                   4690:
                   4691:        /*
                   4692:         * Isolate/power down the PHY.
                   4693:         */
1.157     msaitoh  4694:        if (!(sc->bge_flags & BGE_PHY_FIBER_TBI))
1.1       fvdl     4695:                mii_down(&sc->bge_mii);
                   4696:
1.161     msaitoh  4697:        sc->bge_tx_saved_considx = BGE_TXCONS_UNSET;
1.1       fvdl     4698:
1.161     msaitoh  4699:        /* Clear MAC's link state (PHY may still have link UP). */
                   4700:        BGE_STS_CLRBIT(sc, BGE_STS_LINK);
1.1       fvdl     4701:
                   4702:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   4703: }
                   4704:
1.161     msaitoh  4705: static void
                   4706: bge_link_upd(struct bge_softc *sc)
                   4707: {
                   4708:        struct ifnet *ifp = &sc->ethercom.ec_if;
                   4709:        struct mii_data *mii = &sc->bge_mii;
1.170     msaitoh  4710:        uint32_t status;
1.161     msaitoh  4711:        int link;
                   4712:
                   4713:        /* Clear 'pending link event' flag */
                   4714:        BGE_STS_CLRBIT(sc, BGE_STS_LINK_EVT);
                   4715:
                   4716:        /*
                   4717:         * Process link state changes.
                   4718:         * Grrr. The link status word in the status block does
                   4719:         * not work correctly on the BCM5700 rev AX and BX chips,
                   4720:         * according to all available information. Hence, we have
                   4721:         * to enable MII interrupts in order to properly obtain
                   4722:         * async link changes. Unfortunately, this also means that
                   4723:         * we have to read the MAC status register to detect link
                   4724:         * changes, thereby adding an additional register access to
                   4725:         * the interrupt handler.
                   4726:         */
                   4727:
                   4728:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5700) {
                   4729:                status = CSR_READ_4(sc, BGE_MAC_STS);
                   4730:                if (status & BGE_MACSTAT_MI_INTERRUPT) {
                   4731:                        mii_pollstat(mii);
                   4732:
                   4733:                        if (!BGE_STS_BIT(sc, BGE_STS_LINK) &&
                   4734:                            mii->mii_media_status & IFM_ACTIVE &&
                   4735:                            IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
                   4736:                                BGE_STS_SETBIT(sc, BGE_STS_LINK);
                   4737:                        else if (BGE_STS_BIT(sc, BGE_STS_LINK) &&
                   4738:                            (!(mii->mii_media_status & IFM_ACTIVE) ||
                   4739:                            IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
                   4740:                                BGE_STS_CLRBIT(sc, BGE_STS_LINK);
                   4741:
                   4742:                        /* Clear the interrupt */
                   4743:                        CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
                   4744:                            BGE_EVTENB_MI_INTERRUPT);
                   4745:                        bge_miibus_readreg(sc->bge_dev, 1, BRGPHY_MII_ISR);
                   4746:                        bge_miibus_writereg(sc->bge_dev, 1, BRGPHY_MII_IMR,
                   4747:                            BRGPHY_INTRS);
                   4748:                }
                   4749:                return;
                   4750:        }
                   4751:
                   4752:        if (sc->bge_flags & BGE_PHY_FIBER_TBI) {
                   4753:                status = CSR_READ_4(sc, BGE_MAC_STS);
                   4754:                if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {
                   4755:                        if (!BGE_STS_BIT(sc, BGE_STS_LINK)) {
                   4756:                                BGE_STS_SETBIT(sc, BGE_STS_LINK);
                   4757:                                if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704)
                   4758:                                        BGE_CLRBIT(sc, BGE_MAC_MODE,
                   4759:                                            BGE_MACMODE_TBI_SEND_CFGS);
                   4760:                                CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
                   4761:                                if_link_state_change(ifp, LINK_STATE_UP);
                   4762:                        }
                   4763:                } else if (BGE_STS_BIT(sc, BGE_STS_LINK)) {
                   4764:                        BGE_STS_CLRBIT(sc, BGE_STS_LINK);
                   4765:                        if_link_state_change(ifp, LINK_STATE_DOWN);
                   4766:                }
1.178     msaitoh  4767:        /*
1.161     msaitoh  4768:         * Discard link events for MII/GMII cards if MI auto-polling disabled.
                   4769:         * This should not happen since mii callouts are locked now, but
                   4770:         * we keep this check for debug.
                   4771:         */
                   4772:        } else if (BGE_STS_BIT(sc, BGE_STS_AUTOPOLL)) {
1.178     msaitoh  4773:                /*
1.161     msaitoh  4774:                 * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED
                   4775:                 * bit in status word always set. Workaround this bug by
                   4776:                 * reading PHY link status directly.
                   4777:                 */
                   4778:                link = (CSR_READ_4(sc, BGE_MI_STS) & BGE_MISTS_LINK)?
                   4779:                    BGE_STS_LINK : 0;
                   4780:
                   4781:                if (BGE_STS_BIT(sc, BGE_STS_LINK) != link) {
                   4782:                        mii_pollstat(mii);
                   4783:
                   4784:                        if (!BGE_STS_BIT(sc, BGE_STS_LINK) &&
                   4785:                            mii->mii_media_status & IFM_ACTIVE &&
                   4786:                            IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
                   4787:                                BGE_STS_SETBIT(sc, BGE_STS_LINK);
                   4788:                        else if (BGE_STS_BIT(sc, BGE_STS_LINK) &&
                   4789:                            (!(mii->mii_media_status & IFM_ACTIVE) ||
                   4790:                            IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
                   4791:                                BGE_STS_CLRBIT(sc, BGE_STS_LINK);
                   4792:                }
                   4793:        }
                   4794:
                   4795:        /* Clear the attention */
                   4796:        CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
                   4797:            BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
                   4798:            BGE_MACSTAT_LINK_CHANGED);
                   4799: }
                   4800:
1.64      jonathan 4801: static int
                   4802: sysctl_bge_verify(SYSCTLFN_ARGS)
                   4803: {
                   4804:        int error, t;
                   4805:        struct sysctlnode node;
                   4806:
                   4807:        node = *rnode;
                   4808:        t = *(int*)rnode->sysctl_data;
                   4809:        node.sysctl_data = &t;
                   4810:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   4811:        if (error || newp == NULL)
1.170     msaitoh  4812:                return error;
1.64      jonathan 4813:
                   4814: #if 0
                   4815:        DPRINTF2(("%s: t = %d, nodenum = %d, rnodenum = %d\n", __func__, t,
                   4816:            node.sysctl_num, rnode->sysctl_num));
                   4817: #endif
                   4818:
                   4819:        if (node.sysctl_num == bge_rxthresh_nodenum) {
                   4820:                if (t < 0 || t >= NBGE_RX_THRESH)
1.170     msaitoh  4821:                        return EINVAL;
1.64      jonathan 4822:                bge_update_all_threshes(t);
                   4823:        } else
1.170     msaitoh  4824:                return EINVAL;
1.64      jonathan 4825:
                   4826:        *(int*)rnode->sysctl_data = t;
                   4827:
1.170     msaitoh  4828:        return 0;
1.64      jonathan 4829: }
                   4830:
                   4831: /*
1.65      atatat   4832:  * Set up sysctl(3) MIB, hw.bge.*.
1.64      jonathan 4833:  *
                   4834:  * TBD condition SYSCTL_PERMANENT on being an LKM or not
                   4835:  */
                   4836: SYSCTL_SETUP(sysctl_bge, "sysctl bge subtree setup")
                   4837: {
1.66      atatat   4838:        int rc, bge_root_num;
1.90      atatat   4839:        const struct sysctlnode *node;
1.64      jonathan 4840:
                   4841:        if ((rc = sysctl_createv(clog, 0, NULL, NULL,
                   4842:            CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
                   4843:            NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
                   4844:                goto err;
                   4845:        }
                   4846:
                   4847:        if ((rc = sysctl_createv(clog, 0, NULL, &node,
1.73      atatat   4848:            CTLFLAG_PERMANENT, CTLTYPE_NODE, "bge",
                   4849:            SYSCTL_DESCR("BGE interface controls"),
1.64      jonathan 4850:            NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
                   4851:                goto err;
                   4852:        }
                   4853:
1.66      atatat   4854:        bge_root_num = node->sysctl_num;
                   4855:
1.64      jonathan 4856:        /* BGE Rx interrupt mitigation level */
1.87      perry    4857:        if ((rc = sysctl_createv(clog, 0, NULL, &node,
1.64      jonathan 4858:            CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1.73      atatat   4859:            CTLTYPE_INT, "rx_lvl",
                   4860:            SYSCTL_DESCR("BGE receive interrupt mitigation level"),
                   4861:            sysctl_bge_verify, 0,
1.64      jonathan 4862:            &bge_rx_thresh_lvl,
1.66      atatat   4863:            0, CTL_HW, bge_root_num, CTL_CREATE,
1.64      jonathan 4864:            CTL_EOL)) != 0) {
                   4865:                goto err;
                   4866:        }
                   4867:
                   4868:        bge_rxthresh_nodenum = node->sysctl_num;
                   4869:
                   4870:        return;
                   4871:
                   4872: err:
1.138     joerg    4873:        aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
1.64      jonathan 4874: }
1.151     cegger   4875:
1.172     msaitoh  4876: #ifdef BGE_DEBUG
                   4877: void
                   4878: bge_debug_info(struct bge_softc *sc)
                   4879: {
                   4880:
                   4881:        printf("Hardware Flags:\n");
                   4882:        if (BGE_IS_5755_PLUS(sc))
                   4883:                printf(" - 5755 Plus\n");
                   4884:        if (BGE_IS_5750_OR_BEYOND(sc))
                   4885:                printf(" - 5750 Plus\n");
                   4886:        if (BGE_IS_5705_PLUS(sc))
                   4887:                printf(" - 5705 Plus\n");
                   4888:        if (BGE_IS_5714_FAMILY(sc))
                   4889:                printf(" - 5714 Family\n");
                   4890:        if (BGE_IS_5700_FAMILY(sc))
                   4891:                printf(" - 5700 Family\n");
                   4892:        if (sc->bge_flags & BGE_IS_5788)
                   4893:                printf(" - 5788\n");
                   4894:        if (sc->bge_flags & BGE_JUMBO_CAPABLE)
                   4895:                printf(" - Supports Jumbo Frames\n");
                   4896:        if (sc->bge_flags & BGE_NO_EEPROM)
1.173     msaitoh  4897:                printf(" - No EEPROM\n");
1.172     msaitoh  4898:        if (sc->bge_flags & BGE_PCIX)
                   4899:                printf(" - PCI-X Bus\n");
                   4900:        if (sc->bge_flags & BGE_PCIE)
                   4901:                printf(" - PCI Express Bus\n");
                   4902:        if (sc->bge_flags & BGE_NO_3LED)
                   4903:                printf(" - No 3 LEDs\n");
                   4904:        if (sc->bge_flags & BGE_RX_ALIGNBUG)
                   4905:                printf(" - RX Alignment Bug\n");
                   4906:        if (sc->bge_flags & BGE_TSO)
                   4907:                printf(" - TSO\n");
                   4908: }
                   4909: #endif /* BGE_DEBUG */
                   4910:
                   4911: static int
                   4912: bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[])
                   4913: {
                   4914:        prop_dictionary_t dict;
                   4915:        prop_data_t ea;
                   4916:
                   4917:        if ((sc->bge_flags & BGE_NO_EEPROM) == 0)
                   4918:                return 1;
                   4919:
                   4920:        dict = device_properties(sc->bge_dev);
                   4921:        ea = prop_dictionary_get(dict, "mac-address");
                   4922:        if (ea != NULL) {
                   4923:                KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
                   4924:                KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
                   4925:                memcpy(ether_addr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN);
                   4926:                return 0;
                   4927:        }
                   4928:
                   4929:        return 1;
                   4930: }
                   4931:
1.178     msaitoh  4932: static int
1.170     msaitoh  4933: bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
1.151     cegger   4934: {
1.170     msaitoh  4935:        uint32_t mac_addr;
1.151     cegger   4936:
                   4937:        mac_addr = bge_readmem_ind(sc, 0x0c14);
                   4938:        if ((mac_addr >> 16) == 0x484b) {
                   4939:                ether_addr[0] = (uint8_t)(mac_addr >> 8);
                   4940:                ether_addr[1] = (uint8_t)mac_addr;
                   4941:                mac_addr = bge_readmem_ind(sc, 0x0c18);
                   4942:                ether_addr[2] = (uint8_t)(mac_addr >> 24);
                   4943:                ether_addr[3] = (uint8_t)(mac_addr >> 16);
                   4944:                ether_addr[4] = (uint8_t)(mac_addr >> 8);
                   4945:                ether_addr[5] = (uint8_t)mac_addr;
1.170     msaitoh  4946:                return 0;
1.151     cegger   4947:        }
1.170     msaitoh  4948:        return 1;
1.151     cegger   4949: }
                   4950:
                   4951: static int
1.170     msaitoh  4952: bge_get_eaddr_nvram(struct bge_softc *sc, uint8_t ether_addr[])
1.151     cegger   4953: {
                   4954:        int mac_offset = BGE_EE_MAC_OFFSET;
                   4955:
1.177     msaitoh  4956:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
1.151     cegger   4957:                mac_offset = BGE_EE_MAC_OFFSET_5906;
                   4958:
                   4959:        return (bge_read_nvram(sc, ether_addr, mac_offset + 2,
                   4960:            ETHER_ADDR_LEN));
                   4961: }
                   4962:
                   4963: static int
1.170     msaitoh  4964: bge_get_eaddr_eeprom(struct bge_softc *sc, uint8_t ether_addr[])
1.151     cegger   4965: {
                   4966:
1.170     msaitoh  4967:        if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5906)
                   4968:                return 1;
1.151     cegger   4969:
                   4970:        return (bge_read_eeprom(sc, ether_addr, BGE_EE_MAC_OFFSET + 2,
                   4971:           ETHER_ADDR_LEN));
                   4972: }
                   4973:
                   4974: static int
1.170     msaitoh  4975: bge_get_eaddr(struct bge_softc *sc, uint8_t eaddr[])
1.151     cegger   4976: {
                   4977:        static const bge_eaddr_fcn_t bge_eaddr_funcs[] = {
                   4978:                /* NOTE: Order is critical */
1.172     msaitoh  4979:                bge_get_eaddr_fw,
1.151     cegger   4980:                bge_get_eaddr_mem,
                   4981:                bge_get_eaddr_nvram,
                   4982:                bge_get_eaddr_eeprom,
                   4983:                NULL
                   4984:        };
                   4985:        const bge_eaddr_fcn_t *func;
                   4986:
                   4987:        for (func = bge_eaddr_funcs; *func != NULL; ++func) {
                   4988:                if ((*func)(sc, eaddr) == 0)
                   4989:                        break;
                   4990:        }
                   4991:        return (*func == NULL ? ENXIO : 0);
                   4992: }

CVSweb <webmaster@jp.NetBSD.org>