The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cas/if_cas.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (C) 2001 Eduardo Horvath.
    5  * Copyright (c) 2001-2003 Thomas Moestl
    6  * Copyright (c) 2007-2009 Marius Strobl <marius@FreeBSD.org>
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  *      from: NetBSD: gem.c,v 1.21 2002/06/01 23:50:58 lukem Exp
   31  *      from: FreeBSD: if_gem.c 182060 2008-08-23 15:03:26Z marius
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD$");
   36 
   37 /*
   38  * driver for Sun Cassini/Cassini+ and National Semiconductor DP83065
   39  * Saturn Gigabit Ethernet controllers
   40  */
   41 
   42 #if 0
   43 #define CAS_DEBUG
   44 #endif
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/bus.h>
   49 #include <sys/callout.h>
   50 #include <sys/endian.h>
   51 #include <sys/mbuf.h>
   52 #include <sys/malloc.h>
   53 #include <sys/kernel.h>
   54 #include <sys/lock.h>
   55 #include <sys/module.h>
   56 #include <sys/mutex.h>
   57 #include <sys/refcount.h>
   58 #include <sys/resource.h>
   59 #include <sys/rman.h>
   60 #include <sys/socket.h>
   61 #include <sys/sockio.h>
   62 #include <sys/taskqueue.h>
   63 
   64 #include <net/bpf.h>
   65 #include <net/ethernet.h>
   66 #include <net/if.h>
   67 #include <net/if_var.h>
   68 #include <net/if_arp.h>
   69 #include <net/if_dl.h>
   70 #include <net/if_media.h>
   71 #include <net/if_types.h>
   72 #include <net/if_vlan_var.h>
   73 
   74 #include <netinet/in.h>
   75 #include <netinet/in_systm.h>
   76 #include <netinet/ip.h>
   77 #include <netinet/tcp.h>
   78 #include <netinet/udp.h>
   79 
   80 #include <machine/bus.h>
   81 #if defined(__powerpc__)
   82 #include <dev/ofw/ofw_bus.h>
   83 #include <dev/ofw/openfirm.h>
   84 #include <machine/ofw_machdep.h>
   85 #endif
   86 #include <machine/resource.h>
   87 
   88 #include <dev/mii/mii.h>
   89 #include <dev/mii/miivar.h>
   90 
   91 #include <dev/cas/if_casreg.h>
   92 #include <dev/cas/if_casvar.h>
   93 
   94 #include <dev/pci/pcireg.h>
   95 #include <dev/pci/pcivar.h>
   96 
   97 #include "miibus_if.h"
   98 
   99 #define RINGASSERT(n , min, max)                                        \
  100         CTASSERT(powerof2(n) && (n) >= (min) && (n) <= (max))
  101 
  102 RINGASSERT(CAS_NRXCOMP, 128, 32768);
  103 RINGASSERT(CAS_NRXDESC, 32, 8192);
  104 RINGASSERT(CAS_NRXDESC2, 32, 8192);
  105 RINGASSERT(CAS_NTXDESC, 32, 8192);
  106 
  107 #undef RINGASSERT
  108 
  109 #define CCDASSERT(m, a)                                                 \
  110         CTASSERT((offsetof(struct cas_control_data, m) & ((a) - 1)) == 0)
  111 
  112 CCDASSERT(ccd_rxcomps, CAS_RX_COMP_ALIGN);
  113 CCDASSERT(ccd_rxdescs, CAS_RX_DESC_ALIGN);
  114 CCDASSERT(ccd_rxdescs2, CAS_RX_DESC_ALIGN);
  115 
  116 #undef CCDASSERT
  117 
  118 #define CAS_TRIES       10000
  119 
  120 /*
  121  * According to documentation, the hardware has support for basic TCP
  122  * checksum offloading only, in practice this can be also used for UDP
  123  * however (i.e. the problem of previous Sun NICs that a checksum of 0x0
  124  * is not converted to 0xffff no longer exists).
  125  */
  126 #define CAS_CSUM_FEATURES       (CSUM_TCP | CSUM_UDP)
  127 
  128 static inline void cas_add_rxdesc(struct cas_softc *sc, u_int idx);
  129 static int      cas_attach(struct cas_softc *sc);
  130 static int      cas_bitwait(struct cas_softc *sc, bus_addr_t r, uint32_t clr,
  131                     uint32_t set);
  132 static void     cas_cddma_callback(void *xsc, bus_dma_segment_t *segs,
  133                     int nsegs, int error);
  134 static void     cas_detach(struct cas_softc *sc);
  135 static int      cas_disable_rx(struct cas_softc *sc);
  136 static int      cas_disable_tx(struct cas_softc *sc);
  137 static void     cas_eint(struct cas_softc *sc, u_int status);
  138 static void     cas_free(struct mbuf *m);
  139 static void     cas_init(void *xsc);
  140 static void     cas_init_locked(struct cas_softc *sc);
  141 static void     cas_init_regs(struct cas_softc *sc);
  142 static int      cas_intr(void *v);
  143 static void     cas_intr_task(void *arg, int pending __unused);
  144 static int      cas_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
  145 static int      cas_load_txmbuf(struct cas_softc *sc, struct mbuf **m_head);
  146 static int      cas_mediachange(struct ifnet *ifp);
  147 static void     cas_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr);
  148 static void     cas_meminit(struct cas_softc *sc);
  149 static void     cas_mifinit(struct cas_softc *sc);
  150 static int      cas_mii_readreg(device_t dev, int phy, int reg);
  151 static void     cas_mii_statchg(device_t dev);
  152 static int      cas_mii_writereg(device_t dev, int phy, int reg, int val);
  153 static void     cas_reset(struct cas_softc *sc);
  154 static int      cas_reset_rx(struct cas_softc *sc);
  155 static int      cas_reset_tx(struct cas_softc *sc);
  156 static void     cas_resume(struct cas_softc *sc);
  157 static u_int    cas_descsize(u_int sz);
  158 static void     cas_rint(struct cas_softc *sc);
  159 static void     cas_rint_timeout(void *arg);
  160 static inline void cas_rxcksum(struct mbuf *m, uint16_t cksum);
  161 static inline void cas_rxcompinit(struct cas_rx_comp *rxcomp);
  162 static u_int    cas_rxcompsize(u_int sz);
  163 static void     cas_rxdma_callback(void *xsc, bus_dma_segment_t *segs,
  164                     int nsegs, int error);
  165 static void     cas_setladrf(struct cas_softc *sc);
  166 static void     cas_start(struct ifnet *ifp);
  167 static void     cas_stop(struct ifnet *ifp);
  168 static void     cas_suspend(struct cas_softc *sc);
  169 static void     cas_tick(void *arg);
  170 static void     cas_tint(struct cas_softc *sc);
  171 static void     cas_tx_task(void *arg, int pending __unused);
  172 static inline void cas_txkick(struct cas_softc *sc);
  173 static void     cas_watchdog(struct cas_softc *sc);
  174 
  175 MODULE_DEPEND(cas, ether, 1, 1, 1);
  176 MODULE_DEPEND(cas, miibus, 1, 1, 1);
  177 
  178 #ifdef CAS_DEBUG
  179 #include <sys/ktr.h>
  180 #define KTR_CAS         KTR_SPARE2
  181 #endif
  182 
  183 static int
  184 cas_attach(struct cas_softc *sc)
  185 {
  186         struct cas_txsoft *txs;
  187         struct ifnet *ifp;
  188         int error, i;
  189         uint32_t v;
  190 
  191         /* Set up ifnet structure. */
  192         ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
  193         if (ifp == NULL)
  194                 return (ENOSPC);
  195         ifp->if_softc = sc;
  196         if_initname(ifp, device_get_name(sc->sc_dev),
  197             device_get_unit(sc->sc_dev));
  198         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  199         ifp->if_start = cas_start;
  200         ifp->if_ioctl = cas_ioctl;
  201         ifp->if_init = cas_init;
  202         IFQ_SET_MAXLEN(&ifp->if_snd, CAS_TXQUEUELEN);
  203         ifp->if_snd.ifq_drv_maxlen = CAS_TXQUEUELEN;
  204         IFQ_SET_READY(&ifp->if_snd);
  205 
  206         callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
  207         callout_init_mtx(&sc->sc_rx_ch, &sc->sc_mtx, 0);
  208         /* Create local taskq. */
  209         NET_TASK_INIT(&sc->sc_intr_task, 0, cas_intr_task, sc);
  210         TASK_INIT(&sc->sc_tx_task, 1, cas_tx_task, ifp);
  211         sc->sc_tq = taskqueue_create_fast("cas_taskq", M_WAITOK,
  212             taskqueue_thread_enqueue, &sc->sc_tq);
  213         if (sc->sc_tq == NULL) {
  214                 device_printf(sc->sc_dev, "could not create taskqueue\n");
  215                 error = ENXIO;
  216                 goto fail_ifnet;
  217         }
  218         error = taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
  219             device_get_nameunit(sc->sc_dev));
  220         if (error != 0) {
  221                 device_printf(sc->sc_dev, "could not start threads\n");
  222                 goto fail_taskq;
  223         }
  224 
  225         /* Make sure the chip is stopped. */
  226         cas_reset(sc);
  227 
  228         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
  229             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
  230             BUS_SPACE_MAXSIZE, 0, BUS_SPACE_MAXSIZE, 0, NULL, NULL,
  231             &sc->sc_pdmatag);
  232         if (error != 0)
  233                 goto fail_taskq;
  234 
  235         error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
  236             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
  237             CAS_PAGE_SIZE, 1, CAS_PAGE_SIZE, 0, NULL, NULL, &sc->sc_rdmatag);
  238         if (error != 0)
  239                 goto fail_ptag;
  240 
  241         error = bus_dma_tag_create(sc->sc_pdmatag, 1, 0,
  242             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
  243             MCLBYTES * CAS_NTXSEGS, CAS_NTXSEGS, MCLBYTES,
  244             BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_tdmatag);
  245         if (error != 0)
  246                 goto fail_rtag;
  247 
  248         error = bus_dma_tag_create(sc->sc_pdmatag, CAS_TX_DESC_ALIGN, 0,
  249             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
  250             sizeof(struct cas_control_data), 1,
  251             sizeof(struct cas_control_data), 0,
  252             NULL, NULL, &sc->sc_cdmatag);
  253         if (error != 0)
  254                 goto fail_ttag;
  255 
  256         /*
  257          * Allocate the control data structures, create and load the
  258          * DMA map for it.
  259          */
  260         if ((error = bus_dmamem_alloc(sc->sc_cdmatag,
  261             (void **)&sc->sc_control_data,
  262             BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
  263             &sc->sc_cddmamap)) != 0) {
  264                 device_printf(sc->sc_dev,
  265                     "unable to allocate control data, error = %d\n", error);
  266                 goto fail_ctag;
  267         }
  268 
  269         sc->sc_cddma = 0;
  270         if ((error = bus_dmamap_load(sc->sc_cdmatag, sc->sc_cddmamap,
  271             sc->sc_control_data, sizeof(struct cas_control_data),
  272             cas_cddma_callback, sc, 0)) != 0 || sc->sc_cddma == 0) {
  273                 device_printf(sc->sc_dev,
  274                     "unable to load control data DMA map, error = %d\n",
  275                     error);
  276                 goto fail_cmem;
  277         }
  278 
  279         /*
  280          * Initialize the transmit job descriptors.
  281          */
  282         STAILQ_INIT(&sc->sc_txfreeq);
  283         STAILQ_INIT(&sc->sc_txdirtyq);
  284 
  285         /*
  286          * Create the transmit buffer DMA maps.
  287          */
  288         error = ENOMEM;
  289         for (i = 0; i < CAS_TXQUEUELEN; i++) {
  290                 txs = &sc->sc_txsoft[i];
  291                 txs->txs_mbuf = NULL;
  292                 txs->txs_ndescs = 0;
  293                 if ((error = bus_dmamap_create(sc->sc_tdmatag, 0,
  294                     &txs->txs_dmamap)) != 0) {
  295                         device_printf(sc->sc_dev,
  296                             "unable to create TX DMA map %d, error = %d\n",
  297                             i, error);
  298                         goto fail_txd;
  299                 }
  300                 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
  301         }
  302 
  303         /*
  304          * Allocate the receive buffers, create and load the DMA maps
  305          * for them.
  306          */
  307         for (i = 0; i < CAS_NRXDESC; i++) {
  308                 if ((error = bus_dmamem_alloc(sc->sc_rdmatag,
  309                     &sc->sc_rxdsoft[i].rxds_buf, BUS_DMA_WAITOK,
  310                     &sc->sc_rxdsoft[i].rxds_dmamap)) != 0) {
  311                         device_printf(sc->sc_dev,
  312                             "unable to allocate RX buffer %d, error = %d\n",
  313                             i, error);
  314                         goto fail_rxmem;
  315                 }
  316 
  317                 sc->sc_rxdptr = i;
  318                 sc->sc_rxdsoft[i].rxds_paddr = 0;
  319                 if ((error = bus_dmamap_load(sc->sc_rdmatag,
  320                     sc->sc_rxdsoft[i].rxds_dmamap, sc->sc_rxdsoft[i].rxds_buf,
  321                     CAS_PAGE_SIZE, cas_rxdma_callback, sc, 0)) != 0 ||
  322                     sc->sc_rxdsoft[i].rxds_paddr == 0) {
  323                         device_printf(sc->sc_dev,
  324                             "unable to load RX DMA map %d, error = %d\n",
  325                             i, error);
  326                         goto fail_rxmap;
  327                 }
  328         }
  329 
  330         if ((sc->sc_flags & CAS_SERDES) == 0) {
  331                 CAS_WRITE_4(sc, CAS_PCS_DATAPATH, CAS_PCS_DATAPATH_MII);
  332                 CAS_BARRIER(sc, CAS_PCS_DATAPATH, 4,
  333                     BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  334                 cas_mifinit(sc);
  335                 /*
  336                  * Look for an external PHY.
  337                  */
  338                 error = ENXIO;
  339                 v = CAS_READ_4(sc, CAS_MIF_CONF);
  340                 if ((v & CAS_MIF_CONF_MDI1) != 0) {
  341                         v |= CAS_MIF_CONF_PHY_SELECT;
  342                         CAS_WRITE_4(sc, CAS_MIF_CONF, v);
  343                         CAS_BARRIER(sc, CAS_MIF_CONF, 4,
  344                             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  345                         /* Enable/unfreeze the GMII pins of Saturn. */
  346                         if (sc->sc_variant == CAS_SATURN) {
  347                                 CAS_WRITE_4(sc, CAS_SATURN_PCFG,
  348                                     CAS_READ_4(sc, CAS_SATURN_PCFG) &
  349                                     ~CAS_SATURN_PCFG_FSI);
  350                                 CAS_BARRIER(sc, CAS_SATURN_PCFG, 4,
  351                                     BUS_SPACE_BARRIER_READ |
  352                                     BUS_SPACE_BARRIER_WRITE);
  353                                 DELAY(10000);
  354                         }
  355                         error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
  356                             cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
  357                             MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE);
  358                 }
  359                 /*
  360                  * Fall back on an internal PHY if no external PHY was found.
  361                  */
  362                 if (error != 0 && (v & CAS_MIF_CONF_MDI0) != 0) {
  363                         v &= ~CAS_MIF_CONF_PHY_SELECT;
  364                         CAS_WRITE_4(sc, CAS_MIF_CONF, v);
  365                         CAS_BARRIER(sc, CAS_MIF_CONF, 4,
  366                             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  367                         /* Freeze the GMII pins of Saturn for saving power. */
  368                         if (sc->sc_variant == CAS_SATURN) {
  369                                 CAS_WRITE_4(sc, CAS_SATURN_PCFG,
  370                                     CAS_READ_4(sc, CAS_SATURN_PCFG) |
  371                                     CAS_SATURN_PCFG_FSI);
  372                                 CAS_BARRIER(sc, CAS_SATURN_PCFG, 4,
  373                                     BUS_SPACE_BARRIER_READ |
  374                                     BUS_SPACE_BARRIER_WRITE);
  375                                 DELAY(10000);
  376                         }
  377                         error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
  378                             cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
  379                             MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE);
  380                 }
  381         } else {
  382                 /*
  383                  * Use the external PCS SERDES.
  384                  */
  385                 CAS_WRITE_4(sc, CAS_PCS_DATAPATH, CAS_PCS_DATAPATH_SERDES);
  386                 CAS_BARRIER(sc, CAS_PCS_DATAPATH, 4, BUS_SPACE_BARRIER_WRITE);
  387                 /* Enable/unfreeze the SERDES pins of Saturn. */
  388                 if (sc->sc_variant == CAS_SATURN) {
  389                         CAS_WRITE_4(sc, CAS_SATURN_PCFG, 0);
  390                         CAS_BARRIER(sc, CAS_SATURN_PCFG, 4,
  391                             BUS_SPACE_BARRIER_WRITE);
  392                 }
  393                 CAS_WRITE_4(sc, CAS_PCS_SERDES_CTRL, CAS_PCS_SERDES_CTRL_ESD);
  394                 CAS_BARRIER(sc, CAS_PCS_SERDES_CTRL, 4,
  395                     BUS_SPACE_BARRIER_WRITE);
  396                 CAS_WRITE_4(sc, CAS_PCS_CONF, CAS_PCS_CONF_EN);
  397                 CAS_BARRIER(sc, CAS_PCS_CONF, 4,
  398                     BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  399                 error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
  400                     cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
  401                     CAS_PHYAD_EXTERNAL, MII_OFFSET_ANY, MIIF_DOPAUSE);
  402         }
  403         if (error != 0) {
  404                 device_printf(sc->sc_dev, "attaching PHYs failed\n");
  405                 goto fail_rxmap;
  406         }
  407         sc->sc_mii = device_get_softc(sc->sc_miibus);
  408 
  409         /*
  410          * From this point forward, the attachment cannot fail.  A failure
  411          * before this point releases all resources that may have been
  412          * allocated.
  413          */
  414 
  415         /* Announce FIFO sizes. */
  416         v = CAS_READ_4(sc, CAS_TX_FIFO_SIZE);
  417         device_printf(sc->sc_dev, "%ukB RX FIFO, %ukB TX FIFO\n",
  418             CAS_RX_FIFO_SIZE / 1024, v / 16);
  419 
  420         /* Attach the interface. */
  421         ether_ifattach(ifp, sc->sc_enaddr);
  422 
  423         /*
  424          * Tell the upper layer(s) we support long frames/checksum offloads.
  425          */
  426         ifp->if_hdrlen = sizeof(struct ether_vlan_header);
  427         ifp->if_capabilities = IFCAP_VLAN_MTU;
  428         if ((sc->sc_flags & CAS_NO_CSUM) == 0) {
  429                 ifp->if_capabilities |= IFCAP_HWCSUM;
  430                 ifp->if_hwassist = CAS_CSUM_FEATURES;
  431         }
  432         ifp->if_capenable = ifp->if_capabilities;
  433 
  434         return (0);
  435 
  436         /*
  437          * Free any resources we've allocated during the failed attach
  438          * attempt.  Do this in reverse order and fall through.
  439          */
  440  fail_rxmap:
  441         for (i = 0; i < CAS_NRXDESC; i++)
  442                 if (sc->sc_rxdsoft[i].rxds_paddr != 0)
  443                         bus_dmamap_unload(sc->sc_rdmatag,
  444                             sc->sc_rxdsoft[i].rxds_dmamap);
  445  fail_rxmem:
  446         for (i = 0; i < CAS_NRXDESC; i++)
  447                 if (sc->sc_rxdsoft[i].rxds_buf != NULL)
  448                         bus_dmamem_free(sc->sc_rdmatag,
  449                             sc->sc_rxdsoft[i].rxds_buf,
  450                             sc->sc_rxdsoft[i].rxds_dmamap);
  451  fail_txd:
  452         for (i = 0; i < CAS_TXQUEUELEN; i++)
  453                 if (sc->sc_txsoft[i].txs_dmamap != NULL)
  454                         bus_dmamap_destroy(sc->sc_tdmatag,
  455                             sc->sc_txsoft[i].txs_dmamap);
  456         bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cddmamap);
  457  fail_cmem:
  458         bus_dmamem_free(sc->sc_cdmatag, sc->sc_control_data,
  459             sc->sc_cddmamap);
  460  fail_ctag:
  461         bus_dma_tag_destroy(sc->sc_cdmatag);
  462  fail_ttag:
  463         bus_dma_tag_destroy(sc->sc_tdmatag);
  464  fail_rtag:
  465         bus_dma_tag_destroy(sc->sc_rdmatag);
  466  fail_ptag:
  467         bus_dma_tag_destroy(sc->sc_pdmatag);
  468  fail_taskq:
  469         taskqueue_free(sc->sc_tq);
  470  fail_ifnet:
  471         if_free(ifp);
  472         return (error);
  473 }
  474 
  475 static void
  476 cas_detach(struct cas_softc *sc)
  477 {
  478         struct ifnet *ifp = sc->sc_ifp;
  479         int i;
  480 
  481         ether_ifdetach(ifp);
  482         CAS_LOCK(sc);
  483         cas_stop(ifp);
  484         CAS_UNLOCK(sc);
  485         callout_drain(&sc->sc_tick_ch);
  486         callout_drain(&sc->sc_rx_ch);
  487         taskqueue_drain(sc->sc_tq, &sc->sc_intr_task);
  488         taskqueue_drain(sc->sc_tq, &sc->sc_tx_task);
  489         if_free(ifp);
  490         taskqueue_free(sc->sc_tq);
  491         device_delete_child(sc->sc_dev, sc->sc_miibus);
  492 
  493         for (i = 0; i < CAS_NRXDESC; i++)
  494                 if (sc->sc_rxdsoft[i].rxds_dmamap != NULL)
  495                         bus_dmamap_sync(sc->sc_rdmatag,
  496                             sc->sc_rxdsoft[i].rxds_dmamap,
  497                             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  498         for (i = 0; i < CAS_NRXDESC; i++)
  499                 if (sc->sc_rxdsoft[i].rxds_paddr != 0)
  500                         bus_dmamap_unload(sc->sc_rdmatag,
  501                             sc->sc_rxdsoft[i].rxds_dmamap);
  502         for (i = 0; i < CAS_NRXDESC; i++)
  503                 if (sc->sc_rxdsoft[i].rxds_buf != NULL)
  504                         bus_dmamem_free(sc->sc_rdmatag,
  505                             sc->sc_rxdsoft[i].rxds_buf,
  506                             sc->sc_rxdsoft[i].rxds_dmamap);
  507         for (i = 0; i < CAS_TXQUEUELEN; i++)
  508                 if (sc->sc_txsoft[i].txs_dmamap != NULL)
  509                         bus_dmamap_destroy(sc->sc_tdmatag,
  510                             sc->sc_txsoft[i].txs_dmamap);
  511         CAS_CDSYNC(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  512         bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cddmamap);
  513         bus_dmamem_free(sc->sc_cdmatag, sc->sc_control_data,
  514             sc->sc_cddmamap);
  515         bus_dma_tag_destroy(sc->sc_cdmatag);
  516         bus_dma_tag_destroy(sc->sc_tdmatag);
  517         bus_dma_tag_destroy(sc->sc_rdmatag);
  518         bus_dma_tag_destroy(sc->sc_pdmatag);
  519 }
  520 
  521 static void
  522 cas_suspend(struct cas_softc *sc)
  523 {
  524         struct ifnet *ifp = sc->sc_ifp;
  525 
  526         CAS_LOCK(sc);
  527         cas_stop(ifp);
  528         CAS_UNLOCK(sc);
  529 }
  530 
  531 static void
  532 cas_resume(struct cas_softc *sc)
  533 {
  534         struct ifnet *ifp = sc->sc_ifp;
  535 
  536         CAS_LOCK(sc);
  537         /*
  538          * On resume all registers have to be initialized again like
  539          * after power-on.
  540          */
  541         sc->sc_flags &= ~CAS_INITED;
  542         if (ifp->if_flags & IFF_UP)
  543                 cas_init_locked(sc);
  544         CAS_UNLOCK(sc);
  545 }
  546 
  547 static inline void
  548 cas_rxcksum(struct mbuf *m, uint16_t cksum)
  549 {
  550         struct ether_header *eh;
  551         struct ip *ip;
  552         struct udphdr *uh;
  553         uint16_t *opts;
  554         int32_t hlen, len, pktlen;
  555         uint32_t temp32;
  556 
  557         pktlen = m->m_pkthdr.len;
  558         if (pktlen < sizeof(struct ether_header) + sizeof(struct ip))
  559                 return;
  560         eh = mtod(m, struct ether_header *);
  561         if (eh->ether_type != htons(ETHERTYPE_IP))
  562                 return;
  563         ip = (struct ip *)(eh + 1);
  564         if (ip->ip_v != IPVERSION)
  565                 return;
  566 
  567         hlen = ip->ip_hl << 2;
  568         pktlen -= sizeof(struct ether_header);
  569         if (hlen < sizeof(struct ip))
  570                 return;
  571         if (ntohs(ip->ip_len) < hlen)
  572                 return;
  573         if (ntohs(ip->ip_len) != pktlen)
  574                 return;
  575         if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
  576                 return; /* Cannot handle fragmented packet. */
  577 
  578         switch (ip->ip_p) {
  579         case IPPROTO_TCP:
  580                 if (pktlen < (hlen + sizeof(struct tcphdr)))
  581                         return;
  582                 break;
  583         case IPPROTO_UDP:
  584                 if (pktlen < (hlen + sizeof(struct udphdr)))
  585                         return;
  586                 uh = (struct udphdr *)((uint8_t *)ip + hlen);
  587                 if (uh->uh_sum == 0)
  588                         return; /* no checksum */
  589                 break;
  590         default:
  591                 return;
  592         }
  593 
  594         cksum = ~cksum;
  595         /* checksum fixup for IP options */
  596         len = hlen - sizeof(struct ip);
  597         if (len > 0) {
  598                 opts = (uint16_t *)(ip + 1);
  599                 for (; len > 0; len -= sizeof(uint16_t), opts++) {
  600                         temp32 = cksum - *opts;
  601                         temp32 = (temp32 >> 16) + (temp32 & 65535);
  602                         cksum = temp32 & 65535;
  603                 }
  604         }
  605         m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
  606         m->m_pkthdr.csum_data = cksum;
  607 }
  608 
  609 static void
  610 cas_cddma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
  611 {
  612         struct cas_softc *sc = xsc;
  613 
  614         if (error != 0)
  615                 return;
  616         if (nsegs != 1)
  617                 panic("%s: bad control buffer segment count", __func__);
  618         sc->sc_cddma = segs[0].ds_addr;
  619 }
  620 
  621 static void
  622 cas_rxdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
  623 {
  624         struct cas_softc *sc = xsc;
  625 
  626         if (error != 0)
  627                 return;
  628         if (nsegs != 1)
  629                 panic("%s: bad RX buffer segment count", __func__);
  630         sc->sc_rxdsoft[sc->sc_rxdptr].rxds_paddr = segs[0].ds_addr;
  631 }
  632 
  633 static void
  634 cas_tick(void *arg)
  635 {
  636         struct cas_softc *sc = arg;
  637         struct ifnet *ifp = sc->sc_ifp;
  638         uint32_t v;
  639 
  640         CAS_LOCK_ASSERT(sc, MA_OWNED);
  641 
  642         /*
  643          * Unload collision and error counters.
  644          */
  645         if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
  646             CAS_READ_4(sc, CAS_MAC_NORM_COLL_CNT) +
  647             CAS_READ_4(sc, CAS_MAC_FIRST_COLL_CNT));
  648         v = CAS_READ_4(sc, CAS_MAC_EXCESS_COLL_CNT) +
  649             CAS_READ_4(sc, CAS_MAC_LATE_COLL_CNT);
  650         if_inc_counter(ifp, IFCOUNTER_COLLISIONS, v);
  651         if_inc_counter(ifp, IFCOUNTER_OERRORS, v);
  652         if_inc_counter(ifp, IFCOUNTER_IERRORS,
  653             CAS_READ_4(sc, CAS_MAC_RX_LEN_ERR_CNT) +
  654             CAS_READ_4(sc, CAS_MAC_RX_ALIGN_ERR) +
  655             CAS_READ_4(sc, CAS_MAC_RX_CRC_ERR_CNT) +
  656             CAS_READ_4(sc, CAS_MAC_RX_CODE_VIOL));
  657 
  658         /*
  659          * Then clear the hardware counters.
  660          */
  661         CAS_WRITE_4(sc, CAS_MAC_NORM_COLL_CNT, 0);
  662         CAS_WRITE_4(sc, CAS_MAC_FIRST_COLL_CNT, 0);
  663         CAS_WRITE_4(sc, CAS_MAC_EXCESS_COLL_CNT, 0);
  664         CAS_WRITE_4(sc, CAS_MAC_LATE_COLL_CNT, 0);
  665         CAS_WRITE_4(sc, CAS_MAC_RX_LEN_ERR_CNT, 0);
  666         CAS_WRITE_4(sc, CAS_MAC_RX_ALIGN_ERR, 0);
  667         CAS_WRITE_4(sc, CAS_MAC_RX_CRC_ERR_CNT, 0);
  668         CAS_WRITE_4(sc, CAS_MAC_RX_CODE_VIOL, 0);
  669 
  670         mii_tick(sc->sc_mii);
  671 
  672         if (sc->sc_txfree != CAS_MAXTXFREE)
  673                 cas_tint(sc);
  674 
  675         cas_watchdog(sc);
  676 
  677         callout_reset(&sc->sc_tick_ch, hz, cas_tick, sc);
  678 }
  679 
  680 static int
  681 cas_bitwait(struct cas_softc *sc, bus_addr_t r, uint32_t clr, uint32_t set)
  682 {
  683         int i;
  684         uint32_t reg;
  685 
  686         for (i = CAS_TRIES; i--; DELAY(100)) {
  687                 reg = CAS_READ_4(sc, r);
  688                 if ((reg & clr) == 0 && (reg & set) == set)
  689                         return (1);
  690         }
  691         return (0);
  692 }
  693 
  694 static void
  695 cas_reset(struct cas_softc *sc)
  696 {
  697 
  698 #ifdef CAS_DEBUG
  699         CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__);
  700 #endif
  701         /* Disable all interrupts in order to avoid spurious ones. */
  702         CAS_WRITE_4(sc, CAS_INTMASK, 0xffffffff);
  703 
  704         cas_reset_rx(sc);
  705         cas_reset_tx(sc);
  706 
  707         /*
  708          * Do a full reset modulo the result of the last auto-negotiation
  709          * when using the SERDES.
  710          */
  711         CAS_WRITE_4(sc, CAS_RESET, CAS_RESET_RX | CAS_RESET_TX |
  712             ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0));
  713         CAS_BARRIER(sc, CAS_RESET, 4,
  714             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  715         DELAY(3000);
  716         if (!cas_bitwait(sc, CAS_RESET, CAS_RESET_RX | CAS_RESET_TX, 0))
  717                 device_printf(sc->sc_dev, "cannot reset device\n");
  718 }
  719 
  720 static void
  721 cas_stop(struct ifnet *ifp)
  722 {
  723         struct cas_softc *sc = ifp->if_softc;
  724         struct cas_txsoft *txs;
  725 
  726 #ifdef CAS_DEBUG
  727         CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__);
  728 #endif
  729 
  730         callout_stop(&sc->sc_tick_ch);
  731         callout_stop(&sc->sc_rx_ch);
  732 
  733         /* Disable all interrupts in order to avoid spurious ones. */
  734         CAS_WRITE_4(sc, CAS_INTMASK, 0xffffffff);
  735 
  736         cas_reset_tx(sc);
  737         cas_reset_rx(sc);
  738 
  739         /*
  740          * Release any queued transmit buffers.
  741          */
  742         while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
  743                 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
  744                 if (txs->txs_ndescs != 0) {
  745                         bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap,
  746                             BUS_DMASYNC_POSTWRITE);
  747                         bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap);
  748                         if (txs->txs_mbuf != NULL) {
  749                                 m_freem(txs->txs_mbuf);
  750                                 txs->txs_mbuf = NULL;
  751                         }
  752                 }
  753                 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
  754         }
  755 
  756         /*
  757          * Mark the interface down and cancel the watchdog timer.
  758          */
  759         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
  760         sc->sc_flags &= ~CAS_LINK;
  761         sc->sc_wdog_timer = 0;
  762 }
  763 
  764 static int
  765 cas_reset_rx(struct cas_softc *sc)
  766 {
  767 
  768         /*
  769          * Resetting while DMA is in progress can cause a bus hang, so we
  770          * disable DMA first.
  771          */
  772         (void)cas_disable_rx(sc);
  773         CAS_WRITE_4(sc, CAS_RX_CONF, 0);
  774         CAS_BARRIER(sc, CAS_RX_CONF, 4,
  775             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  776         if (!cas_bitwait(sc, CAS_RX_CONF, CAS_RX_CONF_RXDMA_EN, 0))
  777                 device_printf(sc->sc_dev, "cannot disable RX DMA\n");
  778 
  779         /* Finally, reset the ERX. */
  780         CAS_WRITE_4(sc, CAS_RESET, CAS_RESET_RX |
  781             ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0));
  782         CAS_BARRIER(sc, CAS_RESET, 4,
  783             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  784         if (!cas_bitwait(sc, CAS_RESET, CAS_RESET_RX, 0)) {
  785                 device_printf(sc->sc_dev, "cannot reset receiver\n");
  786                 return (1);
  787         }
  788         return (0);
  789 }
  790 
  791 static int
  792 cas_reset_tx(struct cas_softc *sc)
  793 {
  794 
  795         /*
  796          * Resetting while DMA is in progress can cause a bus hang, so we
  797          * disable DMA first.
  798          */
  799         (void)cas_disable_tx(sc);
  800         CAS_WRITE_4(sc, CAS_TX_CONF, 0);
  801         CAS_BARRIER(sc, CAS_TX_CONF, 4,
  802             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  803         if (!cas_bitwait(sc, CAS_TX_CONF, CAS_TX_CONF_TXDMA_EN, 0))
  804                 device_printf(sc->sc_dev, "cannot disable TX DMA\n");
  805 
  806         /* Finally, reset the ETX. */
  807         CAS_WRITE_4(sc, CAS_RESET, CAS_RESET_TX |
  808             ((sc->sc_flags & CAS_SERDES) != 0 ? CAS_RESET_PCS_DIS : 0));
  809         CAS_BARRIER(sc, CAS_RESET, 4,
  810             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  811         if (!cas_bitwait(sc, CAS_RESET, CAS_RESET_TX, 0)) {
  812                 device_printf(sc->sc_dev, "cannot reset transmitter\n");
  813                 return (1);
  814         }
  815         return (0);
  816 }
  817 
  818 static int
  819 cas_disable_rx(struct cas_softc *sc)
  820 {
  821 
  822         CAS_WRITE_4(sc, CAS_MAC_RX_CONF,
  823             CAS_READ_4(sc, CAS_MAC_RX_CONF) & ~CAS_MAC_RX_CONF_EN);
  824         CAS_BARRIER(sc, CAS_MAC_RX_CONF, 4,
  825             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  826         if (cas_bitwait(sc, CAS_MAC_RX_CONF, CAS_MAC_RX_CONF_EN, 0))
  827                 return (1);
  828         if (bootverbose)
  829                 device_printf(sc->sc_dev, "cannot disable RX MAC\n");
  830         return (0);
  831 }
  832 
  833 static int
  834 cas_disable_tx(struct cas_softc *sc)
  835 {
  836 
  837         CAS_WRITE_4(sc, CAS_MAC_TX_CONF,
  838             CAS_READ_4(sc, CAS_MAC_TX_CONF) & ~CAS_MAC_TX_CONF_EN);
  839         CAS_BARRIER(sc, CAS_MAC_TX_CONF, 4,
  840             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  841         if (cas_bitwait(sc, CAS_MAC_TX_CONF, CAS_MAC_TX_CONF_EN, 0))
  842                 return (1);
  843         if (bootverbose)
  844                 device_printf(sc->sc_dev, "cannot disable TX MAC\n");
  845         return (0);
  846 }
  847 
  848 static inline void
  849 cas_rxcompinit(struct cas_rx_comp *rxcomp)
  850 {
  851 
  852         rxcomp->crc_word1 = 0;
  853         rxcomp->crc_word2 = 0;
  854         rxcomp->crc_word3 =
  855             htole64(CAS_SET(ETHER_HDR_LEN + sizeof(struct ip), CAS_RC3_CSO));
  856         rxcomp->crc_word4 = htole64(CAS_RC4_ZERO);
  857 }
  858 
  859 static void
  860 cas_meminit(struct cas_softc *sc)
  861 {
  862         int i;
  863 
  864         CAS_LOCK_ASSERT(sc, MA_OWNED);
  865 
  866         /*
  867          * Initialize the transmit descriptor ring.
  868          */
  869         for (i = 0; i < CAS_NTXDESC; i++) {
  870                 sc->sc_txdescs[i].cd_flags = 0;
  871                 sc->sc_txdescs[i].cd_buf_ptr = 0;
  872         }
  873         sc->sc_txfree = CAS_MAXTXFREE;
  874         sc->sc_txnext = 0;
  875         sc->sc_txwin = 0;
  876 
  877         /*
  878          * Initialize the receive completion ring.
  879          */
  880         for (i = 0; i < CAS_NRXCOMP; i++)
  881                 cas_rxcompinit(&sc->sc_rxcomps[i]);
  882         sc->sc_rxcptr = 0;
  883 
  884         /*
  885          * Initialize the first receive descriptor ring.  We leave
  886          * the second one zeroed as we don't actually use it.
  887          */
  888         for (i = 0; i < CAS_NRXDESC; i++)
  889                 CAS_INIT_RXDESC(sc, i, i);
  890         sc->sc_rxdptr = 0;
  891 
  892         CAS_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  893 }
  894 
  895 static u_int
  896 cas_descsize(u_int sz)
  897 {
  898 
  899         switch (sz) {
  900         case 32:
  901                 return (CAS_DESC_32);
  902         case 64:
  903                 return (CAS_DESC_64);
  904         case 128:
  905                 return (CAS_DESC_128);
  906         case 256:
  907                 return (CAS_DESC_256);
  908         case 512:
  909                 return (CAS_DESC_512);
  910         case 1024:
  911                 return (CAS_DESC_1K);
  912         case 2048:
  913                 return (CAS_DESC_2K);
  914         case 4096:
  915                 return (CAS_DESC_4K);
  916         case 8192:
  917                 return (CAS_DESC_8K);
  918         default:
  919                 printf("%s: invalid descriptor ring size %d\n", __func__, sz);
  920                 return (CAS_DESC_32);
  921         }
  922 }
  923 
  924 static u_int
  925 cas_rxcompsize(u_int sz)
  926 {
  927 
  928         switch (sz) {
  929         case 128:
  930                 return (CAS_RX_CONF_COMP_128);
  931         case 256:
  932                 return (CAS_RX_CONF_COMP_256);
  933         case 512:
  934                 return (CAS_RX_CONF_COMP_512);
  935         case 1024:
  936                 return (CAS_RX_CONF_COMP_1K);
  937         case 2048:
  938                 return (CAS_RX_CONF_COMP_2K);
  939         case 4096:
  940                 return (CAS_RX_CONF_COMP_4K);
  941         case 8192:
  942                 return (CAS_RX_CONF_COMP_8K);
  943         case 16384:
  944                 return (CAS_RX_CONF_COMP_16K);
  945         case 32768:
  946                 return (CAS_RX_CONF_COMP_32K);
  947         default:
  948                 printf("%s: invalid dcompletion ring size %d\n", __func__, sz);
  949                 return (CAS_RX_CONF_COMP_128);
  950         }
  951 }
  952 
  953 static void
  954 cas_init(void *xsc)
  955 {
  956         struct cas_softc *sc = xsc;
  957 
  958         CAS_LOCK(sc);
  959         cas_init_locked(sc);
  960         CAS_UNLOCK(sc);
  961 }
  962 
  963 /*
  964  * Initialization of interface; set up initialization block
  965  * and transmit/receive descriptor rings.
  966  */
  967 static void
  968 cas_init_locked(struct cas_softc *sc)
  969 {
  970         struct ifnet *ifp = sc->sc_ifp;
  971         uint32_t v;
  972 
  973         CAS_LOCK_ASSERT(sc, MA_OWNED);
  974 
  975         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
  976                 return;
  977 
  978 #ifdef CAS_DEBUG
  979         CTR2(KTR_CAS, "%s: %s: calling stop", device_get_name(sc->sc_dev),
  980             __func__);
  981 #endif
  982         /*
  983          * Initialization sequence.  The numbered steps below correspond
  984          * to the sequence outlined in section 6.3.5.1 in the Ethernet
  985          * Channel Engine manual (part of the PCIO manual).
  986          * See also the STP2002-STQ document from Sun Microsystems.
  987          */
  988 
  989         /* step 1 & 2.  Reset the Ethernet Channel. */
  990         cas_stop(ifp);
  991         cas_reset(sc);
  992 #ifdef CAS_DEBUG
  993         CTR2(KTR_CAS, "%s: %s: restarting", device_get_name(sc->sc_dev),
  994             __func__);
  995 #endif
  996 
  997         if ((sc->sc_flags & CAS_SERDES) == 0)
  998                 /* Re-initialize the MIF. */
  999                 cas_mifinit(sc);
 1000 
 1001         /* step 3.  Setup data structures in host memory. */
 1002         cas_meminit(sc);
 1003 
 1004         /* step 4.  TX MAC registers & counters */
 1005         cas_init_regs(sc);
 1006 
 1007         /* step 5.  RX MAC registers & counters */
 1008 
 1009         /* step 6 & 7.  Program Ring Base Addresses. */
 1010         CAS_WRITE_4(sc, CAS_TX_DESC3_BASE_HI,
 1011             (((uint64_t)CAS_CDTXDADDR(sc, 0)) >> 32));
 1012         CAS_WRITE_4(sc, CAS_TX_DESC3_BASE_LO,
 1013             CAS_CDTXDADDR(sc, 0) & 0xffffffff);
 1014 
 1015         CAS_WRITE_4(sc, CAS_RX_COMP_BASE_HI,
 1016             (((uint64_t)CAS_CDRXCADDR(sc, 0)) >> 32));
 1017         CAS_WRITE_4(sc, CAS_RX_COMP_BASE_LO,
 1018             CAS_CDRXCADDR(sc, 0) & 0xffffffff);
 1019 
 1020         CAS_WRITE_4(sc, CAS_RX_DESC_BASE_HI,
 1021             (((uint64_t)CAS_CDRXDADDR(sc, 0)) >> 32));
 1022         CAS_WRITE_4(sc, CAS_RX_DESC_BASE_LO,
 1023             CAS_CDRXDADDR(sc, 0) & 0xffffffff);
 1024 
 1025         if ((sc->sc_flags & CAS_REG_PLUS) != 0) {
 1026                 CAS_WRITE_4(sc, CAS_RX_DESC2_BASE_HI,
 1027                     (((uint64_t)CAS_CDRXD2ADDR(sc, 0)) >> 32));
 1028                 CAS_WRITE_4(sc, CAS_RX_DESC2_BASE_LO,
 1029                     CAS_CDRXD2ADDR(sc, 0) & 0xffffffff);
 1030         }
 1031 
 1032 #ifdef CAS_DEBUG
 1033         CTR5(KTR_CAS,
 1034             "loading TXDR %lx, RXCR %lx, RXDR %lx, RXD2R %lx, cddma %lx",
 1035             CAS_CDTXDADDR(sc, 0), CAS_CDRXCADDR(sc, 0), CAS_CDRXDADDR(sc, 0),
 1036             CAS_CDRXD2ADDR(sc, 0), sc->sc_cddma);
 1037 #endif
 1038 
 1039         /* step 8.  Global Configuration & Interrupt Masks */
 1040 
 1041         /* Disable weighted round robin. */
 1042         CAS_WRITE_4(sc, CAS_CAW, CAS_CAW_RR_DIS);
 1043 
 1044         /*
 1045          * Enable infinite bursts for revisions without PCI issues if
 1046          * applicable.  Doing so greatly improves the TX performance.
 1047          */
 1048         CAS_WRITE_4(sc, CAS_INF_BURST,
 1049             (sc->sc_flags & CAS_TABORT) == 0 ? CAS_INF_BURST_EN :
 1050             0);
 1051 
 1052         /* Set up interrupts. */
 1053         CAS_WRITE_4(sc, CAS_INTMASK,
 1054             ~(CAS_INTR_TX_INT_ME | CAS_INTR_TX_TAG_ERR |
 1055             CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_TAG_ERR |
 1056             CAS_INTR_RX_COMP_FULL | CAS_INTR_RX_BUF_AEMPTY |
 1057             CAS_INTR_RX_COMP_AFULL | CAS_INTR_RX_LEN_MMATCH |
 1058             CAS_INTR_PCI_ERROR_INT
 1059 #ifdef CAS_DEBUG
 1060             | CAS_INTR_PCS_INT | CAS_INTR_MIF
 1061 #endif
 1062             ));
 1063         /* Don't clear top level interrupts when CAS_STATUS_ALIAS is read. */
 1064         CAS_WRITE_4(sc, CAS_CLEAR_ALIAS, 0);
 1065         CAS_WRITE_4(sc, CAS_MAC_RX_MASK, ~CAS_MAC_RX_OVERFLOW);
 1066         CAS_WRITE_4(sc, CAS_MAC_TX_MASK,
 1067             ~(CAS_MAC_TX_UNDERRUN | CAS_MAC_TX_MAX_PKT_ERR));
 1068 #ifdef CAS_DEBUG
 1069         CAS_WRITE_4(sc, CAS_MAC_CTRL_MASK,
 1070             ~(CAS_MAC_CTRL_PAUSE_RCVD | CAS_MAC_CTRL_PAUSE |
 1071             CAS_MAC_CTRL_NON_PAUSE));
 1072 #else
 1073         CAS_WRITE_4(sc, CAS_MAC_CTRL_MASK,
 1074             CAS_MAC_CTRL_PAUSE_RCVD | CAS_MAC_CTRL_PAUSE |
 1075             CAS_MAC_CTRL_NON_PAUSE);
 1076 #endif
 1077 
 1078         /* Enable PCI error interrupts. */
 1079         CAS_WRITE_4(sc, CAS_ERROR_MASK,
 1080             ~(CAS_ERROR_DTRTO | CAS_ERROR_OTHER | CAS_ERROR_DMAW_ZERO |
 1081             CAS_ERROR_DMAR_ZERO | CAS_ERROR_RTRTO));
 1082 
 1083         /* Enable PCI error interrupts in BIM configuration. */
 1084         CAS_WRITE_4(sc, CAS_BIM_CONF,
 1085             CAS_BIM_CONF_DPAR_EN | CAS_BIM_CONF_RMA_EN | CAS_BIM_CONF_RTA_EN);
 1086 
 1087         /*
 1088          * step 9.  ETX Configuration: encode receive descriptor ring size,
 1089          * enable DMA and disable pre-interrupt writeback completion.
 1090          */
 1091         v = cas_descsize(CAS_NTXDESC) << CAS_TX_CONF_DESC3_SHFT;
 1092         CAS_WRITE_4(sc, CAS_TX_CONF, v | CAS_TX_CONF_TXDMA_EN |
 1093             CAS_TX_CONF_RDPP_DIS | CAS_TX_CONF_PICWB_DIS);
 1094 
 1095         /* step 10.  ERX Configuration */
 1096 
 1097         /*
 1098          * Encode receive completion and descriptor ring sizes, set the
 1099          * swivel offset.
 1100          */
 1101         v = cas_rxcompsize(CAS_NRXCOMP) << CAS_RX_CONF_COMP_SHFT;
 1102         v |= cas_descsize(CAS_NRXDESC) << CAS_RX_CONF_DESC_SHFT;
 1103         if ((sc->sc_flags & CAS_REG_PLUS) != 0)
 1104                 v |= cas_descsize(CAS_NRXDESC2) << CAS_RX_CONF_DESC2_SHFT;
 1105         CAS_WRITE_4(sc, CAS_RX_CONF,
 1106             v | (ETHER_ALIGN << CAS_RX_CONF_SOFF_SHFT));
 1107 
 1108         /* Set the PAUSE thresholds.  We use the maximum OFF threshold. */
 1109         CAS_WRITE_4(sc, CAS_RX_PTHRS,
 1110             (111 << CAS_RX_PTHRS_XOFF_SHFT) | (15 << CAS_RX_PTHRS_XON_SHFT));
 1111 
 1112         /* RX blanking */
 1113         CAS_WRITE_4(sc, CAS_RX_BLANK,
 1114             (15 << CAS_RX_BLANK_TIME_SHFT) | (5 << CAS_RX_BLANK_PKTS_SHFT));
 1115 
 1116         /* Set RX_COMP_AFULL threshold to half of the RX completions. */
 1117         CAS_WRITE_4(sc, CAS_RX_AEMPTY_THRS,
 1118             (CAS_NRXCOMP / 2) << CAS_RX_AEMPTY_COMP_SHFT);
 1119 
 1120         /* Initialize the RX page size register as appropriate for 8k. */
 1121         CAS_WRITE_4(sc, CAS_RX_PSZ,
 1122             (CAS_RX_PSZ_8K << CAS_RX_PSZ_SHFT) |
 1123             (4 << CAS_RX_PSZ_MB_CNT_SHFT) |
 1124             (CAS_RX_PSZ_MB_STRD_2K << CAS_RX_PSZ_MB_STRD_SHFT) |
 1125             (CAS_RX_PSZ_MB_OFF_64 << CAS_RX_PSZ_MB_OFF_SHFT));
 1126 
 1127         /* Disable RX random early detection. */
 1128         CAS_WRITE_4(sc, CAS_RX_RED, 0);
 1129 
 1130         /* Zero the RX reassembly DMA table. */
 1131         for (v = 0; v <= CAS_RX_REAS_DMA_ADDR_LC; v++) {
 1132                 CAS_WRITE_4(sc, CAS_RX_REAS_DMA_ADDR, v);
 1133                 CAS_WRITE_4(sc, CAS_RX_REAS_DMA_DATA_LO, 0);
 1134                 CAS_WRITE_4(sc, CAS_RX_REAS_DMA_DATA_MD, 0);
 1135                 CAS_WRITE_4(sc, CAS_RX_REAS_DMA_DATA_HI, 0);
 1136         }
 1137 
 1138         /* Ensure the RX control FIFO and RX IPP FIFO addresses are zero. */
 1139         CAS_WRITE_4(sc, CAS_RX_CTRL_FIFO, 0);
 1140         CAS_WRITE_4(sc, CAS_RX_IPP_ADDR, 0);
 1141 
 1142         /* Finally, enable RX DMA. */
 1143         CAS_WRITE_4(sc, CAS_RX_CONF,
 1144             CAS_READ_4(sc, CAS_RX_CONF) | CAS_RX_CONF_RXDMA_EN);
 1145 
 1146         /* step 11.  Configure Media. */
 1147 
 1148         /* step 12.  RX_MAC Configuration Register */
 1149         v = CAS_READ_4(sc, CAS_MAC_RX_CONF);
 1150         v &= ~(CAS_MAC_RX_CONF_STRPPAD | CAS_MAC_RX_CONF_EN);
 1151         v |= CAS_MAC_RX_CONF_STRPFCS;
 1152         sc->sc_mac_rxcfg = v;
 1153         /*
 1154          * Clear the RX filter and reprogram it.  This will also set the
 1155          * current RX MAC configuration and enable it.
 1156          */
 1157         cas_setladrf(sc);
 1158 
 1159         /* step 13.  TX_MAC Configuration Register */
 1160         v = CAS_READ_4(sc, CAS_MAC_TX_CONF);
 1161         v |= CAS_MAC_TX_CONF_EN;
 1162         (void)cas_disable_tx(sc);
 1163         CAS_WRITE_4(sc, CAS_MAC_TX_CONF, v);
 1164 
 1165         /* step 14.  Issue Transmit Pending command. */
 1166 
 1167         /* step 15.  Give the receiver a swift kick. */
 1168         CAS_WRITE_4(sc, CAS_RX_KICK, CAS_NRXDESC - 4);
 1169         CAS_WRITE_4(sc, CAS_RX_COMP_TAIL, 0);
 1170         if ((sc->sc_flags & CAS_REG_PLUS) != 0)
 1171                 CAS_WRITE_4(sc, CAS_RX_KICK2, CAS_NRXDESC2 - 4);
 1172 
 1173         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1174         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1175 
 1176         mii_mediachg(sc->sc_mii);
 1177 
 1178         /* Start the one second timer. */
 1179         sc->sc_wdog_timer = 0;
 1180         callout_reset(&sc->sc_tick_ch, hz, cas_tick, sc);
 1181 }
 1182 
 1183 static int
 1184 cas_load_txmbuf(struct cas_softc *sc, struct mbuf **m_head)
 1185 {
 1186         bus_dma_segment_t txsegs[CAS_NTXSEGS];
 1187         struct cas_txsoft *txs;
 1188         struct ip *ip;
 1189         struct mbuf *m;
 1190         uint64_t cflags;
 1191         int error, nexttx, nsegs, offset, seg;
 1192 
 1193         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1194 
 1195         /* Get a work queue entry. */
 1196         if ((txs = STAILQ_FIRST(&sc->sc_txfreeq)) == NULL) {
 1197                 /* Ran out of descriptors. */
 1198                 return (ENOBUFS);
 1199         }
 1200 
 1201         cflags = 0;
 1202         if (((*m_head)->m_pkthdr.csum_flags & CAS_CSUM_FEATURES) != 0) {
 1203                 if (M_WRITABLE(*m_head) == 0) {
 1204                         m = m_dup(*m_head, M_NOWAIT);
 1205                         m_freem(*m_head);
 1206                         *m_head = m;
 1207                         if (m == NULL)
 1208                                 return (ENOBUFS);
 1209                 }
 1210                 offset = sizeof(struct ether_header);
 1211                 m = m_pullup(*m_head, offset + sizeof(struct ip));
 1212                 if (m == NULL) {
 1213                         *m_head = NULL;
 1214                         return (ENOBUFS);
 1215                 }
 1216                 ip = (struct ip *)(mtod(m, caddr_t) + offset);
 1217                 offset += (ip->ip_hl << 2);
 1218                 cflags = (offset << CAS_TD_CKSUM_START_SHFT) |
 1219                     ((offset + m->m_pkthdr.csum_data) <<
 1220                     CAS_TD_CKSUM_STUFF_SHFT) | CAS_TD_CKSUM_EN;
 1221                 *m_head = m;
 1222         }
 1223 
 1224         error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, txs->txs_dmamap,
 1225             *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
 1226         if (error == EFBIG) {
 1227                 m = m_collapse(*m_head, M_NOWAIT, CAS_NTXSEGS);
 1228                 if (m == NULL) {
 1229                         m_freem(*m_head);
 1230                         *m_head = NULL;
 1231                         return (ENOBUFS);
 1232                 }
 1233                 *m_head = m;
 1234                 error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag,
 1235                     txs->txs_dmamap, *m_head, txsegs, &nsegs,
 1236                     BUS_DMA_NOWAIT);
 1237                 if (error != 0) {
 1238                         m_freem(*m_head);
 1239                         *m_head = NULL;
 1240                         return (error);
 1241                 }
 1242         } else if (error != 0)
 1243                 return (error);
 1244         /* If nsegs is wrong then the stack is corrupt. */
 1245         KASSERT(nsegs <= CAS_NTXSEGS,
 1246             ("%s: too many DMA segments (%d)", __func__, nsegs));
 1247         if (nsegs == 0) {
 1248                 m_freem(*m_head);
 1249                 *m_head = NULL;
 1250                 return (EIO);
 1251         }
 1252 
 1253         /*
 1254          * Ensure we have enough descriptors free to describe
 1255          * the packet.  Note, we always reserve one descriptor
 1256          * at the end of the ring as a termination point, in
 1257          * order to prevent wrap-around.
 1258          */
 1259         if (nsegs > sc->sc_txfree - 1) {
 1260                 txs->txs_ndescs = 0;
 1261                 bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap);
 1262                 return (ENOBUFS);
 1263         }
 1264 
 1265         txs->txs_ndescs = nsegs;
 1266         txs->txs_firstdesc = sc->sc_txnext;
 1267         nexttx = txs->txs_firstdesc;
 1268         for (seg = 0; seg < nsegs; seg++, nexttx = CAS_NEXTTX(nexttx)) {
 1269 #ifdef CAS_DEBUG
 1270                 CTR6(KTR_CAS,
 1271                     "%s: mapping seg %d (txd %d), len %lx, addr %#lx (%#lx)",
 1272                     __func__, seg, nexttx, txsegs[seg].ds_len,
 1273                     txsegs[seg].ds_addr, htole64(txsegs[seg].ds_addr));
 1274 #endif
 1275                 sc->sc_txdescs[nexttx].cd_buf_ptr =
 1276                     htole64(txsegs[seg].ds_addr);
 1277                 KASSERT(txsegs[seg].ds_len <
 1278                     CAS_TD_BUF_LEN_MASK >> CAS_TD_BUF_LEN_SHFT,
 1279                     ("%s: segment size too large!", __func__));
 1280                 sc->sc_txdescs[nexttx].cd_flags =
 1281                     htole64(txsegs[seg].ds_len << CAS_TD_BUF_LEN_SHFT);
 1282                 txs->txs_lastdesc = nexttx;
 1283         }
 1284 
 1285         /* Set EOF on the last descriptor. */
 1286 #ifdef CAS_DEBUG
 1287         CTR3(KTR_CAS, "%s: end of frame at segment %d, TX %d",
 1288             __func__, seg, nexttx);
 1289 #endif
 1290         sc->sc_txdescs[txs->txs_lastdesc].cd_flags |=
 1291             htole64(CAS_TD_END_OF_FRAME);
 1292 
 1293         /* Lastly set SOF on the first descriptor. */
 1294 #ifdef CAS_DEBUG
 1295         CTR3(KTR_CAS, "%s: start of frame at segment %d, TX %d",
 1296             __func__, seg, nexttx);
 1297 #endif
 1298         if (sc->sc_txwin += nsegs > CAS_MAXTXFREE * 2 / 3) {
 1299                 sc->sc_txwin = 0;
 1300                 sc->sc_txdescs[txs->txs_firstdesc].cd_flags |=
 1301                     htole64(cflags | CAS_TD_START_OF_FRAME | CAS_TD_INT_ME);
 1302         } else
 1303                 sc->sc_txdescs[txs->txs_firstdesc].cd_flags |=
 1304                     htole64(cflags | CAS_TD_START_OF_FRAME);
 1305 
 1306         /* Sync the DMA map. */
 1307         bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap,
 1308             BUS_DMASYNC_PREWRITE);
 1309 
 1310 #ifdef CAS_DEBUG
 1311         CTR4(KTR_CAS, "%s: setting firstdesc=%d, lastdesc=%d, ndescs=%d",
 1312             __func__, txs->txs_firstdesc, txs->txs_lastdesc,
 1313             txs->txs_ndescs);
 1314 #endif
 1315         STAILQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
 1316         STAILQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
 1317         txs->txs_mbuf = *m_head;
 1318 
 1319         sc->sc_txnext = CAS_NEXTTX(txs->txs_lastdesc);
 1320         sc->sc_txfree -= txs->txs_ndescs;
 1321 
 1322         return (0);
 1323 }
 1324 
 1325 static void
 1326 cas_init_regs(struct cas_softc *sc)
 1327 {
 1328         int i;
 1329         const u_char *laddr = IF_LLADDR(sc->sc_ifp);
 1330 
 1331         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1332 
 1333         /* These registers are not cleared on reset. */
 1334         if ((sc->sc_flags & CAS_INITED) == 0) {
 1335                 /* magic values */
 1336                 CAS_WRITE_4(sc, CAS_MAC_IPG0, 0);
 1337                 CAS_WRITE_4(sc, CAS_MAC_IPG1, 8);
 1338                 CAS_WRITE_4(sc, CAS_MAC_IPG2, 4);
 1339 
 1340                 /* min frame length */
 1341                 CAS_WRITE_4(sc, CAS_MAC_MIN_FRAME, ETHER_MIN_LEN);
 1342                 /* max frame length and max burst size */
 1343                 CAS_WRITE_4(sc, CAS_MAC_MAX_BF,
 1344                     ((ETHER_MAX_LEN_JUMBO + ETHER_VLAN_ENCAP_LEN) <<
 1345                     CAS_MAC_MAX_BF_FRM_SHFT) |
 1346                     (0x2000 << CAS_MAC_MAX_BF_BST_SHFT));
 1347 
 1348                 /* more magic values */
 1349                 CAS_WRITE_4(sc, CAS_MAC_PREAMBLE_LEN, 0x7);
 1350                 CAS_WRITE_4(sc, CAS_MAC_JAM_SIZE, 0x4);
 1351                 CAS_WRITE_4(sc, CAS_MAC_ATTEMPT_LIMIT, 0x10);
 1352                 CAS_WRITE_4(sc, CAS_MAC_CTRL_TYPE, 0x8808);
 1353 
 1354                 /* random number seed */
 1355                 CAS_WRITE_4(sc, CAS_MAC_RANDOM_SEED,
 1356                     ((laddr[5] << 8) | laddr[4]) & 0x3ff);
 1357 
 1358                 /* secondary MAC addresses: 0:0:0:0:0:0 */
 1359                 for (i = CAS_MAC_ADDR3; i <= CAS_MAC_ADDR41;
 1360                     i += CAS_MAC_ADDR4 - CAS_MAC_ADDR3)
 1361                         CAS_WRITE_4(sc, i, 0);
 1362 
 1363                 /* MAC control address: 01:80:c2:00:00:01 */
 1364                 CAS_WRITE_4(sc, CAS_MAC_ADDR42, 0x0001);
 1365                 CAS_WRITE_4(sc, CAS_MAC_ADDR43, 0xc200);
 1366                 CAS_WRITE_4(sc, CAS_MAC_ADDR44, 0x0180);
 1367 
 1368                 /* MAC filter address: 0:0:0:0:0:0 */
 1369                 CAS_WRITE_4(sc, CAS_MAC_AFILTER0, 0);
 1370                 CAS_WRITE_4(sc, CAS_MAC_AFILTER1, 0);
 1371                 CAS_WRITE_4(sc, CAS_MAC_AFILTER2, 0);
 1372                 CAS_WRITE_4(sc, CAS_MAC_AFILTER_MASK1_2, 0);
 1373                 CAS_WRITE_4(sc, CAS_MAC_AFILTER_MASK0, 0);
 1374 
 1375                 /* Zero the hash table. */
 1376                 for (i = CAS_MAC_HASH0; i <= CAS_MAC_HASH15;
 1377                     i += CAS_MAC_HASH1 - CAS_MAC_HASH0)
 1378                         CAS_WRITE_4(sc, i, 0);
 1379 
 1380                 sc->sc_flags |= CAS_INITED;
 1381         }
 1382 
 1383         /* Counters need to be zeroed. */
 1384         CAS_WRITE_4(sc, CAS_MAC_NORM_COLL_CNT, 0);
 1385         CAS_WRITE_4(sc, CAS_MAC_FIRST_COLL_CNT, 0);
 1386         CAS_WRITE_4(sc, CAS_MAC_EXCESS_COLL_CNT, 0);
 1387         CAS_WRITE_4(sc, CAS_MAC_LATE_COLL_CNT, 0);
 1388         CAS_WRITE_4(sc, CAS_MAC_DEFER_TMR_CNT, 0);
 1389         CAS_WRITE_4(sc, CAS_MAC_PEAK_ATTEMPTS, 0);
 1390         CAS_WRITE_4(sc, CAS_MAC_RX_FRAME_COUNT, 0);
 1391         CAS_WRITE_4(sc, CAS_MAC_RX_LEN_ERR_CNT, 0);
 1392         CAS_WRITE_4(sc, CAS_MAC_RX_ALIGN_ERR, 0);
 1393         CAS_WRITE_4(sc, CAS_MAC_RX_CRC_ERR_CNT, 0);
 1394         CAS_WRITE_4(sc, CAS_MAC_RX_CODE_VIOL, 0);
 1395 
 1396         /* Set XOFF PAUSE time. */
 1397         CAS_WRITE_4(sc, CAS_MAC_SPC, 0x1BF0 << CAS_MAC_SPC_TIME_SHFT);
 1398 
 1399         /* Set the station address. */
 1400         CAS_WRITE_4(sc, CAS_MAC_ADDR0, (laddr[4] << 8) | laddr[5]);
 1401         CAS_WRITE_4(sc, CAS_MAC_ADDR1, (laddr[2] << 8) | laddr[3]);
 1402         CAS_WRITE_4(sc, CAS_MAC_ADDR2, (laddr[0] << 8) | laddr[1]);
 1403 
 1404         /* Enable MII outputs. */
 1405         CAS_WRITE_4(sc, CAS_MAC_XIF_CONF, CAS_MAC_XIF_CONF_TX_OE);
 1406 }
 1407 
 1408 static void
 1409 cas_tx_task(void *arg, int pending __unused)
 1410 {
 1411         struct ifnet *ifp;
 1412 
 1413         ifp = (struct ifnet *)arg;
 1414         cas_start(ifp);
 1415 }
 1416 
 1417 static inline void
 1418 cas_txkick(struct cas_softc *sc)
 1419 {
 1420 
 1421         /*
 1422          * Update the TX kick register.  This register has to point to the
 1423          * descriptor after the last valid one and for optimum performance
 1424          * should be incremented in multiples of 4 (the DMA engine fetches/
 1425          * updates descriptors in batches of 4).
 1426          */
 1427 #ifdef CAS_DEBUG
 1428         CTR3(KTR_CAS, "%s: %s: kicking TX %d",
 1429             device_get_name(sc->sc_dev), __func__, sc->sc_txnext);
 1430 #endif
 1431         CAS_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1432         CAS_WRITE_4(sc, CAS_TX_KICK3, sc->sc_txnext);
 1433 }
 1434 
 1435 static void
 1436 cas_start(struct ifnet *ifp)
 1437 {
 1438         struct cas_softc *sc = ifp->if_softc;
 1439         struct mbuf *m;
 1440         int kicked, ntx;
 1441 
 1442         CAS_LOCK(sc);
 1443 
 1444         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 1445             IFF_DRV_RUNNING || (sc->sc_flags & CAS_LINK) == 0) {
 1446                 CAS_UNLOCK(sc);
 1447                 return;
 1448         }
 1449 
 1450         if (sc->sc_txfree < CAS_MAXTXFREE / 4)
 1451                 cas_tint(sc);
 1452 
 1453 #ifdef CAS_DEBUG
 1454         CTR4(KTR_CAS, "%s: %s: txfree %d, txnext %d",
 1455             device_get_name(sc->sc_dev), __func__, sc->sc_txfree,
 1456             sc->sc_txnext);
 1457 #endif
 1458         ntx = 0;
 1459         kicked = 0;
 1460         for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && sc->sc_txfree > 1;) {
 1461                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 1462                 if (m == NULL)
 1463                         break;
 1464                 if (cas_load_txmbuf(sc, &m) != 0) {
 1465                         if (m == NULL)
 1466                                 break;
 1467                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1468                         IFQ_DRV_PREPEND(&ifp->if_snd, m);
 1469                         break;
 1470                 }
 1471                 if ((sc->sc_txnext % 4) == 0) {
 1472                         cas_txkick(sc);
 1473                         kicked = 1;
 1474                 } else
 1475                         kicked = 0;
 1476                 ntx++;
 1477                 BPF_MTAP(ifp, m);
 1478         }
 1479 
 1480         if (ntx > 0) {
 1481                 if (kicked == 0)
 1482                         cas_txkick(sc);
 1483 #ifdef CAS_DEBUG
 1484                 CTR2(KTR_CAS, "%s: packets enqueued, OWN on %d",
 1485                     device_get_name(sc->sc_dev), sc->sc_txnext);
 1486 #endif
 1487 
 1488                 /* Set a watchdog timer in case the chip flakes out. */
 1489                 sc->sc_wdog_timer = 5;
 1490 #ifdef CAS_DEBUG
 1491                 CTR3(KTR_CAS, "%s: %s: watchdog %d",
 1492                     device_get_name(sc->sc_dev), __func__,
 1493                     sc->sc_wdog_timer);
 1494 #endif
 1495         }
 1496 
 1497         CAS_UNLOCK(sc);
 1498 }
 1499 
 1500 static void
 1501 cas_tint(struct cas_softc *sc)
 1502 {
 1503         struct ifnet *ifp = sc->sc_ifp;
 1504         struct cas_txsoft *txs;
 1505         int progress;
 1506         uint32_t txlast;
 1507 #ifdef CAS_DEBUG
 1508         int i;
 1509 
 1510         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1511 
 1512         CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__);
 1513 #endif
 1514 
 1515         /*
 1516          * Go through our TX list and free mbufs for those
 1517          * frames that have been transmitted.
 1518          */
 1519         progress = 0;
 1520         CAS_CDSYNC(sc, BUS_DMASYNC_POSTREAD);
 1521         while ((txs = STAILQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
 1522 #ifdef CAS_DEBUG
 1523                 if ((ifp->if_flags & IFF_DEBUG) != 0) {
 1524                         printf("    txsoft %p transmit chain:\n", txs);
 1525                         for (i = txs->txs_firstdesc;; i = CAS_NEXTTX(i)) {
 1526                                 printf("descriptor %d: ", i);
 1527                                 printf("cd_flags: 0x%016llx\t",
 1528                                     (long long)le64toh(
 1529                                     sc->sc_txdescs[i].cd_flags));
 1530                                 printf("cd_buf_ptr: 0x%016llx\n",
 1531                                     (long long)le64toh(
 1532                                     sc->sc_txdescs[i].cd_buf_ptr));
 1533                                 if (i == txs->txs_lastdesc)
 1534                                         break;
 1535                         }
 1536                 }
 1537 #endif
 1538 
 1539                 /*
 1540                  * In theory, we could harvest some descriptors before
 1541                  * the ring is empty, but that's a bit complicated.
 1542                  *
 1543                  * CAS_TX_COMPn points to the last descriptor
 1544                  * processed + 1.
 1545                  */
 1546                 txlast = CAS_READ_4(sc, CAS_TX_COMP3);
 1547 #ifdef CAS_DEBUG
 1548                 CTR4(KTR_CAS, "%s: txs->txs_firstdesc = %d, "
 1549                     "txs->txs_lastdesc = %d, txlast = %d",
 1550                     __func__, txs->txs_firstdesc, txs->txs_lastdesc, txlast);
 1551 #endif
 1552                 if (txs->txs_firstdesc <= txs->txs_lastdesc) {
 1553                         if ((txlast >= txs->txs_firstdesc) &&
 1554                             (txlast <= txs->txs_lastdesc))
 1555                                 break;
 1556                 } else {
 1557                         /* Ick -- this command wraps. */
 1558                         if ((txlast >= txs->txs_firstdesc) ||
 1559                             (txlast <= txs->txs_lastdesc))
 1560                                 break;
 1561                 }
 1562 
 1563 #ifdef CAS_DEBUG
 1564                 CTR1(KTR_CAS, "%s: releasing a descriptor", __func__);
 1565 #endif
 1566                 STAILQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
 1567 
 1568                 sc->sc_txfree += txs->txs_ndescs;
 1569 
 1570                 bus_dmamap_sync(sc->sc_tdmatag, txs->txs_dmamap,
 1571                     BUS_DMASYNC_POSTWRITE);
 1572                 bus_dmamap_unload(sc->sc_tdmatag, txs->txs_dmamap);
 1573                 if (txs->txs_mbuf != NULL) {
 1574                         m_freem(txs->txs_mbuf);
 1575                         txs->txs_mbuf = NULL;
 1576                 }
 1577 
 1578                 STAILQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
 1579 
 1580                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 1581                 progress = 1;
 1582         }
 1583 
 1584 #ifdef CAS_DEBUG
 1585         CTR5(KTR_CAS, "%s: CAS_TX_SM1 %x CAS_TX_SM2 %x CAS_TX_DESC_BASE %llx "
 1586             "CAS_TX_COMP3 %x",
 1587             __func__, CAS_READ_4(sc, CAS_TX_SM1), CAS_READ_4(sc, CAS_TX_SM2),
 1588             ((long long)CAS_READ_4(sc, CAS_TX_DESC3_BASE_HI) << 32) |
 1589             CAS_READ_4(sc, CAS_TX_DESC3_BASE_LO),
 1590             CAS_READ_4(sc, CAS_TX_COMP3));
 1591 #endif
 1592 
 1593         if (progress) {
 1594                 /* We freed some descriptors, so reset IFF_DRV_OACTIVE. */
 1595                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1596                 if (STAILQ_EMPTY(&sc->sc_txdirtyq))
 1597                         sc->sc_wdog_timer = 0;
 1598         }
 1599 
 1600 #ifdef CAS_DEBUG
 1601         CTR3(KTR_CAS, "%s: %s: watchdog %d",
 1602             device_get_name(sc->sc_dev), __func__, sc->sc_wdog_timer);
 1603 #endif
 1604 }
 1605 
 1606 static void
 1607 cas_rint_timeout(void *arg)
 1608 {
 1609         struct epoch_tracker et;
 1610         struct cas_softc *sc = arg;
 1611 
 1612         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1613 
 1614         NET_EPOCH_ENTER(et);
 1615         cas_rint(sc);
 1616         NET_EPOCH_EXIT(et);
 1617 }
 1618 
 1619 static void
 1620 cas_rint(struct cas_softc *sc)
 1621 {
 1622         struct cas_rxdsoft *rxds, *rxds2;
 1623         struct ifnet *ifp = sc->sc_ifp;
 1624         struct mbuf *m, *m2;
 1625         uint64_t word1, word2, word3 __unused, word4;
 1626         uint32_t rxhead;
 1627         u_int idx, idx2, len, off, skip;
 1628 
 1629         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1630 
 1631         callout_stop(&sc->sc_rx_ch);
 1632 
 1633 #ifdef CAS_DEBUG
 1634         CTR2(KTR_CAS, "%s: %s", device_get_name(sc->sc_dev), __func__);
 1635 #endif
 1636 
 1637 #define PRINTWORD(n, delimiter)                                         \
 1638         printf("word ## n: 0x%016llx%c", (long long)word ## n, delimiter)
 1639 
 1640 #define SKIPASSERT(n)                                                   \
 1641         KASSERT(sc->sc_rxcomps[sc->sc_rxcptr].crc_word ## n == 0,       \
 1642             ("%s: word ## n not 0", __func__))
 1643 
 1644 #define WORDTOH(n)                                                      \
 1645         word ## n = le64toh(sc->sc_rxcomps[sc->sc_rxcptr].crc_word ## n)
 1646 
 1647         /*
 1648          * Read the completion head register once.  This limits
 1649          * how long the following loop can execute.
 1650          */
 1651         rxhead = CAS_READ_4(sc, CAS_RX_COMP_HEAD);
 1652 #ifdef CAS_DEBUG
 1653         CTR4(KTR_CAS, "%s: sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d",
 1654             __func__, sc->sc_rxcptr, sc->sc_rxdptr, rxhead);
 1655 #endif
 1656         skip = 0;
 1657         CAS_CDSYNC(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1658         for (; sc->sc_rxcptr != rxhead;
 1659             sc->sc_rxcptr = CAS_NEXTRXCOMP(sc->sc_rxcptr)) {
 1660                 if (skip != 0) {
 1661                         SKIPASSERT(1);
 1662                         SKIPASSERT(2);
 1663                         SKIPASSERT(3);
 1664 
 1665                         --skip;
 1666                         goto skip;
 1667                 }
 1668 
 1669                 WORDTOH(1);
 1670                 WORDTOH(2);
 1671                 WORDTOH(3);
 1672                 WORDTOH(4);
 1673 
 1674 #ifdef CAS_DEBUG
 1675                 if ((ifp->if_flags & IFF_DEBUG) != 0) {
 1676                         printf("    completion %d: ", sc->sc_rxcptr);
 1677                         PRINTWORD(1, '\t');
 1678                         PRINTWORD(2, '\t');
 1679                         PRINTWORD(3, '\t');
 1680                         PRINTWORD(4, '\n');
 1681                 }
 1682 #endif
 1683 
 1684                 if (__predict_false(
 1685                     (word1 & CAS_RC1_TYPE_MASK) == CAS_RC1_TYPE_HW ||
 1686                     (word4 & CAS_RC4_ZERO) != 0)) {
 1687                         /*
 1688                          * The descriptor is still marked as owned, although
 1689                          * it is supposed to have completed.  This has been
 1690                          * observed on some machines.  Just exiting here
 1691                          * might leave the packet sitting around until another
 1692                          * one arrives to trigger a new interrupt, which is
 1693                          * generally undesirable, so set up a timeout.
 1694                          */
 1695                         callout_reset(&sc->sc_rx_ch, CAS_RXOWN_TICKS,
 1696                             cas_rint_timeout, sc);
 1697                         break;
 1698                 }
 1699 
 1700                 if (__predict_false(
 1701                     (word4 & (CAS_RC4_BAD | CAS_RC4_LEN_MMATCH)) != 0)) {
 1702                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
 1703                         device_printf(sc->sc_dev,
 1704                             "receive error: CRC error\n");
 1705                         continue;
 1706                 }
 1707 
 1708                 KASSERT(CAS_GET(word1, CAS_RC1_DATA_SIZE) == 0 ||
 1709                     CAS_GET(word2, CAS_RC2_HDR_SIZE) == 0,
 1710                     ("%s: data and header present", __func__));
 1711                 KASSERT((word1 & CAS_RC1_SPLIT_PKT) == 0 ||
 1712                     CAS_GET(word2, CAS_RC2_HDR_SIZE) == 0,
 1713                     ("%s: split and header present", __func__));
 1714                 KASSERT(CAS_GET(word1, CAS_RC1_DATA_SIZE) == 0 ||
 1715                     (word1 & CAS_RC1_RELEASE_HDR) == 0,
 1716                     ("%s: data present but header release", __func__));
 1717                 KASSERT(CAS_GET(word2, CAS_RC2_HDR_SIZE) == 0 ||
 1718                     (word1 & CAS_RC1_RELEASE_DATA) == 0,
 1719                     ("%s: header present but data release", __func__));
 1720 
 1721                 if ((len = CAS_GET(word2, CAS_RC2_HDR_SIZE)) != 0) {
 1722                         idx = CAS_GET(word2, CAS_RC2_HDR_INDEX);
 1723                         off = CAS_GET(word2, CAS_RC2_HDR_OFF);
 1724 #ifdef CAS_DEBUG
 1725                         CTR4(KTR_CAS, "%s: hdr at idx %d, off %d, len %d",
 1726                             __func__, idx, off, len);
 1727 #endif
 1728                         rxds = &sc->sc_rxdsoft[idx];
 1729                         MGETHDR(m, M_NOWAIT, MT_DATA);
 1730                         if (m != NULL) {
 1731                                 refcount_acquire(&rxds->rxds_refcount);
 1732                                 bus_dmamap_sync(sc->sc_rdmatag,
 1733                                     rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD);
 1734                                 m_extadd(m, (char *)rxds->rxds_buf +
 1735                                     off * 256 + ETHER_ALIGN, len, cas_free,
 1736                                     sc, (void *)(uintptr_t)idx,
 1737                                     M_RDONLY, EXT_NET_DRV);
 1738                                 if ((m->m_flags & M_EXT) == 0) {
 1739                                         m_freem(m);
 1740                                         m = NULL;
 1741                                 }
 1742                         }
 1743                         if (m != NULL) {
 1744                                 m->m_pkthdr.rcvif = ifp;
 1745                                 m->m_pkthdr.len = m->m_len = len;
 1746                                 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
 1747                                 if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
 1748                                         cas_rxcksum(m, CAS_GET(word4,
 1749                                             CAS_RC4_TCP_CSUM));
 1750                                 /* Pass it on. */
 1751                                 CAS_UNLOCK(sc);
 1752                                 (*ifp->if_input)(ifp, m);
 1753                                 CAS_LOCK(sc);
 1754                         } else
 1755                                 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
 1756 
 1757                         if ((word1 & CAS_RC1_RELEASE_HDR) != 0 &&
 1758                             refcount_release(&rxds->rxds_refcount) != 0)
 1759                                 cas_add_rxdesc(sc, idx);
 1760                 } else if ((len = CAS_GET(word1, CAS_RC1_DATA_SIZE)) != 0) {
 1761                         idx = CAS_GET(word1, CAS_RC1_DATA_INDEX);
 1762                         off = CAS_GET(word1, CAS_RC1_DATA_OFF);
 1763 #ifdef CAS_DEBUG
 1764                         CTR4(KTR_CAS, "%s: data at idx %d, off %d, len %d",
 1765                             __func__, idx, off, len);
 1766 #endif
 1767                         rxds = &sc->sc_rxdsoft[idx];
 1768                         MGETHDR(m, M_NOWAIT, MT_DATA);
 1769                         if (m != NULL) {
 1770                                 refcount_acquire(&rxds->rxds_refcount);
 1771                                 off += ETHER_ALIGN;
 1772                                 m->m_len = min(CAS_PAGE_SIZE - off, len);
 1773                                 bus_dmamap_sync(sc->sc_rdmatag,
 1774                                     rxds->rxds_dmamap, BUS_DMASYNC_POSTREAD);
 1775                                 m_extadd(m, (char *)rxds->rxds_buf + off,
 1776                                     m->m_len, cas_free, sc,
 1777                                     (void *)(uintptr_t)idx, M_RDONLY,
 1778                                     EXT_NET_DRV);
 1779                                 if ((m->m_flags & M_EXT) == 0) {
 1780                                         m_freem(m);
 1781                                         m = NULL;
 1782                                 }
 1783                         }
 1784                         idx2 = 0;
 1785                         m2 = NULL;
 1786                         rxds2 = NULL;
 1787                         if ((word1 & CAS_RC1_SPLIT_PKT) != 0) {
 1788                                 KASSERT((word1 & CAS_RC1_RELEASE_NEXT) != 0,
 1789                                     ("%s: split but no release next",
 1790                                     __func__));
 1791 
 1792                                 idx2 = CAS_GET(word2, CAS_RC2_NEXT_INDEX);
 1793 #ifdef CAS_DEBUG
 1794                                 CTR2(KTR_CAS, "%s: split at idx %d",
 1795                                     __func__, idx2);
 1796 #endif
 1797                                 rxds2 = &sc->sc_rxdsoft[idx2];
 1798                                 if (m != NULL) {
 1799                                         MGET(m2, M_NOWAIT, MT_DATA);
 1800                                         if (m2 != NULL) {
 1801                                                 refcount_acquire(
 1802                                                     &rxds2->rxds_refcount);
 1803                                                 m2->m_len = len - m->m_len;
 1804                                                 bus_dmamap_sync(
 1805                                                     sc->sc_rdmatag,
 1806                                                     rxds2->rxds_dmamap,
 1807                                                     BUS_DMASYNC_POSTREAD);
 1808                                                 m_extadd(m2,
 1809                                                     (char *)rxds2->rxds_buf,
 1810                                                     m2->m_len, cas_free, sc,
 1811                                                     (void *)(uintptr_t)idx2,
 1812                                                     M_RDONLY, EXT_NET_DRV);
 1813                                                 if ((m2->m_flags & M_EXT) ==
 1814                                                     0) {
 1815                                                         m_freem(m2);
 1816                                                         m2 = NULL;
 1817                                                 }
 1818                                         }
 1819                                 }
 1820                                 if (m2 != NULL)
 1821                                         m->m_next = m2;
 1822                                 else if (m != NULL) {
 1823                                         m_freem(m);
 1824                                         m = NULL;
 1825                                 }
 1826                         }
 1827                         if (m != NULL) {
 1828                                 m->m_pkthdr.rcvif = ifp;
 1829                                 m->m_pkthdr.len = len;
 1830                                 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
 1831                                 if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
 1832                                         cas_rxcksum(m, CAS_GET(word4,
 1833                                             CAS_RC4_TCP_CSUM));
 1834                                 /* Pass it on. */
 1835                                 CAS_UNLOCK(sc);
 1836                                 (*ifp->if_input)(ifp, m);
 1837                                 CAS_LOCK(sc);
 1838                         } else
 1839                                 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
 1840 
 1841                         if ((word1 & CAS_RC1_RELEASE_DATA) != 0 &&
 1842                             refcount_release(&rxds->rxds_refcount) != 0)
 1843                                 cas_add_rxdesc(sc, idx);
 1844                         if ((word1 & CAS_RC1_SPLIT_PKT) != 0 &&
 1845                             refcount_release(&rxds2->rxds_refcount) != 0)
 1846                                 cas_add_rxdesc(sc, idx2);
 1847                 }
 1848 
 1849                 skip = CAS_GET(word1, CAS_RC1_SKIP);
 1850 
 1851  skip:
 1852                 cas_rxcompinit(&sc->sc_rxcomps[sc->sc_rxcptr]);
 1853                 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 1854                         break;
 1855         }
 1856         CAS_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1857         CAS_WRITE_4(sc, CAS_RX_COMP_TAIL, sc->sc_rxcptr);
 1858 
 1859 #undef PRINTWORD
 1860 #undef SKIPASSERT
 1861 #undef WORDTOH
 1862 
 1863 #ifdef CAS_DEBUG
 1864         CTR4(KTR_CAS, "%s: done sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d",
 1865             __func__, sc->sc_rxcptr, sc->sc_rxdptr,
 1866             CAS_READ_4(sc, CAS_RX_COMP_HEAD));
 1867 #endif
 1868 }
 1869 
 1870 static void
 1871 cas_free(struct mbuf *m)
 1872 {
 1873         struct cas_rxdsoft *rxds;
 1874         struct cas_softc *sc;
 1875         u_int idx, locked;
 1876 
 1877         sc = m->m_ext.ext_arg1;
 1878         idx = (uintptr_t)m->m_ext.ext_arg2;
 1879         rxds = &sc->sc_rxdsoft[idx];
 1880         if (refcount_release(&rxds->rxds_refcount) == 0)
 1881                 return;
 1882 
 1883         /*
 1884          * NB: this function can be called via m_freem(9) within
 1885          * this driver!
 1886          */
 1887         if ((locked = CAS_LOCK_OWNED(sc)) == 0)
 1888                 CAS_LOCK(sc);
 1889         cas_add_rxdesc(sc, idx);
 1890         if (locked == 0)
 1891                 CAS_UNLOCK(sc);
 1892 }
 1893 
 1894 static inline void
 1895 cas_add_rxdesc(struct cas_softc *sc, u_int idx)
 1896 {
 1897 
 1898         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1899 
 1900         bus_dmamap_sync(sc->sc_rdmatag, sc->sc_rxdsoft[idx].rxds_dmamap,
 1901             BUS_DMASYNC_PREREAD);
 1902         CAS_UPDATE_RXDESC(sc, sc->sc_rxdptr, idx);
 1903         sc->sc_rxdptr = CAS_NEXTRXDESC(sc->sc_rxdptr);
 1904 
 1905         /*
 1906          * Update the RX kick register.  This register has to point to the
 1907          * descriptor after the last valid one (before the current batch)
 1908          * and for optimum performance should be incremented in multiples
 1909          * of 4 (the DMA engine fetches/updates descriptors in batches of 4).
 1910          */
 1911         if ((sc->sc_rxdptr % 4) == 0) {
 1912                 CAS_CDSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1913                 CAS_WRITE_4(sc, CAS_RX_KICK,
 1914                     (sc->sc_rxdptr + CAS_NRXDESC - 4) & CAS_NRXDESC_MASK);
 1915         }
 1916 }
 1917 
 1918 static void
 1919 cas_eint(struct cas_softc *sc, u_int status)
 1920 {
 1921         struct ifnet *ifp = sc->sc_ifp;
 1922 
 1923         CAS_LOCK_ASSERT(sc, MA_OWNED);
 1924 
 1925         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
 1926 
 1927         device_printf(sc->sc_dev, "%s: status 0x%x", __func__, status);
 1928         if ((status & CAS_INTR_PCI_ERROR_INT) != 0) {
 1929                 status = CAS_READ_4(sc, CAS_ERROR_STATUS);
 1930                 printf(", PCI bus error 0x%x", status);
 1931                 if ((status & CAS_ERROR_OTHER) != 0) {
 1932                         status = pci_read_config(sc->sc_dev, PCIR_STATUS, 2);
 1933                         printf(", PCI status 0x%x", status);
 1934                         pci_write_config(sc->sc_dev, PCIR_STATUS, status, 2);
 1935                 }
 1936         }
 1937         printf("\n");
 1938 
 1939         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 1940         cas_init_locked(sc);
 1941         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 1942                 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
 1943 }
 1944 
 1945 static int
 1946 cas_intr(void *v)
 1947 {
 1948         struct cas_softc *sc = v;
 1949 
 1950         if (__predict_false((CAS_READ_4(sc, CAS_STATUS_ALIAS) &
 1951             CAS_INTR_SUMMARY) == 0))
 1952                 return (FILTER_STRAY);
 1953 
 1954         /* Disable interrupts. */
 1955         CAS_WRITE_4(sc, CAS_INTMASK, 0xffffffff);
 1956         taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
 1957 
 1958         return (FILTER_HANDLED);
 1959 }
 1960 
 1961 static void
 1962 cas_intr_task(void *arg, int pending __unused)
 1963 {
 1964         struct cas_softc *sc = arg;
 1965         struct ifnet *ifp = sc->sc_ifp;
 1966         uint32_t status, status2;
 1967 
 1968         CAS_LOCK_ASSERT(sc, MA_NOTOWNED);
 1969 
 1970         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 1971                 return;
 1972 
 1973         status = CAS_READ_4(sc, CAS_STATUS);
 1974         if (__predict_false((status & CAS_INTR_SUMMARY) == 0))
 1975                 goto done;
 1976 
 1977         CAS_LOCK(sc);
 1978 #ifdef CAS_DEBUG
 1979         CTR4(KTR_CAS, "%s: %s: cplt %x, status %x",
 1980             device_get_name(sc->sc_dev), __func__,
 1981             (status >> CAS_STATUS_TX_COMP3_SHFT), (u_int)status);
 1982 
 1983         /*
 1984          * PCS interrupts must be cleared, otherwise no traffic is passed!
 1985          */
 1986         if ((status & CAS_INTR_PCS_INT) != 0) {
 1987                 status2 =
 1988                     CAS_READ_4(sc, CAS_PCS_INTR_STATUS) |
 1989                     CAS_READ_4(sc, CAS_PCS_INTR_STATUS);
 1990                 if ((status2 & CAS_PCS_INTR_LINK) != 0)
 1991                         device_printf(sc->sc_dev,
 1992                             "%s: PCS link status changed\n", __func__);
 1993         }
 1994         if ((status & CAS_MAC_CTRL_STATUS) != 0) {
 1995                 status2 = CAS_READ_4(sc, CAS_MAC_CTRL_STATUS);
 1996                 if ((status2 & CAS_MAC_CTRL_PAUSE) != 0)
 1997                         device_printf(sc->sc_dev,
 1998                             "%s: PAUSE received (PAUSE time %d slots)\n",
 1999                             __func__,
 2000                             (status2 & CAS_MAC_CTRL_STATUS_PT_MASK) >>
 2001                             CAS_MAC_CTRL_STATUS_PT_SHFT);
 2002                 if ((status2 & CAS_MAC_CTRL_PAUSE) != 0)
 2003                         device_printf(sc->sc_dev,
 2004                             "%s: transited to PAUSE state\n", __func__);
 2005                 if ((status2 & CAS_MAC_CTRL_NON_PAUSE) != 0)
 2006                         device_printf(sc->sc_dev,
 2007                             "%s: transited to non-PAUSE state\n", __func__);
 2008         }
 2009         if ((status & CAS_INTR_MIF) != 0)
 2010                 device_printf(sc->sc_dev, "%s: MIF interrupt\n", __func__);
 2011 #endif
 2012 
 2013         if (__predict_false((status &
 2014             (CAS_INTR_TX_TAG_ERR | CAS_INTR_RX_TAG_ERR |
 2015             CAS_INTR_RX_LEN_MMATCH | CAS_INTR_PCI_ERROR_INT)) != 0)) {
 2016                 cas_eint(sc, status);
 2017                 CAS_UNLOCK(sc);
 2018                 return;
 2019         }
 2020 
 2021         if (__predict_false(status & CAS_INTR_TX_MAC_INT)) {
 2022                 status2 = CAS_READ_4(sc, CAS_MAC_TX_STATUS);
 2023                 if ((status2 &
 2024                     (CAS_MAC_TX_UNDERRUN | CAS_MAC_TX_MAX_PKT_ERR)) != 0)
 2025                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 2026                 else if ((status2 & ~CAS_MAC_TX_FRAME_XMTD) != 0)
 2027                         device_printf(sc->sc_dev,
 2028                             "MAC TX fault, status %x\n", status2);
 2029         }
 2030 
 2031         if (__predict_false(status & CAS_INTR_RX_MAC_INT)) {
 2032                 status2 = CAS_READ_4(sc, CAS_MAC_RX_STATUS);
 2033                 if ((status2 & CAS_MAC_RX_OVERFLOW) != 0)
 2034                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
 2035                 else if ((status2 & ~CAS_MAC_RX_FRAME_RCVD) != 0)
 2036                         device_printf(sc->sc_dev,
 2037                             "MAC RX fault, status %x\n", status2);
 2038         }
 2039 
 2040         if ((status &
 2041             (CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_COMP_FULL |
 2042             CAS_INTR_RX_BUF_AEMPTY | CAS_INTR_RX_COMP_AFULL)) != 0) {
 2043                 cas_rint(sc);
 2044 #ifdef CAS_DEBUG
 2045                 if (__predict_false((status &
 2046                     (CAS_INTR_RX_BUF_NA | CAS_INTR_RX_COMP_FULL |
 2047                     CAS_INTR_RX_BUF_AEMPTY | CAS_INTR_RX_COMP_AFULL)) != 0))
 2048                         device_printf(sc->sc_dev,
 2049                             "RX fault, status %x\n", status);
 2050 #endif
 2051         }
 2052 
 2053         if ((status &
 2054             (CAS_INTR_TX_INT_ME | CAS_INTR_TX_ALL | CAS_INTR_TX_DONE)) != 0)
 2055                 cas_tint(sc);
 2056 
 2057         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 2058                 CAS_UNLOCK(sc);
 2059                 return;
 2060         } else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 2061                 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
 2062         CAS_UNLOCK(sc);
 2063 
 2064         status = CAS_READ_4(sc, CAS_STATUS_ALIAS);
 2065         if (__predict_false((status & CAS_INTR_SUMMARY) != 0)) {
 2066                 taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
 2067                 return;
 2068         }
 2069 
 2070  done:
 2071         /* Re-enable interrupts. */
 2072         CAS_WRITE_4(sc, CAS_INTMASK,
 2073             ~(CAS_INTR_TX_INT_ME | CAS_INTR_TX_TAG_ERR |
 2074             CAS_INTR_RX_DONE | CAS_INTR_RX_BUF_NA | CAS_INTR_RX_TAG_ERR |
 2075             CAS_INTR_RX_COMP_FULL | CAS_INTR_RX_BUF_AEMPTY |
 2076             CAS_INTR_RX_COMP_AFULL | CAS_INTR_RX_LEN_MMATCH |
 2077             CAS_INTR_PCI_ERROR_INT
 2078 #ifdef CAS_DEBUG
 2079             | CAS_INTR_PCS_INT | CAS_INTR_MIF
 2080 #endif
 2081         ));
 2082 }
 2083 
 2084 static void
 2085 cas_watchdog(struct cas_softc *sc)
 2086 {
 2087         struct ifnet *ifp = sc->sc_ifp;
 2088 
 2089         CAS_LOCK_ASSERT(sc, MA_OWNED);
 2090 
 2091 #ifdef CAS_DEBUG
 2092         CTR4(KTR_CAS,
 2093             "%s: CAS_RX_CONF %x CAS_MAC_RX_STATUS %x CAS_MAC_RX_CONF %x",
 2094             __func__, CAS_READ_4(sc, CAS_RX_CONF),
 2095             CAS_READ_4(sc, CAS_MAC_RX_STATUS),
 2096             CAS_READ_4(sc, CAS_MAC_RX_CONF));
 2097         CTR4(KTR_CAS,
 2098             "%s: CAS_TX_CONF %x CAS_MAC_TX_STATUS %x CAS_MAC_TX_CONF %x",
 2099             __func__, CAS_READ_4(sc, CAS_TX_CONF),
 2100             CAS_READ_4(sc, CAS_MAC_TX_STATUS),
 2101             CAS_READ_4(sc, CAS_MAC_TX_CONF));
 2102 #endif
 2103 
 2104         if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
 2105                 return;
 2106 
 2107         if ((sc->sc_flags & CAS_LINK) != 0)
 2108                 device_printf(sc->sc_dev, "device timeout\n");
 2109         else if (bootverbose)
 2110                 device_printf(sc->sc_dev, "device timeout (no link)\n");
 2111         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 2112 
 2113         /* Try to get more packets going. */
 2114         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 2115         cas_init_locked(sc);
 2116         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 2117                 taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
 2118 }
 2119 
 2120 static void
 2121 cas_mifinit(struct cas_softc *sc)
 2122 {
 2123 
 2124         /* Configure the MIF in frame mode. */
 2125         CAS_WRITE_4(sc, CAS_MIF_CONF,
 2126             CAS_READ_4(sc, CAS_MIF_CONF) & ~CAS_MIF_CONF_BB_MODE);
 2127         CAS_BARRIER(sc, CAS_MIF_CONF, 4,
 2128             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2129 }
 2130 
 2131 /*
 2132  * MII interface
 2133  *
 2134  * The MII interface supports at least three different operating modes:
 2135  *
 2136  * Bitbang mode is implemented using data, clock and output enable registers.
 2137  *
 2138  * Frame mode is implemented by loading a complete frame into the frame
 2139  * register and polling the valid bit for completion.
 2140  *
 2141  * Polling mode uses the frame register but completion is indicated by
 2142  * an interrupt.
 2143  *
 2144  */
 2145 static int
 2146 cas_mii_readreg(device_t dev, int phy, int reg)
 2147 {
 2148         struct cas_softc *sc;
 2149         int n;
 2150         uint32_t v;
 2151 
 2152 #ifdef CAS_DEBUG_PHY
 2153         printf("%s: phy %d reg %d\n", __func__, phy, reg);
 2154 #endif
 2155 
 2156         sc = device_get_softc(dev);
 2157         if ((sc->sc_flags & CAS_SERDES) != 0) {
 2158                 switch (reg) {
 2159                 case MII_BMCR:
 2160                         reg = CAS_PCS_CTRL;
 2161                         break;
 2162                 case MII_BMSR:
 2163                         reg = CAS_PCS_STATUS;
 2164                         break;
 2165                 case MII_PHYIDR1:
 2166                 case MII_PHYIDR2:
 2167                         return (0);
 2168                 case MII_ANAR:
 2169                         reg = CAS_PCS_ANAR;
 2170                         break;
 2171                 case MII_ANLPAR:
 2172                         reg = CAS_PCS_ANLPAR;
 2173                         break;
 2174                 case MII_EXTSR:
 2175                         return (EXTSR_1000XFDX | EXTSR_1000XHDX);
 2176                 default:
 2177                         device_printf(sc->sc_dev,
 2178                             "%s: unhandled register %d\n", __func__, reg);
 2179                         return (0);
 2180                 }
 2181                 return (CAS_READ_4(sc, reg));
 2182         }
 2183 
 2184         /* Construct the frame command. */
 2185         v = CAS_MIF_FRAME_READ |
 2186             (phy << CAS_MIF_FRAME_PHY_SHFT) |
 2187             (reg << CAS_MIF_FRAME_REG_SHFT);
 2188 
 2189         CAS_WRITE_4(sc, CAS_MIF_FRAME, v);
 2190         CAS_BARRIER(sc, CAS_MIF_FRAME, 4,
 2191             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2192         for (n = 0; n < 100; n++) {
 2193                 DELAY(1);
 2194                 v = CAS_READ_4(sc, CAS_MIF_FRAME);
 2195                 if (v & CAS_MIF_FRAME_TA_LSB)
 2196                         return (v & CAS_MIF_FRAME_DATA);
 2197         }
 2198 
 2199         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
 2200         return (0);
 2201 }
 2202 
 2203 static int
 2204 cas_mii_writereg(device_t dev, int phy, int reg, int val)
 2205 {
 2206         struct cas_softc *sc;
 2207         int n;
 2208         uint32_t v;
 2209 
 2210 #ifdef CAS_DEBUG_PHY
 2211         printf("%s: phy %d reg %d val %x\n", phy, reg, val, __func__);
 2212 #endif
 2213 
 2214         sc = device_get_softc(dev);
 2215         if ((sc->sc_flags & CAS_SERDES) != 0) {
 2216                 switch (reg) {
 2217                 case MII_BMSR:
 2218                         reg = CAS_PCS_STATUS;
 2219                         break;
 2220                 case MII_BMCR:
 2221                         reg = CAS_PCS_CTRL;
 2222                         if ((val & CAS_PCS_CTRL_RESET) == 0)
 2223                                 break;
 2224                         CAS_WRITE_4(sc, CAS_PCS_CTRL, val);
 2225                         CAS_BARRIER(sc, CAS_PCS_CTRL, 4,
 2226                             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2227                         if (!cas_bitwait(sc, CAS_PCS_CTRL,
 2228                             CAS_PCS_CTRL_RESET, 0))
 2229                                 device_printf(sc->sc_dev,
 2230                                     "cannot reset PCS\n");
 2231                         /* FALLTHROUGH */
 2232                 case MII_ANAR:
 2233                         CAS_WRITE_4(sc, CAS_PCS_CONF, 0);
 2234                         CAS_BARRIER(sc, CAS_PCS_CONF, 4,
 2235                             BUS_SPACE_BARRIER_WRITE);
 2236                         CAS_WRITE_4(sc, CAS_PCS_ANAR, val);
 2237                         CAS_BARRIER(sc, CAS_PCS_ANAR, 4,
 2238                             BUS_SPACE_BARRIER_WRITE);
 2239                         CAS_WRITE_4(sc, CAS_PCS_SERDES_CTRL,
 2240                             CAS_PCS_SERDES_CTRL_ESD);
 2241                         CAS_BARRIER(sc, CAS_PCS_CONF, 4,
 2242                             BUS_SPACE_BARRIER_WRITE);
 2243                         CAS_WRITE_4(sc, CAS_PCS_CONF,
 2244                             CAS_PCS_CONF_EN);
 2245                         CAS_BARRIER(sc, CAS_PCS_CONF, 4,
 2246                             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2247                         return (0);
 2248                 case MII_ANLPAR:
 2249                         reg = CAS_PCS_ANLPAR;
 2250                         break;
 2251                 default:
 2252                         device_printf(sc->sc_dev,
 2253                             "%s: unhandled register %d\n", __func__, reg);
 2254                         return (0);
 2255                 }
 2256                 CAS_WRITE_4(sc, reg, val);
 2257                 CAS_BARRIER(sc, reg, 4,
 2258                     BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2259                 return (0);
 2260         }
 2261 
 2262         /* Construct the frame command. */
 2263         v = CAS_MIF_FRAME_WRITE |
 2264             (phy << CAS_MIF_FRAME_PHY_SHFT) |
 2265             (reg << CAS_MIF_FRAME_REG_SHFT) |
 2266             (val & CAS_MIF_FRAME_DATA);
 2267 
 2268         CAS_WRITE_4(sc, CAS_MIF_FRAME, v);
 2269         CAS_BARRIER(sc, CAS_MIF_FRAME, 4,
 2270             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2271         for (n = 0; n < 100; n++) {
 2272                 DELAY(1);
 2273                 v = CAS_READ_4(sc, CAS_MIF_FRAME);
 2274                 if (v & CAS_MIF_FRAME_TA_LSB)
 2275                         return (1);
 2276         }
 2277 
 2278         device_printf(sc->sc_dev, "%s: timed out\n", __func__);
 2279         return (0);
 2280 }
 2281 
 2282 static void
 2283 cas_mii_statchg(device_t dev)
 2284 {
 2285         struct cas_softc *sc;
 2286         struct ifnet *ifp;
 2287         int gigabit;
 2288         uint32_t rxcfg, txcfg, v;
 2289 
 2290         sc = device_get_softc(dev);
 2291         ifp = sc->sc_ifp;
 2292 
 2293         CAS_LOCK_ASSERT(sc, MA_OWNED);
 2294 
 2295 #ifdef CAS_DEBUG
 2296         if ((ifp->if_flags & IFF_DEBUG) != 0)
 2297                 device_printf(sc->sc_dev, "%s: status changen", __func__);
 2298 #endif
 2299 
 2300         if ((sc->sc_mii->mii_media_status & IFM_ACTIVE) != 0 &&
 2301             IFM_SUBTYPE(sc->sc_mii->mii_media_active) != IFM_NONE)
 2302                 sc->sc_flags |= CAS_LINK;
 2303         else
 2304                 sc->sc_flags &= ~CAS_LINK;
 2305 
 2306         switch (IFM_SUBTYPE(sc->sc_mii->mii_media_active)) {
 2307         case IFM_1000_SX:
 2308         case IFM_1000_LX:
 2309         case IFM_1000_CX:
 2310         case IFM_1000_T:
 2311                 gigabit = 1;
 2312                 break;
 2313         default:
 2314                 gigabit = 0;
 2315         }
 2316 
 2317         /*
 2318          * The configuration done here corresponds to the steps F) and
 2319          * G) and as far as enabling of RX and TX MAC goes also step H)
 2320          * of the initialization sequence outlined in section 11.2.1 of
 2321          * the Cassini+ ASIC Specification.
 2322          */
 2323 
 2324         rxcfg = sc->sc_mac_rxcfg;
 2325         rxcfg &= ~CAS_MAC_RX_CONF_CARR;
 2326         txcfg = CAS_MAC_TX_CONF_EN_IPG0 | CAS_MAC_TX_CONF_NGU |
 2327             CAS_MAC_TX_CONF_NGUL;
 2328         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
 2329                 txcfg |= CAS_MAC_TX_CONF_ICARR | CAS_MAC_TX_CONF_ICOLLIS;
 2330         else if (gigabit != 0) {
 2331                 rxcfg |= CAS_MAC_RX_CONF_CARR;
 2332                 txcfg |= CAS_MAC_TX_CONF_CARR;
 2333         }
 2334         (void)cas_disable_tx(sc);
 2335         CAS_WRITE_4(sc, CAS_MAC_TX_CONF, txcfg);
 2336         (void)cas_disable_rx(sc);
 2337         CAS_WRITE_4(sc, CAS_MAC_RX_CONF, rxcfg);
 2338 
 2339         v = CAS_READ_4(sc, CAS_MAC_CTRL_CONF) &
 2340             ~(CAS_MAC_CTRL_CONF_TXP | CAS_MAC_CTRL_CONF_RXP);
 2341         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
 2342             IFM_ETH_RXPAUSE) != 0)
 2343                 v |= CAS_MAC_CTRL_CONF_RXP;
 2344         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
 2345             IFM_ETH_TXPAUSE) != 0)
 2346                 v |= CAS_MAC_CTRL_CONF_TXP;
 2347         CAS_WRITE_4(sc, CAS_MAC_CTRL_CONF, v);
 2348 
 2349         /*
 2350          * All supported chips have a bug causing incorrect checksum
 2351          * to be calculated when letting them strip the FCS in half-
 2352          * duplex mode.  In theory we could disable FCS stripping and
 2353          * manually adjust the checksum accordingly.  It seems to make
 2354          * more sense to optimze for the common case and just disable
 2355          * hardware checksumming in half-duplex mode though.
 2356          */
 2357         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0) {
 2358                 ifp->if_capenable &= ~IFCAP_HWCSUM;
 2359                 ifp->if_hwassist = 0;
 2360         } else if ((sc->sc_flags & CAS_NO_CSUM) == 0) {
 2361                 ifp->if_capenable = ifp->if_capabilities;
 2362                 ifp->if_hwassist = CAS_CSUM_FEATURES;
 2363         }
 2364 
 2365         if (sc->sc_variant == CAS_SATURN) {
 2366                 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0)
 2367                         /* silicon bug workaround */
 2368                         CAS_WRITE_4(sc, CAS_MAC_PREAMBLE_LEN, 0x41);
 2369                 else
 2370                         CAS_WRITE_4(sc, CAS_MAC_PREAMBLE_LEN, 0x7);
 2371         }
 2372 
 2373         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0 &&
 2374             gigabit != 0)
 2375                 CAS_WRITE_4(sc, CAS_MAC_SLOT_TIME,
 2376                     CAS_MAC_SLOT_TIME_CARR);
 2377         else
 2378                 CAS_WRITE_4(sc, CAS_MAC_SLOT_TIME,
 2379                     CAS_MAC_SLOT_TIME_NORM);
 2380 
 2381         /* XIF Configuration */
 2382         v = CAS_MAC_XIF_CONF_TX_OE | CAS_MAC_XIF_CONF_LNKLED;
 2383         if ((sc->sc_flags & CAS_SERDES) == 0) {
 2384                 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0)
 2385                         v |= CAS_MAC_XIF_CONF_NOECHO;
 2386                 v |= CAS_MAC_XIF_CONF_BUF_OE;
 2387         }
 2388         if (gigabit != 0)
 2389                 v |= CAS_MAC_XIF_CONF_GMII;
 2390         if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
 2391                 v |= CAS_MAC_XIF_CONF_FDXLED;
 2392         CAS_WRITE_4(sc, CAS_MAC_XIF_CONF, v);
 2393 
 2394         sc->sc_mac_rxcfg = rxcfg;
 2395         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
 2396             (sc->sc_flags & CAS_LINK) != 0) {
 2397                 CAS_WRITE_4(sc, CAS_MAC_TX_CONF,
 2398                     txcfg | CAS_MAC_TX_CONF_EN);
 2399                 CAS_WRITE_4(sc, CAS_MAC_RX_CONF,
 2400                     rxcfg | CAS_MAC_RX_CONF_EN);
 2401         }
 2402 }
 2403 
 2404 static int
 2405 cas_mediachange(struct ifnet *ifp)
 2406 {
 2407         struct cas_softc *sc = ifp->if_softc;
 2408         int error;
 2409 
 2410         /* XXX add support for serial media. */
 2411 
 2412         CAS_LOCK(sc);
 2413         error = mii_mediachg(sc->sc_mii);
 2414         CAS_UNLOCK(sc);
 2415         return (error);
 2416 }
 2417 
 2418 static void
 2419 cas_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
 2420 {
 2421         struct cas_softc *sc = ifp->if_softc;
 2422 
 2423         CAS_LOCK(sc);
 2424         if ((ifp->if_flags & IFF_UP) == 0) {
 2425                 CAS_UNLOCK(sc);
 2426                 return;
 2427         }
 2428 
 2429         mii_pollstat(sc->sc_mii);
 2430         ifmr->ifm_active = sc->sc_mii->mii_media_active;
 2431         ifmr->ifm_status = sc->sc_mii->mii_media_status;
 2432         CAS_UNLOCK(sc);
 2433 }
 2434 
 2435 static int
 2436 cas_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 2437 {
 2438         struct cas_softc *sc = ifp->if_softc;
 2439         struct ifreq *ifr = (struct ifreq *)data;
 2440         int error;
 2441 
 2442         error = 0;
 2443         switch (cmd) {
 2444         case SIOCSIFFLAGS:
 2445                 CAS_LOCK(sc);
 2446                 if ((ifp->if_flags & IFF_UP) != 0) {
 2447                         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
 2448                             ((ifp->if_flags ^ sc->sc_ifflags) &
 2449                             (IFF_ALLMULTI | IFF_PROMISC)) != 0)
 2450                                 cas_setladrf(sc);
 2451                         else
 2452                                 cas_init_locked(sc);
 2453                 } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
 2454                         cas_stop(ifp);
 2455                 sc->sc_ifflags = ifp->if_flags;
 2456                 CAS_UNLOCK(sc);
 2457                 break;
 2458         case SIOCSIFCAP:
 2459                 CAS_LOCK(sc);
 2460                 if ((sc->sc_flags & CAS_NO_CSUM) != 0) {
 2461                         error = EINVAL;
 2462                         CAS_UNLOCK(sc);
 2463                         break;
 2464                 }
 2465                 ifp->if_capenable = ifr->ifr_reqcap;
 2466                 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
 2467                         ifp->if_hwassist = CAS_CSUM_FEATURES;
 2468                 else
 2469                         ifp->if_hwassist = 0;
 2470                 CAS_UNLOCK(sc);
 2471                 break;
 2472         case SIOCADDMULTI:
 2473         case SIOCDELMULTI:
 2474                 CAS_LOCK(sc);
 2475                 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
 2476                         cas_setladrf(sc);
 2477                 CAS_UNLOCK(sc);
 2478                 break;
 2479         case SIOCSIFMTU:
 2480                 if ((ifr->ifr_mtu < ETHERMIN) ||
 2481                     (ifr->ifr_mtu > ETHERMTU_JUMBO))
 2482                         error = EINVAL;
 2483                 else
 2484                         ifp->if_mtu = ifr->ifr_mtu;
 2485                 break;
 2486         case SIOCGIFMEDIA:
 2487         case SIOCSIFMEDIA:
 2488                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
 2489                 break;
 2490         default:
 2491                 error = ether_ioctl(ifp, cmd, data);
 2492                 break;
 2493         }
 2494 
 2495         return (error);
 2496 }
 2497 
 2498 static u_int
 2499 cas_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
 2500 {
 2501         uint32_t crc, *hash = arg;
 2502 
 2503         crc = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN);
 2504         /* We just want the 8 most significant bits. */
 2505         crc >>= 24;
 2506         /* Set the corresponding bit in the filter. */
 2507         hash[crc >> 4] |= 1 << (15 - (crc & 15));
 2508 
 2509         return (1);
 2510 }
 2511 
 2512 static void
 2513 cas_setladrf(struct cas_softc *sc)
 2514 {
 2515         struct ifnet *ifp = sc->sc_ifp;
 2516         int i;
 2517         uint32_t hash[16];
 2518         uint32_t v;
 2519 
 2520         CAS_LOCK_ASSERT(sc, MA_OWNED);
 2521 
 2522         /*
 2523          * Turn off the RX MAC and the hash filter as required by the Sun
 2524          * Cassini programming restrictions.
 2525          */
 2526         v = sc->sc_mac_rxcfg & ~(CAS_MAC_RX_CONF_HFILTER |
 2527             CAS_MAC_RX_CONF_EN);
 2528         CAS_WRITE_4(sc, CAS_MAC_RX_CONF, v);
 2529         CAS_BARRIER(sc, CAS_MAC_RX_CONF, 4,
 2530             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
 2531         if (!cas_bitwait(sc, CAS_MAC_RX_CONF, CAS_MAC_RX_CONF_HFILTER |
 2532             CAS_MAC_RX_CONF_EN, 0))
 2533                 device_printf(sc->sc_dev,
 2534                     "cannot disable RX MAC or hash filter\n");
 2535 
 2536         v &= ~(CAS_MAC_RX_CONF_PROMISC | CAS_MAC_RX_CONF_PGRP);
 2537         if ((ifp->if_flags & IFF_PROMISC) != 0) {
 2538                 v |= CAS_MAC_RX_CONF_PROMISC;
 2539                 goto chipit;
 2540         }
 2541         if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
 2542                 v |= CAS_MAC_RX_CONF_PGRP;
 2543                 goto chipit;
 2544         }
 2545 
 2546         /*
 2547          * Set up multicast address filter by passing all multicast
 2548          * addresses through a crc generator, and then using the high
 2549          * order 8 bits as an index into the 256 bit logical address
 2550          * filter.  The high order 4 bits selects the word, while the
 2551          * other 4 bits select the bit within the word (where bit 0
 2552          * is the MSB).
 2553          */
 2554 
 2555         memset(hash, 0, sizeof(hash));
 2556         if_foreach_llmaddr(ifp, cas_hash_maddr, &hash);
 2557 
 2558         v |= CAS_MAC_RX_CONF_HFILTER;
 2559 
 2560         /* Now load the hash table into the chip (if we are using it). */
 2561         for (i = 0; i < 16; i++)
 2562                 CAS_WRITE_4(sc,
 2563                     CAS_MAC_HASH0 + i * (CAS_MAC_HASH1 - CAS_MAC_HASH0),
 2564                     hash[i]);
 2565 
 2566  chipit:
 2567         sc->sc_mac_rxcfg = v;
 2568         CAS_WRITE_4(sc, CAS_MAC_RX_CONF, v | CAS_MAC_RX_CONF_EN);
 2569 }
 2570 
 2571 static int      cas_pci_attach(device_t dev);
 2572 static int      cas_pci_detach(device_t dev);
 2573 static int      cas_pci_probe(device_t dev);
 2574 static int      cas_pci_resume(device_t dev);
 2575 static int      cas_pci_suspend(device_t dev);
 2576 
 2577 static device_method_t cas_pci_methods[] = {
 2578         /* Device interface */
 2579         DEVMETHOD(device_probe,         cas_pci_probe),
 2580         DEVMETHOD(device_attach,        cas_pci_attach),
 2581         DEVMETHOD(device_detach,        cas_pci_detach),
 2582         DEVMETHOD(device_suspend,       cas_pci_suspend),
 2583         DEVMETHOD(device_resume,        cas_pci_resume),
 2584         /* Use the suspend handler here, it is all that is required. */
 2585         DEVMETHOD(device_shutdown,      cas_pci_suspend),
 2586 
 2587         /* MII interface */
 2588         DEVMETHOD(miibus_readreg,       cas_mii_readreg),
 2589         DEVMETHOD(miibus_writereg,      cas_mii_writereg),
 2590         DEVMETHOD(miibus_statchg,       cas_mii_statchg),
 2591 
 2592         DEVMETHOD_END
 2593 };
 2594 
 2595 static driver_t cas_pci_driver = {
 2596         "cas",
 2597         cas_pci_methods,
 2598         sizeof(struct cas_softc)
 2599 };
 2600 
 2601 static const struct cas_pci_dev {
 2602         uint32_t        cpd_devid;
 2603         uint8_t         cpd_revid;
 2604         int             cpd_variant;
 2605         const char      *cpd_desc;
 2606 } cas_pci_devlist[] = {
 2607         { 0x0035100b, 0x0, CAS_SATURN, "NS DP83065 Saturn Gigabit Ethernet" },
 2608         { 0xabba108e, 0x10, CAS_CASPLUS, "Sun Cassini+ Gigabit Ethernet" },
 2609         { 0xabba108e, 0x0, CAS_CAS, "Sun Cassini Gigabit Ethernet" },
 2610         { 0, 0, 0, NULL }
 2611 };
 2612 
 2613 DRIVER_MODULE(cas, pci, cas_pci_driver, 0, 0);
 2614 MODULE_PNP_INFO("W32:vendor/device", pci, cas, cas_pci_devlist,
 2615     nitems(cas_pci_devlist) - 1);
 2616 DRIVER_MODULE(miibus, cas, miibus_driver, 0, 0);
 2617 MODULE_DEPEND(cas, pci, 1, 1, 1);
 2618 
 2619 static int
 2620 cas_pci_probe(device_t dev)
 2621 {
 2622         int i;
 2623 
 2624         for (i = 0; cas_pci_devlist[i].cpd_desc != NULL; i++) {
 2625                 if (pci_get_devid(dev) == cas_pci_devlist[i].cpd_devid &&
 2626                     pci_get_revid(dev) >= cas_pci_devlist[i].cpd_revid) {
 2627                         device_set_desc(dev, cas_pci_devlist[i].cpd_desc);
 2628                         return (BUS_PROBE_DEFAULT);
 2629                 }
 2630         }
 2631 
 2632         return (ENXIO);
 2633 }
 2634 
 2635 static struct resource_spec cas_pci_res_spec[] = {
 2636         { SYS_RES_IRQ, 0, RF_SHAREABLE | RF_ACTIVE },   /* CAS_RES_INTR */
 2637         { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },     /* CAS_RES_MEM */
 2638         { -1, 0 }
 2639 };
 2640 
 2641 #define CAS_LOCAL_MAC_ADDRESS   "local-mac-address"
 2642 #define CAS_PHY_INTERFACE       "phy-interface"
 2643 #define CAS_PHY_TYPE            "phy-type"
 2644 #define CAS_PHY_TYPE_PCS        "pcs"
 2645 
 2646 static int
 2647 cas_pci_attach(device_t dev)
 2648 {
 2649         char buf[sizeof(CAS_LOCAL_MAC_ADDRESS)];
 2650         struct cas_softc *sc;
 2651         int i;
 2652 #if !defined(__powerpc__)
 2653         u_char enaddr[4][ETHER_ADDR_LEN];
 2654         u_int j, k, lma, pcs[4], phy;
 2655 #endif
 2656 
 2657         sc = device_get_softc(dev);
 2658         sc->sc_variant = CAS_UNKNOWN;
 2659         for (i = 0; cas_pci_devlist[i].cpd_desc != NULL; i++) {
 2660                 if (pci_get_devid(dev) == cas_pci_devlist[i].cpd_devid &&
 2661                     pci_get_revid(dev) >= cas_pci_devlist[i].cpd_revid) {
 2662                         sc->sc_variant = cas_pci_devlist[i].cpd_variant;
 2663                         break;
 2664                 }
 2665         }
 2666         if (sc->sc_variant == CAS_UNKNOWN) {
 2667                 device_printf(dev, "unknown adaptor\n");
 2668                 return (ENXIO);
 2669         }
 2670 
 2671         /* PCI configuration */
 2672         pci_write_config(dev, PCIR_COMMAND,
 2673             pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_BUSMASTEREN |
 2674             PCIM_CMD_MWRICEN | PCIM_CMD_PERRESPEN | PCIM_CMD_SERRESPEN, 2);
 2675 
 2676         sc->sc_dev = dev;
 2677         if (sc->sc_variant == CAS_CAS && pci_get_devid(dev) < 0x02)
 2678                 /* Hardware checksumming may hang TX. */
 2679                 sc->sc_flags |= CAS_NO_CSUM;
 2680         if (sc->sc_variant == CAS_CASPLUS || sc->sc_variant == CAS_SATURN)
 2681                 sc->sc_flags |= CAS_REG_PLUS;
 2682         if (sc->sc_variant == CAS_CAS ||
 2683             (sc->sc_variant == CAS_CASPLUS && pci_get_revid(dev) < 0x11))
 2684                 sc->sc_flags |= CAS_TABORT;
 2685         if (bootverbose)
 2686                 device_printf(dev, "flags=0x%x\n", sc->sc_flags);
 2687 
 2688         if (bus_alloc_resources(dev, cas_pci_res_spec, sc->sc_res)) {
 2689                 device_printf(dev, "failed to allocate resources\n");
 2690                 bus_release_resources(dev, cas_pci_res_spec, sc->sc_res);
 2691                 return (ENXIO);
 2692         }
 2693 
 2694         CAS_LOCK_INIT(sc, device_get_nameunit(dev));
 2695 
 2696 #if defined(__powerpc__)
 2697         OF_getetheraddr(dev, sc->sc_enaddr);
 2698         if (OF_getprop(ofw_bus_get_node(dev), CAS_PHY_INTERFACE, buf,
 2699             sizeof(buf)) > 0 || OF_getprop(ofw_bus_get_node(dev),
 2700             CAS_PHY_TYPE, buf, sizeof(buf)) > 0) {
 2701                 buf[sizeof(buf) - 1] = '\0';
 2702                 if (strcmp(buf, CAS_PHY_TYPE_PCS) == 0)
 2703                         sc->sc_flags |= CAS_SERDES;
 2704         }
 2705 #else
 2706         /*
 2707          * Dig out VPD (vital product data) and read the MAC address as well
 2708          * as the PHY type.  The VPD resides in the PCI Expansion ROM (PCI
 2709          * FCode) and can't be accessed via the PCI capability pointer.
 2710          * SUNW,pci-ce and SUNW,pci-qge use the Enhanced VPD format described
 2711          * in the free US Patent 7149820.
 2712          */
 2713 
 2714 #define PCI_ROMHDR_SIZE                 0x1c
 2715 #define PCI_ROMHDR_SIG                  0x00
 2716 #define PCI_ROMHDR_SIG_MAGIC            0xaa55          /* little endian */
 2717 #define PCI_ROMHDR_PTR_DATA             0x18
 2718 #define PCI_ROM_SIZE                    0x18
 2719 #define PCI_ROM_SIG                     0x00
 2720 #define PCI_ROM_SIG_MAGIC               0x52494350      /* "PCIR", endian */
 2721                                                         /* reversed */
 2722 #define PCI_ROM_VENDOR                  0x04
 2723 #define PCI_ROM_DEVICE                  0x06
 2724 #define PCI_ROM_PTR_VPD                 0x08
 2725 #define PCI_VPDRES_BYTE0                0x00
 2726 #define PCI_VPDRES_ISLARGE(x)           ((x) & 0x80)
 2727 #define PCI_VPDRES_LARGE_NAME(x)        ((x) & 0x7f)
 2728 #define PCI_VPDRES_LARGE_LEN_LSB        0x01
 2729 #define PCI_VPDRES_LARGE_LEN_MSB        0x02
 2730 #define PCI_VPDRES_LARGE_SIZE           0x03
 2731 #define PCI_VPDRES_TYPE_ID_STRING       0x02            /* large */
 2732 #define PCI_VPDRES_TYPE_VPD             0x10            /* large */
 2733 #define PCI_VPD_KEY0                    0x00
 2734 #define PCI_VPD_KEY1                    0x01
 2735 #define PCI_VPD_LEN                     0x02
 2736 #define PCI_VPD_SIZE                    0x03
 2737 
 2738 #define CAS_ROM_READ_1(sc, offs)                                        \
 2739         CAS_READ_1((sc), CAS_PCI_ROM_OFFSET + (offs))
 2740 #define CAS_ROM_READ_2(sc, offs)                                        \
 2741         CAS_READ_2((sc), CAS_PCI_ROM_OFFSET + (offs))
 2742 #define CAS_ROM_READ_4(sc, offs)                                        \
 2743         CAS_READ_4((sc), CAS_PCI_ROM_OFFSET + (offs))
 2744 
 2745         lma = phy = 0;
 2746         memset(enaddr, 0, sizeof(enaddr));
 2747         memset(pcs, 0, sizeof(pcs));
 2748 
 2749         /* Enable PCI Expansion ROM access. */
 2750         CAS_WRITE_4(sc, CAS_BIM_LDEV_OEN,
 2751             CAS_BIM_LDEV_OEN_PAD | CAS_BIM_LDEV_OEN_PROM);
 2752 
 2753         /* Read PCI Expansion ROM header. */
 2754         if (CAS_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
 2755             (i = CAS_ROM_READ_2(sc, PCI_ROMHDR_PTR_DATA)) <
 2756             PCI_ROMHDR_SIZE) {
 2757                 device_printf(dev, "unexpected PCI Expansion ROM header\n");
 2758                 goto fail_prom;
 2759         }
 2760 
 2761         /* Read PCI Expansion ROM data. */
 2762         if (CAS_ROM_READ_4(sc, i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC ||
 2763             CAS_ROM_READ_2(sc, i + PCI_ROM_VENDOR) != pci_get_vendor(dev) ||
 2764             CAS_ROM_READ_2(sc, i + PCI_ROM_DEVICE) != pci_get_device(dev) ||
 2765             (j = CAS_ROM_READ_2(sc, i + PCI_ROM_PTR_VPD)) <
 2766             i + PCI_ROM_SIZE) {
 2767                 device_printf(dev, "unexpected PCI Expansion ROM data\n");
 2768                 goto fail_prom;
 2769         }
 2770 
 2771         /* Read PCI VPD. */
 2772  next:
 2773         if (PCI_VPDRES_ISLARGE(CAS_ROM_READ_1(sc,
 2774             j + PCI_VPDRES_BYTE0)) == 0) {
 2775                 device_printf(dev, "no large PCI VPD\n");
 2776                 goto fail_prom;
 2777         }
 2778 
 2779         i = (CAS_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB) << 8) |
 2780             CAS_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB);
 2781         switch (PCI_VPDRES_LARGE_NAME(CAS_ROM_READ_1(sc,
 2782             j + PCI_VPDRES_BYTE0))) {
 2783         case PCI_VPDRES_TYPE_ID_STRING:
 2784                 /* Skip identifier string. */
 2785                 j += PCI_VPDRES_LARGE_SIZE + i;
 2786                 goto next;
 2787         case PCI_VPDRES_TYPE_VPD:
 2788                 for (j += PCI_VPDRES_LARGE_SIZE; i > 0;
 2789                     i -= PCI_VPD_SIZE + CAS_ROM_READ_1(sc, j + PCI_VPD_LEN),
 2790                     j += PCI_VPD_SIZE + CAS_ROM_READ_1(sc, j + PCI_VPD_LEN)) {
 2791                         if (CAS_ROM_READ_1(sc, j + PCI_VPD_KEY0) != 'Z')
 2792                                 /* no Enhanced VPD */
 2793                                 continue;
 2794                         if (CAS_ROM_READ_1(sc, j + PCI_VPD_SIZE) != 'I')
 2795                                 /* no instance property */
 2796                                 continue;
 2797                         if (CAS_ROM_READ_1(sc, j + PCI_VPD_SIZE + 3) == 'B') {
 2798                                 /* byte array */
 2799                                 if (CAS_ROM_READ_1(sc,
 2800                                     j + PCI_VPD_SIZE + 4) != ETHER_ADDR_LEN)
 2801                                         continue;
 2802                                 bus_read_region_1(sc->sc_res[CAS_RES_MEM],
 2803                                     CAS_PCI_ROM_OFFSET + j + PCI_VPD_SIZE + 5,
 2804                                     buf, sizeof(buf));
 2805                                 buf[sizeof(buf) - 1] = '\0';
 2806                                 if (strcmp(buf, CAS_LOCAL_MAC_ADDRESS) != 0)
 2807                                         continue;
 2808                                 bus_read_region_1(sc->sc_res[CAS_RES_MEM],
 2809                                     CAS_PCI_ROM_OFFSET + j + PCI_VPD_SIZE +
 2810                                     5 + sizeof(CAS_LOCAL_MAC_ADDRESS),
 2811                                     enaddr[lma], sizeof(enaddr[lma]));
 2812                                 lma++;
 2813                                 if (lma == 4 && phy == 4)
 2814                                         break;
 2815                         } else if (CAS_ROM_READ_1(sc, j + PCI_VPD_SIZE + 3) ==
 2816                            'S') {
 2817                                 /* string */
 2818                                 if (CAS_ROM_READ_1(sc,
 2819                                     j + PCI_VPD_SIZE + 4) !=
 2820                                     sizeof(CAS_PHY_TYPE_PCS))
 2821                                         continue;
 2822                                 bus_read_region_1(sc->sc_res[CAS_RES_MEM],
 2823                                     CAS_PCI_ROM_OFFSET + j + PCI_VPD_SIZE + 5,
 2824                                     buf, sizeof(buf));
 2825                                 buf[sizeof(buf) - 1] = '\0';
 2826                                 if (strcmp(buf, CAS_PHY_INTERFACE) == 0)
 2827                                         k = sizeof(CAS_PHY_INTERFACE);
 2828                                 else if (strcmp(buf, CAS_PHY_TYPE) == 0)
 2829                                         k = sizeof(CAS_PHY_TYPE);
 2830                                 else
 2831                                         continue;
 2832                                 bus_read_region_1(sc->sc_res[CAS_RES_MEM],
 2833                                     CAS_PCI_ROM_OFFSET + j + PCI_VPD_SIZE +
 2834                                     5 + k, buf, sizeof(buf));
 2835                                 buf[sizeof(buf) - 1] = '\0';
 2836                                 if (strcmp(buf, CAS_PHY_TYPE_PCS) == 0)
 2837                                         pcs[phy] = 1;
 2838                                 phy++;
 2839                                 if (lma == 4 && phy == 4)
 2840                                         break;
 2841                         }
 2842                 }
 2843                 break;
 2844         default:
 2845                 device_printf(dev, "unexpected PCI VPD\n");
 2846                 goto fail_prom;
 2847         }
 2848 
 2849  fail_prom:
 2850         CAS_WRITE_4(sc, CAS_BIM_LDEV_OEN, 0);
 2851 
 2852         if (lma == 0) {
 2853                 device_printf(dev, "could not determine Ethernet address\n");
 2854                 goto fail;
 2855         }
 2856         i = 0;
 2857         if (lma > 1 && pci_get_slot(dev) < nitems(enaddr))
 2858                 i = pci_get_slot(dev);
 2859         memcpy(sc->sc_enaddr, enaddr[i], ETHER_ADDR_LEN);
 2860 
 2861         if (phy == 0) {
 2862                 device_printf(dev, "could not determine PHY type\n");
 2863                 goto fail;
 2864         }
 2865         i = 0;
 2866         if (phy > 1 && pci_get_slot(dev) < nitems(pcs))
 2867                 i = pci_get_slot(dev);
 2868         if (pcs[i] != 0)
 2869                 sc->sc_flags |= CAS_SERDES;
 2870 #endif
 2871 
 2872         if (cas_attach(sc) != 0) {
 2873                 device_printf(dev, "could not be attached\n");
 2874                 goto fail;
 2875         }
 2876 
 2877         if (bus_setup_intr(dev, sc->sc_res[CAS_RES_INTR], INTR_TYPE_NET |
 2878             INTR_MPSAFE, cas_intr, NULL, sc, &sc->sc_ih) != 0) {
 2879                 device_printf(dev, "failed to set up interrupt\n");
 2880                 cas_detach(sc);
 2881                 goto fail;
 2882         }
 2883         return (0);
 2884 
 2885  fail:
 2886         CAS_LOCK_DESTROY(sc);
 2887         bus_release_resources(dev, cas_pci_res_spec, sc->sc_res);
 2888         return (ENXIO);
 2889 }
 2890 
 2891 static int
 2892 cas_pci_detach(device_t dev)
 2893 {
 2894         struct cas_softc *sc;
 2895 
 2896         sc = device_get_softc(dev);
 2897         bus_teardown_intr(dev, sc->sc_res[CAS_RES_INTR], sc->sc_ih);
 2898         cas_detach(sc);
 2899         CAS_LOCK_DESTROY(sc);
 2900         bus_release_resources(dev, cas_pci_res_spec, sc->sc_res);
 2901         return (0);
 2902 }
 2903 
 2904 static int
 2905 cas_pci_suspend(device_t dev)
 2906 {
 2907 
 2908         cas_suspend(device_get_softc(dev));
 2909         return (0);
 2910 }
 2911 
 2912 static int
 2913 cas_pci_resume(device_t dev)
 2914 {
 2915 
 2916         cas_resume(device_get_softc(dev));
 2917         return (0);
 2918 }

Cache object: 8a3b984e759f01d531e034b387dbc421


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.