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

          Line data    Source code
       1             : /*      $OpenBSD: if_sk.c,v 1.189 2017/06/04 04:29:23 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             : #include <dev/mii/brgphyreg.h>
     116             : 
     117             : #include <dev/pci/pcireg.h>
     118             : #include <dev/pci/pcivar.h>
     119             : #include <dev/pci/pcidevs.h>
     120             : 
     121             : #include <dev/pci/if_skreg.h>
     122             : #include <dev/pci/if_skvar.h>
     123             : 
     124             : int skc_probe(struct device *, void *, void *);
     125             : void skc_attach(struct device *, struct device *self, void *aux);
     126             : int skc_detach(struct device *, int);
     127             : int skc_activate(struct device *, int);
     128             : int sk_probe(struct device *, void *, void *);
     129             : void sk_attach(struct device *, struct device *self, void *aux);
     130             : int sk_detach(struct device *, int);
     131             : int sk_activate(struct device *, int);
     132             : int skcprint(void *, const char *);
     133             : int sk_intr(void *);
     134             : void sk_intr_bcom(struct sk_if_softc *);
     135             : void sk_intr_xmac(struct sk_if_softc *);
     136             : void sk_intr_yukon(struct sk_if_softc *);
     137             : static __inline int sk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
     138             : void sk_rxeof(struct sk_if_softc *);
     139             : void sk_txeof(struct sk_if_softc *);
     140             : int sk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
     141             : void sk_start(struct ifnet *);
     142             : int sk_ioctl(struct ifnet *, u_long, caddr_t);
     143             : void sk_init(void *);
     144             : void sk_init_xmac(struct sk_if_softc *);
     145             : void sk_init_yukon(struct sk_if_softc *);
     146             : void sk_stop(struct sk_if_softc *, int softonly);
     147             : void sk_watchdog(struct ifnet *);
     148             : int sk_ifmedia_upd(struct ifnet *);
     149             : void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
     150             : void skc_reset(struct sk_softc *);
     151             : int sk_newbuf(struct sk_if_softc *);
     152             : int sk_reset(struct sk_if_softc *);
     153             : int sk_init_rx_ring(struct sk_if_softc *);
     154             : void sk_fill_rx_ring(struct sk_if_softc *);
     155             : int sk_init_tx_ring(struct sk_if_softc *);
     156             : 
     157             : int sk_xmac_miibus_readreg(struct device *, int, int);
     158             : void sk_xmac_miibus_writereg(struct device *, int, int, int);
     159             : void sk_xmac_miibus_statchg(struct device *);
     160             : 
     161             : int sk_marv_miibus_readreg(struct device *, int, int);
     162             : void sk_marv_miibus_writereg(struct device *, int, int, int);
     163             : void sk_marv_miibus_statchg(struct device *);
     164             : 
     165             : void sk_setfilt(struct sk_if_softc *, caddr_t, int);
     166             : void sk_iff(struct sk_if_softc *);
     167             : void sk_iff_xmac(struct sk_if_softc *);
     168             : void sk_iff_yukon(struct sk_if_softc *);
     169             : 
     170             : void sk_tick(void *);
     171             : void sk_yukon_tick(void *);
     172             : 
     173             : #ifdef SK_DEBUG
     174             : #define DPRINTF(x)      if (skdebug) printf x
     175             : #define DPRINTFN(n,x)   if (skdebug >= (n)) printf x
     176             : int     skdebug = 0;
     177             : 
     178             : void sk_dump_txdesc(struct sk_tx_desc *, int);
     179             : void sk_dump_mbuf(struct mbuf *);
     180             : void sk_dump_bytes(const char *, int);
     181             : #else
     182             : #define DPRINTF(x)
     183             : #define DPRINTFN(n,x)
     184             : #endif
     185             : 
     186             : /* supported device vendors */
     187             : const struct pci_matchid skc_devices[] = {
     188             :         { PCI_VENDOR_3COM,              PCI_PRODUCT_3COM_3C940 },
     189             :         { PCI_VENDOR_3COM,              PCI_PRODUCT_3COM_3C940B },
     190             :         { PCI_VENDOR_CNET,              PCI_PRODUCT_CNET_GIGACARD },
     191             :         { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE530T_A1 },
     192             :         { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DGE530T_B1 },
     193             :         { PCI_VENDOR_LINKSYS,           PCI_PRODUCT_LINKSYS_EG1064 },
     194             :         { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON },
     195             :         { PCI_VENDOR_MARVELL,           PCI_PRODUCT_MARVELL_YUKON_BELKIN },
     196             :         { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK98XX },
     197             :         { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK98XX2 },
     198             :         { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK9821 },
     199             :         { PCI_VENDOR_SCHNEIDERKOCH,     PCI_PRODUCT_SCHNEIDERKOCH_SK9843 }
     200             : };
     201             : 
     202             : #define SK_LINKSYS_EG1032_SUBID 0x00151737
     203             : 
     204             : static inline u_int32_t
     205           0 : sk_win_read_4(struct sk_softc *sc, u_int32_t reg)
     206             : {
     207           0 :         return CSR_READ_4(sc, reg);
     208             : }
     209             : 
     210             : static inline u_int16_t
     211           0 : sk_win_read_2(struct sk_softc *sc, u_int32_t reg)
     212             : {
     213           0 :         return CSR_READ_2(sc, reg);
     214             : }
     215             : 
     216             : static inline u_int8_t
     217           0 : sk_win_read_1(struct sk_softc *sc, u_int32_t reg)
     218             : {
     219           0 :         return CSR_READ_1(sc, reg);
     220             : }
     221             : 
     222             : static inline void
     223           0 : sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x)
     224             : {
     225           0 :         CSR_WRITE_4(sc, reg, x);
     226           0 : }
     227             : 
     228             : static inline void
     229           0 : sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x)
     230             : {
     231           0 :         CSR_WRITE_2(sc, reg, x);
     232           0 : }
     233             : 
     234             : static inline void
     235           0 : sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x)
     236             : {
     237           0 :         CSR_WRITE_1(sc, reg, x);
     238           0 : }
     239             : 
     240             : int
     241           0 : sk_xmac_miibus_readreg(struct device *dev, int phy, int reg)
     242             : {
     243           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
     244             :         int i;
     245             : 
     246             :         DPRINTFN(9, ("sk_xmac_miibus_readreg\n"));
     247             : 
     248           0 :         if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0)
     249           0 :                 return (0);
     250             : 
     251           0 :         SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
     252           0 :         SK_XM_READ_2(sc_if, XM_PHY_DATA);
     253           0 :         if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
     254           0 :                 for (i = 0; i < SK_TIMEOUT; i++) {
     255           0 :                         DELAY(1);
     256           0 :                         if (SK_XM_READ_2(sc_if, XM_MMUCMD) &
     257             :                             XM_MMUCMD_PHYDATARDY)
     258             :                                 break;
     259             :                 }
     260             : 
     261           0 :                 if (i == SK_TIMEOUT) {
     262           0 :                         printf("%s: phy failed to come ready\n",
     263           0 :                             sc_if->sk_dev.dv_xname);
     264           0 :                         return (0);
     265             :                 }
     266             :         }
     267           0 :         DELAY(1);
     268           0 :         return (SK_XM_READ_2(sc_if, XM_PHY_DATA));
     269           0 : }
     270             : 
     271             : void
     272           0 : sk_xmac_miibus_writereg(struct device *dev, int phy, int reg, int val)
     273             : {
     274           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
     275             :         int i;
     276             : 
     277             :         DPRINTFN(9, ("sk_xmac_miibus_writereg\n"));
     278             : 
     279           0 :         SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
     280           0 :         for (i = 0; i < SK_TIMEOUT; i++) {
     281           0 :                 if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
     282             :                         break;
     283             :         }
     284             : 
     285           0 :         if (i == SK_TIMEOUT) {
     286           0 :                 printf("%s: phy failed to come ready\n",
     287           0 :                     sc_if->sk_dev.dv_xname);
     288           0 :                 return;
     289             :         }
     290             : 
     291           0 :         SK_XM_WRITE_2(sc_if, XM_PHY_DATA, val);
     292           0 :         for (i = 0; i < SK_TIMEOUT; i++) {
     293           0 :                 DELAY(1);
     294           0 :                 if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY))
     295             :                         break;
     296             :         }
     297             : 
     298           0 :         if (i == SK_TIMEOUT)
     299           0 :                 printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
     300           0 : }
     301             : 
     302             : void
     303           0 : sk_xmac_miibus_statchg(struct device *dev)
     304             : {
     305           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
     306           0 :         struct mii_data *mii = &sc_if->sk_mii;
     307             : 
     308             :         DPRINTFN(9, ("sk_xmac_miibus_statchg\n"));
     309             : 
     310             :         /*
     311             :          * If this is a GMII PHY, manually set the XMAC's
     312             :          * duplex mode accordingly.
     313             :          */
     314           0 :         if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
     315           0 :                 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
     316           0 :                         SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
     317             :                 else
     318           0 :                         SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
     319             :         }
     320           0 : }
     321             : 
     322             : int
     323           0 : sk_marv_miibus_readreg(struct device *dev, int phy, int reg)
     324             : {
     325           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
     326             :         u_int16_t val;
     327             :         int i;
     328             : 
     329           0 :         if (phy != 0 ||
     330           0 :             (sc_if->sk_phytype != SK_PHYTYPE_MARV_COPPER &&
     331           0 :              sc_if->sk_phytype != SK_PHYTYPE_MARV_FIBER)) {
     332             :                 DPRINTFN(9, ("sk_marv_miibus_readreg (skip) phy=%d, reg=%#x\n",
     333             :                     phy, reg));
     334           0 :                 return (0);
     335             :         }
     336             : 
     337           0 :         SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
     338             :             YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ);
     339             : 
     340           0 :         for (i = 0; i < SK_TIMEOUT; i++) {
     341           0 :                 DELAY(1);
     342           0 :                 val = SK_YU_READ_2(sc_if, YUKON_SMICR);
     343           0 :                 if (val & YU_SMICR_READ_VALID)
     344             :                         break;
     345             :         }
     346             : 
     347           0 :         if (i == SK_TIMEOUT) {
     348           0 :                 printf("%s: phy failed to come ready\n",
     349           0 :                     sc_if->sk_dev.dv_xname);
     350           0 :                 return (0);
     351             :         }
     352             : 
     353             :         DPRINTFN(9, ("sk_marv_miibus_readreg: i=%d, timeout=%d\n", i,
     354             :             SK_TIMEOUT));
     355             : 
     356           0 :         val = SK_YU_READ_2(sc_if, YUKON_SMIDR);
     357             : 
     358             :         DPRINTFN(9, ("sk_marv_miibus_readreg phy=%d, reg=%#x, val=%#x\n",
     359             :             phy, reg, val));
     360             : 
     361           0 :         return (val);
     362           0 : }
     363             : 
     364             : void
     365           0 : sk_marv_miibus_writereg(struct device *dev, int phy, int reg, int val)
     366             : {
     367           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)dev;
     368             :         int i;
     369             : 
     370             :         DPRINTFN(9, ("sk_marv_miibus_writereg phy=%d reg=%#x val=%#x\n",
     371             :             phy, reg, val));
     372             : 
     373           0 :         SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val);
     374           0 :         SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |
     375             :             YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE);
     376             : 
     377           0 :         for (i = 0; i < SK_TIMEOUT; i++) {
     378           0 :                 DELAY(1);
     379           0 :                 if (!(SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY))
     380             :                         break;
     381             :         }
     382             : 
     383           0 :         if (i == SK_TIMEOUT)
     384           0 :                 printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname);
     385           0 : }
     386             : 
     387             : void
     388           0 : sk_marv_miibus_statchg(struct device *dev)
     389             : {
     390             :         DPRINTFN(9, ("sk_marv_miibus_statchg: gpcr=%x\n",
     391             :             SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR)));
     392           0 : }
     393             : 
     394             : void
     395           0 : sk_setfilt(struct sk_if_softc *sc_if, caddr_t addr, int slot)
     396             : {
     397           0 :         int base = XM_RXFILT_ENTRY(slot);
     398             : 
     399           0 :         SK_XM_WRITE_2(sc_if, base, letoh16(*(u_int16_t *)(&addr[0])));
     400           0 :         SK_XM_WRITE_2(sc_if, base + 2, letoh16(*(u_int16_t *)(&addr[2])));
     401           0 :         SK_XM_WRITE_2(sc_if, base + 4, letoh16(*(u_int16_t *)(&addr[4])));
     402           0 : }
     403             : 
     404             : void
     405           0 : sk_iff(struct sk_if_softc *sc_if)
     406             : {
     407           0 :         struct sk_softc *sc = sc_if->sk_softc;
     408             : 
     409           0 :         if (SK_IS_GENESIS(sc))
     410           0 :                 sk_iff_xmac(sc_if);
     411             :         else
     412           0 :                 sk_iff_yukon(sc_if);
     413           0 : }
     414             : 
     415             : void
     416           0 : sk_iff_xmac(struct sk_if_softc *sc_if)
     417             : {
     418           0 :         struct ifnet *ifp = &sc_if->arpcom.ac_if;
     419             :         struct arpcom *ac = &sc_if->arpcom;
     420             :         struct ether_multi *enm;
     421             :         struct ether_multistep step;
     422             :         u_int32_t reg, hashes[2];
     423           0 :         u_int8_t dummy[] = { 0, 0, 0, 0, 0 ,0 };
     424             :         int h, i;
     425             : 
     426           0 :         reg = SK_XM_READ_4(sc_if, XM_MODE);
     427           0 :         reg &= ~(XM_MODE_RX_NOBROAD | XM_MODE_RX_PROMISC | XM_MODE_RX_USE_HASH |
     428             :             XM_MODE_RX_USE_PERFECT | XM_MODE_RX_USE_STATION);
     429           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
     430             : 
     431             :         /*
     432             :          * Always accept frames destined to our station address.
     433             :          */
     434           0 :         reg |= XM_MODE_RX_USE_STATION;
     435             : 
     436             :         /* don't use perfect filter. */
     437           0 :         for (i = 1; i < XM_RXFILT_MAX; i++)
     438           0 :                 sk_setfilt(sc_if, (caddr_t)&dummy, i);
     439             : 
     440           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
     441           0 :                 ifp->if_flags |= IFF_ALLMULTI;
     442           0 :                 if (ifp->if_flags & IFF_PROMISC)
     443           0 :                         reg |= XM_MODE_RX_PROMISC;
     444             :                 else
     445           0 :                         reg |= XM_MODE_RX_USE_HASH;
     446             :                 hashes[0] = hashes[1] = 0xFFFFFFFF;
     447           0 :         } else {
     448           0 :                 reg |= XM_MODE_RX_USE_HASH;
     449             :                 /* Program new filter. */
     450             :                 bzero(hashes, sizeof(hashes));
     451             : 
     452           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
     453           0 :                 while (enm != NULL) {
     454           0 :                         h = ether_crc32_le(enm->enm_addrlo,
     455           0 :                             ETHER_ADDR_LEN) & ((1 << SK_HASH_BITS) - 1);
     456             : 
     457           0 :                         if (h < 32)
     458           0 :                                 hashes[0] |= (1 << h);
     459             :                         else
     460           0 :                                 hashes[1] |= (1 << (h - 32));
     461             : 
     462           0 :                         ETHER_NEXT_MULTI(step, enm);
     463             :                 }
     464             :         }
     465             : 
     466           0 :         SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]);
     467           0 :         SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
     468           0 :         SK_XM_WRITE_4(sc_if, XM_MODE, reg);
     469           0 : }
     470             : 
     471             : void
     472           0 : sk_iff_yukon(struct sk_if_softc *sc_if)
     473             : {
     474           0 :         struct ifnet *ifp = &sc_if->arpcom.ac_if;
     475             :         struct arpcom *ac = &sc_if->arpcom;
     476             :         struct ether_multi *enm;
     477             :         struct ether_multistep step;
     478             :         u_int32_t hashes[2];
     479             :         u_int16_t rcr;
     480             :         int h;
     481             : 
     482           0 :         rcr = SK_YU_READ_2(sc_if, YUKON_RCR);
     483           0 :         rcr &= ~(YU_RCR_MUFLEN | YU_RCR_UFLEN);
     484           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
     485             : 
     486             :         /*
     487             :          * Always accept frames destined to our station address.
     488             :          */
     489           0 :         rcr |= YU_RCR_UFLEN;
     490             : 
     491           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
     492           0 :                 ifp->if_flags |= IFF_ALLMULTI;
     493           0 :                 if (ifp->if_flags & IFF_PROMISC)
     494           0 :                         rcr &= ~YU_RCR_UFLEN;
     495             :                 else
     496           0 :                         rcr |= YU_RCR_MUFLEN;
     497             :                 hashes[0] = hashes[1] = 0xFFFFFFFF;
     498           0 :         } else {
     499           0 :                 rcr |= YU_RCR_MUFLEN;
     500             :                 /* Program new filter. */
     501             :                 bzero(hashes, sizeof(hashes));
     502             : 
     503           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
     504           0 :                 while (enm != NULL) {
     505           0 :                         h = ether_crc32_be(enm->enm_addrlo,
     506           0 :                             ETHER_ADDR_LEN) & ((1 << SK_HASH_BITS) - 1);
     507             : 
     508           0 :                         if (h < 32)
     509           0 :                                 hashes[0] |= (1 << h);
     510             :                         else
     511           0 :                                 hashes[1] |= (1 << (h - 32));
     512             : 
     513           0 :                         ETHER_NEXT_MULTI(step, enm);
     514             :                 }
     515             :         }
     516             : 
     517           0 :         SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
     518           0 :         SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
     519           0 :         SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
     520           0 :         SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff);
     521           0 :         SK_YU_WRITE_2(sc_if, YUKON_RCR, rcr);
     522           0 : }
     523             : 
     524             : int
     525           0 : sk_init_rx_ring(struct sk_if_softc *sc_if)
     526             : {
     527           0 :         struct sk_chain_data    *cd = &sc_if->sk_cdata;
     528           0 :         struct sk_ring_data     *rd = sc_if->sk_rdata;
     529             :         int                     i, nexti;
     530             : 
     531           0 :         bzero(rd->sk_rx_ring, sizeof(struct sk_rx_desc) * SK_RX_RING_CNT);
     532             : 
     533           0 :         for (i = 0; i < SK_RX_RING_CNT; i++) {
     534           0 :                 cd->sk_rx_chain[i].sk_desc = &rd->sk_rx_ring[i];
     535           0 :                 if (i == (SK_RX_RING_CNT - 1))
     536           0 :                         nexti = 0;
     537             :                 else
     538           0 :                         nexti = i + 1;
     539           0 :                 cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
     540           0 :                 htolem32(&rd->sk_rx_ring[i].sk_next,
     541             :                     SK_RX_RING_ADDR(sc_if, nexti));
     542             :         }
     543             : 
     544           0 :         sc_if->sk_cdata.sk_rx_prod = 0;
     545           0 :         sc_if->sk_cdata.sk_rx_cons = 0;
     546             : 
     547           0 :         if_rxr_init(&sc_if->sk_cdata.sk_rx_ring, 2, SK_RX_RING_CNT);
     548             : 
     549           0 :         sk_fill_rx_ring(sc_if);
     550             : 
     551           0 :         return (0);
     552             : }
     553             : 
     554             : void
     555           0 : sk_fill_rx_ring(struct sk_if_softc *sc_if)
     556             : {
     557           0 :         struct if_rxring *rxr = &sc_if->sk_cdata.sk_rx_ring;
     558             :         u_int slots;
     559             : 
     560           0 :         for (slots = if_rxr_get(rxr, SK_RX_RING_CNT); slots > 0; slots--) {
     561           0 :                 if (sk_newbuf(sc_if) == ENOBUFS)
     562             :                         break;
     563             :         }
     564           0 :         if_rxr_put(rxr, slots);
     565           0 : }
     566             : 
     567             : int
     568           0 : sk_init_tx_ring(struct sk_if_softc *sc_if)
     569             : {
     570           0 :         struct sk_softc         *sc = sc_if->sk_softc;
     571           0 :         struct sk_chain_data    *cd = &sc_if->sk_cdata;
     572           0 :         struct sk_ring_data     *rd = sc_if->sk_rdata;
     573           0 :         bus_dmamap_t            dmamap;
     574             :         struct sk_txmap_entry   *entry;
     575             :         int                     i, nexti;
     576             : 
     577           0 :         bzero(sc_if->sk_rdata->sk_tx_ring,
     578             :             sizeof(struct sk_tx_desc) * SK_TX_RING_CNT);
     579             : 
     580           0 :         SIMPLEQ_INIT(&sc_if->sk_txmap_head);
     581           0 :         for (i = 0; i < SK_TX_RING_CNT; i++) {
     582           0 :                 cd->sk_tx_chain[i].sk_desc = &rd->sk_tx_ring[i];
     583           0 :                 if (i == (SK_TX_RING_CNT - 1))
     584           0 :                         nexti = 0;
     585             :                 else
     586           0 :                         nexti = i + 1;
     587           0 :                 cd->sk_tx_chain[i].sk_next = &cd->sk_tx_chain[nexti];
     588           0 :                 htolem32(&rd->sk_tx_ring[i].sk_next,
     589             :                     SK_TX_RING_ADDR(sc_if, nexti));
     590             : 
     591           0 :                 if (bus_dmamap_create(sc->sc_dmatag, SK_JLEN, SK_NTXSEG,
     592             :                    SK_JLEN, 0, BUS_DMA_NOWAIT, &dmamap))
     593           0 :                         return (ENOBUFS);
     594             : 
     595           0 :                 entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT);
     596           0 :                 if (!entry) {
     597           0 :                         bus_dmamap_destroy(sc->sc_dmatag, dmamap);
     598           0 :                         return (ENOBUFS);
     599             :                 }
     600           0 :                 entry->dmamap = dmamap;
     601           0 :                 SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
     602             :         }
     603             : 
     604           0 :         sc_if->sk_cdata.sk_tx_prod = 0;
     605           0 :         sc_if->sk_cdata.sk_tx_cons = 0;
     606           0 :         sc_if->sk_cdata.sk_tx_cnt = 0;
     607             : 
     608           0 :         SK_CDTXSYNC(sc_if, 0, SK_TX_RING_CNT,
     609             :             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     610             : 
     611           0 :         return (0);
     612           0 : }
     613             : 
     614             : int
     615           0 : sk_newbuf(struct sk_if_softc *sc_if)
     616             : {
     617             :         struct mbuf             *m;
     618             :         struct sk_chain         *c;
     619             :         struct sk_rx_desc       *r;
     620             :         bus_dmamap_t            dmamap;
     621             :         u_int                   prod;
     622             :         int                     error;
     623             :         uint64_t                dva;
     624             : 
     625           0 :         m = MCLGETI(NULL, M_DONTWAIT, NULL, SK_JLEN);
     626           0 :         if (m == NULL)
     627           0 :                 return (ENOBUFS);
     628             : 
     629           0 :         m->m_len = m->m_pkthdr.len = SK_JLEN;
     630           0 :         m_adj(m, ETHER_ALIGN);
     631             : 
     632           0 :         prod = sc_if->sk_cdata.sk_rx_prod;
     633           0 :         dmamap = sc_if->sk_cdata.sk_rx_map[prod];
     634             : 
     635           0 :         error = bus_dmamap_load_mbuf(sc_if->sk_softc->sc_dmatag, dmamap, m,
     636             :             BUS_DMA_READ|BUS_DMA_NOWAIT);
     637           0 :         if (error) {
     638           0 :                 m_freem(m);
     639           0 :                 return (ENOBUFS);
     640             :         }
     641             : 
     642           0 :         bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
     643             :             dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
     644             : 
     645           0 :         c = &sc_if->sk_cdata.sk_rx_chain[prod];
     646           0 :         c->sk_mbuf = m;
     647             : 
     648           0 :         r = c->sk_desc;
     649           0 :         dva = dmamap->dm_segs[0].ds_addr;
     650           0 :         htolem32(&r->sk_data_lo, dva);
     651           0 :         htolem32(&r->sk_data_hi, dva >> 32);
     652           0 :         htolem32(&r->sk_ctl, dmamap->dm_segs[0].ds_len | SK_RXSTAT);
     653             : 
     654           0 :         SK_CDRXSYNC(sc_if, prod, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
     655             : 
     656           0 :         SK_INC(prod, SK_RX_RING_CNT);
     657           0 :         sc_if->sk_cdata.sk_rx_prod = prod;
     658             : 
     659           0 :         return (0);
     660           0 : }
     661             : 
     662             : /*
     663             :  * Set media options.
     664             :  */
     665             : int
     666           0 : sk_ifmedia_upd(struct ifnet *ifp)
     667             : {
     668           0 :         struct sk_if_softc *sc_if = ifp->if_softc;
     669             : 
     670           0 :         mii_mediachg(&sc_if->sk_mii);
     671           0 :         return (0);
     672             : }
     673             : 
     674             : /*
     675             :  * Report current media status.
     676             :  */
     677             : void
     678           0 : sk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
     679             : {
     680           0 :         struct sk_if_softc *sc_if = ifp->if_softc;
     681             : 
     682           0 :         mii_pollstat(&sc_if->sk_mii);
     683           0 :         ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
     684           0 :         ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
     685           0 : }
     686             : 
     687             : int
     688           0 : sk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
     689             : {
     690           0 :         struct sk_if_softc *sc_if = ifp->if_softc;
     691           0 :         struct ifreq *ifr = (struct ifreq *) data;
     692             :         struct mii_data *mii;
     693             :         int s, error = 0;
     694             : 
     695           0 :         s = splnet();
     696             : 
     697           0 :         switch(command) {
     698             :         case SIOCSIFADDR:
     699           0 :                 ifp->if_flags |= IFF_UP;
     700           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
     701           0 :                         sk_init(sc_if);
     702             :                 break;
     703             : 
     704             :         case SIOCSIFFLAGS:
     705           0 :                 if (ifp->if_flags & IFF_UP) {
     706           0 :                         if (ifp->if_flags & IFF_RUNNING)
     707           0 :                                 error = ENETRESET;
     708             :                         else
     709           0 :                                 sk_init(sc_if);
     710             :                 } else {
     711           0 :                         if (ifp->if_flags & IFF_RUNNING)
     712           0 :                                 sk_stop(sc_if, 0);
     713             :                 }
     714             :                 break;
     715             : 
     716             :         case SIOCGIFMEDIA:
     717             :         case SIOCSIFMEDIA:
     718           0 :                 mii = &sc_if->sk_mii;
     719           0 :                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
     720           0 :                 break;
     721             : 
     722             :         case SIOCGIFRXR:
     723           0 :                 error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
     724           0 :                     NULL, SK_JLEN, &sc_if->sk_cdata.sk_rx_ring);
     725             : 
     726           0 :                 break;
     727             : 
     728             :         default:
     729           0 :                 error = ether_ioctl(ifp, &sc_if->arpcom, command, data);
     730           0 :         }
     731             : 
     732           0 :         if (error == ENETRESET) {
     733           0 :                 if (ifp->if_flags & IFF_RUNNING)
     734           0 :                         sk_iff(sc_if);
     735             :                 error = 0;
     736           0 :         }
     737             : 
     738           0 :         splx(s);
     739           0 :         return (error);
     740             : }
     741             : 
     742             : /*
     743             :  * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device
     744             :  * IDs against our list and return a device name if we find a match.
     745             :  */
     746             : int
     747           0 : skc_probe(struct device *parent, void *match, void *aux)
     748             : {
     749           0 :         struct pci_attach_args *pa = aux;
     750           0 :         pci_chipset_tag_t pc = pa->pa_pc;
     751             :         pcireg_t subid;
     752             : 
     753           0 :         subid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
     754             : 
     755           0 :         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LINKSYS &&
     756           0 :             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032 &&
     757           0 :             subid == SK_LINKSYS_EG1032_SUBID)
     758           0 :                 return (1);
     759             : 
     760           0 :         return (pci_matchbyid((struct pci_attach_args *)aux, skc_devices,
     761             :             nitems(skc_devices)));
     762           0 : }
     763             : 
     764             : /*
     765             :  * Force the GEnesis into reset, then bring it out of reset.
     766             :  */
     767             : void
     768           0 : skc_reset(struct sk_softc *sc)
     769             : {
     770             :         u_int32_t imtimer_ticks;
     771             : 
     772             :         DPRINTFN(2, ("skc_reset\n"));
     773             : 
     774           0 :         CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
     775           0 :         CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
     776           0 :         if (SK_IS_YUKON(sc))
     777           0 :                 CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
     778             : 
     779           0 :         DELAY(1000);
     780           0 :         CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
     781           0 :         DELAY(2);
     782           0 :         CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
     783           0 :         if (SK_IS_YUKON(sc))
     784           0 :                 CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
     785             : 
     786             :         DPRINTFN(2, ("sk_reset: sk_csr=%x\n", CSR_READ_2(sc, SK_CSR)));
     787             :         DPRINTFN(2, ("sk_reset: sk_link_ctrl=%x\n",
     788             :             CSR_READ_2(sc, SK_LINK_CTRL)));
     789             : 
     790           0 :         if (SK_IS_GENESIS(sc)) {
     791             :                 /* Configure packet arbiter */
     792           0 :                 sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET);
     793           0 :                 sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT);
     794           0 :                 sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT);
     795           0 :                 sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT);
     796           0 :                 sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT);
     797           0 :         }
     798             : 
     799             :         /* Enable RAM interface */
     800           0 :         sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET);
     801             : 
     802             :         /*
     803             :          * Configure interrupt moderation. The moderation timer
     804             :          * defers interrupts specified in the interrupt moderation
     805             :          * timer mask based on the timeout specified in the interrupt
     806             :          * moderation timer init register. Each bit in the timer
     807             :          * register represents one tick, so to specify a timeout in
     808             :          * microseconds, we have to multiply by the correct number of
     809             :          * ticks-per-microsecond.
     810             :          */
     811           0 :         switch (sc->sk_type) {
     812             :         case SK_GENESIS:
     813             :                 imtimer_ticks = SK_IMTIMER_TICKS_GENESIS;
     814           0 :                 break;
     815             :         default:
     816             :                 imtimer_ticks = SK_IMTIMER_TICKS_YUKON;
     817           0 :                 break;
     818             :         }
     819           0 :         sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(100));
     820           0 :         sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF|
     821             :             SK_ISR_RX1_EOF|SK_ISR_RX2_EOF);
     822           0 :         sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START);
     823           0 : }
     824             : 
     825             : int
     826           0 : sk_probe(struct device *parent, void *match, void *aux)
     827             : {
     828           0 :         struct skc_attach_args *sa = aux;
     829             : 
     830           0 :         if (sa->skc_port != SK_PORT_A && sa->skc_port != SK_PORT_B)
     831           0 :                 return (0);
     832             : 
     833           0 :         switch (sa->skc_type) {
     834             :         case SK_GENESIS:
     835             :         case SK_YUKON:
     836             :         case SK_YUKON_LITE:
     837             :         case SK_YUKON_LP:
     838           0 :                 return (1);
     839             :         }
     840             : 
     841           0 :         return (0);
     842           0 : }
     843             : 
     844             : /*
     845             :  * Each XMAC chip is attached as a separate logical IP interface.
     846             :  * Single port cards will have only one logical interface of course.
     847             :  */
     848             : void
     849           0 : sk_attach(struct device *parent, struct device *self, void *aux)
     850             : {
     851           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *) self;
     852           0 :         struct sk_softc *sc = (struct sk_softc *)parent;
     853           0 :         struct skc_attach_args *sa = aux;
     854             :         struct ifnet *ifp;
     855           0 :         caddr_t kva;
     856             :         int i, error;
     857             : 
     858           0 :         sc_if->sk_port = sa->skc_port;
     859           0 :         sc_if->sk_softc = sc;
     860           0 :         sc->sk_if[sa->skc_port] = sc_if;
     861             : 
     862           0 :         if (sa->skc_port == SK_PORT_A)
     863           0 :                 sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0;
     864           0 :         if (sa->skc_port == SK_PORT_B)
     865           0 :                 sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
     866             : 
     867             :         DPRINTFN(2, ("begin sk_attach: port=%d\n", sc_if->sk_port));
     868             : 
     869             :         /*
     870             :          * Get station address for this interface. Note that
     871             :          * dual port cards actually come with three station
     872             :          * addresses: one for each port, plus an extra. The
     873             :          * extra one is used by the SysKonnect driver software
     874             :          * as a 'virtual' station address for when both ports
     875             :          * are operating in failover mode. Currently we don't
     876             :          * use this extra address.
     877             :          */
     878           0 :         for (i = 0; i < ETHER_ADDR_LEN; i++)
     879           0 :                 sc_if->arpcom.ac_enaddr[i] =
     880           0 :                     sk_win_read_1(sc, SK_MAC0_0 + (sa->skc_port * 8) + i);
     881             : 
     882           0 :         printf(": address %s\n",
     883           0 :             ether_sprintf(sc_if->arpcom.ac_enaddr));
     884             : 
     885             :         /*
     886             :          * Set up RAM buffer addresses. The NIC will have a certain
     887             :          * amount of SRAM on it, somewhere between 512K and 2MB. We
     888             :          * need to divide this up a) between the transmitter and
     889             :          * receiver and b) between the two XMACs, if this is a
     890             :          * dual port NIC. Our algorithm is to divide up the memory
     891             :          * evenly so that everyone gets a fair share.
     892             :          */
     893           0 :         if (sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC) {
     894             :                 u_int32_t               chunk, val;
     895             : 
     896           0 :                 chunk = sc->sk_ramsize / 2;
     897           0 :                 val = sc->sk_rboff / sizeof(u_int64_t);
     898           0 :                 sc_if->sk_rx_ramstart = val;
     899           0 :                 val += (chunk / sizeof(u_int64_t));
     900           0 :                 sc_if->sk_rx_ramend = val - 1;
     901           0 :                 sc_if->sk_tx_ramstart = val;
     902           0 :                 val += (chunk / sizeof(u_int64_t));
     903           0 :                 sc_if->sk_tx_ramend = val - 1;
     904           0 :         } else {
     905             :                 u_int32_t               chunk, val;
     906             : 
     907           0 :                 chunk = sc->sk_ramsize / 4;
     908           0 :                 val = (sc->sk_rboff + (chunk * 2 * sc_if->sk_port)) /
     909             :                     sizeof(u_int64_t);
     910           0 :                 sc_if->sk_rx_ramstart = val;
     911           0 :                 val += (chunk / sizeof(u_int64_t));
     912           0 :                 sc_if->sk_rx_ramend = val - 1;
     913           0 :                 sc_if->sk_tx_ramstart = val;
     914           0 :                 val += (chunk / sizeof(u_int64_t));
     915           0 :                 sc_if->sk_tx_ramend = val - 1;
     916             :         }
     917             : 
     918             :         DPRINTFN(2, ("sk_attach: rx_ramstart=%#x rx_ramend=%#x\n"
     919             :             "           tx_ramstart=%#x tx_ramend=%#x\n",
     920             :             sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend,
     921             :             sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend));
     922             : 
     923             :         /* Read and save PHY type */
     924           0 :         sc_if->sk_phytype = sk_win_read_1(sc, SK_EPROM1) & 0xF;
     925             : 
     926             :         /* Set PHY address */
     927           0 :         if (SK_IS_GENESIS(sc)) {
     928           0 :                 switch (sc_if->sk_phytype) {
     929             :                 case SK_PHYTYPE_XMAC:
     930           0 :                         sc_if->sk_phyaddr = SK_PHYADDR_XMAC;
     931           0 :                         break;
     932             :                 case SK_PHYTYPE_BCOM:
     933           0 :                         sc_if->sk_phyaddr = SK_PHYADDR_BCOM;
     934           0 :                         break;
     935             :                 default:
     936           0 :                         printf("%s: unsupported PHY type: %d\n",
     937           0 :                             sc->sk_dev.dv_xname, sc_if->sk_phytype);
     938           0 :                         return;
     939             :                 }
     940             :         }
     941             : 
     942           0 :         if (SK_IS_YUKON(sc)) {
     943           0 :                 if ((sc_if->sk_phytype < SK_PHYTYPE_MARV_COPPER &&
     944           0 :                     sc->sk_pmd != 'L' && sc->sk_pmd != 'S')) {
     945             :                         /* not initialized, punt */
     946           0 :                         sc_if->sk_phytype = SK_PHYTYPE_MARV_COPPER;
     947             : 
     948           0 :                         sc->sk_coppertype = 1;
     949           0 :                 }
     950             : 
     951           0 :                 sc_if->sk_phyaddr = SK_PHYADDR_MARV;
     952             : 
     953           0 :                 if (!(sc->sk_coppertype))
     954           0 :                         sc_if->sk_phytype = SK_PHYTYPE_MARV_FIBER;
     955             :         }
     956             : 
     957             :         /* Allocate the descriptor queues. */
     958           0 :         if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct sk_ring_data),
     959             :             PAGE_SIZE, 0, &sc_if->sk_ring_seg, 1, &sc_if->sk_ring_nseg,
     960             :             BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
     961           0 :                 printf(": can't alloc rx buffers\n");
     962           0 :                 goto fail;
     963             :         }
     964           0 :         if (bus_dmamem_map(sc->sc_dmatag, &sc_if->sk_ring_seg,
     965             :             sc_if->sk_ring_nseg, sizeof(struct sk_ring_data),
     966             :             &kva, BUS_DMA_NOWAIT)) {
     967           0 :                 printf(": can't map dma buffers (%lu bytes)\n",
     968             :                     (ulong)sizeof(struct sk_ring_data));
     969           0 :                 goto fail_1;
     970             :         }
     971           0 :         if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct sk_ring_data), 1,
     972             :             sizeof(struct sk_ring_data), 0, BUS_DMA_NOWAIT,
     973             :             &sc_if->sk_ring_map)) {
     974           0 :                 printf(": can't create dma map\n");
     975           0 :                 goto fail_2;
     976             :         }
     977           0 :         if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,
     978             :             sizeof(struct sk_ring_data), NULL, BUS_DMA_NOWAIT)) {
     979           0 :                 printf(": can't load dma map\n");
     980           0 :                 goto fail_3;
     981             :         }
     982           0 :         sc_if->sk_rdata = (struct sk_ring_data *)kva;
     983             : 
     984           0 :         for (i = 0; i < SK_RX_RING_CNT; i++) {
     985           0 :                 error = bus_dmamap_create(sc->sc_dmatag, SK_JLEN, 1,
     986             :                     SK_JLEN, 0, 0, &sc_if->sk_cdata.sk_rx_map[i]);
     987           0 :                 if (error != 0) {
     988           0 :                         printf(": unable to create rx DMA map %d, "
     989             :                             "error = %d\n", i, error);
     990             :                         goto fail_4;
     991             :                 }
     992             :         }
     993             : 
     994           0 :         ifp = &sc_if->arpcom.ac_if;
     995           0 :         ifp->if_softc = sc_if;
     996           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     997           0 :         ifp->if_ioctl = sk_ioctl;
     998           0 :         ifp->if_start = sk_start;
     999           0 :         ifp->if_watchdog = sk_watchdog;
    1000           0 :         ifp->if_hardmtu = SK_JUMBO_MTU;
    1001           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1);
    1002           0 :         bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
    1003             : 
    1004           0 :         ifp->if_capabilities = IFCAP_VLAN_MTU;
    1005             : 
    1006           0 :         if (sk_reset(sc_if) == -1) {
    1007           0 :                 printf(": unknown device type %d\n", sc_if->sk_softc->sk_type);
    1008             :                 /* dealloc jumbo on error */
    1009           0 :                 goto fail_3;
    1010             :         }
    1011             : 
    1012             :         DPRINTFN(2, ("sk_attach: 1\n"));
    1013             : 
    1014           0 :         sc_if->sk_mii.mii_ifp = ifp;
    1015           0 :         if (SK_IS_GENESIS(sc)) {
    1016           0 :                 sc_if->sk_mii.mii_readreg = sk_xmac_miibus_readreg;
    1017           0 :                 sc_if->sk_mii.mii_writereg = sk_xmac_miibus_writereg;
    1018           0 :                 sc_if->sk_mii.mii_statchg = sk_xmac_miibus_statchg;
    1019           0 :         } else {
    1020           0 :                 sc_if->sk_mii.mii_readreg = sk_marv_miibus_readreg;
    1021           0 :                 sc_if->sk_mii.mii_writereg = sk_marv_miibus_writereg;
    1022           0 :                 sc_if->sk_mii.mii_statchg = sk_marv_miibus_statchg;
    1023             :         }
    1024             : 
    1025           0 :         ifmedia_init(&sc_if->sk_mii.mii_media, 0,
    1026             :             sk_ifmedia_upd, sk_ifmedia_sts);
    1027           0 :         if (SK_IS_GENESIS(sc)) {
    1028           0 :                 mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
    1029             :                     MII_OFFSET_ANY, 0);
    1030           0 :         } else {
    1031           0 :                 mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
    1032             :                     MII_OFFSET_ANY, MIIF_DOPAUSE);
    1033             :         }
    1034           0 :         if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
    1035           0 :                 printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
    1036           0 :                 ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
    1037             :                             0, NULL);
    1038           0 :                 ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL);
    1039           0 :         } else
    1040           0 :                 ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_AUTO);
    1041             : 
    1042           0 :         if (SK_IS_GENESIS(sc)) {
    1043           0 :                 timeout_set(&sc_if->sk_tick_ch, sk_tick, sc_if);
    1044           0 :                 timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1045           0 :         } else
    1046           0 :                 timeout_set(&sc_if->sk_tick_ch, sk_yukon_tick, sc_if);
    1047             : 
    1048             :         /*
    1049             :          * Call MI attach routines.
    1050             :          */
    1051           0 :         if_attach(ifp);
    1052           0 :         ether_ifattach(ifp);
    1053             : 
    1054             :         DPRINTFN(2, ("sk_attach: end\n"));
    1055           0 :         return;
    1056             : fail_4:
    1057           0 :         for (i = 0; i < SK_RX_RING_CNT; i++) {
    1058           0 :                 if (sc_if->sk_cdata.sk_rx_map[i] == NULL)
    1059             :                         continue;
    1060             : 
    1061           0 :                 bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_cdata.sk_rx_map[i]);
    1062           0 :         }
    1063             : fail_3:
    1064           0 :         bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct sk_ring_data));
    1065             : fail_2:
    1066           0 :         bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
    1067             : fail_1:
    1068           0 :         bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
    1069             : fail:
    1070           0 :         sc->sk_if[sa->skc_port] = NULL;
    1071           0 : }
    1072             : 
    1073             : int
    1074           0 : sk_reset(struct sk_if_softc *sc_if)
    1075             : {
    1076             :         /*
    1077             :          * Do miibus setup.
    1078             :          */
    1079           0 :         switch (sc_if->sk_softc->sk_type) {
    1080             :         case SK_GENESIS:
    1081           0 :                 sk_init_xmac(sc_if);
    1082           0 :                 break;
    1083             :         case SK_YUKON:
    1084             :         case SK_YUKON_LITE:
    1085             :         case SK_YUKON_LP:
    1086           0 :                 sk_init_yukon(sc_if);
    1087           0 :                 break;
    1088             :         default:
    1089           0 :                 return (-1);
    1090             :         }
    1091           0 :         return (0);
    1092           0 : }
    1093             : 
    1094             : int
    1095           0 : sk_detach(struct device *self, int flags)
    1096             : {
    1097           0 :         struct sk_if_softc *sc_if = (struct sk_if_softc *)self;
    1098           0 :         struct sk_softc *sc = sc_if->sk_softc;
    1099           0 :         struct ifnet *ifp= &sc_if->arpcom.ac_if;
    1100             : 
    1101           0 :         if (sc->sk_if[sc_if->sk_port] == NULL)
    1102           0 :                 return (0);
    1103             : 
    1104           0 :         sk_stop(sc_if, 1);
    1105             : 
    1106             :         /* Detach any PHYs we might have. */
    1107           0 :         if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL)
    1108           0 :                 mii_detach(&sc_if->sk_mii, MII_PHY_ANY, MII_OFFSET_ANY);
    1109             : 
    1110             :         /* Delete any remaining media. */
    1111           0 :         ifmedia_delete_instance(&sc_if->sk_mii.mii_media, IFM_INST_ANY);
    1112             : 
    1113           0 :         ether_ifdetach(ifp);
    1114           0 :         if_detach(ifp);
    1115             : 
    1116           0 :         bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc_if->sk_rdata,
    1117             :             sizeof(struct sk_ring_data));
    1118           0 :         bus_dmamem_free(sc->sc_dmatag,
    1119             :             &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
    1120           0 :         bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
    1121           0 :         sc->sk_if[sc_if->sk_port] = NULL;
    1122             : 
    1123           0 :         return (0);
    1124           0 : }
    1125             : 
    1126             : int
    1127           0 : sk_activate(struct device *self, int act)
    1128             : {
    1129           0 :         struct sk_if_softc *sc_if = (void *)self;
    1130           0 :         struct ifnet *ifp = &sc_if->arpcom.ac_if;
    1131             :         int rv = 0;
    1132             : 
    1133           0 :         switch (act) {
    1134             :         case DVACT_RESUME:
    1135           0 :                 sk_reset(sc_if);
    1136           0 :                 if (ifp->if_flags & IFF_RUNNING)
    1137           0 :                         sk_init(sc_if);
    1138             :                 break;
    1139             :         default:
    1140           0 :                 rv = config_activate_children(self, act);
    1141           0 :                 break;
    1142             :         }
    1143           0 :         return (rv);
    1144             : }
    1145             : 
    1146             : int
    1147           0 : skcprint(void *aux, const char *pnp)
    1148             : {
    1149           0 :         struct skc_attach_args *sa = aux;
    1150             : 
    1151           0 :         if (pnp)
    1152           0 :                 printf("sk port %c at %s",
    1153             :                     (sa->skc_port == SK_PORT_A) ? 'A' : 'B', pnp);
    1154             :         else
    1155           0 :                 printf(" port %c", (sa->skc_port == SK_PORT_A) ? 'A' : 'B');
    1156           0 :         return (UNCONF);
    1157             : }
    1158             : 
    1159             : /*
    1160             :  * Attach the interface. Allocate softc structures, do ifmedia
    1161             :  * setup and ethernet/BPF attach.
    1162             :  */
    1163             : void
    1164           0 : skc_attach(struct device *parent, struct device *self, void *aux)
    1165             : {
    1166           0 :         struct sk_softc *sc = (struct sk_softc *)self;
    1167           0 :         struct pci_attach_args *pa = aux;
    1168           0 :         struct skc_attach_args skca;
    1169           0 :         pci_chipset_tag_t pc = pa->pa_pc;
    1170             :         pcireg_t memtype;
    1171           0 :         pci_intr_handle_t ih;
    1172             :         const char *intrstr = NULL;
    1173             :         u_int8_t skrs;
    1174             :         char *revstr = NULL;
    1175             : 
    1176             :         DPRINTFN(2, ("begin skc_attach\n"));
    1177             : 
    1178           0 :         pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
    1179             : 
    1180             :         /*
    1181             :          * Map control/status registers.
    1182             :          */
    1183           0 :         memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
    1184           0 :         if (pci_mapreg_map(pa, SK_PCI_LOMEM, memtype, 0, &sc->sk_btag,
    1185           0 :             &sc->sk_bhandle, NULL, &sc->sk_bsize, 0)) {
    1186           0 :                 printf(": can't map mem space\n");
    1187           0 :                 return;
    1188             :         }
    1189             : 
    1190           0 :         sc->sc_dmatag = pa->pa_dmat;
    1191             : 
    1192           0 :         sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
    1193           0 :         sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
    1194           0 :         sc->sk_pc = pc;
    1195             : 
    1196             :         /* bail out here if chip is not recognized */
    1197           0 :         if (! SK_IS_GENESIS(sc) && ! SK_IS_YUKON(sc)) {
    1198           0 :                 printf(": unknown chip type: %d\n", sc->sk_type);
    1199           0 :                 goto fail_1;
    1200             :         }
    1201             :         DPRINTFN(2, ("skc_attach: allocate interrupt\n"));
    1202             : 
    1203             :         /* Allocate interrupt */
    1204           0 :         if (pci_intr_map(pa, &ih)) {
    1205           0 :                 printf(": couldn't map interrupt\n");
    1206           0 :                 goto fail_1;
    1207             :         }
    1208             : 
    1209           0 :         intrstr = pci_intr_string(pc, ih);
    1210           0 :         sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, sk_intr, sc,
    1211           0 :             self->dv_xname);
    1212           0 :         if (sc->sk_intrhand == NULL) {
    1213           0 :                 printf(": couldn't establish interrupt");
    1214           0 :                 if (intrstr != NULL)
    1215           0 :                         printf(" at %s", intrstr);
    1216           0 :                 printf("\n");
    1217           0 :                 goto fail_1;
    1218             :         }
    1219             : 
    1220             :         /* Reset the adapter. */
    1221           0 :         skc_reset(sc);
    1222             : 
    1223           0 :         skrs = sk_win_read_1(sc, SK_EPROM0);
    1224           0 :         if (SK_IS_GENESIS(sc)) {
    1225             :                 /* Read and save RAM size and RAMbuffer offset */
    1226           0 :                 switch(skrs) {
    1227             :                 case SK_RAMSIZE_512K_64:
    1228           0 :                         sc->sk_ramsize = 0x80000;
    1229           0 :                         sc->sk_rboff = SK_RBOFF_0;
    1230           0 :                         break;
    1231             :                 case SK_RAMSIZE_1024K_64:
    1232           0 :                         sc->sk_ramsize = 0x100000;
    1233           0 :                         sc->sk_rboff = SK_RBOFF_80000;
    1234           0 :                         break;
    1235             :                 case SK_RAMSIZE_1024K_128:
    1236           0 :                         sc->sk_ramsize = 0x100000;
    1237           0 :                         sc->sk_rboff = SK_RBOFF_0;
    1238           0 :                         break;
    1239             :                 case SK_RAMSIZE_2048K_128:
    1240           0 :                         sc->sk_ramsize = 0x200000;
    1241           0 :                         sc->sk_rboff = SK_RBOFF_0;
    1242           0 :                         break;
    1243             :                 default:
    1244           0 :                         printf(": unknown ram size: %d\n", skrs);
    1245             :                         goto fail_2;
    1246             :                         break;
    1247             :                 }
    1248             :         } else {
    1249           0 :                 if (skrs == 0x00)
    1250           0 :                         sc->sk_ramsize = 0x20000;
    1251             :                 else
    1252           0 :                         sc->sk_ramsize = skrs * (1<<12);
    1253           0 :                 sc->sk_rboff = SK_RBOFF_0;
    1254             :         }
    1255             : 
    1256             :         DPRINTFN(2, ("skc_attach: ramsize=%d (%dk), rboff=%d\n",
    1257             :             sc->sk_ramsize, sc->sk_ramsize / 1024, sc->sk_rboff));
    1258             : 
    1259             :         /* Read and save physical media type */
    1260           0 :         sc->sk_pmd = sk_win_read_1(sc, SK_PMDTYPE);
    1261             : 
    1262           0 :         if (sc->sk_pmd == 'T' || sc->sk_pmd == '1')
    1263           0 :                 sc->sk_coppertype = 1;
    1264             :         else
    1265           0 :                 sc->sk_coppertype = 0;
    1266             : 
    1267           0 :         switch (sc->sk_type) {
    1268             :         case SK_GENESIS:
    1269           0 :                 sc->sk_name = "GEnesis";
    1270           0 :                 break;
    1271             :         case SK_YUKON:
    1272           0 :                 sc->sk_name = "Yukon";
    1273           0 :                 break;
    1274             :         case SK_YUKON_LITE:
    1275           0 :                 sc->sk_name = "Yukon Lite";
    1276           0 :                 break;
    1277             :         case SK_YUKON_LP:
    1278           0 :                 sc->sk_name = "Yukon LP";
    1279           0 :                 break;
    1280             :         default:
    1281           0 :                 sc->sk_name = "Yukon (Unknown)";
    1282           0 :         }
    1283             : 
    1284             :         /* Yukon Lite Rev A0 needs special test, from sk98lin driver */
    1285           0 :         if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {
    1286             :                 u_int32_t flashaddr;
    1287             :                 u_int8_t testbyte;
    1288             : 
    1289           0 :                 flashaddr = sk_win_read_4(sc, SK_EP_ADDR);
    1290             : 
    1291             :                 /* test Flash-Address Register */
    1292           0 :                 sk_win_write_1(sc, SK_EP_ADDR+3, 0xff);
    1293           0 :                 testbyte = sk_win_read_1(sc, SK_EP_ADDR+3);
    1294             : 
    1295           0 :                 if (testbyte != 0) {
    1296             :                         /* This is a Yukon Lite Rev A0 */
    1297           0 :                         sc->sk_type = SK_YUKON_LITE;
    1298           0 :                         sc->sk_rev = SK_YUKON_LITE_REV_A0;
    1299             :                         /* restore Flash-Address Register */
    1300           0 :                         sk_win_write_4(sc, SK_EP_ADDR, flashaddr);
    1301           0 :                 }
    1302           0 :         }
    1303             : 
    1304           0 :         if (sc->sk_type == SK_YUKON_LITE) {
    1305           0 :                 switch (sc->sk_rev) {
    1306             :                 case SK_YUKON_LITE_REV_A0:
    1307             :                         revstr = "A0";
    1308           0 :                         break;
    1309             :                 case SK_YUKON_LITE_REV_A1:
    1310             :                         revstr = "A1";
    1311           0 :                         break;
    1312             :                 case SK_YUKON_LITE_REV_A3:
    1313             :                         revstr = "A3";
    1314           0 :                         break;
    1315             :                 default:
    1316             :                         ;
    1317             :                 }
    1318             :         }
    1319             : 
    1320             :         /* Announce the product name. */
    1321           0 :         printf(", %s", sc->sk_name);
    1322           0 :         if (revstr != NULL)
    1323           0 :                 printf(" rev. %s", revstr);
    1324           0 :         printf(" (0x%x): %s\n", sc->sk_rev, intrstr);
    1325             : 
    1326           0 :         sc->sk_macs = 1;
    1327             : 
    1328           0 :         if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC))
    1329           0 :                 sc->sk_macs++;
    1330             : 
    1331           0 :         skca.skc_port = SK_PORT_A;
    1332           0 :         skca.skc_type = sc->sk_type;
    1333           0 :         skca.skc_rev = sc->sk_rev;
    1334           0 :         (void)config_found(&sc->sk_dev, &skca, skcprint);
    1335             : 
    1336           0 :         if (sc->sk_macs > 1) {
    1337           0 :                 skca.skc_port = SK_PORT_B;
    1338           0 :                 skca.skc_type = sc->sk_type;
    1339           0 :                 skca.skc_rev = sc->sk_rev;
    1340           0 :                 (void)config_found(&sc->sk_dev, &skca, skcprint);
    1341           0 :         }
    1342             : 
    1343             :         /* Turn on the 'driver is loaded' LED. */
    1344           0 :         CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
    1345             : 
    1346           0 :         return;
    1347             : 
    1348             : fail_2:
    1349           0 :         pci_intr_disestablish(pc, sc->sk_intrhand);
    1350             : fail_1:
    1351           0 :         bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
    1352           0 : }
    1353             : 
    1354             : int
    1355           0 : skc_detach(struct device *self, int flags)
    1356             : {
    1357           0 :         struct sk_softc *sc = (struct sk_softc *)self;
    1358             :         int rv;
    1359             : 
    1360           0 :         if (sc->sk_intrhand)
    1361           0 :                 pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
    1362             : 
    1363           0 :         rv = config_detach_children(self, flags);
    1364           0 :         if (rv != 0)
    1365           0 :                 return (rv);
    1366             : 
    1367           0 :         if (sc->sk_bsize > 0)
    1368           0 :                 bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
    1369             : 
    1370           0 :         return(0);
    1371           0 : }
    1372             : 
    1373             : int
    1374           0 : skc_activate(struct device *self, int act)
    1375             : {
    1376           0 :         struct sk_softc *sc = (void *)self;
    1377             :         int rv = 0;
    1378             : 
    1379           0 :         switch (act) {
    1380             :         case DVACT_RESUME:
    1381           0 :                 skc_reset(sc);
    1382           0 :                 rv = config_activate_children(self, act);
    1383           0 :                 break;
    1384             :         default:
    1385           0 :                 rv = config_activate_children(self, act);
    1386           0 :                 break;
    1387             :         }
    1388           0 :         return (rv);
    1389             : }
    1390             : 
    1391             : int
    1392           0 : sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx)
    1393             : {
    1394           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    1395             :         struct sk_tx_desc       *f = NULL;
    1396             :         u_int32_t               frag, cur, sk_ctl;
    1397             :         int                     i;
    1398             :         struct sk_txmap_entry   *entry;
    1399             :         bus_dmamap_t            txmap;
    1400             :         uint64_t                dva;
    1401             : 
    1402             :         DPRINTFN(2, ("sk_encap\n"));
    1403             : 
    1404           0 :         entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
    1405           0 :         if (entry == NULL) {
    1406             :                 DPRINTFN(2, ("sk_encap: no txmap available\n"));
    1407           0 :                 return (ENOBUFS);
    1408             :         }
    1409           0 :         txmap = entry->dmamap;
    1410             : 
    1411           0 :         cur = frag = *txidx;
    1412             : 
    1413           0 :         switch (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
    1414             :             BUS_DMA_STREAMING | BUS_DMA_NOWAIT)) {
    1415             :         case 0:
    1416             :                 break;
    1417             : 
    1418             :         case EFBIG: /* mbuf chain is too fragmented */
    1419           0 :                 if (m_defrag(m_head, M_DONTWAIT) == 0 &&
    1420           0 :                     bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head,
    1421           0 :                     BUS_DMA_STREAMING | BUS_DMA_NOWAIT) == 0)
    1422             :                         break;
    1423             :         default:
    1424           0 :                 return (1);
    1425             :         }
    1426             : 
    1427             :         /* Sync the DMA map. */
    1428           0 :         bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize,
    1429             :             BUS_DMASYNC_PREWRITE);
    1430             : 
    1431           0 :         for (i = 0; i < txmap->dm_nsegs; i++) {
    1432           0 :                 f = &sc_if->sk_rdata->sk_tx_ring[frag];
    1433           0 :                 dva = txmap->dm_segs[i].ds_addr;
    1434           0 :                 htolem32(&f->sk_data_lo, dva);
    1435           0 :                 htolem32(&f->sk_data_hi, dva >> 32);
    1436           0 :                 sk_ctl = txmap->dm_segs[i].ds_len | SK_OPCODE_DEFAULT;
    1437           0 :                 if (i == 0)
    1438           0 :                         sk_ctl |= SK_TXCTL_FIRSTFRAG;
    1439             :                 else
    1440           0 :                         sk_ctl |= SK_TXCTL_OWN;
    1441           0 :                 htolem32(&f->sk_ctl, sk_ctl);
    1442             :                 cur = frag;
    1443           0 :                 SK_INC(frag, SK_TX_RING_CNT);
    1444             :         }
    1445             : 
    1446           0 :         sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
    1447           0 :         SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
    1448             : 
    1449           0 :         sc_if->sk_cdata.sk_tx_map[cur] = entry;
    1450           0 :         sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |=
    1451             :                 htole32(SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR);
    1452             : 
    1453             :         /* Sync descriptors before handing to chip */
    1454           0 :         SK_CDTXSYNC(sc_if, *txidx, txmap->dm_nsegs,
    1455             :             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1456             : 
    1457           0 :         sc_if->sk_rdata->sk_tx_ring[*txidx].sk_ctl |=
    1458             :                 htole32(SK_TXCTL_OWN);
    1459             : 
    1460             :         /* Sync first descriptor to hand it off */
    1461           0 :         SK_CDTXSYNC(sc_if, *txidx, 1, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    1462             : 
    1463           0 :         sc_if->sk_cdata.sk_tx_cnt += txmap->dm_nsegs;
    1464             : 
    1465             : #ifdef SK_DEBUG
    1466             :         if (skdebug >= 2) {
    1467             :                 struct sk_tx_desc *desc;
    1468             :                 u_int32_t idx;
    1469             :                 for (idx = *txidx; idx != frag; SK_INC(idx, SK_TX_RING_CNT)) {
    1470             :                         desc = &sc_if->sk_rdata->sk_tx_ring[idx];
    1471             :                         sk_dump_txdesc(desc, idx);
    1472             :                 }
    1473             :         }
    1474             : #endif
    1475             : 
    1476           0 :         *txidx = frag;
    1477             : 
    1478             :         DPRINTFN(2, ("sk_encap: completed successfully\n"));
    1479             : 
    1480           0 :         return (0);
    1481           0 : }
    1482             : 
    1483             : void
    1484           0 : sk_start(struct ifnet *ifp)
    1485             : {
    1486           0 :         struct sk_if_softc      *sc_if = ifp->if_softc;
    1487           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    1488             :         struct mbuf             *m_head = NULL;
    1489           0 :         u_int32_t               idx = sc_if->sk_cdata.sk_tx_prod;
    1490             :         int                     post = 0;
    1491             : 
    1492             :         DPRINTFN(2, ("sk_start\n"));
    1493             : 
    1494           0 :         for (;;) {
    1495           0 :                 if (sc_if->sk_cdata.sk_tx_cnt + SK_NTXSEG + 1 >
    1496             :                     SK_TX_RING_CNT) {
    1497           0 :                         ifq_set_oactive(&ifp->if_snd);
    1498           0 :                         break;
    1499             :                 }
    1500             :                 
    1501           0 :                 m_head = ifq_dequeue(&ifp->if_snd);
    1502           0 :                 if (m_head == NULL)
    1503             :                         break;
    1504             : 
    1505             :                 /*
    1506             :                  * Pack the data into the transmit ring. If we
    1507             :                  * don't have room, set the OACTIVE flag and wait
    1508             :                  * for the NIC to drain the ring.
    1509             :                  */
    1510           0 :                 if (sk_encap(sc_if, m_head, &idx)) {
    1511           0 :                         m_freem(m_head);
    1512           0 :                         continue;
    1513             :                 }
    1514             : 
    1515             :                 /* now we are committed to transmit the packet */
    1516             : 
    1517             :                 /*
    1518             :                  * If there's a BPF listener, bounce a copy of this frame
    1519             :                  * to him.
    1520             :                  */
    1521             : #if NBPFILTER > 0
    1522           0 :                 if (ifp->if_bpf)
    1523           0 :                         bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
    1524             : #endif
    1525             : 
    1526             :                 post = 1;
    1527             :         }
    1528           0 :         if (post == 0)
    1529           0 :                 return;
    1530             : 
    1531             :         /* Transmit */
    1532           0 :         sc_if->sk_cdata.sk_tx_prod = idx;
    1533           0 :         CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
    1534             : 
    1535             :         /* Set a timeout in case the chip goes out to lunch. */
    1536           0 :         ifp->if_timer = SK_TX_TIMEOUT;
    1537           0 : }
    1538             : 
    1539             : 
    1540             : void
    1541           0 : sk_watchdog(struct ifnet *ifp)
    1542             : {
    1543           0 :         struct sk_if_softc *sc_if = ifp->if_softc;
    1544             : 
    1545             :         /*
    1546             :          * Reclaim first as there is a possibility of losing Tx completion
    1547             :          * interrupts.
    1548             :          */
    1549           0 :         sk_txeof(sc_if);
    1550           0 :         if (sc_if->sk_cdata.sk_tx_cnt != 0) {
    1551           0 :                 printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname);
    1552             : 
    1553           0 :                 ifp->if_oerrors++;
    1554             : 
    1555           0 :                 sk_init(sc_if);
    1556           0 :         }
    1557           0 : }
    1558             : 
    1559             : static __inline int
    1560           0 : sk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len)
    1561             : {
    1562           0 :         if (sc->sk_type == SK_GENESIS) {
    1563           0 :                 if ((stat & XM_RXSTAT_ERRFRAME) == XM_RXSTAT_ERRFRAME ||
    1564           0 :                     XM_RXSTAT_BYTES(stat) != len)
    1565           0 :                         return (0);
    1566             :         } else {
    1567           0 :                 if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR |
    1568             :                     YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC |
    1569           0 :                     YU_RXSTAT_JABBER)) != 0 ||
    1570           0 :                     (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK ||
    1571           0 :                     YU_RXSTAT_BYTES(stat) != len)
    1572           0 :                         return (0);
    1573             :         }
    1574             : 
    1575           0 :         return (1);
    1576           0 : }
    1577             : 
    1578             : void
    1579           0 : sk_rxeof(struct sk_if_softc *sc_if)
    1580             : {
    1581           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    1582           0 :         struct ifnet            *ifp = &sc_if->arpcom.ac_if;
    1583           0 :         struct if_rxring        *rxr = &sc_if->sk_cdata.sk_rx_ring;
    1584             :         struct mbuf             *m;
    1585           0 :         struct mbuf_list        ml = MBUF_LIST_INITIALIZER();
    1586             :         struct sk_chain         *cur_rx;
    1587             :         struct sk_rx_desc       *cur_desc;
    1588             :         int                     cur, total_len = 0;
    1589             :         u_int32_t               rxstat, sk_ctl;
    1590             :         bus_dmamap_t            dmamap;
    1591             : 
    1592             :         DPRINTFN(2, ("sk_rxeof\n"));
    1593             : 
    1594           0 :         cur = sc_if->sk_cdata.sk_rx_cons;
    1595           0 :         while (if_rxr_inuse(rxr) > 0) {
    1596             :                 /* Sync the descriptor */
    1597           0 :                 SK_CDRXSYNC(sc_if, cur,
    1598             :                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1599             : 
    1600           0 :                 cur_rx = &sc_if->sk_cdata.sk_rx_chain[cur];
    1601           0 :                 if (cur_rx->sk_mbuf == NULL)
    1602             :                         break;
    1603             : 
    1604           0 :                 cur_desc = &sc_if->sk_rdata->sk_rx_ring[cur];
    1605           0 :                 sk_ctl = lemtoh32(&cur_desc->sk_ctl);
    1606           0 :                 if ((sk_ctl & SK_RXCTL_OWN) != 0)
    1607             :                         break;
    1608             : 
    1609           0 :                 dmamap = sc_if->sk_cdata.sk_rx_map[cur];
    1610             : 
    1611           0 :                 bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
    1612             :                     dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
    1613           0 :                 bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, dmamap);
    1614             : 
    1615           0 :                 m = cur_rx->sk_mbuf;
    1616           0 :                 cur_rx->sk_mbuf = NULL;
    1617           0 :                 if_rxr_put(rxr, 1);
    1618           0 :                 SK_INC(cur, SK_RX_RING_CNT);
    1619             : 
    1620           0 :                 total_len = SK_RXBYTES(sk_ctl);
    1621           0 :                 rxstat = lemtoh32(&cur_desc->sk_xmac_rxstat);
    1622             : 
    1623           0 :                 if ((sk_ctl & (SK_RXCTL_STATUS_VALID | SK_RXCTL_FIRSTFRAG |
    1624           0 :                     SK_RXCTL_LASTFRAG)) != (SK_RXCTL_STATUS_VALID |
    1625           0 :                     SK_RXCTL_FIRSTFRAG | SK_RXCTL_LASTFRAG) ||
    1626           0 :                     total_len < SK_MIN_FRAMELEN ||
    1627           0 :                     total_len > SK_JUMBO_FRAMELEN ||
    1628           0 :                     sk_rxvalid(sc, rxstat, total_len) == 0) {
    1629           0 :                         ifp->if_ierrors++;
    1630           0 :                         m_freem(m);
    1631           0 :                         continue;
    1632             :                 }
    1633             : 
    1634           0 :                 m->m_pkthdr.len = m->m_len = total_len;
    1635             : 
    1636           0 :                 ml_enqueue(&ml, m);
    1637             :         }
    1638           0 :         sc_if->sk_cdata.sk_rx_cons = cur;
    1639             : 
    1640           0 :         sk_fill_rx_ring(sc_if);
    1641             : 
    1642           0 :         if_input(ifp, &ml);
    1643           0 : }
    1644             : 
    1645             : void
    1646           0 : sk_txeof(struct sk_if_softc *sc_if)
    1647             : {
    1648           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    1649             :         struct sk_tx_desc       *cur_tx;
    1650           0 :         struct ifnet            *ifp = &sc_if->arpcom.ac_if;
    1651             :         u_int32_t               idx, sk_ctl;
    1652             :         struct sk_txmap_entry   *entry;
    1653             : 
    1654             :         DPRINTFN(2, ("sk_txeof\n"));
    1655             : 
    1656             :         /*
    1657             :          * Go through our tx ring and free mbufs for those
    1658             :          * frames that have been sent.
    1659             :          */
    1660           0 :         idx = sc_if->sk_cdata.sk_tx_cons;
    1661           0 :         while (idx != sc_if->sk_cdata.sk_tx_prod) {
    1662           0 :                 SK_CDTXSYNC(sc_if, idx, 1,
    1663             :                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1664             : 
    1665           0 :                 cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
    1666           0 :                 sk_ctl = lemtoh32(&cur_tx->sk_ctl);
    1667             : #ifdef SK_DEBUG
    1668             :                 if (skdebug >= 2)
    1669             :                         sk_dump_txdesc(cur_tx, idx);
    1670             : #endif
    1671           0 :                 if (sk_ctl & SK_TXCTL_OWN) {
    1672           0 :                         SK_CDTXSYNC(sc_if, idx, 1, BUS_DMASYNC_PREREAD);
    1673           0 :                         break;
    1674             :                 }
    1675           0 :                 if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
    1676           0 :                         entry = sc_if->sk_cdata.sk_tx_map[idx];
    1677             : 
    1678           0 :                         m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
    1679           0 :                         sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
    1680             : 
    1681           0 :                         bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
    1682             :                             entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    1683             : 
    1684           0 :                         bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
    1685           0 :                         SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
    1686             :                                           link);
    1687           0 :                         sc_if->sk_cdata.sk_tx_map[idx] = NULL;
    1688           0 :                 }
    1689           0 :                 sc_if->sk_cdata.sk_tx_cnt--;
    1690           0 :                 SK_INC(idx, SK_TX_RING_CNT);
    1691             :         }
    1692           0 :         ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? SK_TX_TIMEOUT : 0;
    1693             : 
    1694           0 :         if (sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 2)
    1695           0 :                 ifq_clr_oactive(&ifp->if_snd);
    1696             : 
    1697           0 :         sc_if->sk_cdata.sk_tx_cons = idx;
    1698           0 : }
    1699             : 
    1700             : void
    1701           0 : sk_tick(void *xsc_if)
    1702             : {
    1703           0 :         struct sk_if_softc *sc_if = xsc_if;
    1704           0 :         struct mii_data *mii = &sc_if->sk_mii;
    1705           0 :         struct ifnet *ifp = &sc_if->arpcom.ac_if;
    1706             :         int i;
    1707             : 
    1708             :         DPRINTFN(2, ("sk_tick\n"));
    1709             : 
    1710           0 :         if (!(ifp->if_flags & IFF_UP))
    1711           0 :                 return;
    1712             : 
    1713           0 :         if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
    1714           0 :                 sk_intr_bcom(sc_if);
    1715           0 :                 return;
    1716             :         }
    1717             : 
    1718             :         /*
    1719             :          * According to SysKonnect, the correct way to verify that
    1720             :          * the link has come back up is to poll bit 0 of the GPIO
    1721             :          * register three times. This pin has the signal from the
    1722             :          * link sync pin connected to it; if we read the same link
    1723             :          * state 3 times in a row, we know the link is up.
    1724             :          */
    1725           0 :         for (i = 0; i < 3; i++) {
    1726           0 :                 if (SK_XM_READ_2(sc_if, XM_GPIO) & XM_GPIO_GP0_SET)
    1727             :                         break;
    1728             :         }
    1729             : 
    1730           0 :         if (i != 3) {
    1731           0 :                 timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1732           0 :                 return;
    1733             :         }
    1734             : 
    1735             :         /* Turn the GP0 interrupt back on. */
    1736           0 :         SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
    1737           0 :         SK_XM_READ_2(sc_if, XM_ISR);
    1738           0 :         mii_tick(mii);
    1739           0 :         timeout_del(&sc_if->sk_tick_ch);
    1740           0 : }
    1741             : 
    1742             : void
    1743           0 : sk_yukon_tick(void *xsc_if)
    1744             : {
    1745           0 :         struct sk_if_softc *sc_if = xsc_if;
    1746           0 :         struct mii_data *mii = &sc_if->sk_mii;
    1747             :         int s;
    1748             : 
    1749           0 :         s = splnet();
    1750           0 :         mii_tick(mii);
    1751           0 :         splx(s);
    1752           0 :         timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1753           0 : }
    1754             : 
    1755             : void
    1756           0 : sk_intr_bcom(struct sk_if_softc *sc_if)
    1757             : {
    1758           0 :         struct mii_data *mii = &sc_if->sk_mii;
    1759           0 :         struct ifnet *ifp = &sc_if->arpcom.ac_if;
    1760             :         int status;
    1761             : 
    1762             :         DPRINTFN(2, ("sk_intr_bcom\n"));
    1763             : 
    1764           0 :         SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
    1765             : 
    1766             :         /*
    1767             :          * Read the PHY interrupt register to make sure
    1768             :          * we clear any pending interrupts.
    1769             :          */
    1770           0 :         status = sk_xmac_miibus_readreg((struct device *)sc_if,
    1771             :             SK_PHYADDR_BCOM, BRGPHY_MII_ISR);
    1772             : 
    1773           0 :         if (!(ifp->if_flags & IFF_RUNNING)) {
    1774           0 :                 sk_init_xmac(sc_if);
    1775           0 :                 return;
    1776             :         }
    1777             : 
    1778           0 :         if (status & (BRGPHY_ISR_LNK_CHG|BRGPHY_ISR_AN_PR)) {
    1779             :                 int lstat;
    1780           0 :                 lstat = sk_xmac_miibus_readreg((struct device *)sc_if,
    1781             :                     SK_PHYADDR_BCOM, BRGPHY_MII_AUXSTS);
    1782             : 
    1783           0 :                 if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) {
    1784           0 :                         mii_mediachg(mii);
    1785             :                         /* Turn off the link LED. */
    1786           0 :                         SK_IF_WRITE_1(sc_if, 0,
    1787             :                             SK_LINKLED1_CTL, SK_LINKLED_OFF);
    1788           0 :                         sc_if->sk_link = 0;
    1789           0 :                 } else if (status & BRGPHY_ISR_LNK_CHG) {
    1790           0 :                         sk_xmac_miibus_writereg((struct device *)sc_if,
    1791             :                             SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFF00);
    1792           0 :                         mii_tick(mii);
    1793           0 :                         sc_if->sk_link = 1;
    1794             :                         /* Turn on the link LED. */
    1795           0 :                         SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
    1796             :                             SK_LINKLED_ON|SK_LINKLED_LINKSYNC_OFF|
    1797             :                             SK_LINKLED_BLINK_OFF);
    1798           0 :                 } else {
    1799           0 :                         mii_tick(mii);
    1800           0 :                         timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1801             :                 }
    1802           0 :         }
    1803             : 
    1804           0 :         SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
    1805           0 : }
    1806             : 
    1807             : void
    1808           0 : sk_intr_xmac(struct sk_if_softc *sc_if)
    1809             : {
    1810           0 :         u_int16_t status = SK_XM_READ_2(sc_if, XM_ISR);
    1811             : 
    1812             :         DPRINTFN(2, ("sk_intr_xmac\n"));
    1813             : 
    1814           0 :         if (sc_if->sk_phytype == SK_PHYTYPE_XMAC) {
    1815           0 :                 if (status & XM_ISR_GP0_SET) {
    1816           0 :                         SK_XM_SETBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET);
    1817           0 :                         timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1818           0 :                 }
    1819             : 
    1820           0 :                 if (status & XM_ISR_AUTONEG_DONE) {
    1821           0 :                         timeout_add_sec(&sc_if->sk_tick_ch, 1);
    1822           0 :                 }
    1823             :         }
    1824             : 
    1825           0 :         if (status & XM_IMR_TX_UNDERRUN)
    1826           0 :                 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_TXFIFO);
    1827             : 
    1828           0 :         if (status & XM_IMR_RX_OVERRUN)
    1829           0 :                 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_RXFIFO);
    1830           0 : }
    1831             : 
    1832             : void
    1833           0 : sk_intr_yukon(struct sk_if_softc *sc_if)
    1834             : {
    1835             :         u_int8_t status;
    1836             : 
    1837           0 :         status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR);
    1838             :         /* RX overrun */
    1839           0 :         if ((status & SK_GMAC_INT_RX_OVER) != 0) {
    1840           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,
    1841             :                     SK_RFCTL_RX_FIFO_OVER);
    1842           0 :         }
    1843             :         /* TX underrun */
    1844           0 :         if ((status & SK_GMAC_INT_TX_UNDER) != 0) {
    1845           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,
    1846             :                     SK_TFCTL_TX_FIFO_UNDER);
    1847           0 :         }
    1848             : 
    1849             :         DPRINTFN(2, ("sk_intr_yukon status=%#x\n", status));
    1850           0 : }
    1851             : 
    1852             : int
    1853           0 : sk_intr(void *xsc)
    1854             : {
    1855           0 :         struct sk_softc         *sc = xsc;
    1856           0 :         struct sk_if_softc      *sc_if0 = sc->sk_if[SK_PORT_A];
    1857           0 :         struct sk_if_softc      *sc_if1 = sc->sk_if[SK_PORT_B];
    1858             :         struct ifnet            *ifp0 = NULL, *ifp1 = NULL;
    1859             :         u_int32_t               status;
    1860             :         int                     claimed = 0;
    1861             : 
    1862           0 :         status = CSR_READ_4(sc, SK_ISSR);
    1863           0 :         if (status == 0 || status == 0xffffffff)
    1864           0 :                 return (0);
    1865             : 
    1866           0 :         if (sc_if0 != NULL)
    1867           0 :                 ifp0 = &sc_if0->arpcom.ac_if;
    1868           0 :         if (sc_if1 != NULL)
    1869           0 :                 ifp1 = &sc_if1->arpcom.ac_if;
    1870             : 
    1871           0 :         for (; (status &= sc->sk_intrmask) != 0;) {
    1872             :                 claimed = 1;
    1873             : 
    1874             :                 /* Handle receive interrupts first. */
    1875           0 :                 if (sc_if0 && (status & SK_ISR_RX1_EOF)) {
    1876           0 :                         sk_rxeof(sc_if0);
    1877           0 :                         CSR_WRITE_4(sc, SK_BMU_RX_CSR0,
    1878             :                             SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
    1879           0 :                 }
    1880           0 :                 if (sc_if1 && (status & SK_ISR_RX2_EOF)) {
    1881           0 :                         sk_rxeof(sc_if1);
    1882           0 :                         CSR_WRITE_4(sc, SK_BMU_RX_CSR1,
    1883             :                             SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START);
    1884           0 :                 }
    1885             : 
    1886             :                 /* Then transmit interrupts. */
    1887           0 :                 if (sc_if0 && (status & SK_ISR_TX1_S_EOF)) {
    1888           0 :                         sk_txeof(sc_if0);
    1889           0 :                         CSR_WRITE_4(sc, SK_BMU_TXS_CSR0,
    1890             :                             SK_TXBMU_CLR_IRQ_EOF);
    1891           0 :                 }
    1892           0 :                 if (sc_if1 && (status & SK_ISR_TX2_S_EOF)) {
    1893           0 :                         sk_txeof(sc_if1);
    1894           0 :                         CSR_WRITE_4(sc, SK_BMU_TXS_CSR1,
    1895             :                             SK_TXBMU_CLR_IRQ_EOF);
    1896           0 :                 }
    1897             : 
    1898             :                 /* Then MAC interrupts. */
    1899           0 :                 if (sc_if0 && (status & SK_ISR_MAC1) &&
    1900           0 :                     (ifp0->if_flags & IFF_RUNNING)) {
    1901           0 :                         if (SK_IS_GENESIS(sc))
    1902           0 :                                 sk_intr_xmac(sc_if0);
    1903             :                         else
    1904           0 :                                 sk_intr_yukon(sc_if0);
    1905             :                 }
    1906             : 
    1907           0 :                 if (sc_if1 && (status & SK_ISR_MAC2) &&
    1908           0 :                     (ifp1->if_flags & IFF_RUNNING)) {
    1909           0 :                         if (SK_IS_GENESIS(sc))
    1910           0 :                                 sk_intr_xmac(sc_if1);
    1911             :                         else
    1912           0 :                                 sk_intr_yukon(sc_if1);
    1913             : 
    1914             :                 }
    1915             : 
    1916           0 :                 if (status & SK_ISR_EXTERNAL_REG) {
    1917           0 :                         if (sc_if0 != NULL &&
    1918           0 :                             sc_if0->sk_phytype == SK_PHYTYPE_BCOM)
    1919           0 :                                 sk_intr_bcom(sc_if0);
    1920             : 
    1921           0 :                         if (sc_if1 != NULL &&
    1922           0 :                             sc_if1->sk_phytype == SK_PHYTYPE_BCOM)
    1923           0 :                                 sk_intr_bcom(sc_if1);
    1924             :                 }
    1925           0 :                 status = CSR_READ_4(sc, SK_ISSR);
    1926             :         }
    1927             : 
    1928           0 :         CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
    1929             : 
    1930           0 :         if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
    1931           0 :                 sk_start(ifp0);
    1932           0 :         if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
    1933           0 :                 sk_start(ifp1);
    1934             : 
    1935           0 :         return (claimed);
    1936           0 : }
    1937             : 
    1938             : void
    1939           0 : sk_init_xmac(struct sk_if_softc *sc_if)
    1940             : {
    1941           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    1942           0 :         struct sk_bcom_hack     bhack[] = {
    1943             :         { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
    1944             :         { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
    1945             :         { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
    1946             :         { 0, 0 } };
    1947             : 
    1948             :         DPRINTFN(2, ("sk_init_xmac\n"));
    1949             : 
    1950             :         /* Unreset the XMAC. */
    1951           0 :         SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_UNRESET);
    1952           0 :         DELAY(1000);
    1953             : 
    1954             :         /* Reset the XMAC's internal state. */
    1955           0 :         SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
    1956             : 
    1957             :         /* Save the XMAC II revision */
    1958           0 :         sc_if->sk_xmac_rev = XM_XMAC_REV(SK_XM_READ_4(sc_if, XM_DEVID));
    1959             : 
    1960             :         /*
    1961             :          * Perform additional initialization for external PHYs,
    1962             :          * namely for the 1000baseTX cards that use the XMAC's
    1963             :          * GMII mode.
    1964             :          */
    1965           0 :         if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
    1966             :                 int                     i = 0;
    1967             :                 u_int32_t               val;
    1968             : 
    1969             :                 /* Take PHY out of reset. */
    1970           0 :                 val = sk_win_read_4(sc, SK_GPIO);
    1971           0 :                 if (sc_if->sk_port == SK_PORT_A)
    1972           0 :                         val |= SK_GPIO_DIR0|SK_GPIO_DAT0;
    1973             :                 else
    1974           0 :                         val |= SK_GPIO_DIR2|SK_GPIO_DAT2;
    1975           0 :                 sk_win_write_4(sc, SK_GPIO, val);
    1976             : 
    1977             :                 /* Enable GMII mode on the XMAC. */
    1978           0 :                 SK_XM_SETBIT_2(sc_if, XM_HWCFG, XM_HWCFG_GMIIMODE);
    1979             : 
    1980           0 :                 sk_xmac_miibus_writereg((struct device *)sc_if,
    1981             :                     SK_PHYADDR_BCOM, MII_BMCR, BMCR_RESET);
    1982           0 :                 DELAY(10000);
    1983           0 :                 sk_xmac_miibus_writereg((struct device *)sc_if,
    1984             :                     SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFFF0);
    1985             : 
    1986             :                 /*
    1987             :                  * Early versions of the BCM5400 apparently have
    1988             :                  * a bug that requires them to have their reserved
    1989             :                  * registers initialized to some magic values. I don't
    1990             :                  * know what the numbers do, I'm just the messenger.
    1991             :                  */
    1992           0 :                 if (sk_xmac_miibus_readreg((struct device *)sc_if,
    1993           0 :                     SK_PHYADDR_BCOM, 0x03) == 0x6041) {
    1994           0 :                         while(bhack[i].reg) {
    1995           0 :                                 sk_xmac_miibus_writereg((struct device *)sc_if,
    1996             :                                     SK_PHYADDR_BCOM, bhack[i].reg,
    1997           0 :                                     bhack[i].val);
    1998           0 :                                 i++;
    1999             :                         }
    2000             :                 }
    2001           0 :         }
    2002             : 
    2003             :         /* Set station address */
    2004           0 :         SK_XM_WRITE_2(sc_if, XM_PAR0,
    2005             :             letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[0])));
    2006           0 :         SK_XM_WRITE_2(sc_if, XM_PAR1,
    2007             :             letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[2])));
    2008           0 :         SK_XM_WRITE_2(sc_if, XM_PAR2,
    2009             :             letoh16(*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4])));
    2010             : 
    2011             :         /* We don't need the FCS appended to the packet. */
    2012           0 :         SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_STRIPFCS);
    2013             : 
    2014             :         /* We want short frames padded to 60 bytes. */
    2015           0 :         SK_XM_SETBIT_2(sc_if, XM_TXCMD, XM_TXCMD_AUTOPAD);
    2016             : 
    2017             :         /*
    2018             :          * Enable the reception of all error frames. This is
    2019             :          * a necessary evil due to the design of the XMAC. The
    2020             :          * XMAC's receive FIFO is only 8K in size, however jumbo
    2021             :          * frames can be up to 9000 bytes in length. When bad
    2022             :          * frame filtering is enabled, the XMAC's RX FIFO operates
    2023             :          * in 'store and forward' mode. For this to work, the
    2024             :          * entire frame has to fit into the FIFO, but that means
    2025             :          * that jumbo frames larger than 8192 bytes will be
    2026             :          * truncated. Disabling all bad frame filtering causes
    2027             :          * the RX FIFO to operate in streaming mode, in which
    2028             :          * case the XMAC will start transferring frames out of the
    2029             :          * RX FIFO as soon as the FIFO threshold is reached.
    2030             :          */
    2031           0 :         SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_BADFRAMES|
    2032             :             XM_MODE_RX_GIANTS|XM_MODE_RX_RUNTS|XM_MODE_RX_CRCERRS|
    2033             :             XM_MODE_RX_INRANGELEN);
    2034             : 
    2035           0 :         SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK);
    2036             : 
    2037             :         /*
    2038             :          * Bump up the transmit threshold. This helps hold off transmit
    2039             :          * underruns when we're blasting traffic from both ports at once.
    2040             :          */
    2041           0 :         SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH);
    2042             : 
    2043             :         /* Program promiscuous mode and multicast filters. */
    2044           0 :         sk_iff(sc_if);
    2045             : 
    2046             :         /* Clear and enable interrupts */
    2047           0 :         SK_XM_READ_2(sc_if, XM_ISR);
    2048           0 :         if (sc_if->sk_phytype == SK_PHYTYPE_XMAC)
    2049           0 :                 SK_XM_WRITE_2(sc_if, XM_IMR, XM_INTRS);
    2050             :         else
    2051           0 :                 SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
    2052             : 
    2053             :         /* Configure MAC arbiter */
    2054           0 :         switch(sc_if->sk_xmac_rev) {
    2055             :         case XM_XMAC_REV_B2:
    2056           0 :                 sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_B2);
    2057           0 :                 sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_B2);
    2058           0 :                 sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_B2);
    2059           0 :                 sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_B2);
    2060           0 :                 sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_B2);
    2061           0 :                 sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_B2);
    2062           0 :                 sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_B2);
    2063           0 :                 sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_B2);
    2064           0 :                 sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
    2065           0 :                 break;
    2066             :         case XM_XMAC_REV_C1:
    2067           0 :                 sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_C1);
    2068           0 :                 sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_C1);
    2069           0 :                 sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_C1);
    2070           0 :                 sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_C1);
    2071           0 :                 sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_C1);
    2072           0 :                 sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_C1);
    2073           0 :                 sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_C1);
    2074           0 :                 sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_C1);
    2075           0 :                 sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2);
    2076           0 :                 break;
    2077             :         default:
    2078             :                 break;
    2079             :         }
    2080           0 :         sk_win_write_2(sc, SK_MACARB_CTL,
    2081             :             SK_MACARBCTL_UNRESET|SK_MACARBCTL_FASTOE_OFF);
    2082             : 
    2083           0 :         sc_if->sk_link = 1;
    2084           0 : }
    2085             : 
    2086           0 : void sk_init_yukon(struct sk_if_softc *sc_if)
    2087             : {
    2088             :         u_int32_t               phy, v;
    2089             :         u_int16_t               reg;
    2090             :         struct sk_softc         *sc;
    2091             :         int                     i;
    2092             : 
    2093           0 :         sc = sc_if->sk_softc;
    2094             : 
    2095             :         DPRINTFN(2, ("sk_init_yukon: start: sk_csr=%#x\n",
    2096             :             CSR_READ_4(sc_if->sk_softc, SK_CSR)));
    2097             : 
    2098           0 :         if (sc->sk_type == SK_YUKON_LITE &&
    2099           0 :             sc->sk_rev >= SK_YUKON_LITE_REV_A3) {
    2100             :                 /*
    2101             :                  * Workaround code for COMA mode, set PHY reset.
    2102             :                  * Otherwise it will not correctly take chip out of
    2103             :                  * powerdown (coma)
    2104             :                  */
    2105           0 :                 v = sk_win_read_4(sc, SK_GPIO);
    2106           0 :                 v |= SK_GPIO_DIR9 | SK_GPIO_DAT9;
    2107           0 :                 sk_win_write_4(sc, SK_GPIO, v);
    2108           0 :         }
    2109             : 
    2110             :         DPRINTFN(6, ("sk_init_yukon: 1\n"));
    2111             : 
    2112             :         /* GMAC and GPHY Reset */
    2113           0 :         SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
    2114           0 :         SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
    2115           0 :         DELAY(1000);
    2116             : 
    2117             :         DPRINTFN(6, ("sk_init_yukon: 2\n"));
    2118             : 
    2119           0 :         if (sc->sk_type == SK_YUKON_LITE &&
    2120           0 :             sc->sk_rev >= SK_YUKON_LITE_REV_A3) {
    2121             :                 /*
    2122             :                  * Workaround code for COMA mode, clear PHY reset
    2123             :                  */
    2124           0 :                 v = sk_win_read_4(sc, SK_GPIO);
    2125           0 :                 v |= SK_GPIO_DIR9;
    2126           0 :                 v &= ~SK_GPIO_DAT9;
    2127           0 :                 sk_win_write_4(sc, SK_GPIO, v);
    2128           0 :         }
    2129             : 
    2130             :         phy = SK_GPHY_INT_POL_HI | SK_GPHY_DIS_FC | SK_GPHY_DIS_SLEEP |
    2131             :                 SK_GPHY_ENA_XC | SK_GPHY_ANEG_ALL | SK_GPHY_ENA_PAUSE;
    2132             : 
    2133           0 :         if (sc->sk_coppertype)
    2134           0 :                 phy |= SK_GPHY_COPPER;
    2135             :         else
    2136             :                 phy |= SK_GPHY_FIBER;
    2137             : 
    2138             :         DPRINTFN(3, ("sk_init_yukon: phy=%#x\n", phy));
    2139             : 
    2140           0 :         SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_SET);
    2141           0 :         DELAY(1000);
    2142           0 :         SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_CLEAR);
    2143           0 :         SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
    2144             :             SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
    2145             : 
    2146             :         DPRINTFN(3, ("sk_init_yukon: gmac_ctrl=%#x\n",
    2147             :             SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
    2148             : 
    2149             :         DPRINTFN(6, ("sk_init_yukon: 3\n"));
    2150             : 
    2151             :         /* unused read of the interrupt source register */
    2152             :         DPRINTFN(6, ("sk_init_yukon: 4\n"));
    2153           0 :         SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR);
    2154             : 
    2155             :         DPRINTFN(6, ("sk_init_yukon: 4a\n"));
    2156           0 :         reg = SK_YU_READ_2(sc_if, YUKON_PAR);
    2157             :         DPRINTFN(6, ("sk_init_yukon: YUKON_PAR=%#x\n", reg));
    2158             : 
    2159             :         /* MIB Counter Clear Mode set */
    2160           0 :         reg |= YU_PAR_MIB_CLR;
    2161             :         DPRINTFN(6, ("sk_init_yukon: YUKON_PAR=%#x\n", reg));
    2162             :         DPRINTFN(6, ("sk_init_yukon: 4b\n"));
    2163           0 :         SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
    2164             : 
    2165             :         /* MIB Counter Clear Mode clear */
    2166             :         DPRINTFN(6, ("sk_init_yukon: 5\n"));
    2167           0 :         reg &= ~YU_PAR_MIB_CLR;
    2168           0 :         SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
    2169             : 
    2170             :         /* receive control reg */
    2171             :         DPRINTFN(6, ("sk_init_yukon: 7\n"));
    2172           0 :         SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
    2173             : 
    2174             :         /* transmit parameter register */
    2175             :         DPRINTFN(6, ("sk_init_yukon: 8\n"));
    2176           0 :         SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
    2177             :             YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) );
    2178             : 
    2179             :         /* serial mode register */
    2180             :         DPRINTFN(6, ("sk_init_yukon: 9\n"));
    2181           0 :         SK_YU_WRITE_2(sc_if, YUKON_SMR, YU_SMR_DATA_BLIND(0x1c) |
    2182             :             YU_SMR_MFL_VLAN | YU_SMR_MFL_JUMBO | YU_SMR_IPG_DATA(0x1e));
    2183             : 
    2184             :         DPRINTFN(6, ("sk_init_yukon: 10\n"));
    2185             :         /* Setup Yukon's address */
    2186           0 :         for (i = 0; i < 3; i++) {
    2187             :                 /* Write Source Address 1 (unicast filter) */
    2188           0 :                 SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,
    2189             :                     sc_if->arpcom.ac_enaddr[i * 2] |
    2190             :                     sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8);
    2191             :         }
    2192             : 
    2193           0 :         for (i = 0; i < 3; i++) {
    2194           0 :                 reg = sk_win_read_2(sc_if->sk_softc,
    2195           0 :                                     SK_MAC1_0 + i * 2 + sc_if->sk_port * 8);
    2196           0 :                 SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
    2197             :         }
    2198             : 
    2199             :         /* Program promiscuous mode and multicast filters. */
    2200             :         DPRINTFN(6, ("sk_init_yukon: 11\n"));
    2201           0 :         sk_iff(sc_if);
    2202             : 
    2203             :         /* enable interrupt mask for counter overflows */
    2204             :         DPRINTFN(6, ("sk_init_yukon: 12\n"));
    2205           0 :         SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
    2206           0 :         SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0);
    2207           0 :         SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0);
    2208             : 
    2209             :         /* Configure RX MAC FIFO Flush Mask */
    2210             :         v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR |
    2211             :             YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT |
    2212             :             YU_RXSTAT_JABBER;
    2213           0 :         SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v);
    2214             : 
    2215             :         /* Disable RX MAC FIFO Flush for YUKON-Lite Rev. A0 only */
    2216           0 :         if (sc->sk_type == SK_YUKON_LITE && sc->sk_rev == SK_YUKON_LITE_REV_A0)
    2217           0 :                 v = SK_TFCTL_OPERATION_ON;
    2218             :         else
    2219             :                 v = SK_TFCTL_OPERATION_ON | SK_RFCTL_FIFO_FLUSH_ON;
    2220             :         /* Configure RX MAC FIFO */
    2221           0 :         SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR);
    2222           0 :         SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, v);
    2223             : 
    2224             :         /* Increase flush threshould to 64 bytes */
    2225           0 :         SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,
    2226             :             SK_RFCTL_FIFO_THRESHOLD + 1);
    2227             : 
    2228             :         /* Configure TX MAC FIFO */
    2229           0 :         SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR);
    2230           0 :         SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON);
    2231             : 
    2232             :         DPRINTFN(6, ("sk_init_yukon: end\n"));
    2233           0 : }
    2234             : 
    2235             : /*
    2236             :  * Note that to properly initialize any part of the GEnesis chip,
    2237             :  * you first have to take it out of reset mode.
    2238             :  */
    2239             : void
    2240           0 : sk_init(void *xsc_if)
    2241             : {
    2242           0 :         struct sk_if_softc      *sc_if = xsc_if;
    2243           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    2244           0 :         struct ifnet            *ifp = &sc_if->arpcom.ac_if;
    2245           0 :         struct mii_data         *mii = &sc_if->sk_mii;
    2246             :         int                     s;
    2247             : 
    2248             :         DPRINTFN(2, ("sk_init\n"));
    2249             : 
    2250           0 :         s = splnet();
    2251             : 
    2252             :         /* Cancel pending I/O and free all RX/TX buffers. */
    2253           0 :         sk_stop(sc_if, 0);
    2254             : 
    2255           0 :         if (SK_IS_GENESIS(sc)) {
    2256             :                 /* Configure LINK_SYNC LED */
    2257           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON);
    2258           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL,
    2259             :                     SK_LINKLED_LINKSYNC_ON);
    2260             : 
    2261             :                 /* Configure RX LED */
    2262           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL,
    2263             :                     SK_RXLEDCTL_COUNTER_START);
    2264             : 
    2265             :                 /* Configure TX LED */
    2266           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL,
    2267             :                     SK_TXLEDCTL_COUNTER_START);
    2268           0 :         }
    2269             : 
    2270             :         /*
    2271             :          * Configure descriptor poll timer
    2272             :          *
    2273             :          * SK-NET GENESIS data sheet says that possibility of losing Start
    2274             :          * transmit command due to CPU/cache related interim storage problems
    2275             :          * under certain conditions. The document recommends a polling
    2276             :          * mechanism to send a Start transmit command to initiate transfer
    2277             :          * of ready descriptors regulary. To cope with this issue sk(4) now
    2278             :          * enables descriptor poll timer to initiate descriptor processing
    2279             :          * periodically as defined by SK_DPT_TIMER_MAX. However sk(4) still
    2280             :          * issue SK_TXBMU_TX_START to Tx BMU to get fast execution of Tx
    2281             :          * command instead of waiting for next descriptor polling time.
    2282             :          * The same rule may apply to Rx side too but it seems that is not
    2283             :          * needed at the moment.
    2284             :          * Since sk(4) uses descriptor polling as a last resort there is no
    2285             :          * need to set smaller polling time than maximum allowable one.
    2286             :          */
    2287           0 :         SK_IF_WRITE_4(sc_if, 0, SK_DPT_INIT, SK_DPT_TIMER_MAX);
    2288             : 
    2289             :         /* Configure I2C registers */
    2290             : 
    2291             :         /* Configure XMAC(s) */
    2292           0 :         switch (sc->sk_type) {
    2293             :         case SK_GENESIS:
    2294           0 :                 sk_init_xmac(sc_if);
    2295           0 :                 break;
    2296             :         case SK_YUKON:
    2297             :         case SK_YUKON_LITE:
    2298             :         case SK_YUKON_LP:
    2299           0 :                 sk_init_yukon(sc_if);
    2300           0 :                 break;
    2301             :         }
    2302           0 :         mii_mediachg(mii);
    2303             : 
    2304           0 :         if (SK_IS_GENESIS(sc)) {
    2305             :                 /* Configure MAC FIFOs */
    2306           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET);
    2307           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END);
    2308           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON);
    2309             : 
    2310           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET);
    2311           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END);
    2312           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON);
    2313           0 :         }
    2314             : 
    2315             :         /* Configure transmit arbiter(s) */
    2316           0 :         SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL,
    2317             :             SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON);
    2318             : 
    2319             :         /* Configure RAMbuffers */
    2320           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET);
    2321           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart);
    2322           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart);
    2323           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart);
    2324           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend);
    2325           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON);
    2326             : 
    2327           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_UNRESET);
    2328           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_STORENFWD_ON);
    2329           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_START, sc_if->sk_tx_ramstart);
    2330           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_WR_PTR, sc_if->sk_tx_ramstart);
    2331           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_RD_PTR, sc_if->sk_tx_ramstart);
    2332           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_END, sc_if->sk_tx_ramend);
    2333           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_ON);
    2334             : 
    2335             :         /* Configure BMUs */
    2336           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_ONLINE);
    2337           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO,
    2338             :             SK_RX_RING_ADDR(sc_if, 0));
    2339           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 0);
    2340             : 
    2341           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_ONLINE);
    2342           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_LO,
    2343             :             SK_TX_RING_ADDR(sc_if, 0));
    2344           0 :         SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_HI, 0);
    2345             : 
    2346             :         /* Init descriptors */
    2347           0 :         if (sk_init_rx_ring(sc_if) == ENOBUFS) {
    2348           0 :                 printf("%s: initialization failed: no "
    2349           0 :                     "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
    2350           0 :                 sk_stop(sc_if, 0);
    2351           0 :                 splx(s);
    2352           0 :                 return;
    2353             :         }
    2354             : 
    2355           0 :         if (sk_init_tx_ring(sc_if) == ENOBUFS) {
    2356           0 :                 printf("%s: initialization failed: no "
    2357           0 :                     "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
    2358           0 :                 sk_stop(sc_if, 0);
    2359           0 :                 splx(s);
    2360           0 :                 return;
    2361             :         }
    2362             : 
    2363             :         /* Configure interrupt handling */
    2364           0 :         CSR_READ_4(sc, SK_ISSR);
    2365           0 :         if (sc_if->sk_port == SK_PORT_A)
    2366           0 :                 sc->sk_intrmask |= SK_INTRS1;
    2367             :         else
    2368           0 :                 sc->sk_intrmask |= SK_INTRS2;
    2369             : 
    2370           0 :         sc->sk_intrmask |= SK_ISR_EXTERNAL_REG;
    2371             : 
    2372           0 :         CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
    2373             : 
    2374             :         /* Start BMUs. */
    2375           0 :         SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START);
    2376             : 
    2377           0 :         if (SK_IS_GENESIS(sc)) {
    2378             :                 /* Enable XMACs TX and RX state machines */
    2379           0 :                 SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE);
    2380           0 :                 SK_XM_SETBIT_2(sc_if, XM_MMUCMD,
    2381             :                     XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
    2382           0 :         }
    2383             : 
    2384           0 :         if (SK_IS_YUKON(sc)) {
    2385           0 :                 u_int16_t reg = SK_YU_READ_2(sc_if, YUKON_GPCR);
    2386           0 :                 reg |= YU_GPCR_TXEN | YU_GPCR_RXEN;
    2387           0 :                 SK_YU_WRITE_2(sc_if, YUKON_GPCR, reg);
    2388           0 :         }
    2389             : 
    2390             :         /* Activate descriptor polling timer */
    2391           0 :         SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_START);
    2392             :         /* start transfer of Tx descriptors */
    2393           0 :         CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
    2394             : 
    2395           0 :         ifp->if_flags |= IFF_RUNNING;
    2396           0 :         ifq_clr_oactive(&ifp->if_snd);
    2397             : 
    2398           0 :         if (SK_IS_YUKON(sc))
    2399           0 :                 timeout_add_sec(&sc_if->sk_tick_ch, 1);
    2400             : 
    2401           0 :         splx(s);
    2402           0 : }
    2403             : 
    2404             : void
    2405           0 : sk_stop(struct sk_if_softc *sc_if, int softonly)
    2406             : {
    2407           0 :         struct sk_softc         *sc = sc_if->sk_softc;
    2408           0 :         struct ifnet            *ifp = &sc_if->arpcom.ac_if;
    2409             :         bus_dmamap_t            dmamap;
    2410             :         struct sk_txmap_entry   *dma;
    2411             :         int                     i;
    2412             :         u_int32_t               val;
    2413             : 
    2414             :         DPRINTFN(2, ("sk_stop\n"));
    2415             : 
    2416           0 :         timeout_del(&sc_if->sk_tick_ch);
    2417             : 
    2418           0 :         ifp->if_flags &= ~IFF_RUNNING;
    2419           0 :         ifq_clr_oactive(&ifp->if_snd);
    2420             : 
    2421           0 :         if (!softonly) {
    2422             :                 /* stop Tx descriptor polling timer */
    2423           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
    2424             :                 /* stop transfer of Tx descriptors */
    2425           0 :                 CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_STOP);
    2426           0 :                 for (i = 0; i < SK_TIMEOUT; i++) {
    2427           0 :                         val = CSR_READ_4(sc, sc_if->sk_tx_bmu);
    2428           0 :                         if (!(val & SK_TXBMU_TX_STOP))
    2429             :                                 break;
    2430           0 :                         DELAY(1);
    2431             :                 }
    2432           0 :                 if (i == SK_TIMEOUT) {
    2433           0 :                         printf("%s: cannot stop transfer of Tx descriptors\n",
    2434           0 :                             sc_if->sk_dev.dv_xname);
    2435           0 :                 }
    2436             :                 /* stop transfer of Rx descriptors */
    2437           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_STOP);
    2438           0 :                 for (i = 0; i < SK_TIMEOUT; i++) {
    2439           0 :                         val = SK_IF_READ_4(sc_if, 0, SK_RXQ1_BMU_CSR);
    2440           0 :                         if (!(val & SK_RXBMU_RX_STOP))
    2441             :                                 break;
    2442           0 :                         DELAY(1);
    2443             :                 }
    2444           0 :                 if (i == SK_TIMEOUT) {
    2445           0 :                         printf("%s: cannot stop transfer of Rx descriptors\n",
    2446           0 :                             sc_if->sk_dev.dv_xname);
    2447           0 :                 }
    2448             : 
    2449           0 :                 if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
    2450             :                         u_int32_t               val;
    2451             : 
    2452             :                         /* Put PHY back into reset. */
    2453           0 :                         val = sk_win_read_4(sc, SK_GPIO);
    2454           0 :                         if (sc_if->sk_port == SK_PORT_A) {
    2455           0 :                                 val |= SK_GPIO_DIR0;
    2456           0 :                                 val &= ~SK_GPIO_DAT0;
    2457           0 :                         } else {
    2458           0 :                                 val |= SK_GPIO_DIR2;
    2459           0 :                                 val &= ~SK_GPIO_DAT2;
    2460             :                         }
    2461           0 :                         sk_win_write_4(sc, SK_GPIO, val);
    2462           0 :                 }
    2463             : 
    2464             :                 /* Turn off various components of this interface. */
    2465           0 :                 SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
    2466           0 :                 switch (sc->sk_type) {
    2467             :                 case SK_GENESIS:
    2468           0 :                         SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL,
    2469             :                             SK_TXMACCTL_XMAC_RESET);
    2470           0 :                         SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET);
    2471           0 :                         break;
    2472             :                 case SK_YUKON:
    2473             :                 case SK_YUKON_LITE:
    2474             :                 case SK_YUKON_LP:
    2475           0 :                         SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
    2476           0 :                         SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
    2477           0 :                         break;
    2478             :                 }
    2479           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
    2480           0 :                 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
    2481           0 :                 SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE);
    2482           0 :                 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
    2483           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
    2484           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
    2485           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
    2486           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
    2487           0 :                 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
    2488             : 
    2489             :                 /* Disable interrupts */
    2490           0 :                 if (sc_if->sk_port == SK_PORT_A)
    2491           0 :                         sc->sk_intrmask &= ~SK_INTRS1;
    2492             :                 else
    2493           0 :                         sc->sk_intrmask &= ~SK_INTRS2;
    2494           0 :                 CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
    2495             : 
    2496           0 :                 SK_XM_READ_2(sc_if, XM_ISR);
    2497           0 :                 SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
    2498           0 :         }
    2499             : 
    2500             :         /* Free RX and TX mbufs still in the queues. */
    2501           0 :         for (i = 0; i < SK_RX_RING_CNT; i++) {
    2502           0 :                 if (sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf != NULL) {
    2503           0 :                         dmamap = sc_if->sk_cdata.sk_rx_map[i];
    2504           0 :                         bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
    2505             :                             dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
    2506           0 :                         bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, dmamap);
    2507           0 :                         m_freem(sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf);
    2508           0 :                         sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
    2509           0 :                 }
    2510             :         }
    2511             : 
    2512           0 :         for (i = 0; i < SK_TX_RING_CNT; i++) {
    2513           0 :                 if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
    2514           0 :                         m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
    2515           0 :                         sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
    2516           0 :                         SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head,
    2517             :                             sc_if->sk_cdata.sk_tx_map[i], link);
    2518           0 :                         sc_if->sk_cdata.sk_tx_map[i] = 0;
    2519           0 :                 }
    2520             :         }
    2521             : 
    2522           0 :         while ((dma = SIMPLEQ_FIRST(&sc_if->sk_txmap_head))) {
    2523           0 :                 SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
    2524           0 :                 bus_dmamap_destroy(sc->sc_dmatag, dma->dmamap);
    2525           0 :                 free(dma, M_DEVBUF, 0);
    2526             :         }
    2527           0 : }
    2528             : 
    2529             : struct cfattach skc_ca = {
    2530             :         sizeof(struct sk_softc), skc_probe, skc_attach, skc_detach,
    2531             :         skc_activate
    2532             : };
    2533             : 
    2534             : struct cfdriver skc_cd = {
    2535             :         0, "skc", DV_DULL
    2536             : };
    2537             : 
    2538             : struct cfattach sk_ca = {
    2539             :         sizeof(struct sk_if_softc), sk_probe, sk_attach, sk_detach,
    2540             :         sk_activate
    2541             : };
    2542             : 
    2543             : struct cfdriver sk_cd = {
    2544             :         NULL, "sk", DV_IFNET
    2545             : };
    2546             : 
    2547             : #ifdef SK_DEBUG
    2548             : void
    2549             : sk_dump_txdesc(struct sk_tx_desc *desc, int idx)
    2550             : {
    2551             : #define DESC_PRINT(X)                                   \
    2552             :         if (X)                                          \
    2553             :                 printf("txdesc[%d]." #X "=%#x\n", idx, X);
    2554             : 
    2555             :         DESC_PRINT(letoh32(desc->sk_ctl));
    2556             :         DESC_PRINT(letoh32(desc->sk_next));
    2557             :         DESC_PRINT(letoh32(desc->sk_data_lo));
    2558             :         DESC_PRINT(letoh32(desc->sk_data_hi));
    2559             :         DESC_PRINT(letoh32(desc->sk_xmac_txstat));
    2560             :         DESC_PRINT(letoh16(desc->sk_rsvd0));
    2561             :         DESC_PRINT(letoh16(desc->sk_rsvd1));
    2562             : #undef PRINT
    2563             : }
    2564             : 
    2565             : void
    2566             : sk_dump_bytes(const char *data, int len)
    2567             : {
    2568             :         int c, i, j;
    2569             : 
    2570             :         for (i = 0; i < len; i += 16) {
    2571             :                 printf("%08x  ", i);
    2572             :                 c = len - i;
    2573             :                 if (c > 16) c = 16;
    2574             : 
    2575             :                 for (j = 0; j < c; j++) {
    2576             :                         printf("%02x ", data[i + j] & 0xff);
    2577             :                         if ((j & 0xf) == 7 && j > 0)
    2578             :                                 printf(" ");
    2579             :                 }
    2580             : 
    2581             :                 for (; j < 16; j++)
    2582             :                         printf("   ");
    2583             :                 printf("  ");
    2584             : 
    2585             :                 for (j = 0; j < c; j++) {
    2586             :                         int ch = data[i + j] & 0xff;
    2587             :                         printf("%c", ' ' <= ch && ch <= '~' ? ch : ' ');
    2588             :                 }
    2589             : 
    2590             :                 printf("\n");
    2591             : 
    2592             :                 if (c < 16)
    2593             :                         break;
    2594             :         }
    2595             : }
    2596             : 
    2597             : void
    2598             : sk_dump_mbuf(struct mbuf *m)
    2599             : {
    2600             :         int count = m->m_pkthdr.len;
    2601             : 
    2602             :         printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdr.len);
    2603             : 
    2604             :         while (count > 0 && m) {
    2605             :                 printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n",
    2606             :                     m, m->m_data, m->m_len);
    2607             :                 sk_dump_bytes(mtod(m, char *), m->m_len);
    2608             : 
    2609             :                 count -= m->m_len;
    2610             :                 m = m->m_next;
    2611             :         }
    2612             : }
    2613             : #endif

Generated by: LCOV version 1.13