LCOV - code coverage report
Current view: top level - dev/pci - if_msk.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 952 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 41 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13