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

Annotation of sys/dev/pci/if_msk.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_msk.c,v 1.56 2007/06/27 19:15:47 kettenis Exp $    */
                      2:
                      3: /*
                      4:  * Copyright (c) 1997, 1998, 1999, 2000
                      5:  *     Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by Bill Paul.
                     18:  * 4. Neither the name of the author nor the names of any co-contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
                     26:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     32:  * THE POSSIBILITY OF SUCH DAMAGE.
                     33:  *
                     34:  * $FreeBSD: /c/ncvs/src/sys/pci/if_sk.c,v 1.20 2000/04/22 02:16:37 wpaul Exp $
                     35:  */
                     36:
                     37: /*
                     38:  * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu>
                     39:  *
                     40:  * Permission to use, copy, modify, and distribute this software for any
                     41:  * purpose with or without fee is hereby granted, provided that the above
                     42:  * copyright notice and this permission notice appear in all copies.
                     43:  *
                     44:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     45:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     46:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     47:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     48:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     49:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     50:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     51:  */
                     52:
                     53: /*
                     54:  * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports
                     55:  * the SK-984x series adapters, both single port and dual port.
                     56:  * References:
                     57:  *     The XaQti XMAC II datasheet,
                     58:  * http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
                     59:  *     The SysKonnect GEnesis manual, http://www.syskonnect.com
                     60:  *
                     61:  * Note: XaQti has been acquired by Vitesse, and Vitesse does not have the
                     62:  * XMAC II datasheet online. I have put my copy at people.freebsd.org as a
                     63:  * convenience to others until Vitesse corrects this problem:
                     64:  *
                     65:  * http://people.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf
                     66:  *
                     67:  * Written by Bill Paul <wpaul@ee.columbia.edu>
                     68:  * Department of Electrical Engineering
                     69:  * Columbia University, New York City
                     70:  */
                     71:
                     72: /*
                     73:  * The SysKonnect gigabit ethernet adapters consist of two main
                     74:  * components: the SysKonnect GEnesis controller chip and the XaQti Corp.
                     75:  * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC
                     76:  * components and a PHY while the GEnesis controller provides a PCI
                     77:  * interface with DMA support. Each card may have between 512K and
                     78:  * 2MB of SRAM on board depending on the configuration.
                     79:  *
                     80:  * The SysKonnect GEnesis controller can have either one or two XMAC
                     81:  * chips connected to it, allowing single or dual port NIC configurations.
                     82:  * SysKonnect has the distinction of being the only vendor on the market
                     83:  * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs,
                     84:  * dual DMA queues, packet/MAC/transmit arbiters and direct access to the
                     85:  * XMAC registers. This driver takes advantage of these features to allow
                     86:  * both XMACs to operate as independent interfaces.
                     87:  */
                     88:
                     89: #include "bpfilter.h"
                     90:
                     91: #include <sys/param.h>
                     92: #include <sys/systm.h>
                     93: #include <sys/sockio.h>
                     94: #include <sys/mbuf.h>
                     95: #include <sys/malloc.h>
                     96: #include <sys/kernel.h>
                     97: #include <sys/socket.h>
                     98: #include <sys/timeout.h>
                     99: #include <sys/device.h>
                    100: #include <sys/queue.h>
                    101:
                    102: #include <net/if.h>
                    103: #include <net/if_dl.h>
                    104: #include <net/if_types.h>
                    105:
                    106: #ifdef INET
                    107: #include <netinet/in.h>
                    108: #include <netinet/in_systm.h>
                    109: #include <netinet/in_var.h>
                    110: #include <netinet/ip.h>
                    111: #include <netinet/udp.h>
                    112: #include <netinet/tcp.h>
                    113: #include <netinet/if_ether.h>
                    114: #endif
                    115:
                    116: #include <net/if_media.h>
                    117: #include <net/if_vlan_var.h>
                    118:
                    119: #if NBPFILTER > 0
                    120: #include <net/bpf.h>
                    121: #endif
                    122:
                    123: #include <dev/mii/mii.h>
                    124: #include <dev/mii/miivar.h>
                    125: #include <dev/mii/brgphyreg.h>
                    126:
                    127: #include <dev/pci/pcireg.h>
                    128: #include <dev/pci/pcivar.h>
                    129: #include <dev/pci/pcidevs.h>
                    130:
                    131: #include <dev/pci/if_skreg.h>
                    132: #include <dev/pci/if_mskvar.h>
                    133:
                    134: int mskc_probe(struct device *, void *, void *);
                    135: void mskc_attach(struct device *, struct device *self, void *aux);
                    136: void mskc_reset(struct sk_softc *);
                    137: void mskc_shutdown(void *);
                    138: int msk_probe(struct device *, void *, void *);
                    139: void msk_attach(struct device *, struct device *self, void *aux);
                    140: void msk_reset(struct sk_if_softc *);
                    141: int mskcprint(void *, const char *);
                    142: int msk_intr(void *);
                    143: void msk_intr_yukon(struct sk_if_softc *);
                    144: static __inline int msk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
                    145: void msk_rxeof(struct sk_if_softc *, u_int16_t, u_int32_t);
                    146: void msk_txeof(struct sk_if_softc *);
                    147: int msk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
                    148: void msk_start(struct ifnet *);
                    149: int msk_ioctl(struct ifnet *, u_long, caddr_t);
                    150: void msk_init(void *);
                    151: void msk_init_yukon(struct sk_if_softc *);
                    152: void msk_stop(struct sk_if_softc *);
                    153: void msk_watchdog(struct ifnet *);
                    154: int msk_ifmedia_upd(struct ifnet *);
                    155: void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
                    156: int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
                    157: int msk_alloc_jumbo_mem(struct sk_if_softc *);
                    158: void *msk_jalloc(struct sk_if_softc *);
                    159: void msk_jfree(caddr_t, u_int, void *);
                    160: int msk_init_rx_ring(struct sk_if_softc *);
                    161: int msk_init_tx_ring(struct sk_if_softc *);
                    162:
                    163: int msk_miibus_readreg(struct device *, int, int);
                    164: void msk_miibus_writereg(struct device *, int, int, int);
                    165: void msk_miibus_statchg(struct device *);
                    166:
                    167: void msk_setfilt(struct sk_if_softc *, caddr_t, int);
                    168: void msk_setmulti(struct sk_if_softc *);
                    169: void msk_setpromisc(struct sk_if_softc *);
                    170: void msk_tick(void *);
                    171:
                    172: #ifdef MSK_DEBUG
                    173: #define DPRINTF(x)     if (mskdebug) printf x
                    174: #define DPRINTFN(n,x)  if (mskdebug >= (n)) printf x
                    175: int    mskdebug = 0;
                    176:
                    177: void msk_dump_txdesc(struct msk_tx_desc *, int);
                    178: void msk_dump_mbuf(struct mbuf *);
                    179: void msk_dump_bytes(const char *, int);
                    180: #else
                    181: #define DPRINTF(x)
                    182: #define DPRINTFN(n,x)
                    183: #endif
                    184:
                    185: /* supported device vendors */
                    186: const struct pci_matchid mskc_devices[] = {
                    187:        { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE550SX },
                    188:        { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE550T_B1 },
                    189:        { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE560SX },
                    190:        { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE560T },
                    191:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_C032 },
                    192:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_C033 },
                    193:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_C034 },
                    194:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_C036 },
                    195:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_C042 },
                    196:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8021CU },
                    197:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8021X },
                    198:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8022CU },
                    199:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8022X },
                    200:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8035 },
                    201:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8036 },
                    202:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8038 },
                    203:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8039 },
                    204:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8050 },
                    205:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8052 },
                    206:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8053 },
                    207:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8055 },
                    208:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8056 },
                    209:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8058 },
                    210:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8061CU },
                    211:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8061X },
                    212:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8062CU },
                    213:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8062X },
                    214:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8070 },
                    215:        { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_8071 },
                    216:        { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK9Sxx },
                    217:        { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK9Exx }
                    218: };
                    219:
                    220: static inline u_int32_t
                    221: sk_win_read_4(struct sk_softc *sc, u_int32_t reg)
                    222: {
                    223:        return CSR_READ_4(sc, reg);
                    224: }
                    225:
                    226: static inline u_int16_t
                    227: sk_win_read_2(struct sk_softc *sc, u_int32_t reg)
                    228: {
                    229:        return CSR_READ_2(sc, reg);
                    230: }
                    231:
                    232: static inline u_int8_t
                    233: sk_win_read_1(struct sk_softc *sc, u_int32_t reg)
                    234: {
                    235:        return CSR_READ_1(sc, reg);
                    236: }
                    237:
                    238: static inline void
                    239: sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x)
                    240: {
                    241:        CSR_WRITE_4(sc, reg, x);
                    242: }
                    243:
                    244: static inline void
                    245: sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x)
                    246: {
                    247:        CSR_WRITE_2(sc, reg, x);
                    248: }
                    249:
                    250: static inline void
                    251: sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x)
                    252: {
                    253:        CSR_WRITE_1(sc, reg, x);
                    254: }
                    255:
                    256: int
                    257: msk_miibus_readreg(struct device *dev, int phy, int reg)
                    258: {
                    259:        struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
                    260:        u_int16_t val;
                    261:        int i;
                    262:
                    263:         SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
                    264:                      YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
                    265:
                    266:        for (i = 0; i < SK_TIMEOUT; i++) {
                    267:                DELAY(1);
                    268:                val = SK_YU_READ_2(sc_if, YUKON_SMICR);
                    269:                if (val & YU_SMICR_READ_VALID)
                    270:                        break;
                    271:        }
                    272:
                    273:        if (i == SK_TIMEOUT) {
                    274:                printf("%s: phy failed to come ready\n",
                    275:                       sc_if->sk_dev.dv_xname);
                    276:                return (0);
                    277:        }
                    278:
                    279:        DPRINTFN(9, ("msk_miibus_readreg: i=%d, timeout=%d\n", i,
                    280:                     SK_TIMEOUT));
                    281:
                    282:         val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
                    283:
                    284:        DPRINTFN(9, ("msk_miibus_readreg phy=%d, reg=%#x, val=%#x\n",
                    285:                     phy, reg, val));
                    286:
                    287:        return (val);
                    288: }
                    289:
                    290: void
                    291: msk_miibus_writereg(struct device *dev, int phy, int reg, int val)
                    292: {
                    293:        struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
                    294:        int i;
                    295:
                    296:        DPRINTFN(9, ("msk_miibus_writereg phy=%d reg=%#x val=%#x\n",
                    297:                     phy, reg, val));
                    298:
                    299:        SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
                    300:        SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
                    301:                      YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
                    302:
                    303:        for (i = 0; i < SK_TIMEOUT; i++) {
                    304:                DELAY(1);
                    305:                if (!(SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY))
                    306:                        break;
                    307:        }
                    308:
                    309:        if (i == SK_TIMEOUT)
                    310:                printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
                    311: }
                    312:
                    313: void
                    314: msk_miibus_statchg(struct device *dev)
                    315: {
                    316:        struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
                    317:        struct mii_data *mii = &sc_if->sk_mii;
                    318:        struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
                    319:        int gpcr;
                    320:
                    321:        gpcr = SK_YU_READ_2(sc_if, YUKON_GPCR);
                    322:        gpcr &= (YU_GPCR_TXEN | YU_GPCR_RXEN);
                    323:
                    324:        if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
                    325:                /* Set speed. */
                    326:                gpcr |= YU_GPCR_SPEED_DIS;
                    327:                switch (IFM_SUBTYPE(mii->mii_media_active)) {
                    328:                case IFM_1000_SX:
                    329:                case IFM_1000_LX:
                    330:                case IFM_1000_CX:
                    331:                case IFM_1000_T:
                    332:                        gpcr |= (YU_GPCR_GIG | YU_GPCR_SPEED);
                    333:                        break;
                    334:                case IFM_100_TX:
                    335:                        gpcr |= YU_GPCR_SPEED;
                    336:                        break;
                    337:                }
                    338:
                    339:                /* Set duplex. */
                    340:                gpcr |= YU_GPCR_DPLX_DIS;
                    341:                if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
                    342:                        gpcr |= YU_GPCR_DUPLEX;
                    343:
                    344:                /* Disable flow control. */
                    345:                gpcr |= YU_GPCR_FCTL_DIS;
                    346:                gpcr |= (YU_GPCR_FCTL_TX_DIS | YU_GPCR_FCTL_RX_DIS);
                    347:        }
                    348:
                    349:        SK_YU_WRITE_2(sc_if, YUKON_GPCR, gpcr);
                    350:
                    351:        DPRINTFN(9, ("msk_miibus_statchg: gpcr=%x\n",
                    352:                     SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR)));
                    353: }
                    354:
                    355: void
                    356: msk_setfilt(struct sk_if_softc *sc_if, caddr_t addr, int slot)
                    357: {
                    358:        int base = XM_RXFILT_ENTRY(slot);
                    359:
                    360:        SK_XM_WRITE_2(sc_if, base, *(u_int16_t *)(&addr[0]));
                    361:        SK_XM_WRITE_2(sc_if, base + 2, *(u_int16_t *)(&addr[2]));
                    362:        SK_XM_WRITE_2(sc_if, base + 4, *(u_int16_t *)(&addr[4]));
                    363: }
                    364:
                    365: void
                    366: msk_setmulti(struct sk_if_softc *sc_if)
                    367: {
                    368:        struct ifnet *ifp= &sc_if->arpcom.ac_if;
                    369:        u_int32_t hashes[2] = { 0, 0 };
                    370:        int h;
                    371:        struct arpcom *ac = &sc_if->arpcom;
                    372:        struct ether_multi *enm;
                    373:        struct ether_multistep step;
                    374:
                    375:        /* First, zot all the existing filters. */
                    376:        SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
                    377:        SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
                    378:        SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
                    379:        SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
                    380:
                    381:
                    382:        /* Now program new ones. */
                    383: allmulti:
                    384:        if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
                    385:                hashes[0] = 0xFFFFFFFF;
                    386:                hashes[1] = 0xFFFFFFFF;
                    387:        } else {
                    388:                /* First find the tail of the list. */
                    389:                ETHER_FIRST_MULTI(step, ac, enm);
                    390:                while (enm != NULL) {
                    391:                        if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
                    392:                                 ETHER_ADDR_LEN)) {
                    393:                                ifp->if_flags |= IFF_ALLMULTI;
                    394:                                goto allmulti;
                    395:                        }
                    396:                        h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) &
                    397:                            ((1 << SK_HASH_BITS) - 1);
                    398:                        if (h < 32)
                    399:                                hashes[0] |= (1 << h);
                    400:                        else
                    401:                                hashes[1] |= (1 << (h - 32));
                    402:
                    403:                        ETHER_NEXT_MULTI(step, enm);
                    404:                }
                    405:        }
                    406:
                    407:        SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
                    408:        SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
                    409:        SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
                    410:        SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
                    411: }
                    412:
                    413: void
                    414: msk_setpromisc(struct sk_if_softc *sc_if)
                    415: {
                    416:        struct ifnet *ifp = &sc_if->arpcom.ac_if;
                    417:
                    418:        if (ifp->if_flags & IFF_PROMISC)
                    419:                SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
                    420:                    YU_RCR_UFLEN | YU_RCR_MUFLEN);
                    421:        else
                    422:                SK_YU_SETBIT_2(sc_if, YUKON_RCR,
                    423:                    YU_RCR_UFLEN | YU_RCR_MUFLEN);
                    424: }
                    425:
                    426: int
                    427: msk_init_rx_ring(struct sk_if_softc *sc_if)
                    428: {
                    429:        struct msk_chain_data   *cd = &sc_if->sk_cdata;
                    430:        struct msk_ring_data    *rd = sc_if->sk_rdata;
                    431:        int                     i, nexti;
                    432:
                    433:        bzero((char *)rd->sk_rx_ring,
                    434:            sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
                    435:
                    436:        for (i = 0; i < MSK_RX_RING_CNT; i++) {
                    437:                cd->sk_rx_chain[i].sk_le = &rd->sk_rx_ring[i];
                    438:                if (i == (MSK_RX_RING_CNT - 1))
                    439:                        nexti = 0;
                    440:                else
                    441:                        nexti = i + 1;
                    442:                cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
                    443:        }
                    444:
                    445:        for (i = 0; i < MSK_RX_RING_CNT; i++) {
                    446:                if (msk_newbuf(sc_if, i, NULL,
                    447:                    sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
                    448:                        printf("%s: failed alloc of %dth mbuf\n",
                    449:                            sc_if->sk_dev.dv_xname, i);
                    450:                        return (ENOBUFS);
                    451:                }
                    452:        }
                    453:
                    454:        sc_if->sk_cdata.sk_rx_prod = MSK_RX_RING_CNT - 1;
                    455:        sc_if->sk_cdata.sk_rx_cons = 0;
                    456:
                    457:        return (0);
                    458: }
                    459:
                    460: int
                    461: msk_init_tx_ring(struct sk_if_softc *sc_if)
                    462: {
                    463:        struct sk_softc         *sc = sc_if->sk_softc;
                    464:        struct msk_chain_data   *cd = &sc_if->sk_cdata;
                    465:        struct msk_ring_data    *rd = sc_if->sk_rdata;
                    466:        bus_dmamap_t            dmamap;
                    467:        struct sk_txmap_entry   *entry;
                    468:        int                     i, nexti;
                    469:
                    470:        bzero((char *)sc_if->sk_rdata->sk_tx_ring,
                    471:            sizeof(struct msk_tx_desc) * MSK_TX_RING_CNT);
                    472:
                    473:        SIMPLEQ_INIT(&sc_if->sk_txmap_head);
                    474:        for (i = 0; i < MSK_TX_RING_CNT; i++) {
                    475:                cd->sk_tx_chain[i].sk_le = &rd->sk_tx_ring[i];
                    476:                if (i == (MSK_TX_RING_CNT - 1))
                    477:                        nexti = 0;
                    478:                else
                    479:                        nexti = i + 1;
                    480:                cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[nexti];
                    481:
                    482:                if (bus_dmamap_create(sc->sc_dmatag, SK_JLEN, SK_NTXSEG,
                    483:                   SK_JLEN, 0, BUS_DMA_NOWAIT, &dmamap))
                    484:                        return (ENOBUFS);
                    485:
                    486:                entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT);
                    487:                if (!entry) {
                    488:                        bus_dmamap_destroy(sc->sc_dmatag, dmamap);
                    489:                        return (ENOBUFS);
                    490:                }
                    491:                entry->dmamap = dmamap;
                    492:                SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
                    493:        }
                    494:
                    495:        sc_if->sk_cdata.sk_tx_prod = 0;
                    496:        sc_if->sk_cdata.sk_tx_cons = 0;
                    497:        sc_if->sk_cdata.sk_tx_cnt = 0;
                    498:
                    499:        MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT,
                    500:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                    501:
                    502:        return (0);
                    503: }
                    504:
                    505: int
                    506: msk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
                    507:          bus_dmamap_t dmamap)
                    508: {
                    509:        struct mbuf             *m_new = NULL;
                    510:        struct sk_chain         *c;
                    511:        struct msk_rx_desc      *r;
                    512:
                    513:        if (m == NULL) {
                    514:                caddr_t buf = NULL;
                    515:
                    516:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
                    517:                if (m_new == NULL)
                    518:                        return (ENOBUFS);
                    519:
                    520:                /* Allocate the jumbo buffer */
                    521:                buf = msk_jalloc(sc_if);
                    522:                if (buf == NULL) {
                    523:                        m_freem(m_new);
                    524:                        DPRINTFN(1, ("%s jumbo allocation failed -- packet "
                    525:                            "dropped!\n", sc_if->arpcom.ac_if.if_xname));
                    526:                        return (ENOBUFS);
                    527:                }
                    528:
                    529:                /* Attach the buffer to the mbuf */
                    530:                m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
                    531:                MEXTADD(m_new, buf, SK_JLEN, 0, msk_jfree, sc_if);
                    532:        } else {
                    533:                /*
                    534:                 * We're re-using a previously allocated mbuf;
                    535:                 * be sure to re-init pointers and lengths to
                    536:                 * default values.
                    537:                 */
                    538:                m_new = m;
                    539:                m_new->m_len = m_new->m_pkthdr.len = SK_JLEN;
                    540:                m_new->m_data = m_new->m_ext.ext_buf;
                    541:        }
                    542:        m_adj(m_new, ETHER_ALIGN);
                    543:
                    544:        c = &sc_if->sk_cdata.sk_rx_chain[i];
                    545:        r = c->sk_le;
                    546:        c->sk_mbuf = m_new;
                    547:        r->sk_addr = htole32(dmamap->dm_segs[0].ds_addr +
                    548:            (((vaddr_t)m_new->m_data
                    549:              - (vaddr_t)sc_if->sk_cdata.sk_jumbo_buf)));
                    550:        r->sk_len = htole16(SK_JLEN);
                    551:        r->sk_ctl = 0;
                    552:        r->sk_opcode = SK_Y2_RXOPC_PACKET | SK_Y2_RXOPC_OWN;
                    553:
                    554:        MSK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
                    555:
                    556:        return (0);
                    557: }
                    558:
                    559: /*
                    560:  * Memory management for jumbo frames.
                    561:  */
                    562:
                    563: int
                    564: msk_alloc_jumbo_mem(struct sk_if_softc *sc_if)
                    565: {
                    566:        struct sk_softc         *sc = sc_if->sk_softc;
                    567:        caddr_t                 ptr, kva;
                    568:        bus_dma_segment_t       seg;
                    569:        int             i, rseg, state, error;
                    570:        struct sk_jpool_entry   *entry;
                    571:
                    572:        state = error = 0;
                    573:
                    574:        /* Grab a big chunk o' storage. */
                    575:        if (bus_dmamem_alloc(sc->sc_dmatag, MSK_JMEM, PAGE_SIZE, 0,
                    576:                             &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
                    577:                printf(": can't alloc rx buffers");
                    578:                return (ENOBUFS);
                    579:        }
                    580:
                    581:        state = 1;
                    582:        if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg, MSK_JMEM, &kva,
                    583:                           BUS_DMA_NOWAIT)) {
                    584:                printf(": can't map dma buffers (%d bytes)", MSK_JMEM);
                    585:                error = ENOBUFS;
                    586:                goto out;
                    587:        }
                    588:
                    589:        state = 2;
                    590:        if (bus_dmamap_create(sc->sc_dmatag, MSK_JMEM, 1, MSK_JMEM, 0,
                    591:            BUS_DMA_NOWAIT, &sc_if->sk_cdata.sk_rx_jumbo_map)) {
                    592:                printf(": can't create dma map");
                    593:                error = ENOBUFS;
                    594:                goto out;
                    595:        }
                    596:
                    597:        state = 3;
                    598:        if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_cdata.sk_rx_jumbo_map,
                    599:                            kva, MSK_JMEM, NULL, BUS_DMA_NOWAIT)) {
                    600:                printf(": can't load dma map");
                    601:                error = ENOBUFS;
                    602:                goto out;
                    603:        }
                    604:
                    605:        state = 4;
                    606:        sc_if->sk_cdata.sk_jumbo_buf = (caddr_t)kva;
                    607:        DPRINTFN(1,("msk_jumbo_buf = 0x%08X\n", sc_if->sk_cdata.sk_jumbo_buf));
                    608:
                    609:        LIST_INIT(&sc_if->sk_jfree_listhead);
                    610:        LIST_INIT(&sc_if->sk_jinuse_listhead);
                    611:
                    612:        /*
                    613:         * Now divide it up into 9K pieces and save the addresses
                    614:         * in an array.
                    615:         */
                    616:        ptr = sc_if->sk_cdata.sk_jumbo_buf;
                    617:        for (i = 0; i < MSK_JSLOTS; i++) {
                    618:                sc_if->sk_cdata.sk_jslots[i] = ptr;
                    619:                ptr += SK_JLEN;
                    620:                entry = malloc(sizeof(struct sk_jpool_entry),
                    621:                    M_DEVBUF, M_NOWAIT);
                    622:                if (entry == NULL) {
                    623:                        sc_if->sk_cdata.sk_jumbo_buf = NULL;
                    624:                        printf(": no memory for jumbo buffer queue!");
                    625:                        error = ENOBUFS;
                    626:                        goto out;
                    627:                }
                    628:                entry->slot = i;
                    629:                LIST_INSERT_HEAD(&sc_if->sk_jfree_listhead,
                    630:                                 entry, jpool_entries);
                    631:        }
                    632: out:
                    633:        if (error != 0) {
                    634:                switch (state) {
                    635:                case 4:
                    636:                        bus_dmamap_unload(sc->sc_dmatag,
                    637:                            sc_if->sk_cdata.sk_rx_jumbo_map);
                    638:                case 3:
                    639:                        bus_dmamap_destroy(sc->sc_dmatag,
                    640:                            sc_if->sk_cdata.sk_rx_jumbo_map);
                    641:                case 2:
                    642:                        bus_dmamem_unmap(sc->sc_dmatag, kva, MSK_JMEM);
                    643:                case 1:
                    644:                        bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
                    645:                        break;
                    646:                default:
                    647:                        break;
                    648:                }
                    649:        }
                    650:
                    651:        return (error);
                    652: }
                    653:
                    654: /*
                    655:  * Allocate a jumbo buffer.
                    656:  */
                    657: void *
                    658: msk_jalloc(struct sk_if_softc *sc_if)
                    659: {
                    660:        struct sk_jpool_entry   *entry;
                    661:
                    662:        entry = LIST_FIRST(&sc_if->sk_jfree_listhead);
                    663:
                    664:        if (entry == NULL)
                    665:                return (NULL);
                    666:
                    667:        LIST_REMOVE(entry, jpool_entries);
                    668:        LIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries);
                    669:        return (sc_if->sk_cdata.sk_jslots[entry->slot]);
                    670: }
                    671:
                    672: /*
                    673:  * Release a jumbo buffer.
                    674:  */
                    675: void
                    676: msk_jfree(caddr_t buf, u_int size, void        *arg)
                    677: {
                    678:        struct sk_jpool_entry *entry;
                    679:        struct sk_if_softc *sc;
                    680:        int i;
                    681:
                    682:        /* Extract the softc struct pointer. */
                    683:        sc = (struct sk_if_softc *)arg;
                    684:
                    685:        if (sc == NULL)
                    686:                panic("msk_jfree: can't find softc pointer!");
                    687:
                    688:        /* calculate the slot this buffer belongs to */
                    689:        i = ((vaddr_t)buf
                    690:             - (vaddr_t)sc->sk_cdata.sk_jumbo_buf) / SK_JLEN;
                    691:
                    692:        if ((i < 0) || (i >= MSK_JSLOTS))
                    693:                panic("msk_jfree: asked to free buffer that we don't manage!");
                    694:
                    695:        entry = LIST_FIRST(&sc->sk_jinuse_listhead);
                    696:        if (entry == NULL)
                    697:                panic("msk_jfree: buffer not in use!");
                    698:        entry->slot = i;
                    699:        LIST_REMOVE(entry, jpool_entries);
                    700:        LIST_INSERT_HEAD(&sc->sk_jfree_listhead, entry, jpool_entries);
                    701: }
                    702:
                    703: /*
                    704:  * Set media options.
                    705:  */
                    706: int
                    707: msk_ifmedia_upd(struct ifnet *ifp)
                    708: {
                    709:        struct sk_if_softc *sc_if = ifp->if_softc;
                    710:
                    711:        mii_mediachg(&sc_if->sk_mii);
                    712:        return (0);
                    713: }
                    714:
                    715: /*
                    716:  * Report current media status.
                    717:  */
                    718: void
                    719: msk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
                    720: {
                    721:        struct sk_if_softc *sc_if = ifp->if_softc;
                    722:
                    723:        mii_pollstat(&sc_if->sk_mii);
                    724:        ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
                    725:        ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
                    726: }
                    727:
                    728: int
                    729: msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
                    730: {
                    731:        struct sk_if_softc *sc_if = ifp->if_softc;
                    732:        struct ifreq *ifr = (struct ifreq *) data;
                    733:        struct ifaddr *ifa = (struct ifaddr *) data;
                    734:        struct mii_data *mii;
                    735:        int s, error = 0;
                    736:
                    737:        s = splnet();
                    738:
                    739:        if ((error = ether_ioctl(ifp, &sc_if->arpcom, command, data)) > 0) {
                    740:                splx(s);
                    741:                return (error);
                    742:        }
                    743:
                    744:        switch(command) {
                    745:        case SIOCSIFADDR:
                    746:                ifp->if_flags |= IFF_UP;
                    747:                if (!(ifp->if_flags & IFF_RUNNING))
                    748:                        msk_init(sc_if);
                    749: #ifdef INET
                    750:                if (ifa->ifa_addr->sa_family == AF_INET)
                    751:                        arp_ifinit(&sc_if->arpcom, ifa);
                    752: #endif /* INET */
                    753:                break;
                    754:        case SIOCSIFMTU:
                    755:                if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
                    756:                        error = EINVAL;
                    757:                else if (ifp->if_mtu != ifr->ifr_mtu)
                    758:                        ifp->if_mtu = ifr->ifr_mtu;
                    759:                break;
                    760:        case SIOCSIFFLAGS:
                    761:                if (ifp->if_flags & IFF_UP) {
                    762:                        if (ifp->if_flags & IFF_RUNNING &&
                    763:                            (sc_if->sk_if_flags ^ ifp->if_flags) &
                    764:                             IFF_PROMISC) {
                    765:                                msk_setpromisc(sc_if);
                    766:                                msk_setmulti(sc_if);
                    767:                        } else {
                    768:                                if (!(ifp->if_flags & IFF_RUNNING))
                    769:                                        msk_init(sc_if);
                    770:                        }
                    771:                } else {
                    772:                        if (ifp->if_flags & IFF_RUNNING)
                    773:                                msk_stop(sc_if);
                    774:                }
                    775:                sc_if->sk_if_flags = ifp->if_flags;
                    776:                break;
                    777:        case SIOCADDMULTI:
                    778:        case SIOCDELMULTI:
                    779:                error = (command == SIOCADDMULTI) ?
                    780:                    ether_addmulti(ifr, &sc_if->arpcom) :
                    781:                    ether_delmulti(ifr, &sc_if->arpcom);
                    782:
                    783:                if (error == ENETRESET) {
                    784:                        /*
                    785:                         * Multicast list has changed; set the hardware
                    786:                         * filter accordingly.
                    787:                         */
                    788:                        if (ifp->if_flags & IFF_RUNNING)
                    789:                                msk_setmulti(sc_if);
                    790:                        error = 0;
                    791:                }
                    792:                break;
                    793:        case SIOCGIFMEDIA:
                    794:        case SIOCSIFMEDIA:
                    795:                mii = &sc_if->sk_mii;
                    796:                error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
                    797:                break;
                    798:        default:
                    799:                error = ENOTTY;
                    800:                break;
                    801:        }
                    802:
                    803:        splx(s);
                    804:
                    805:        return (error);
                    806: }
                    807:
                    808: /*
                    809:  * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
                    810:  * IDs against our list and return a device name if we find a match.
                    811:  */
                    812: int
                    813: mskc_probe(struct device *parent, void *match, void *aux)
                    814: {
                    815:        return (pci_matchbyid((struct pci_attach_args *)aux, mskc_devices,
                    816:            sizeof(mskc_devices)/sizeof(mskc_devices[0])));
                    817: }
                    818:
                    819: /*
                    820:  * Force the GEnesis into reset, then bring it out of reset.
                    821:  */
                    822: void
                    823: mskc_reset(struct sk_softc *sc)
                    824: {
                    825:        u_int32_t imtimer_ticks, reg1;
                    826:        int reg;
                    827:
                    828:        DPRINTFN(2, ("mskc_reset\n"));
                    829:
                    830:        CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_RESET);
                    831:        CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_RESET);
                    832:
                    833:        DELAY(1000);
                    834:        CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_UNRESET);
                    835:        DELAY(2);
                    836:        CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
                    837:
                    838:        sk_win_write_1(sc, SK_TESTCTL1, 2);
                    839:
                    840:        reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1));
                    841:        if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
                    842:                reg1 |= (SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
                    843:        else
                    844:                reg1 &= ~(SK_Y2_REG1_PHY1_COMA | SK_Y2_REG1_PHY2_COMA);
                    845:        sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1), reg1);
                    846:
                    847:        if (sc->sk_type == SK_YUKON_XL && sc->sk_rev > SK_YUKON_XL_REV_A1)
                    848:                sk_win_write_1(sc, SK_Y2_CLKGATE,
                    849:                    SK_Y2_CLKGATE_LINK1_GATE_DIS |
                    850:                    SK_Y2_CLKGATE_LINK2_GATE_DIS |
                    851:                    SK_Y2_CLKGATE_LINK1_CORE_DIS |
                    852:                    SK_Y2_CLKGATE_LINK2_CORE_DIS |
                    853:                    SK_Y2_CLKGATE_LINK1_PCI_DIS | SK_Y2_CLKGATE_LINK2_PCI_DIS);
                    854:        else
                    855:                sk_win_write_1(sc, SK_Y2_CLKGATE, 0);
                    856:
                    857:        CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
                    858:        CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_SET);
                    859:        DELAY(1000);
                    860:        CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
                    861:        CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_CLEAR);
                    862:
                    863:        sk_win_write_1(sc, SK_TESTCTL1, 1);
                    864:
                    865:        DPRINTFN(2, ("mskc_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR)));
                    866:        DPRINTFN(2, ("mskc_reset: sk_link_ctrl=%x\n",
                    867:                     CSR_READ_2(sc, SK_LINK_CTRL)));
                    868:
                    869:        /* Disable ASF */
                    870:        CSR_WRITE_1(sc, SK_Y2_ASF_CSR, SK_Y2_ASF_RESET);
                    871:        CSR_WRITE_2(sc, SK_CSR, SK_CSR_ASF_OFF);
                    872:
                    873:        /* Clear I2C IRQ noise */
                    874:        CSR_WRITE_4(sc, SK_I2CHWIRQ, 1);
                    875:
                    876:        /* Disable hardware timer */
                    877:        CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_STOP);
                    878:        CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_IRQ_CLEAR);
                    879:
                    880:        /* Disable descriptor polling */
                    881:        CSR_WRITE_4(sc, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
                    882:
                    883:        /* Disable time stamps */
                    884:        CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_STOP);
                    885:        CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_IRQ_CLEAR);
                    886:
                    887:        /* Enable RAM interface */
                    888:        sk_win_write_1(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
                    889:        for (reg = SK_TO0;reg <= SK_TO11; reg++)
                    890:                sk_win_write_1(sc, reg, 36);
                    891:        sk_win_write_1(sc, SK_RAMCTL + (SK_WIN_LEN / 2), SK_RAMCTL_UNRESET);
                    892:        for (reg = SK_TO0;reg <= SK_TO11; reg++)
                    893:                sk_win_write_1(sc, reg + (SK_WIN_LEN / 2), 36);
                    894:
                    895:        /*
                    896:         * Configure interrupt moderation. The moderation timer
                    897:         * defers interrupts specified in the interrupt moderation
                    898:         * timer mask based on the timeout specified in the interrupt
                    899:         * moderation timer init register. Each bit in the timer
                    900:         * register represents one tick, so to specify a timeout in
                    901:         * microseconds, we have to multiply by the correct number of
                    902:         * ticks-per-microsecond.
                    903:         */
                    904:        switch (sc->sk_type) {
                    905:        case SK_YUKON_EC:
                    906:        case SK_YUKON_XL:
                    907:        case SK_YUKON_FE:
                    908:                imtimer_ticks = SK_IMTIMER_TICKS_YUKON_EC;
                    909:                break;
                    910:        default:
                    911:                imtimer_ticks = SK_IMTIMER_TICKS_YUKON;
                    912:        }
                    913:
                    914:        /* Reset status ring. */
                    915:        bzero((char *)sc->sk_status_ring,
                    916:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
                    917:        sc->sk_status_idx = 0;
                    918:
                    919:        sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_RESET);
                    920:        sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_UNRESET);
                    921:
                    922:        sk_win_write_2(sc, SK_STAT_BMU_LIDX, MSK_STATUS_RING_CNT - 1);
                    923:        sk_win_write_4(sc, SK_STAT_BMU_ADDRLO,
                    924:            sc->sk_status_map->dm_segs[0].ds_addr);
                    925:        sk_win_write_4(sc, SK_STAT_BMU_ADDRHI,
                    926:            (u_int64_t)sc->sk_status_map->dm_segs[0].ds_addr >> 32);
                    927:        sk_win_write_2(sc, SK_STAT_BMU_TX_THRESH, 10);
                    928:        sk_win_write_1(sc, SK_STAT_BMU_FIFOWM, 16);
                    929:        sk_win_write_1(sc, SK_STAT_BMU_FIFOIWM, 16);
                    930:
                    931: #if 0
                    932:        sk_win_write_4(sc, SK_Y2_LEV_TIMERINIT, SK_IM_USECS(100));
                    933:        sk_win_write_4(sc, 0x0ec0, SK_IM_USECS(1000));
                    934:
                    935:        sk_win_write_4(sc, 0x0ed0, SK_IM_USECS(20));
                    936: #else
                    937:        sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT, SK_IM_USECS(4));
                    938: #endif
                    939:
                    940:        sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_ON);
                    941:
                    942:        sk_win_write_1(sc, SK_Y2_LEV_ITIMERCTL, SK_IMCTL_START);
                    943:        sk_win_write_1(sc, SK_Y2_TX_ITIMERCTL, SK_IMCTL_START);
                    944:        sk_win_write_1(sc, SK_Y2_ISR_ITIMERCTL, SK_IMCTL_START);
                    945: }
                    946:
                    947: int
                    948: msk_probe(struct device *parent, void *match, void *aux)
                    949: {
                    950:        struct skc_attach_args *sa = aux;
                    951:
                    952:        if (sa->skc_port != SK_PORT_A && sa->skc_port != SK_PORT_B)
                    953:                return (0);
                    954:
                    955:        switch (sa->skc_type) {
                    956:        case SK_YUKON_XL:
                    957:        case SK_YUKON_EC_U:
                    958:        case SK_YUKON_EX:
                    959:        case SK_YUKON_EC:
                    960:        case SK_YUKON_FE:
                    961:                return (1);
                    962:        }
                    963:
                    964:        return (0);
                    965: }
                    966:
                    967: void
                    968: msk_reset(struct sk_if_softc *sc_if)
                    969: {
                    970:        /* GMAC and GPHY Reset */
                    971:        SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
                    972:        SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
                    973:        DELAY(1000);
                    974:        SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR);
                    975:        SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
                    976:                      SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
                    977: }
                    978:
                    979: /*
                    980:  * Each XMAC chip is attached as a separate logical IP interface.
                    981:  * Single port cards will have only one logical interface of course.
                    982:  */
                    983: void
                    984: msk_attach(struct device *parent, struct device *self, void *aux)
                    985: {
                    986:        struct sk_if_softc *sc_if = (struct sk_if_softc *) self;
                    987:        struct sk_softc *sc = (struct sk_softc *)parent;
                    988:        struct skc_attach_args *sa = aux;
                    989:        struct ifnet *ifp;
                    990:        caddr_t kva;
                    991:        bus_dma_segment_t seg;
                    992:        int i, rseg;
                    993:        u_int32_t chunk;
                    994:        int mii_flags;
                    995:
                    996:        sc_if->sk_port = sa->skc_port;
                    997:        sc_if->sk_softc = sc;
                    998:        sc->sk_if[sa->skc_port] = sc_if;
                    999:
                   1000:        DPRINTFN(2, ("begin msk_attach: port=%d\n", sc_if->sk_port));
                   1001:
                   1002:        /*
                   1003:         * Get station address for this interface. Note that
                   1004:         * dual port cards actually come with three station
                   1005:         * addresses: one for each port, plus an extra. The
                   1006:         * extra one is used by the SysKonnect driver software
                   1007:         * as a 'virtual' station address for when both ports
                   1008:         * are operating in failover mode. Currently we don't
                   1009:         * use this extra address.
                   1010:         */
                   1011:        for (i = 0; i < ETHER_ADDR_LEN; i++)
                   1012:                sc_if->arpcom.ac_enaddr[i] =
                   1013:                    sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
                   1014:
                   1015:        printf(": address %s\n",
                   1016:            ether_sprintf(sc_if->arpcom.ac_enaddr));
                   1017:
                   1018:        /*
                   1019:         * Set up RAM buffer addresses. The Yukon2 has a small amount
                   1020:         * of SRAM on it, somewhere between 4K and 48K.  We need to
                   1021:         * divide this up between the transmitter and receiver.  We
                   1022:         * give the receiver 2/3 of the memory (rounded down), and the
                   1023:         * transmitter whatever remains.
                   1024:         */
                   1025:        chunk = (2 * (sc->sk_ramsize / sizeof(u_int64_t)) / 3) & ~0xff;
                   1026:        sc_if->sk_rx_ramstart = 0;
                   1027:        sc_if->sk_rx_ramend = sc_if->sk_rx_ramstart + chunk - 1;
                   1028:        chunk = (sc->sk_ramsize / sizeof(u_int64_t)) - chunk;
                   1029:        sc_if->sk_tx_ramstart = sc_if->sk_rx_ramend + 1;
                   1030:        sc_if->sk_tx_ramend = sc_if->sk_tx_ramstart + chunk - 1;
                   1031:
                   1032:        DPRINTFN(2, ("msk_attach: rx_ramstart=%#x rx_ramend=%#x\n"
                   1033:                     "           tx_ramstart=%#x tx_ramend=%#x\n",
                   1034:                     sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend,
                   1035:                     sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend));
                   1036:
                   1037:        /* Allocate the descriptor queues. */
                   1038:        if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct msk_ring_data),
                   1039:            PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
                   1040:                printf(": can't alloc rx buffers\n");
                   1041:                goto fail;
                   1042:        }
                   1043:        if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
                   1044:            sizeof(struct msk_ring_data), &kva, BUS_DMA_NOWAIT)) {
                   1045:                printf(": can't map dma buffers (%lu bytes)\n",
                   1046:                       (ulong)sizeof(struct msk_ring_data));
                   1047:                goto fail_1;
                   1048:        }
                   1049:        if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct msk_ring_data), 1,
                   1050:            sizeof(struct msk_ring_data), 0, BUS_DMA_NOWAIT,
                   1051:             &sc_if->sk_ring_map)) {
                   1052:                printf(": can't create dma map\n");
                   1053:                goto fail_2;
                   1054:        }
                   1055:        if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,
                   1056:            sizeof(struct msk_ring_data), NULL, BUS_DMA_NOWAIT)) {
                   1057:                printf(": can't load dma map\n");
                   1058:                goto fail_3;
                   1059:        }
                   1060:         sc_if->sk_rdata = (struct msk_ring_data *)kva;
                   1061:        bzero(sc_if->sk_rdata, sizeof(struct msk_ring_data));
                   1062:
                   1063:        /* Try to allocate memory for jumbo buffers. */
                   1064:        if (msk_alloc_jumbo_mem(sc_if)) {
                   1065:                printf(": jumbo buffer allocation failed\n");
                   1066:                goto fail_3;
                   1067:        }
                   1068:
                   1069:        ifp = &sc_if->arpcom.ac_if;
                   1070:        ifp->if_softc = sc_if;
                   1071:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                   1072:        ifp->if_ioctl = msk_ioctl;
                   1073:        ifp->if_start = msk_start;
                   1074:        ifp->if_watchdog = msk_watchdog;
                   1075:        ifp->if_baudrate = 1000000000;
                   1076:        if (sc->sk_type != SK_YUKON_FE)
                   1077:                ifp->if_hardmtu = SK_JUMBO_MTU;
                   1078:        IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
                   1079:        IFQ_SET_READY(&ifp->if_snd);
                   1080:        bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
                   1081:
                   1082:        ifp->if_capabilities = IFCAP_VLAN_MTU;
                   1083:
                   1084:        msk_reset(sc_if);
                   1085:
                   1086:        /*
                   1087:         * Do miibus setup.
                   1088:         */
                   1089:        msk_init_yukon(sc_if);
                   1090:
                   1091:        DPRINTFN(2, ("msk_attach: 1\n"));
                   1092:
                   1093:        sc_if->sk_mii.mii_ifp = ifp;
                   1094:        sc_if->sk_mii.mii_readreg = msk_miibus_readreg;
                   1095:        sc_if->sk_mii.mii_writereg = msk_miibus_writereg;
                   1096:        sc_if->sk_mii.mii_statchg = msk_miibus_statchg;
                   1097:
                   1098:        ifmedia_init(&sc_if->sk_mii.mii_media, 0,
                   1099:            msk_ifmedia_upd, msk_ifmedia_sts);
                   1100:        mii_flags = MIIF_DOPAUSE;
                   1101:        if (sc->sk_fibertype)
                   1102:                mii_flags |= MIIF_HAVEFIBER;
                   1103:        mii_attach(self, &sc_if->sk_mii, 0xffffffff, 0,
                   1104:            MII_OFFSET_ANY, mii_flags);
                   1105:        if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
                   1106:                printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
                   1107:                ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
                   1108:                            0, NULL);
                   1109:                ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL);
                   1110:        } else
                   1111:                ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
                   1112:
                   1113:        timeout_set(&sc_if->sk_tick_ch, msk_tick, sc_if);
                   1114:
                   1115:        /*
                   1116:         * Call MI attach routines.
                   1117:         */
                   1118:        if_attach(ifp);
                   1119:        ether_ifattach(ifp);
                   1120:
                   1121:        shutdownhook_establish(mskc_shutdown, sc);
                   1122:
                   1123:        DPRINTFN(2, ("msk_attach: end\n"));
                   1124:        return;
                   1125:
                   1126: fail_3:
                   1127:        bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
                   1128: fail_2:
                   1129:        bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct msk_ring_data));
                   1130: fail_1:
                   1131:        bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
                   1132: fail:
                   1133:        sc->sk_if[sa->skc_port] = NULL;
                   1134: }
                   1135:
                   1136: int
                   1137: mskcprint(void *aux, const char *pnp)
                   1138: {
                   1139:        struct skc_attach_args *sa = aux;
                   1140:
                   1141:        if (pnp)
                   1142:                printf("sk port %c at %s",
                   1143:                    (sa->skc_port == SK_PORT_A) ? 'A' : 'B', pnp);
                   1144:        else
                   1145:                printf(" port %c", (sa->skc_port == SK_PORT_A) ? 'A' : 'B');
                   1146:        return (UNCONF);
                   1147: }
                   1148:
                   1149: /*
                   1150:  * Attach the interface. Allocate softc structures, do ifmedia
                   1151:  * setup and ethernet/BPF attach.
                   1152:  */
                   1153: void
                   1154: mskc_attach(struct device *parent, struct device *self, void *aux)
                   1155: {
                   1156:        struct sk_softc *sc = (struct sk_softc *)self;
                   1157:        struct pci_attach_args *pa = aux;
                   1158:        struct skc_attach_args skca;
                   1159:        pci_chipset_tag_t pc = pa->pa_pc;
                   1160:        pcireg_t command, memtype;
                   1161:        pci_intr_handle_t ih;
                   1162:        const char *intrstr = NULL;
                   1163:        bus_size_t size;
                   1164:        u_int8_t hw, pmd;
                   1165:        char *revstr = NULL;
                   1166:        caddr_t kva;
                   1167:        bus_dma_segment_t seg;
                   1168:        int rseg;
                   1169:
                   1170:        DPRINTFN(2, ("begin mskc_attach\n"));
                   1171:
                   1172:        /*
                   1173:         * Handle power management nonsense.
                   1174:         */
                   1175:        command = pci_conf_read(pc, pa->pa_tag, SK_PCI_CAPID) & 0x000000FF;
                   1176:
                   1177:        if (command == 0x01) {
                   1178:                command = pci_conf_read(pc, pa->pa_tag, SK_PCI_PWRMGMTCTRL);
                   1179:                if (command & SK_PSTATE_MASK) {
                   1180:                        u_int32_t               iobase, membase, irq;
                   1181:
                   1182:                        /* Save important PCI config data. */
                   1183:                        iobase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOIO);
                   1184:                        membase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOMEM);
                   1185:                        irq = pci_conf_read(pc, pa->pa_tag, SK_PCI_INTLINE);
                   1186:
                   1187:                        /* Reset the power state. */
                   1188:                        printf("%s chip is in D%d power mode "
                   1189:                            "-- setting to D0\n", sc->sk_dev.dv_xname,
                   1190:                            command & SK_PSTATE_MASK);
                   1191:                        command &= 0xFFFFFFFC;
                   1192:                        pci_conf_write(pc, pa->pa_tag,
                   1193:                            SK_PCI_PWRMGMTCTRL, command);
                   1194:
                   1195:                        /* Restore PCI config data. */
                   1196:                        pci_conf_write(pc, pa->pa_tag, SK_PCI_LOIO, iobase);
                   1197:                        pci_conf_write(pc, pa->pa_tag, SK_PCI_LOMEM, membase);
                   1198:                        pci_conf_write(pc, pa->pa_tag, SK_PCI_INTLINE, irq);
                   1199:                }
                   1200:        }
                   1201:
                   1202:        /*
                   1203:         * Map control/status registers.
                   1204:         */
                   1205:
                   1206:        memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
                   1207:        switch (memtype) {
                   1208:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                   1209:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                   1210:                if (pci_mapreg_map(pa, SK_PCI_LOMEM,
                   1211:                                   memtype, 0, &sc->sk_btag, &sc->sk_bhandle,
                   1212:                                   NULL, &size, 0) == 0)
                   1213:                        break;
                   1214:        default:
                   1215:                printf(": can't map mem space\n");
                   1216:                return;
                   1217:        }
                   1218:
                   1219:        sc->sc_dmatag = pa->pa_dmat;
                   1220:
                   1221:        sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
                   1222:        sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
                   1223:
                   1224:        /* bail out here if chip is not recognized */
                   1225:        if (!(SK_IS_YUKON2(sc))) {
                   1226:                printf(": unknown chip type: %d\n", sc->sk_type);
                   1227:                goto fail_1;
                   1228:        }
                   1229:        DPRINTFN(2, ("mskc_attach: allocate interrupt\n"));
                   1230:
                   1231:        /* Allocate interrupt */
                   1232:        if (pci_intr_map(pa, &ih)) {
                   1233:                printf(": couldn't map interrupt\n");
                   1234:                goto fail_1;
                   1235:        }
                   1236:
                   1237:        intrstr = pci_intr_string(pc, ih);
                   1238:        sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, msk_intr, sc,
                   1239:            self->dv_xname);
                   1240:        if (sc->sk_intrhand == NULL) {
                   1241:                printf(": couldn't establish interrupt");
                   1242:                if (intrstr != NULL)
                   1243:                        printf(" at %s", intrstr);
                   1244:                printf("\n");
                   1245:                goto fail_1;
                   1246:        }
                   1247:
                   1248:        if (bus_dmamem_alloc(sc->sc_dmatag,
                   1249:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
                   1250:            PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
                   1251:                printf(": can't alloc status buffers\n");
                   1252:                goto fail_2;
                   1253:        }
                   1254:
                   1255:        if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
                   1256:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
                   1257:            &kva, BUS_DMA_NOWAIT)) {
                   1258:                printf(": can't map dma buffers (%lu bytes)\n",
                   1259:                    (ulong)(MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc)));
                   1260:                goto fail_3;
                   1261:        }
                   1262:        if (bus_dmamap_create(sc->sc_dmatag,
                   1263:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 1,
                   1264:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 0,
                   1265:            BUS_DMA_NOWAIT, &sc->sk_status_map)) {
                   1266:                printf(": can't create dma map\n");
                   1267:                goto fail_4;
                   1268:        }
                   1269:        if (bus_dmamap_load(sc->sc_dmatag, sc->sk_status_map, kva,
                   1270:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
                   1271:            NULL, BUS_DMA_NOWAIT)) {
                   1272:                printf(": can't load dma map\n");
                   1273:                goto fail_5;
                   1274:        }
                   1275:        sc->sk_status_ring = (struct msk_status_desc *)kva;
                   1276:        bzero(sc->sk_status_ring,
                   1277:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
                   1278:
                   1279:        /* Reset the adapter. */
                   1280:        mskc_reset(sc);
                   1281:
                   1282:        sc->sk_ramsize = sk_win_read_1(sc, SK_EPROM0) * 4096;
                   1283:        DPRINTFN(2, ("mskc_attach: ramsize=%dK\n", sc->sk_ramsize / 1024));
                   1284:
                   1285:        pmd = sk_win_read_1(sc, SK_PMDTYPE);
                   1286:        if (pmd == 'L' || pmd == 'S' || pmd == 'P')
                   1287:                sc->sk_fibertype = 1;
                   1288:
                   1289:        switch (sc->sk_type) {
                   1290:        case SK_YUKON_XL:
                   1291:                sc->sk_name = "Yukon-2 XL";
                   1292:                break;
                   1293:        case SK_YUKON_EC_U:
                   1294:                sc->sk_name = "Yukon-2 EC Ultra";
                   1295:                break;
                   1296:        case SK_YUKON_EX:
                   1297:                sc->sk_name = "Yukon-2 Extreme";
                   1298:                break;
                   1299:        case SK_YUKON_EC:
                   1300:                sc->sk_name = "Yukon-2 EC";
                   1301:                break;
                   1302:        case SK_YUKON_FE:
                   1303:                sc->sk_name = "Yukon-2 FE";
                   1304:                break;
                   1305:        default:
                   1306:                sc->sk_name = "Yukon (Unknown)";
                   1307:        }
                   1308:
                   1309:        if (sc->sk_type == SK_YUKON_XL) {
                   1310:                switch (sc->sk_rev) {
                   1311:                case SK_YUKON_XL_REV_A0:
                   1312:                        revstr = "A0";
                   1313:                        break;
                   1314:                case SK_YUKON_XL_REV_A1:
                   1315:                        revstr = "A1";
                   1316:                        break;
                   1317:                case SK_YUKON_XL_REV_A2:
                   1318:                        revstr = "A2";
                   1319:                        break;
                   1320:                case SK_YUKON_XL_REV_A3:
                   1321:                        revstr = "A3";
                   1322:                        break;
                   1323:                default:
                   1324:                        ;
                   1325:                }
                   1326:        }
                   1327:
                   1328:        if (sc->sk_type == SK_YUKON_EC) {
                   1329:                switch (sc->sk_rev) {
                   1330:                case SK_YUKON_EC_REV_A1:
                   1331:                        revstr = "A1";
                   1332:                        break;
                   1333:                case SK_YUKON_EC_REV_A2:
                   1334:                        revstr = "A2";
                   1335:                        break;
                   1336:                case SK_YUKON_EC_REV_A3:
                   1337:                        revstr = "A3";
                   1338:                        break;
                   1339:                default:
                   1340:                        ;
                   1341:                }
                   1342:        }
                   1343:
                   1344:        if (sc->sk_type == SK_YUKON_EC_U) {
                   1345:                switch (sc->sk_rev) {
                   1346:                case SK_YUKON_EC_U_REV_A0:
                   1347:                        revstr = "A0";
                   1348:                        break;
                   1349:                case SK_YUKON_EC_U_REV_A1:
                   1350:                        revstr = "A1";
                   1351:                        break;
                   1352:                default:
                   1353:                        ;
                   1354:                }
                   1355:        }
                   1356:
                   1357:        /* Announce the product name. */
                   1358:        printf(", %s", sc->sk_name);
                   1359:        if (revstr != NULL)
                   1360:                printf(" rev. %s", revstr);
                   1361:        printf(" (0x%x): %s\n", sc->sk_rev, intrstr);
                   1362:
                   1363:        sc->sk_macs = 1;
                   1364:
                   1365:        hw = sk_win_read_1(sc, SK_Y2_HWRES);
                   1366:        if ((hw & SK_Y2_HWRES_LINK_MASK) == SK_Y2_HWRES_LINK_DUAL) {
                   1367:                if ((sk_win_read_1(sc, SK_Y2_CLKGATE) &
                   1368:                    SK_Y2_CLKGATE_LINK2_INACTIVE) == 0)
                   1369:                        sc->sk_macs++;
                   1370:        }
                   1371:
                   1372:        skca.skc_port = SK_PORT_A;
                   1373:        skca.skc_type = sc->sk_type;
                   1374:        skca.skc_rev = sc->sk_rev;
                   1375:        (void)config_found(&sc->sk_dev, &skca, mskcprint);
                   1376:
                   1377:        if (sc->sk_macs > 1) {
                   1378:                skca.skc_port = SK_PORT_B;
                   1379:                skca.skc_type = sc->sk_type;
                   1380:                skca.skc_rev = sc->sk_rev;
                   1381:                (void)config_found(&sc->sk_dev, &skca, mskcprint);
                   1382:        }
                   1383:
                   1384:        /* Turn on the 'driver is loaded' LED. */
                   1385:        CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
                   1386:
                   1387:        return;
                   1388:
                   1389: fail_5:
                   1390:        bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
                   1391: fail_4:
                   1392:        bus_dmamem_unmap(sc->sc_dmatag, kva,
                   1393:            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
                   1394: fail_3:
                   1395:        bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
                   1396: fail_2:
                   1397:        pci_intr_disestablish(pc, sc->sk_intrhand);
                   1398: fail_1:
                   1399:        bus_space_unmap(sc->sk_btag, sc->sk_bhandle, size);
                   1400: }
                   1401:
                   1402: int
                   1403: msk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx)
                   1404: {
                   1405:        struct sk_softc         *sc = sc_if->sk_softc;
                   1406:        struct msk_tx_desc              *f = NULL;
                   1407:        u_int32_t               frag, cur;
                   1408:        int                     i;
                   1409:        struct sk_txmap_entry   *entry;
                   1410:        bus_dmamap_t            txmap;
                   1411:
                   1412:        DPRINTFN(2, ("msk_encap\n"));
                   1413:
                   1414:        entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
                   1415:        if (entry == NULL) {
                   1416:                DPRINTFN(2, ("msk_encap: no txmap available\n"));
                   1417:                return (ENOBUFS);
                   1418:        }
                   1419:        txmap = entry->dmamap;
                   1420:
                   1421:        cur = frag = *txidx;
                   1422:
                   1423: #ifdef MSK_DEBUG
                   1424:        if (mskdebug >= 2)
                   1425:                msk_dump_mbuf(m_head);
                   1426: #endif
                   1427:
                   1428:        /*
                   1429:         * Start packing the mbufs in this chain into
                   1430:         * the fragment pointers. Stop when we run out
                   1431:         * of fragments or hit the end of the mbuf chain.
                   1432:         */
                   1433:        if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
                   1434:            BUS_DMA_NOWAIT)) {
                   1435:                DPRINTFN(2, ("msk_encap: dmamap failed\n"));
                   1436:                return (ENOBUFS);
                   1437:        }
                   1438:
                   1439:        if (txmap->dm_nsegs > (MSK_TX_RING_CNT - sc_if->sk_cdata.sk_tx_cnt - 2)) {
                   1440:                DPRINTFN(2, ("msk_encap: too few descriptors free\n"));
                   1441:                bus_dmamap_unload(sc->sc_dmatag, txmap);
                   1442:                return (ENOBUFS);
                   1443:        }
                   1444:
                   1445:        DPRINTFN(2, ("msk_encap: dm_nsegs=%d\n", txmap->dm_nsegs));
                   1446:
                   1447:        /* Sync the DMA map. */
                   1448:        bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
                   1449:            BUS_DMASYNC_PREWRITE);
                   1450:
                   1451:        for (i = 0; i < txmap->dm_nsegs; i++) {
                   1452:                f = &sc_if->sk_rdata->sk_tx_ring[frag];
                   1453:                f->sk_addr = htole32(txmap->dm_segs[i].ds_addr);
                   1454:                f->sk_len = htole16(txmap->dm_segs[i].ds_len);
                   1455:                f->sk_ctl = 0;
                   1456:                if (i == 0)
                   1457:                        f->sk_opcode = SK_Y2_TXOPC_PACKET;
                   1458:                else
                   1459:                        f->sk_opcode = SK_Y2_TXOPC_BUFFER | SK_Y2_TXOPC_OWN;
                   1460:                cur = frag;
                   1461:                SK_INC(frag, MSK_TX_RING_CNT);
                   1462:        }
                   1463:
                   1464:        sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
                   1465:        SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
                   1466:
                   1467:        sc_if->sk_cdata.sk_tx_map[cur] = entry;
                   1468:        sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |= SK_Y2_TXCTL_LASTFRAG;
                   1469:
                   1470:        /* Sync descriptors before handing to chip */
                   1471:        MSK_CDTXSYNC(sc_if, *txidx, txmap->dm_nsegs,
                   1472:             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1473:
                   1474:        sc_if->sk_rdata->sk_tx_ring[*txidx].sk_opcode |= SK_Y2_TXOPC_OWN;
                   1475:
                   1476:        /* Sync first descriptor to hand it off */
                   1477:        MSK_CDTXSYNC(sc_if, *txidx, 1,
                   1478:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1479:
                   1480:        sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs;
                   1481:
                   1482: #ifdef MSK_DEBUG
                   1483:        if (mskdebug >= 2) {
                   1484:                struct msk_tx_desc *le;
                   1485:                u_int32_t idx;
                   1486:                for (idx = *txidx; idx != frag; SK_INC(idx, MSK_TX_RING_CNT)) {
                   1487:                        le = &sc_if->sk_rdata->sk_tx_ring[idx];
                   1488:                        msk_dump_txdesc(le, idx);
                   1489:                }
                   1490:        }
                   1491: #endif
                   1492:
                   1493:        *txidx = frag;
                   1494:
                   1495:        DPRINTFN(2, ("msk_encap: completed successfully\n"));
                   1496:
                   1497:        return (0);
                   1498: }
                   1499:
                   1500: void
                   1501: msk_start(struct ifnet *ifp)
                   1502: {
                   1503:         struct sk_if_softc     *sc_if = ifp->if_softc;
                   1504:         struct mbuf            *m_head = NULL;
                   1505:         u_int32_t              idx = sc_if->sk_cdata.sk_tx_prod;
                   1506:        int                     pkts = 0;
                   1507:
                   1508:        DPRINTFN(2, ("msk_start\n"));
                   1509:
                   1510:        while (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
                   1511:                IFQ_POLL(&ifp->if_snd, m_head);
                   1512:                if (m_head == NULL)
                   1513:                        break;
                   1514:
                   1515:                /*
                   1516:                 * Pack the data into the transmit ring. If we
                   1517:                 * don't have room, set the OACTIVE flag and wait
                   1518:                 * for the NIC to drain the ring.
                   1519:                 */
                   1520:                if (msk_encap(sc_if, m_head, &idx)) {
                   1521:                        ifp->if_flags |= IFF_OACTIVE;
                   1522:                        break;
                   1523:                }
                   1524:
                   1525:                /* now we are committed to transmit the packet */
                   1526:                IFQ_DEQUEUE(&ifp->if_snd, m_head);
                   1527:                pkts++;
                   1528:
                   1529:                /*
                   1530:                 * If there's a BPF listener, bounce a copy of this frame
                   1531:                 * to him.
                   1532:                 */
                   1533: #if NBPFILTER > 0
                   1534:                if (ifp->if_bpf)
                   1535:                        bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
                   1536: #endif
                   1537:        }
                   1538:        if (pkts == 0)
                   1539:                return;
                   1540:
                   1541:        /* Transmit */
                   1542:        if (idx != sc_if->sk_cdata.sk_tx_prod) {
                   1543:                sc_if->sk_cdata.sk_tx_prod = idx;
                   1544:                SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX, idx);
                   1545:
                   1546:                /* Set a timeout in case the chip goes out to lunch. */
                   1547:                ifp->if_timer = 5;
                   1548:        }
                   1549: }
                   1550:
                   1551: void
                   1552: msk_watchdog(struct ifnet *ifp)
                   1553: {
                   1554:        struct sk_if_softc *sc_if = ifp->if_softc;
                   1555:
                   1556:        /*
                   1557:         * Reclaim first as there is a possibility of losing Tx completion
                   1558:         * interrupts.
                   1559:         */
                   1560:        msk_txeof(sc_if);
                   1561:        if (sc_if->sk_cdata.sk_tx_cnt != 0) {
                   1562:                printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname);
                   1563:
                   1564:                ifp->if_oerrors++;
                   1565:
                   1566:                /* XXX Resets both ports; we shouldn't do that. */
                   1567:                mskc_reset(sc_if->sk_softc);
                   1568:                msk_reset(sc_if);
                   1569:                msk_init(sc_if);
                   1570:        }
                   1571: }
                   1572:
                   1573: void
                   1574: mskc_shutdown(void *v)
                   1575: {
                   1576:        struct sk_softc         *sc = v;
                   1577:
                   1578:        DPRINTFN(2, ("msk_shutdown\n"));
                   1579:
                   1580:        /* Turn off the 'driver is loaded' LED. */
                   1581:        CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF);
                   1582:
                   1583:        /*
                   1584:         * Reset the GEnesis controller. Doing this should also
                   1585:         * assert the resets on the attached XMAC(s).
                   1586:         */
                   1587:        mskc_reset(sc);
                   1588: }
                   1589:
                   1590: static __inline int
                   1591: msk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len)
                   1592: {
                   1593:        if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR |
                   1594:            YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC |
                   1595:            YU_RXSTAT_JABBER)) != 0 ||
                   1596:            (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK ||
                   1597:            YU_RXSTAT_BYTES(stat) != len)
                   1598:                return (0);
                   1599:
                   1600:        return (1);
                   1601: }
                   1602:
                   1603: void
                   1604: msk_rxeof(struct sk_if_softc *sc_if, u_int16_t len, u_int32_t rxstat)
                   1605: {
                   1606:        struct sk_softc         *sc = sc_if->sk_softc;
                   1607:        struct ifnet            *ifp = &sc_if->arpcom.ac_if;
                   1608:        struct mbuf             *m;
                   1609:        struct sk_chain         *cur_rx;
                   1610:        int                     cur, total_len = len;
                   1611:        bus_dmamap_t            dmamap;
                   1612:
                   1613:        DPRINTFN(2, ("msk_rxeof\n"));
                   1614:
                   1615:        cur = sc_if->sk_cdata.sk_rx_cons;
                   1616:        SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
                   1617:        SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
                   1618:
                   1619:        /* Sync the descriptor */
                   1620:        MSK_CDRXSYNC(sc_if, cur, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1621:
                   1622:        cur_rx = &sc_if->sk_cdata.sk_rx_chain[cur];
                   1623:        dmamap = sc_if->sk_cdata.sk_rx_jumbo_map;
                   1624:
                   1625:        bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
                   1626:            dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1627:
                   1628:        m = cur_rx->sk_mbuf;
                   1629:        cur_rx->sk_mbuf = NULL;
                   1630:
                   1631:        if (total_len < SK_MIN_FRAMELEN ||
                   1632:            total_len > SK_JUMBO_FRAMELEN ||
                   1633:            msk_rxvalid(sc, rxstat, total_len) == 0) {
                   1634:                ifp->if_ierrors++;
                   1635:                msk_newbuf(sc_if, cur, m, dmamap);
                   1636:                return;
                   1637:        }
                   1638:
                   1639:        /*
                   1640:         * Try to allocate a new jumbo buffer. If that fails, copy the
                   1641:         * packet to mbufs and put the jumbo buffer back in the ring
                   1642:         * so it can be re-used. If allocating mbufs fails, then we
                   1643:         * have to drop the packet.
                   1644:         */
                   1645:        if (msk_newbuf(sc_if, cur, NULL, dmamap) == ENOBUFS) {
                   1646:                struct mbuf             *m0;
                   1647:                m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
                   1648:                    total_len + ETHER_ALIGN, 0, ifp, NULL);
                   1649:                msk_newbuf(sc_if, cur, m, dmamap);
                   1650:                if (m0 == NULL) {
                   1651:                        ifp->if_ierrors++;
                   1652:                        return;
                   1653:                }
                   1654:                m_adj(m0, ETHER_ALIGN);
                   1655:                m = m0;
                   1656:        } else {
                   1657:                m->m_pkthdr.rcvif = ifp;
                   1658:                m->m_pkthdr.len = m->m_len = total_len;
                   1659:        }
                   1660:
                   1661:        ifp->if_ipackets++;
                   1662:
                   1663: #if NBPFILTER > 0
                   1664:        if (ifp->if_bpf)
                   1665:                bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
                   1666: #endif
                   1667:
                   1668:        /* pass it on. */
                   1669:        ether_input_mbuf(ifp, m);
                   1670: }
                   1671:
                   1672: void
                   1673: msk_txeof(struct sk_if_softc *sc_if)
                   1674: {
                   1675:        struct sk_softc         *sc = sc_if->sk_softc;
                   1676:        struct msk_tx_desc      *cur_tx;
                   1677:        struct ifnet            *ifp = &sc_if->arpcom.ac_if;
                   1678:        u_int32_t               idx, reg, sk_ctl;
                   1679:        struct sk_txmap_entry   *entry;
                   1680:
                   1681:        DPRINTFN(2, ("msk_txeof\n"));
                   1682:
                   1683:        if (sc_if->sk_port == SK_PORT_A)
                   1684:                reg = SK_STAT_BMU_TXA1_RIDX;
                   1685:        else
                   1686:                reg = SK_STAT_BMU_TXA2_RIDX;
                   1687:
                   1688:        /*
                   1689:         * Go through our tx ring and free mbufs for those
                   1690:         * frames that have been sent.
                   1691:         */
                   1692:        idx = sc_if->sk_cdata.sk_tx_cons;
                   1693:        while (idx != sk_win_read_2(sc, reg)) {
                   1694:                MSK_CDTXSYNC(sc_if, idx, 1,
                   1695:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1696:
                   1697:                cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
                   1698:                sk_ctl = cur_tx->sk_ctl;
                   1699: #ifdef MSK_DEBUG
                   1700:                if (mskdebug >= 2)
                   1701:                        msk_dump_txdesc(cur_tx, idx);
                   1702: #endif
                   1703:                if (sk_ctl & SK_Y2_TXCTL_LASTFRAG)
                   1704:                        ifp->if_opackets++;
                   1705:                if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
                   1706:                        entry = sc_if->sk_cdata.sk_tx_map[idx];
                   1707:
                   1708:                        m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
                   1709:                        sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
                   1710:
                   1711:                        bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
                   1712:                            entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1713:
                   1714:                        bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
                   1715:                        SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
                   1716:                                          link);
                   1717:                        sc_if->sk_cdata.sk_tx_map[idx] = NULL;
                   1718:                }
                   1719:                sc_if->sk_cdata.sk_tx_cnt--;
                   1720:                SK_INC(idx, MSK_TX_RING_CNT);
                   1721:        }
                   1722:        ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
                   1723:
                   1724:        if (sc_if->sk_cdata.sk_tx_cnt < MSK_TX_RING_CNT - 2)
                   1725:                ifp->if_flags &= ~IFF_OACTIVE;
                   1726:
                   1727:        sc_if->sk_cdata.sk_tx_cons = idx;
                   1728: }
                   1729:
                   1730: void
                   1731: msk_tick(void *xsc_if)
                   1732: {
                   1733:        struct sk_if_softc *sc_if = xsc_if;
                   1734:        struct mii_data *mii = &sc_if->sk_mii;
                   1735:        int s;
                   1736:
                   1737:        s = splnet();
                   1738:        mii_tick(mii);
                   1739:        splx(s);
                   1740:        timeout_add(&sc_if->sk_tick_ch, hz);
                   1741: }
                   1742:
                   1743: void
                   1744: msk_intr_yukon(struct sk_if_softc *sc_if)
                   1745: {
                   1746:        u_int8_t status;
                   1747:
                   1748:        status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR);
                   1749:        /* RX overrun */
                   1750:        if ((status & SK_GMAC_INT_RX_OVER) != 0) {
                   1751:                SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,
                   1752:                    SK_RFCTL_RX_FIFO_OVER);
                   1753:        }
                   1754:        /* TX underrun */
                   1755:        if ((status & SK_GMAC_INT_TX_UNDER) != 0) {
                   1756:                SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,
                   1757:                    SK_TFCTL_TX_FIFO_UNDER);
                   1758:        }
                   1759:
                   1760:        DPRINTFN(2, ("msk_intr_yukon status=%#x\n", status));
                   1761: }
                   1762:
                   1763: int
                   1764: msk_intr(void *xsc)
                   1765: {
                   1766:        struct sk_softc         *sc = xsc;
                   1767:        struct sk_if_softc      *sc_if0 = sc->sk_if[SK_PORT_A];
                   1768:        struct sk_if_softc      *sc_if1 = sc->sk_if[SK_PORT_B];
                   1769:        struct ifnet            *ifp0 = NULL, *ifp1 = NULL;
                   1770:        int                     claimed = 0;
                   1771:        u_int32_t               status;
                   1772:        struct msk_status_desc  *cur_st;
                   1773:
                   1774:        status = CSR_READ_4(sc, SK_Y2_ISSR2);
                   1775:        if (status == 0) {
                   1776:                CSR_WRITE_4(sc, SK_Y2_ICR, 2);
                   1777:                return (0);
                   1778:        }
                   1779:
                   1780:        status = CSR_READ_4(sc, SK_ISR);
                   1781:
                   1782:        if (sc_if0 != NULL)
                   1783:                ifp0 = &sc_if0->arpcom.ac_if;
                   1784:        if (sc_if1 != NULL)
                   1785:                ifp1 = &sc_if1->arpcom.ac_if;
                   1786:
                   1787:        if (sc_if0 && (status & SK_Y2_IMR_MAC1) &&
                   1788:            (ifp0->if_flags & IFF_RUNNING)) {
                   1789:                msk_intr_yukon(sc_if0);
                   1790:        }
                   1791:
                   1792:        if (sc_if1 && (status & SK_Y2_IMR_MAC2) &&
                   1793:            (ifp1->if_flags & IFF_RUNNING)) {
                   1794:                msk_intr_yukon(sc_if1);
                   1795:        }
                   1796:
                   1797:        MSK_CDSTSYNC(sc, sc->sk_status_idx,
                   1798:            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1799:        cur_st = &sc->sk_status_ring[sc->sk_status_idx];
                   1800:
                   1801:        while (cur_st->sk_opcode & SK_Y2_STOPC_OWN) {
                   1802:                cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
                   1803:                switch (cur_st->sk_opcode) {
                   1804:                case SK_Y2_STOPC_RXSTAT:
                   1805:                        msk_rxeof(sc->sk_if[cur_st->sk_link],
                   1806:                            letoh16(cur_st->sk_len),
                   1807:                            letoh32(cur_st->sk_status));
                   1808:                        SK_IF_WRITE_2(sc->sk_if[cur_st->sk_link], 0,
                   1809:                            SK_RXQ1_Y2_PREF_PUTIDX,
                   1810:                            sc->sk_if[cur_st->sk_link]->sk_cdata.sk_rx_prod);
                   1811:                        break;
                   1812:                case SK_Y2_STOPC_TXSTAT:
                   1813:                        if (sc_if0)
                   1814:                                msk_txeof(sc_if0);
                   1815:                        if (sc_if1)
                   1816:                                msk_txeof(sc_if1);
                   1817:                        break;
                   1818:                default:
                   1819:                        printf("opcode=0x%x\n", cur_st->sk_opcode);
                   1820:                        break;
                   1821:                }
                   1822:                SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
                   1823:
                   1824:                MSK_CDSTSYNC(sc, sc->sk_status_idx,
                   1825:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1826:                cur_st = &sc->sk_status_ring[sc->sk_status_idx];
                   1827:        }
                   1828:
                   1829:        if (status & SK_Y2_IMR_BMU) {
                   1830:                CSR_WRITE_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_IRQ_CLEAR);
                   1831:                claimed = 1;
                   1832:        }
                   1833:
                   1834:        CSR_WRITE_4(sc, SK_Y2_ICR, 2);
                   1835:
                   1836:        if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
                   1837:                msk_start(ifp0);
                   1838:        if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
                   1839:                msk_start(ifp1);
                   1840:
                   1841:        return (claimed);
                   1842: }
                   1843:
                   1844: void
                   1845: msk_init_yukon(struct sk_if_softc *sc_if)
                   1846: {
                   1847:        u_int32_t               v;
                   1848:        u_int16_t               reg;
                   1849:        struct sk_softc         *sc;
                   1850:        int                     i;
                   1851:
                   1852:        sc = sc_if->sk_softc;
                   1853:
                   1854:        DPRINTFN(2, ("msk_init_yukon: start: sk_csr=%#x\n",
                   1855:                     CSR_READ_4(sc_if->sk_softc, SK_CSR)));
                   1856:
                   1857:        DPRINTFN(6, ("msk_init_yukon: 1\n"));
                   1858:
                   1859:        DPRINTFN(3, ("msk_init_yukon: gmac_ctrl=%#x\n",
                   1860:                     SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
                   1861:
                   1862:        DPRINTFN(6, ("msk_init_yukon: 3\n"));
                   1863:
                   1864:        /* unused read of the interrupt source register */
                   1865:        DPRINTFN(6, ("msk_init_yukon: 4\n"));
                   1866:        SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
                   1867:
                   1868:        DPRINTFN(6, ("msk_init_yukon: 4a\n"));
                   1869:        reg = SK_YU_READ_2(sc_if, YUKON_PAR);
                   1870:        DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
                   1871:
                   1872:        /* MIB Counter Clear Mode set */
                   1873:         reg |= YU_PAR_MIB_CLR;
                   1874:        DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg));
                   1875:        DPRINTFN(6, ("msk_init_yukon: 4b\n"));
                   1876:        SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
                   1877:
                   1878:        /* MIB Counter Clear Mode clear */
                   1879:        DPRINTFN(6, ("msk_init_yukon: 5\n"));
                   1880:         reg &= ~YU_PAR_MIB_CLR;
                   1881:        SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
                   1882:
                   1883:        /* receive control reg */
                   1884:        DPRINTFN(6, ("msk_init_yukon: 7\n"));
                   1885:        SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
                   1886:
                   1887:        /* transmit parameter register */
                   1888:        DPRINTFN(6, ("msk_init_yukon: 8\n"));
                   1889:        SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
                   1890:                      YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
                   1891:
                   1892:        /* serial mode register */
                   1893:        DPRINTFN(6, ("msk_init_yukon: 9\n"));
                   1894:        reg = YU_SMR_DATA_BLIND(0x1c) |
                   1895:              YU_SMR_MFL_VLAN |
                   1896:              YU_SMR_IPG_DATA(0x1e);
                   1897:
                   1898:        if (sc->sk_type != SK_YUKON_FE)
                   1899:                reg |= YU_SMR_MFL_JUMBO;
                   1900:
                   1901:        SK_YU_WRITE_2(sc_if, YUKON_SMR, reg);
                   1902:
                   1903:        DPRINTFN(6, ("msk_init_yukon: 10\n"));
                   1904:        /* Setup Yukon's address */
                   1905:        for (i = 0; i < 3; i++) {
                   1906:                /* Write Source Address 1 (unicast filter) */
                   1907:                SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
                   1908:                              sc_if->arpcom.ac_enaddr[i * 2] |
                   1909:                              sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8);
                   1910:        }
                   1911:
                   1912:        for (i = 0; i < 3; i++) {
                   1913:                reg = sk_win_read_2(sc_if->sk_softc,
                   1914:                                    SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
                   1915:                SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
                   1916:        }
                   1917:
                   1918:        /* Set promiscuous mode */
                   1919:        msk_setpromisc(sc_if);
                   1920:
                   1921:        /* Set multicast filter */
                   1922:        DPRINTFN(6, ("msk_init_yukon: 11\n"));
                   1923:        msk_setmulti(sc_if);
                   1924:
                   1925:        /* enable interrupt mask for counter overflows */
                   1926:        DPRINTFN(6, ("msk_init_yukon: 12\n"));
                   1927:        SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
                   1928:        SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
                   1929:        SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
                   1930:
                   1931:        /* Configure RX MAC FIFO Flush Mask */
                   1932:        v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR |
                   1933:            YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT |
                   1934:            YU_RXSTAT_JABBER;
                   1935:        SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v);
                   1936:
                   1937:        /* Configure RX MAC FIFO */
                   1938:        SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
                   1939:        SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON |
                   1940:            SK_RFCTL_FIFO_FLUSH_ON);
                   1941:
                   1942:        /* Increase flush threshould to 64 bytes */
                   1943:        SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,
                   1944:            SK_RFCTL_FIFO_THRESHOLD + 1);
                   1945:
                   1946:        /* Configure TX MAC FIFO */
                   1947:        SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
                   1948:        SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
                   1949:
                   1950: #if 1
                   1951:        SK_YU_WRITE_2(sc_if, YUKON_GPCR, YU_GPCR_TXEN | YU_GPCR_RXEN);
                   1952: #endif
                   1953:        DPRINTFN(6, ("msk_init_yukon: end\n"));
                   1954: }
                   1955:
                   1956: /*
                   1957:  * Note that to properly initialize any part of the GEnesis chip,
                   1958:  * you first have to take it out of reset mode.
                   1959:  */
                   1960: void
                   1961: msk_init(void *xsc_if)
                   1962: {
                   1963:        struct sk_if_softc      *sc_if = xsc_if;
                   1964:        struct sk_softc         *sc = sc_if->sk_softc;
                   1965:        struct ifnet            *ifp = &sc_if->arpcom.ac_if;
                   1966:        struct mii_data         *mii = &sc_if->sk_mii;
                   1967:        int                     s;
                   1968:
                   1969:        DPRINTFN(2, ("msk_init\n"));
                   1970:
                   1971:        s = splnet();
                   1972:
                   1973:        /* Cancel pending I/O and free all RX/TX buffers. */
                   1974:        msk_stop(sc_if);
                   1975:
                   1976:        /* Configure I2C registers */
                   1977:
                   1978:        /* Configure XMAC(s) */
                   1979:        msk_init_yukon(sc_if);
                   1980:        mii_mediachg(mii);
                   1981:
                   1982:        /* Configure transmit arbiter(s) */
                   1983:        SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON);
                   1984: #if 0
                   1985:            SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
                   1986: #endif
                   1987:
                   1988:        /* Configure RAMbuffers */
                   1989:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
                   1990:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
                   1991:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
                   1992:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
                   1993:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
                   1994:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
                   1995:
                   1996:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_UNRESET);
                   1997:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_STORENFWD_ON);
                   1998:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_START, sc_if->sk_tx_ramstart);
                   1999:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_WR_PTR, sc_if->sk_tx_ramstart);
                   2000:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_RD_PTR, sc_if->sk_tx_ramstart);
                   2001:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_END, sc_if->sk_tx_ramend);
                   2002:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_ON);
                   2003:
                   2004:        /* Configure BMUs */
                   2005:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000016);
                   2006:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000d28);
                   2007:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000080);
                   2008:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_WATERMARK, 0x00000600);
                   2009:
                   2010:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000016);
                   2011:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000d28);
                   2012:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000080);
                   2013:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_WATERMARK, 0x00000600);
                   2014:
                   2015:        /* Make sure the sync transmit queue is disabled. */
                   2016:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET);
                   2017:
                   2018:        /* Init descriptors */
                   2019:        if (msk_init_rx_ring(sc_if) == ENOBUFS) {
                   2020:                printf("%s: initialization failed: no "
                   2021:                    "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
                   2022:                msk_stop(sc_if);
                   2023:                splx(s);
                   2024:                return;
                   2025:        }
                   2026:
                   2027:        if (msk_init_tx_ring(sc_if) == ENOBUFS) {
                   2028:                printf("%s: initialization failed: no "
                   2029:                    "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
                   2030:                msk_stop(sc_if);
                   2031:                splx(s);
                   2032:                return;
                   2033:        }
                   2034:
                   2035:        /* Initialize prefetch engine. */
                   2036:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
                   2037:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000002);
                   2038:        SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_LIDX, MSK_RX_RING_CNT - 1);
                   2039:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRLO,
                   2040:            MSK_RX_RING_ADDR(sc_if, 0));
                   2041:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRHI,
                   2042:            (u_int64_t)MSK_RX_RING_ADDR(sc_if, 0) >> 32);
                   2043:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000008);
                   2044:        SK_IF_READ_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR);
                   2045:
                   2046:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
                   2047:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000002);
                   2048:        SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_LIDX, MSK_TX_RING_CNT - 1);
                   2049:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRLO,
                   2050:            MSK_TX_RING_ADDR(sc_if, 0));
                   2051:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRHI,
                   2052:            (u_int64_t)MSK_TX_RING_ADDR(sc_if, 0) >> 32);
                   2053:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000008);
                   2054:        SK_IF_READ_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR);
                   2055:
                   2056:        SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
                   2057:            sc_if->sk_cdata.sk_rx_prod);
                   2058:
                   2059:        /* Configure interrupt handling */
                   2060:        if (sc_if->sk_port == SK_PORT_A)
                   2061:                sc->sk_intrmask |= SK_Y2_INTRS1;
                   2062:        else
                   2063:                sc->sk_intrmask |= SK_Y2_INTRS2;
                   2064:        sc->sk_intrmask |= SK_Y2_IMR_BMU;
                   2065:        CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
                   2066:
                   2067:        ifp->if_flags |= IFF_RUNNING;
                   2068:        ifp->if_flags &= ~IFF_OACTIVE;
                   2069:
                   2070:        timeout_add(&sc_if->sk_tick_ch, hz);
                   2071:
                   2072:        splx(s);
                   2073: }
                   2074:
                   2075: void
                   2076: msk_stop(struct sk_if_softc *sc_if)
                   2077: {
                   2078:        struct sk_softc         *sc = sc_if->sk_softc;
                   2079:        struct ifnet            *ifp = &sc_if->arpcom.ac_if;
                   2080:        struct sk_txmap_entry   *dma;
                   2081:        int                     i;
                   2082:
                   2083:        DPRINTFN(2, ("msk_stop\n"));
                   2084:
                   2085:        timeout_del(&sc_if->sk_tick_ch);
                   2086:
                   2087:        ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
                   2088:
                   2089:        /* Stop transfer of Tx descriptors */
                   2090:
                   2091:        /* Stop transfer of Rx descriptors */
                   2092:
                   2093:        /* Turn off various components of this interface. */
                   2094:        SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
                   2095:        SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
                   2096:        SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
                   2097:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
                   2098:        SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
                   2099:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE);
                   2100:        SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
                   2101:        SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
                   2102:        SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
                   2103:        SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP);
                   2104:        SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
                   2105:        SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
                   2106:
                   2107:        SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
                   2108:        SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
                   2109:
                   2110:        /* Disable interrupts */
                   2111:        if (sc_if->sk_port == SK_PORT_A)
                   2112:                sc->sk_intrmask &= ~SK_Y2_INTRS1;
                   2113:        else
                   2114:                sc->sk_intrmask &= ~SK_Y2_INTRS2;
                   2115:        CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
                   2116:
                   2117:        SK_XM_READ_2(sc_if, XM_ISR);
                   2118:        SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
                   2119:
                   2120:        /* Free RX and TX mbufs still in the queues. */
                   2121:        for (i = 0; i < MSK_RX_RING_CNT; i++) {
                   2122:                if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) {
                   2123:                        m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf);
                   2124:                        sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
                   2125:                }
                   2126:        }
                   2127:
                   2128:        for (i = 0; i < MSK_TX_RING_CNT; i++) {
                   2129:                if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
                   2130:                        m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
                   2131:                        sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
                   2132:                        SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head,
                   2133:                            sc_if->sk_cdata.sk_tx_map[i], link);
                   2134:                        sc_if->sk_cdata.sk_tx_map[i] = 0;
                   2135:                }
                   2136:        }
                   2137:
                   2138:        while ((dma = SIMPLEQ_FIRST(&sc_if->sk_txmap_head))) {
                   2139:                SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
                   2140:                bus_dmamap_destroy(sc->sc_dmatag, dma->dmamap);
                   2141:                free(dma, M_DEVBUF);
                   2142:        }
                   2143: }
                   2144:
                   2145: struct cfattach mskc_ca = {
                   2146:        sizeof(struct sk_softc), mskc_probe, mskc_attach,
                   2147: };
                   2148:
                   2149: struct cfdriver mskc_cd = {
                   2150:        0, "mskc", DV_DULL
                   2151: };
                   2152:
                   2153: struct cfattach msk_ca = {
                   2154:        sizeof(struct sk_if_softc), msk_probe, msk_attach,
                   2155: };
                   2156:
                   2157: struct cfdriver msk_cd = {
                   2158:        0, "msk", DV_IFNET
                   2159: };
                   2160:
                   2161: #ifdef MSK_DEBUG
                   2162: void
                   2163: msk_dump_txdesc(struct msk_tx_desc *le, int idx)
                   2164: {
                   2165: #define DESC_PRINT(X)                                  \
                   2166:        if (X)                                  \
                   2167:                printf("txdesc[%d]." #X "=%#x\n",       \
                   2168:                       idx, X);
                   2169:
                   2170:        DESC_PRINT(letoh32(le->sk_addr));
                   2171:        DESC_PRINT(letoh16(le->sk_len));
                   2172:        DESC_PRINT(le->sk_ctl);
                   2173:        DESC_PRINT(le->sk_opcode);
                   2174: #undef DESC_PRINT
                   2175: }
                   2176:
                   2177: void
                   2178: msk_dump_bytes(const char *data, int len)
                   2179: {
                   2180:        int c, i, j;
                   2181:
                   2182:        for (i = 0; i < len; i += 16) {
                   2183:                printf("%08x  ", i);
                   2184:                c = len - i;
                   2185:                if (c > 16) c = 16;
                   2186:
                   2187:                for (j = 0; j < c; j++) {
                   2188:                        printf("%02x ", data[i + j] & 0xff);
                   2189:                        if ((j & 0xf) == 7 && j > 0)
                   2190:                                printf(" ");
                   2191:                }
                   2192:
                   2193:                for (; j < 16; j++)
                   2194:                        printf("   ");
                   2195:                printf("  ");
                   2196:
                   2197:                for (j = 0; j < c; j++) {
                   2198:                        int ch = data[i + j] & 0xff;
                   2199:                        printf("%c", ' ' <= ch && ch <= '~' ? ch : ' ');
                   2200:                }
                   2201:
                   2202:                printf("\n");
                   2203:
                   2204:                if (c < 16)
                   2205:                        break;
                   2206:        }
                   2207: }
                   2208:
                   2209: void
                   2210: msk_dump_mbuf(struct mbuf *m)
                   2211: {
                   2212:        int count = m->m_pkthdr.len;
                   2213:
                   2214:        printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdr.len);
                   2215:
                   2216:        while (count > 0 && m) {
                   2217:                printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
                   2218:                       m, m->m_data, m->m_len);
                   2219:                msk_dump_bytes(mtod(m, char *), m->m_len);
                   2220:
                   2221:                count -= m->m_len;
                   2222:                m = m->m_next;
                   2223:        }
                   2224: }
                   2225: #endif

CVSweb