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

          Line data    Source code
       1             : /*      $OpenBSD: if_stge.c,v 1.69 2017/01/22 10:17:38 dlg Exp $        */
       2             : /*      $NetBSD: if_stge.c,v 1.27 2005/05/16 21:35:32 bouyer Exp $      */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 2001 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Jason R. Thorpe.
      10             :  *
      11             :  * Redistribution and use in source and binary forms, with or without
      12             :  * modification, are permitted provided that the following conditions
      13             :  * are met:
      14             :  * 1. Redistributions of source code must retain the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer.
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in the
      18             :  *    documentation and/or other materials provided with the distribution.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      21             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      22             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      23             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      24             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : /*
      34             :  * Device driver for the Sundance Tech. TC9021 10/100/1000
      35             :  * Ethernet controller.
      36             :  */
      37             : 
      38             : #include "bpfilter.h"
      39             : #include "vlan.h"
      40             : 
      41             : #include <sys/param.h>
      42             : #include <sys/systm.h>
      43             : #include <sys/timeout.h>
      44             : #include <sys/mbuf.h>
      45             : #include <sys/malloc.h>
      46             : #include <sys/kernel.h>
      47             : #include <sys/socket.h>
      48             : #include <sys/ioctl.h>
      49             : #include <sys/errno.h>
      50             : #include <sys/device.h>
      51             : #include <sys/queue.h>
      52             : 
      53             : #include <net/if.h>
      54             : 
      55             : #include <netinet/in.h>
      56             : #include <netinet/if_ether.h>
      57             : 
      58             : #include <net/if_media.h>
      59             : 
      60             : #if NBPFILTER > 0
      61             : #include <net/bpf.h>
      62             : #endif
      63             : 
      64             : #include <machine/bus.h>
      65             : #include <machine/intr.h>
      66             : 
      67             : #include <dev/mii/miivar.h>
      68             : #include <dev/mii/mii_bitbang.h>
      69             : 
      70             : #include <dev/pci/pcireg.h>
      71             : #include <dev/pci/pcivar.h>
      72             : #include <dev/pci/pcidevs.h>
      73             : 
      74             : #include <dev/pci/if_stgereg.h>
      75             : 
      76             : void    stge_start(struct ifnet *);
      77             : void    stge_watchdog(struct ifnet *);
      78             : int     stge_ioctl(struct ifnet *, u_long, caddr_t);
      79             : int     stge_init(struct ifnet *);
      80             : void    stge_stop(struct ifnet *, int);
      81             : 
      82             : void    stge_reset(struct stge_softc *);
      83             : void    stge_rxdrain(struct stge_softc *);
      84             : int     stge_add_rxbuf(struct stge_softc *, int);
      85             : void    stge_read_eeprom(struct stge_softc *, int, uint16_t *);
      86             : void    stge_tick(void *);
      87             : 
      88             : void    stge_stats_update(struct stge_softc *);
      89             : 
      90             : void    stge_iff(struct stge_softc *);
      91             : 
      92             : int     stge_intr(void *);
      93             : void    stge_txintr(struct stge_softc *);
      94             : void    stge_rxintr(struct stge_softc *);
      95             : 
      96             : int     stge_mii_readreg(struct device *, int, int);
      97             : void    stge_mii_writereg(struct device *, int, int, int);
      98             : void    stge_mii_statchg(struct device *);
      99             : 
     100             : int     stge_mediachange(struct ifnet *);
     101             : void    stge_mediastatus(struct ifnet *, struct ifmediareq *);
     102             : 
     103             : int     stge_match(struct device *, void *, void *);
     104             : void    stge_attach(struct device *, struct device *, void *);
     105             : 
     106             : int     stge_copy_small = 0;
     107             : 
     108             : struct cfattach stge_ca = {
     109             :         sizeof(struct stge_softc), stge_match, stge_attach,
     110             : };
     111             : 
     112             : struct cfdriver stge_cd = {
     113             :         NULL, "stge", DV_IFNET
     114             : };
     115             : 
     116             : uint32_t stge_mii_bitbang_read(struct device *);
     117             : void    stge_mii_bitbang_write(struct device *, uint32_t);
     118             : 
     119             : const struct mii_bitbang_ops stge_mii_bitbang_ops = {
     120             :         stge_mii_bitbang_read,
     121             :         stge_mii_bitbang_write,
     122             :         {
     123             :                 PC_MgmtData,            /* MII_BIT_MDO */
     124             :                 PC_MgmtData,            /* MII_BIT_MDI */
     125             :                 PC_MgmtClk,             /* MII_BIT_MDC */
     126             :                 PC_MgmtDir,             /* MII_BIT_DIR_HOST_PHY */
     127             :                 0,                      /* MII_BIT_DIR_PHY_HOST */
     128             :         }
     129             : };
     130             : 
     131             : /*
     132             :  * Devices supported by this driver.
     133             :  */
     134             : const struct pci_matchid stge_devices[] = {
     135             :         { PCI_VENDOR_ANTARES, PCI_PRODUCT_ANTARES_TC9021 },
     136             :         { PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE550T },
     137             :         { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_ST1023 },
     138             :         { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_ST2021 },
     139             :         { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_TC9021 },
     140             :         { PCI_VENDOR_SUNDANCE, PCI_PRODUCT_SUNDANCE_TC9021_ALT },
     141             :         { PCI_VENDOR_TAMARACK, PCI_PRODUCT_TAMARACK_TC9021 },
     142             :         { PCI_VENDOR_TAMARACK, PCI_PRODUCT_TAMARACK_TC9021_ALT }
     143             : };
     144             : 
     145             : int
     146           0 : stge_match(struct device *parent, void *match, void *aux)
     147             : {
     148           0 :         return (pci_matchbyid((struct pci_attach_args *)aux, stge_devices,
     149             :             sizeof(stge_devices) / sizeof(stge_devices[0])));
     150             : }
     151             : 
     152             : void
     153           0 : stge_attach(struct device *parent, struct device *self, void *aux)
     154             : {
     155           0 :         struct stge_softc *sc = (struct stge_softc *) self;
     156           0 :         struct pci_attach_args *pa = aux;
     157           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     158           0 :         pci_chipset_tag_t pc = pa->pa_pc;
     159           0 :         pci_intr_handle_t ih;
     160             :         const char *intrstr = NULL;
     161           0 :         bus_space_tag_t iot, memt;
     162           0 :         bus_space_handle_t ioh, memh;
     163           0 :         bus_dma_segment_t seg;
     164           0 :         bus_size_t iosize;
     165             :         int ioh_valid, memh_valid;
     166           0 :         int i, rseg, error;
     167             : 
     168           0 :         timeout_set(&sc->sc_timeout, stge_tick, sc);
     169             : 
     170           0 :         sc->sc_rev = PCI_REVISION(pa->pa_class);
     171             : 
     172             :         /*
     173             :          * Map the device.
     174             :          */
     175           0 :         ioh_valid = (pci_mapreg_map(pa, STGE_PCI_IOBA,
     176             :             PCI_MAPREG_TYPE_IO, 0,
     177           0 :             &iot, &ioh, NULL, &iosize, 0) == 0);
     178           0 :         memh_valid = (pci_mapreg_map(pa, STGE_PCI_MMBA,
     179             :             PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
     180           0 :             &memt, &memh, NULL, &iosize, 0) == 0);
     181             : 
     182           0 :         if (memh_valid) {
     183           0 :                 sc->sc_st = memt;
     184           0 :                 sc->sc_sh = memh;
     185           0 :         } else if (ioh_valid) {
     186           0 :                 sc->sc_st = iot;
     187           0 :                 sc->sc_sh = ioh;
     188             :         } else {
     189           0 :                 printf(": unable to map device registers\n");
     190           0 :                 return;
     191             :         }
     192             : 
     193           0 :         sc->sc_dmat = pa->pa_dmat;
     194             : 
     195             :         /* Get it out of power save mode if needed. */
     196           0 :         pci_set_powerstate(pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
     197             : 
     198             :         /*
     199             :          * Map and establish our interrupt.
     200             :          */
     201           0 :         if (pci_intr_map(pa, &ih)) {
     202           0 :                 printf(": unable to map interrupt\n");
     203           0 :                 goto fail_0;
     204             :         }
     205           0 :         intrstr = pci_intr_string(pc, ih);
     206           0 :         sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, stge_intr, sc,
     207           0 :                                        sc->sc_dev.dv_xname);
     208           0 :         if (sc->sc_ih == NULL) {
     209           0 :                 printf(": unable to establish interrupt");
     210           0 :                 if (intrstr != NULL)
     211           0 :                         printf(" at %s", intrstr);
     212           0 :                 printf("\n");
     213           0 :                 goto fail_0;
     214             :         }
     215           0 :         printf(": %s", intrstr);
     216             : 
     217             :         /*
     218             :          * Allocate the control data structures, and create and load the
     219             :          * DMA map for it.
     220             :          */
     221           0 :         if ((error = bus_dmamem_alloc(sc->sc_dmat,
     222             :             sizeof(struct stge_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
     223           0 :             0)) != 0) {
     224           0 :                 printf("%s: unable to allocate control data, error = %d\n",
     225             :                     sc->sc_dev.dv_xname, error);
     226           0 :                 goto fail_0;
     227             :         }
     228             : 
     229           0 :         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
     230             :             sizeof(struct stge_control_data), (caddr_t *)&sc->sc_control_data,
     231           0 :             BUS_DMA_COHERENT)) != 0) {
     232           0 :                 printf("%s: unable to map control data, error = %d\n",
     233             :                     sc->sc_dev.dv_xname, error);
     234           0 :                 goto fail_1;
     235             :         }
     236             : 
     237           0 :         if ((error = bus_dmamap_create(sc->sc_dmat,
     238             :             sizeof(struct stge_control_data), 1,
     239           0 :             sizeof(struct stge_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
     240           0 :                 printf("%s: unable to create control data DMA map, "
     241             :                     "error = %d\n", sc->sc_dev.dv_xname, error);
     242           0 :                 goto fail_2;
     243             :         }
     244             : 
     245           0 :         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
     246             :             sc->sc_control_data, sizeof(struct stge_control_data), NULL,
     247           0 :             0)) != 0) {
     248           0 :                 printf("%s: unable to load control data DMA map, error = %d\n",
     249             :                     sc->sc_dev.dv_xname, error);
     250           0 :                 goto fail_3;
     251             :         }
     252             : 
     253             :         /*
     254             :          * Create the transmit buffer DMA maps.  Note that rev B.3
     255             :          * and earlier seem to have a bug regarding multi-fragment
     256             :          * packets.  We need to limit the number of Tx segments on
     257             :          * such chips to 1.
     258             :          */
     259           0 :         for (i = 0; i < STGE_NTXDESC; i++) {
     260           0 :                 if ((error = bus_dmamap_create(sc->sc_dmat,
     261             :                     STGE_JUMBO_FRAMELEN, STGE_NTXFRAGS, MCLBYTES, 0, 0,
     262           0 :                     &sc->sc_txsoft[i].ds_dmamap)) != 0) {
     263           0 :                         printf("%s: unable to create tx DMA map %d, "
     264             :                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
     265           0 :                         goto fail_4;
     266             :                 }
     267             :         }
     268             : 
     269             :         /*
     270             :          * Create the receive buffer DMA maps.
     271             :          */
     272           0 :         for (i = 0; i < STGE_NRXDESC; i++) {
     273           0 :                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
     274           0 :                     MCLBYTES, 0, 0, &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
     275           0 :                         printf("%s: unable to create rx DMA map %d, "
     276             :                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
     277             :                         goto fail_5;
     278             :                 }
     279           0 :                 sc->sc_rxsoft[i].ds_mbuf = NULL;
     280             :         }
     281             : 
     282             :         /*
     283             :          * Determine if we're copper or fiber.  It affects how we
     284             :          * reset the card.
     285             :          */
     286           0 :         if (CSR_READ_4(sc, STGE_AsicCtrl) & AC_PhyMedia)
     287           0 :                 sc->sc_usefiber = 1;
     288             :         else
     289           0 :                 sc->sc_usefiber = 0;
     290             : 
     291             :         /*
     292             :          * Reset the chip to a known state.
     293             :          */
     294           0 :         stge_reset(sc);
     295             : 
     296             :         /*
     297             :          * Reading the station address from the EEPROM doesn't seem
     298             :          * to work, at least on my sample boards.  Instead, since
     299             :          * the reset sequence does AutoInit, read it from the station
     300             :          * address registers. For Sundance 1023 you can only read it
     301             :          * from EEPROM.
     302             :          */
     303           0 :         if (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_SUNDANCE_ST1023) {
     304           0 :                 sc->sc_arpcom.ac_enaddr[0] = CSR_READ_2(sc,
     305           0 :                     STGE_StationAddress0) & 0xff;
     306           0 :                 sc->sc_arpcom.ac_enaddr[1] = CSR_READ_2(sc,
     307           0 :                     STGE_StationAddress0) >> 8;
     308           0 :                 sc->sc_arpcom.ac_enaddr[2] = CSR_READ_2(sc,
     309           0 :                     STGE_StationAddress1) & 0xff;
     310           0 :                 sc->sc_arpcom.ac_enaddr[3] = CSR_READ_2(sc,
     311           0 :                     STGE_StationAddress1) >> 8;
     312           0 :                 sc->sc_arpcom.ac_enaddr[4] = CSR_READ_2(sc,
     313           0 :                     STGE_StationAddress2) & 0xff;
     314           0 :                 sc->sc_arpcom.ac_enaddr[5] = CSR_READ_2(sc,
     315           0 :                     STGE_StationAddress2) >> 8;
     316           0 :                 sc->sc_stge1023 = 0;
     317           0 :         } else {
     318           0 :                 uint16_t myaddr[ETHER_ADDR_LEN / 2];
     319           0 :                 for (i = 0; i < ETHER_ADDR_LEN / 2; i++) {
     320           0 :                         stge_read_eeprom(sc, STGE_EEPROM_StationAddress0 + i, 
     321           0 :                             &myaddr[i]);
     322           0 :                         myaddr[i] = letoh16(myaddr[i]);
     323             :                 }
     324           0 :                 (void)memcpy(sc->sc_arpcom.ac_enaddr, myaddr,
     325             :                     sizeof(sc->sc_arpcom.ac_enaddr));
     326           0 :                 sc->sc_stge1023 = 1;
     327           0 :         }
     328             : 
     329           0 :         printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
     330             : 
     331             :         /*
     332             :          * Read some important bits from the PhyCtrl register.
     333             :          */
     334           0 :         sc->sc_PhyCtrl = CSR_READ_1(sc, STGE_PhyCtrl) &
     335             :             (PC_PhyDuplexPolarity | PC_PhyLnkPolarity);
     336             : 
     337             :         /*
     338             :          * Initialize our media structures and probe the MII.
     339             :          */
     340           0 :         sc->sc_mii.mii_ifp = ifp;
     341           0 :         sc->sc_mii.mii_readreg = stge_mii_readreg;
     342           0 :         sc->sc_mii.mii_writereg = stge_mii_writereg;
     343           0 :         sc->sc_mii.mii_statchg = stge_mii_statchg;
     344           0 :         ifmedia_init(&sc->sc_mii.mii_media, 0, stge_mediachange,
     345             :             stge_mediastatus);
     346           0 :         mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
     347             :             MII_OFFSET_ANY, MIIF_DOPAUSE);
     348           0 :         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
     349           0 :                 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
     350           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
     351           0 :         } else
     352           0 :                 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
     353             : 
     354             :         ifp = &sc->sc_arpcom.ac_if;
     355           0 :         strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
     356           0 :         ifp->if_softc = sc;
     357           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     358           0 :         ifp->if_ioctl = stge_ioctl;
     359           0 :         ifp->if_start = stge_start;
     360           0 :         ifp->if_watchdog = stge_watchdog;
     361             : #ifdef STGE_JUMBO
     362             :         ifp->if_hardmtu = STGE_JUMBO_MTU;
     363             : #endif
     364           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, STGE_NTXDESC - 1);
     365             : 
     366           0 :         ifp->if_capabilities = IFCAP_VLAN_MTU;
     367             : 
     368             : #if NVLAN > 0
     369           0 :         ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
     370             : #endif
     371             : 
     372             :         /*
     373             :          * The manual recommends disabling early transmit, so we
     374             :          * do.  It's disabled anyway, if using IP checksumming,
     375             :          * since the entire packet must be in the FIFO in order
     376             :          * for the chip to perform the checksum.
     377             :          */
     378           0 :         sc->sc_txthresh = 0x0fff;
     379             : 
     380             :         /*
     381             :          * Disable MWI if the PCI layer tells us to.
     382             :          */
     383           0 :         sc->sc_DMACtrl = 0;
     384             : #ifdef fake
     385             :         if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0)
     386             :                 sc->sc_DMACtrl |= DMAC_MWIDisable;
     387             : #endif
     388             : 
     389             : #ifdef STGE_CHECKSUM
     390             :         /*
     391             :          * We can do IPv4/TCPv4/UDPv4 checksums in hardware.
     392             :          */
     393             :         sc->sc_arpcom.ac_if.if_capabilities |= IFCAP_CSUM_IPv4 |
     394             :             IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
     395             : #endif
     396             : 
     397             :         /*
     398             :          * Attach the interface.
     399             :          */
     400           0 :         if_attach(ifp);
     401           0 :         ether_ifattach(ifp);
     402           0 :         return;
     403             : 
     404             :         /*
     405             :          * Free any resources we've allocated during the failed attach
     406             :          * attempt.  Do this in reverse order and fall through.
     407             :          */
     408             :  fail_5:
     409           0 :         for (i = 0; i < STGE_NRXDESC; i++) {
     410           0 :                 if (sc->sc_rxsoft[i].ds_dmamap != NULL)
     411           0 :                         bus_dmamap_destroy(sc->sc_dmat,
     412             :                             sc->sc_rxsoft[i].ds_dmamap);
     413             :         }
     414             :  fail_4:
     415           0 :         for (i = 0; i < STGE_NTXDESC; i++) {
     416           0 :                 if (sc->sc_txsoft[i].ds_dmamap != NULL)
     417           0 :                         bus_dmamap_destroy(sc->sc_dmat,
     418             :                             sc->sc_txsoft[i].ds_dmamap);
     419             :         }
     420           0 :         bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
     421             :  fail_3:
     422           0 :         bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
     423             :  fail_2:
     424           0 :         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
     425             :             sizeof(struct stge_control_data));
     426             :  fail_1:
     427           0 :         bus_dmamem_free(sc->sc_dmat, &seg, rseg);
     428             :  fail_0:
     429           0 :         bus_space_unmap(sc->sc_st, sc->sc_sh, iosize);
     430           0 :         return;
     431           0 : }
     432             : 
     433             : static void
     434           0 : stge_dma_wait(struct stge_softc *sc)
     435             : {
     436             :         int i;
     437             : 
     438           0 :         for (i = 0; i < STGE_TIMEOUT; i++) {
     439           0 :                 delay(2);
     440           0 :                 if ((CSR_READ_4(sc, STGE_DMACtrl) & DMAC_TxDMAInProg) == 0)
     441             :                         break;
     442             :         }
     443             : 
     444           0 :         if (i == STGE_TIMEOUT)
     445           0 :                 printf("%s: DMA wait timed out\n", sc->sc_dev.dv_xname);
     446           0 : }
     447             : 
     448             : /*
     449             :  * stge_start:          [ifnet interface function]
     450             :  *
     451             :  *      Start packet transmission on the interface.
     452             :  */
     453             : void
     454           0 : stge_start(struct ifnet *ifp)
     455             : {
     456           0 :         struct stge_softc *sc = ifp->if_softc;
     457             :         struct mbuf *m0;
     458             :         struct stge_descsoft *ds;
     459             :         struct stge_tfd *tfd;
     460             :         bus_dmamap_t dmamap;
     461             :         int error, firsttx, nexttx, opending, seg, totlen;
     462             :         uint64_t csum_flags = 0, tfc;
     463             : 
     464           0 :         if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
     465           0 :                 return;
     466             : 
     467             :         /*
     468             :          * Remember the previous number of pending transmissions
     469             :          * and the first descriptor we will use.
     470             :          */
     471           0 :         opending = sc->sc_txpending;
     472           0 :         firsttx = STGE_NEXTTX(sc->sc_txlast);
     473             : 
     474             :         /*
     475             :          * Loop through the send queue, setting up transmit descriptors
     476             :          * until we drain the queue, or use up all available transmit
     477             :          * descriptors.
     478             :          */
     479           0 :         for (;;) {
     480             :                 /*
     481             :                  * Grab a packet off the queue.
     482             :                  */
     483           0 :                 m0 = ifq_deq_begin(&ifp->if_snd);
     484           0 :                 if (m0 == NULL)
     485             :                         break;
     486             : 
     487             :                 /*
     488             :                  * Leave one unused descriptor at the end of the
     489             :                  * list to prevent wrapping completely around.
     490             :                  */
     491           0 :                 if (sc->sc_txpending == (STGE_NTXDESC - 1)) {
     492           0 :                         ifq_deq_rollback(&ifp->if_snd, m0);
     493           0 :                         break;
     494             :                 }
     495             : 
     496             :                 /*
     497             :                  * Get the last and next available transmit descriptor.
     498             :                  */
     499           0 :                 nexttx = STGE_NEXTTX(sc->sc_txlast);
     500           0 :                 tfd = &sc->sc_txdescs[nexttx];
     501           0 :                 ds = &sc->sc_txsoft[nexttx];
     502             : 
     503           0 :                 dmamap = ds->ds_dmamap;
     504             : 
     505             :                 /*
     506             :                  * Load the DMA map.  If this fails, the packet either
     507             :                  * didn't fit in the alloted number of segments, or we
     508             :                  * were short on resources.  For the too-many-segments
     509             :                  * case, we simply report an error and drop the packet,
     510             :                  * since we can't sanely copy a jumbo packet to a single
     511             :                  * buffer.
     512             :                  */
     513           0 :                 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
     514             :                     BUS_DMA_NOWAIT);
     515           0 :                 if (error) {
     516           0 :                         if (error == EFBIG) {
     517           0 :                                 printf("%s: Tx packet consumes too many "
     518             :                                     "DMA segments (%u), dropping...\n",
     519           0 :                                     sc->sc_dev.dv_xname, dmamap->dm_nsegs);
     520           0 :                                 ifq_deq_commit(&ifp->if_snd, m0);
     521           0 :                                 m_freem(m0);
     522           0 :                                 continue;
     523             :                         }
     524             :                         /*
     525             :                          * Short on resources, just stop for now.
     526             :                          */
     527           0 :                         ifq_deq_rollback(&ifp->if_snd, m0);
     528           0 :                         break;
     529             :                 }
     530             : 
     531           0 :                 ifq_deq_commit(&ifp->if_snd, m0);
     532             : 
     533             :                 /*
     534             :                  * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
     535             :                  */
     536             : 
     537             :                 /* Sync the DMA map. */
     538           0 :                 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
     539             :                     BUS_DMASYNC_PREWRITE);
     540             : 
     541             :                 /* Initialize the fragment list. */
     542           0 :                 for (totlen = 0, seg = 0; seg < dmamap->dm_nsegs; seg++) {
     543           0 :                         tfd->tfd_frags[seg].frag_word0 =
     544           0 :                             htole64(FRAG_ADDR(dmamap->dm_segs[seg].ds_addr) |
     545             :                             FRAG_LEN(dmamap->dm_segs[seg].ds_len));
     546           0 :                         totlen += dmamap->dm_segs[seg].ds_len;
     547             :                 }
     548             : 
     549             : #ifdef STGE_CHECKSUM
     550             :                 /*
     551             :                  * Initialize checksumming flags in the descriptor.
     552             :                  * Byte-swap constants so the compiler can optimize.
     553             :                  */
     554             :                 if (m0->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
     555             :                         csum_flags |= TFD_IPChecksumEnable;
     556             : 
     557             :                 if (m0->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
     558             :                         csum_flags |= TFD_TCPChecksumEnable;
     559             :                 else if (m0->m_pkthdr.csum_flags & M_UDP_CSUM_OUT)
     560             :                         csum_flags |= TFD_UDPChecksumEnable;
     561             : #endif
     562             : 
     563             :                 /*
     564             :                  * Initialize the descriptor and give it to the chip.
     565             :                  */
     566           0 :                 tfc = TFD_FrameId(nexttx) | TFD_WordAlign(/*totlen & */3) |
     567           0 :                     TFD_FragCount(seg) | csum_flags;
     568           0 :                 if ((nexttx & STGE_TXINTR_SPACING_MASK) == 0)
     569           0 :                         tfc |= TFD_TxDMAIndicate;
     570             : 
     571             : #if NVLAN > 0
     572             :                 /* Check if we have a VLAN tag to insert. */
     573           0 :                 if (m0->m_flags & M_VLANTAG)
     574           0 :                         tfc |= (TFD_VLANTagInsert |
     575           0 :                             TFD_VID(m0->m_pkthdr.ether_vtag));
     576             : #endif
     577             : 
     578           0 :                 tfd->tfd_control = htole64(tfc);
     579             : 
     580             :                 /* Sync the descriptor. */
     581           0 :                 STGE_CDTXSYNC(sc, nexttx,
     582             :                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
     583             : 
     584             :                 /*
     585             :                  * Kick the transmit DMA logic.
     586             :                  */
     587           0 :                 CSR_WRITE_4(sc, STGE_DMACtrl,
     588             :                     sc->sc_DMACtrl | DMAC_TxDMAPollNow);
     589             : 
     590             :                 /*
     591             :                  * Store a pointer to the packet so we can free it later.
     592             :                  */
     593           0 :                 ds->ds_mbuf = m0;
     594             : 
     595             :                 /* Advance the tx pointer. */
     596           0 :                 sc->sc_txpending++;
     597           0 :                 sc->sc_txlast = nexttx;
     598             : 
     599             : #if NBPFILTER > 0
     600             :                 /*
     601             :                  * Pass the packet to any BPF listeners.
     602             :                  */
     603           0 :                 if (ifp->if_bpf)
     604           0 :                         bpf_mtap_ether(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
     605             : #endif /* NBPFILTER > 0 */
     606             :         }
     607             : 
     608           0 :         if (sc->sc_txpending == (STGE_NTXDESC - 1)) {
     609             :                 /* No more slots left; notify upper layer. */
     610           0 :                 ifq_set_oactive(&ifp->if_snd);
     611           0 :         }
     612             : 
     613           0 :         if (sc->sc_txpending != opending) {
     614             :                 /*
     615             :                  * We enqueued packets.  If the transmitter was idle,
     616             :                  * reset the txdirty pointer.
     617             :                  */
     618           0 :                 if (opending == 0)
     619           0 :                         sc->sc_txdirty = firsttx;
     620             : 
     621             :                 /* Set a watchdog timer in case the chip flakes out. */
     622           0 :                 ifp->if_timer = 5;
     623           0 :         }
     624           0 : }
     625             : 
     626             : /*
     627             :  * stge_watchdog:       [ifnet interface function]
     628             :  *
     629             :  *      Watchdog timer handler.
     630             :  */
     631             : void
     632           0 : stge_watchdog(struct ifnet *ifp)
     633             : {
     634           0 :         struct stge_softc *sc = ifp->if_softc;
     635             : 
     636             :         /*
     637             :          * Sweep up first, since we don't interrupt every frame.
     638             :          */
     639           0 :         stge_txintr(sc);
     640           0 :         if (sc->sc_txpending != 0) {
     641           0 :                 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
     642           0 :                 ifp->if_oerrors++;
     643             : 
     644           0 :                 (void) stge_init(ifp);
     645             : 
     646             :                 /* Try to get more packets going. */
     647           0 :                 stge_start(ifp);
     648           0 :         }
     649           0 : }
     650             : 
     651             : /*
     652             :  * stge_ioctl:          [ifnet interface function]
     653             :  *
     654             :  *      Handle control requests from the operator.
     655             :  */
     656             : int
     657           0 : stge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     658             : {
     659           0 :         struct stge_softc *sc = ifp->if_softc;
     660           0 :         struct ifreq *ifr = (struct ifreq *)data;
     661             :         int s, error = 0;
     662             : 
     663           0 :         s = splnet();
     664             : 
     665           0 :         switch (cmd) {
     666             :         case SIOCSIFADDR:
     667           0 :                 ifp->if_flags |= IFF_UP;
     668           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
     669           0 :                         stge_init(ifp);
     670             :                 break;
     671             : 
     672             :         case SIOCSIFFLAGS:
     673           0 :                 if (ifp->if_flags & IFF_UP) {
     674           0 :                         if (ifp->if_flags & IFF_RUNNING)
     675           0 :                                 error = ENETRESET;
     676             :                         else
     677           0 :                                 stge_init(ifp);
     678             :                 } else {
     679           0 :                         if (ifp->if_flags & IFF_RUNNING)
     680           0 :                                 stge_stop(ifp, 1);
     681             :                 }
     682             :                 break;
     683             : 
     684             :         case SIOCSIFMEDIA:
     685             :         case SIOCGIFMEDIA:
     686           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
     687           0 :                 break;
     688             : 
     689             :         default:
     690           0 :                 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
     691           0 :         }
     692             : 
     693           0 :         if (error == ENETRESET) {
     694           0 :                 if (ifp->if_flags & IFF_RUNNING)
     695           0 :                         stge_iff(sc);
     696             :                 error = 0;
     697           0 :         }
     698             : 
     699           0 :         splx(s);
     700           0 :         return (error);
     701             : }
     702             : 
     703             : /*
     704             :  * stge_intr:
     705             :  *
     706             :  *      Interrupt service routine.
     707             :  */
     708             : int
     709           0 : stge_intr(void *arg)
     710             : {
     711           0 :         struct stge_softc *sc = arg;
     712           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     713             :         uint32_t txstat;
     714             :         int wantinit;
     715             :         uint16_t isr;
     716             : 
     717           0 :         if ((CSR_READ_2(sc, STGE_IntStatus) & IS_InterruptStatus) == 0)
     718           0 :                 return (0);
     719             : 
     720           0 :         for (wantinit = 0; wantinit == 0;) {
     721           0 :                 isr = CSR_READ_2(sc, STGE_IntStatusAck);
     722           0 :                 if ((isr & sc->sc_IntEnable) == 0)
     723             :                         break;
     724             : 
     725             :                 /* Host interface errors. */
     726           0 :                 if (isr & IS_HostError) {
     727           0 :                         printf("%s: Host interface error\n",
     728           0 :                             sc->sc_dev.dv_xname);
     729             :                         wantinit = 1;
     730           0 :                         continue;
     731             :                 }
     732             : 
     733             :                 /* Receive interrupts. */
     734           0 :                 if (isr & (IS_RxDMAComplete|IS_RFDListEnd)) {
     735           0 :                         stge_rxintr(sc);
     736           0 :                         if (isr & IS_RFDListEnd) {
     737           0 :                                 printf("%s: receive ring overflow\n",
     738           0 :                                     sc->sc_dev.dv_xname);
     739             :                                 /*
     740             :                                  * XXX Should try to recover from this
     741             :                                  * XXX more gracefully.
     742             :                                  */
     743             :                                 wantinit = 1;
     744           0 :                         }
     745             :                 }
     746             : 
     747             :                 /* Transmit interrupts. */
     748           0 :                 if (isr & (IS_TxDMAComplete|IS_TxComplete))
     749           0 :                         stge_txintr(sc);
     750             : 
     751             :                 /* Statistics overflow. */
     752           0 :                 if (isr & IS_UpdateStats)
     753           0 :                         stge_stats_update(sc);
     754             : 
     755             :                 /* Transmission errors. */
     756           0 :                 if (isr & IS_TxComplete) {
     757           0 :                         for (;;) {
     758           0 :                                 txstat = CSR_READ_4(sc, STGE_TxStatus);
     759           0 :                                 if ((txstat & TS_TxComplete) == 0)
     760             :                                         break;
     761           0 :                                 if (txstat & TS_TxUnderrun) {
     762           0 :                                         sc->sc_txthresh++;
     763           0 :                                         if (sc->sc_txthresh > 0x0fff)
     764           0 :                                                 sc->sc_txthresh = 0x0fff;
     765           0 :                                         printf("%s: transmit underrun, new "
     766             :                                             "threshold: %d bytes\n",
     767           0 :                                             sc->sc_dev.dv_xname,
     768           0 :                                             sc->sc_txthresh << 5);
     769           0 :                                 }
     770           0 :                                 if (txstat & TS_MaxCollisions)
     771           0 :                                         printf("%s: excessive collisions\n",
     772           0 :                                             sc->sc_dev.dv_xname);
     773             :                         }
     774             :                         wantinit = 1;
     775           0 :                 }
     776             : 
     777             :         }
     778             : 
     779           0 :         if (wantinit)
     780           0 :                 stge_init(ifp);
     781             : 
     782           0 :         CSR_WRITE_2(sc, STGE_IntEnable, sc->sc_IntEnable);
     783             : 
     784             :         /* Try to get more packets going. */
     785           0 :         stge_start(ifp);
     786             : 
     787           0 :         return (1);
     788           0 : }
     789             : 
     790             : /*
     791             :  * stge_txintr:
     792             :  *
     793             :  *      Helper; handle transmit interrupts.
     794             :  */
     795             : void
     796           0 : stge_txintr(struct stge_softc *sc)
     797             : {
     798           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     799             :         struct stge_descsoft *ds;
     800             :         uint64_t control;
     801             :         int i;
     802             : 
     803           0 :         ifq_clr_oactive(&ifp->if_snd);
     804             : 
     805             :         /*
     806             :          * Go through our Tx list and free mbufs for those
     807             :          * frames which have been transmitted.
     808             :          */
     809           0 :         for (i = sc->sc_txdirty; sc->sc_txpending != 0;
     810           0 :              i = STGE_NEXTTX(i), sc->sc_txpending--) {
     811           0 :                 ds = &sc->sc_txsoft[i];
     812             : 
     813           0 :                 STGE_CDTXSYNC(sc, i,
     814             :                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
     815             : 
     816           0 :                 control = letoh64(sc->sc_txdescs[i].tfd_control);
     817           0 :                 if ((control & TFD_TFDDone) == 0)
     818             :                         break;
     819             : 
     820           0 :                 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap,
     821             :                     0, ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     822           0 :                 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
     823           0 :                 m_freem(ds->ds_mbuf);
     824           0 :                 ds->ds_mbuf = NULL;
     825             :         }
     826             : 
     827             :         /* Update the dirty transmit buffer pointer. */
     828           0 :         sc->sc_txdirty = i;
     829             : 
     830             :         /*
     831             :          * If there are no more pending transmissions, cancel the watchdog
     832             :          * timer.
     833             :          */
     834           0 :         if (sc->sc_txpending == 0)
     835           0 :                 ifp->if_timer = 0;
     836           0 : }
     837             : 
     838             : /*
     839             :  * stge_rxintr:
     840             :  *
     841             :  *      Helper; handle receive interrupts.
     842             :  */
     843             : void
     844           0 : stge_rxintr(struct stge_softc *sc)
     845             : {
     846           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     847             :         struct stge_descsoft *ds;
     848             :         struct mbuf *m, *tailm;
     849           0 :         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
     850             :         uint64_t status;
     851             :         int i, len;
     852             : 
     853           0 :         for (i = sc->sc_rxptr;; i = STGE_NEXTRX(i)) {
     854           0 :                 ds = &sc->sc_rxsoft[i];
     855             : 
     856           0 :                 STGE_CDRXSYNC(sc, i,
     857             :                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
     858             : 
     859           0 :                 status = letoh64(sc->sc_rxdescs[i].rfd_status);
     860             : 
     861           0 :                 if ((status & RFD_RFDDone) == 0)
     862             :                         break;
     863             : 
     864           0 :                 if (__predict_false(sc->sc_rxdiscard)) {
     865           0 :                         STGE_INIT_RXDESC(sc, i);
     866           0 :                         if (status & RFD_FrameEnd) {
     867             :                                 /* Reset our state. */
     868           0 :                                 sc->sc_rxdiscard = 0;
     869           0 :                         }
     870             :                         continue;
     871             :                 }
     872             : 
     873           0 :                 bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
     874             :                     ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
     875             : 
     876           0 :                 m = ds->ds_mbuf;
     877             : 
     878             :                 /*
     879             :                  * Add a new receive buffer to the ring.
     880             :                  */
     881           0 :                 if (stge_add_rxbuf(sc, i) != 0) {
     882             :                         /*
     883             :                          * Failed, throw away what we've done so
     884             :                          * far, and discard the rest of the packet.
     885             :                          */
     886           0 :                         ifp->if_ierrors++;
     887           0 :                         bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
     888             :                             ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
     889           0 :                         STGE_INIT_RXDESC(sc, i);
     890           0 :                         if ((status & RFD_FrameEnd) == 0)
     891           0 :                                 sc->sc_rxdiscard = 1;
     892           0 :                         m_freem(sc->sc_rxhead);
     893           0 :                         STGE_RXCHAIN_RESET(sc);
     894           0 :                         continue;
     895             :                 }
     896             : 
     897             : #ifdef DIAGNOSTIC
     898           0 :                 if (status & RFD_FrameStart) {
     899           0 :                         KASSERT(sc->sc_rxhead == NULL);
     900           0 :                         KASSERT(sc->sc_rxtailp == &sc->sc_rxhead);
     901             :                 }
     902             : #endif
     903             : 
     904           0 :                 STGE_RXCHAIN_LINK(sc, m);
     905             : 
     906             :                 /*
     907             :                  * If this is not the end of the packet, keep
     908             :                  * looking.
     909             :                  */
     910           0 :                 if ((status & RFD_FrameEnd) == 0) {
     911           0 :                         sc->sc_rxlen += m->m_len;
     912           0 :                         continue;
     913             :                 }
     914             : 
     915             :                 /*
     916             :                  * Okay, we have the entire packet now...
     917             :                  */
     918           0 :                 *sc->sc_rxtailp = NULL;
     919           0 :                 m = sc->sc_rxhead;
     920           0 :                 tailm = sc->sc_rxtail;
     921             : 
     922           0 :                 STGE_RXCHAIN_RESET(sc);
     923             : 
     924             :                 /*
     925             :                  * If the packet had an error, drop it.  Note we
     926             :                  * count the error later in the periodic stats update.
     927             :                  */
     928           0 :                 if (status & (RFD_RxFIFOOverrun | RFD_RxRuntFrame |
     929             :                               RFD_RxAlignmentError | RFD_RxFCSError |
     930             :                               RFD_RxLengthError)) {
     931           0 :                         m_freem(m);
     932           0 :                         continue;
     933             :                 }
     934             : 
     935             :                 /*
     936             :                  * No errors.
     937             :                  *
     938             :                  * Note we have configured the chip to not include
     939             :                  * the CRC at the end of the packet.
     940             :                  */
     941           0 :                 len = RFD_RxDMAFrameLen(status);
     942           0 :                 tailm->m_len = len - sc->sc_rxlen;
     943             : 
     944             :                 /*
     945             :                  * If the packet is small enough to fit in a
     946             :                  * single header mbuf, allocate one and copy
     947             :                  * the data into it.  This greatly reduces
     948             :                  * memory consumption when we receive lots
     949             :                  * of small packets.
     950             :                  */
     951           0 :                 if (stge_copy_small != 0 && len <= (MHLEN - 2)) {
     952             :                         struct mbuf *nm;
     953           0 :                         MGETHDR(nm, M_DONTWAIT, MT_DATA);
     954           0 :                         if (nm == NULL) {
     955           0 :                                 ifp->if_ierrors++;
     956           0 :                                 m_freem(m);
     957           0 :                                 continue;
     958             :                         }
     959           0 :                         nm->m_data += 2;
     960           0 :                         nm->m_pkthdr.len = nm->m_len = len;
     961           0 :                         m_copydata(m, 0, len, mtod(nm, caddr_t));
     962           0 :                         m_freem(m);
     963             :                         m = nm;
     964           0 :                 }
     965             : 
     966             :                 /*
     967             :                  * Set the incoming checksum information for the packet.
     968             :                  */
     969           0 :                 if ((status & RFD_IPDetected) &&
     970           0 :                     (!(status & RFD_IPError)))
     971           0 :                         m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
     972           0 :                 if ((status & RFD_TCPDetected) &&
     973           0 :                     (!(status & RFD_TCPError)))
     974           0 :                         m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
     975           0 :                 else if ((status & RFD_UDPDetected) &&
     976           0 :                     (!(status & RFD_UDPError)))
     977           0 :                         m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_OK;
     978             : 
     979             : #if NVLAN > 0
     980             :                 /* Check for VLAN tagged packets. */
     981           0 :                 if (status & RFD_VLANDetected) {
     982           0 :                         m->m_pkthdr.ether_vtag = RFD_TCI(status);
     983           0 :                         m->m_flags |= M_VLANTAG;
     984           0 :                 }
     985             : #endif
     986             : 
     987           0 :                 m->m_pkthdr.len = len;
     988             : 
     989           0 :                 ml_enqueue(&ml, m);
     990           0 :         }
     991             : 
     992             :         /* Update the receive pointer. */
     993           0 :         sc->sc_rxptr = i;
     994             : 
     995           0 :         if_input(ifp, &ml);
     996           0 : }
     997             : 
     998             : /*
     999             :  * stge_tick:
    1000             :  *
    1001             :  *      One second timer, used to tick the MII.
    1002             :  */
    1003             : void
    1004           0 : stge_tick(void *arg)
    1005             : {
    1006           0 :         struct stge_softc *sc = arg;
    1007             :         int s;
    1008             : 
    1009           0 :         s = splnet();
    1010           0 :         mii_tick(&sc->sc_mii);
    1011           0 :         stge_stats_update(sc);
    1012           0 :         splx(s);
    1013             : 
    1014           0 :         timeout_add_sec(&sc->sc_timeout, 1);
    1015           0 : }
    1016             : 
    1017             : /*
    1018             :  * stge_stats_update:
    1019             :  *
    1020             :  *      Read the TC9021 statistics counters.
    1021             :  */
    1022             : void
    1023           0 : stge_stats_update(struct stge_softc *sc)
    1024             : {
    1025           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1026             : 
    1027           0 :         (void) CSR_READ_4(sc, STGE_OctetRcvOk);
    1028             : 
    1029           0 :         ifp->if_ierrors +=
    1030           0 :             (u_int) CSR_READ_2(sc, STGE_FramesLostRxErrors);
    1031             : 
    1032           0 :         (void) CSR_READ_4(sc, STGE_OctetXmtdOk);
    1033             : 
    1034           0 :         ifp->if_collisions +=
    1035           0 :             CSR_READ_4(sc, STGE_LateCollisions) +
    1036           0 :             CSR_READ_4(sc, STGE_MultiColFrames) +
    1037           0 :             CSR_READ_4(sc, STGE_SingleColFrames);
    1038             : 
    1039           0 :         ifp->if_oerrors +=
    1040           0 :             (u_int) CSR_READ_2(sc, STGE_FramesAbortXSColls) +
    1041           0 :             (u_int) CSR_READ_2(sc, STGE_FramesWEXDeferal);
    1042           0 : }
    1043             : 
    1044             : /*
    1045             :  * stge_reset:
    1046             :  *
    1047             :  *      Perform a soft reset on the TC9021.
    1048             :  */
    1049             : void
    1050           0 : stge_reset(struct stge_softc *sc)
    1051             : {
    1052             :         uint32_t ac;
    1053             :         int i;
    1054             : 
    1055           0 :         ac = CSR_READ_4(sc, STGE_AsicCtrl);
    1056             : 
    1057             :         /*
    1058             :          * Only assert RstOut if we're fiber.  We need GMII clocks
    1059             :          * to be present in order for the reset to complete on fiber
    1060             :          * cards.
    1061             :          */
    1062           0 :         CSR_WRITE_4(sc, STGE_AsicCtrl,
    1063             :             ac | AC_GlobalReset | AC_RxReset | AC_TxReset |
    1064             :             AC_DMA | AC_FIFO | AC_Network | AC_Host | AC_AutoInit |
    1065             :             (sc->sc_usefiber ? AC_RstOut : 0));
    1066             : 
    1067           0 :         delay(50000);
    1068             : 
    1069           0 :         for (i = 0; i < STGE_TIMEOUT; i++) {
    1070           0 :                 delay(5000);
    1071           0 :                 if ((CSR_READ_4(sc, STGE_AsicCtrl) & AC_ResetBusy) == 0)
    1072             :                         break;
    1073             :         }
    1074             : 
    1075           0 :         if (i == STGE_TIMEOUT)
    1076           0 :                 printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
    1077             : 
    1078           0 :         delay(1000);
    1079           0 : }
    1080             : 
    1081             : /*
    1082             :  * stge_init:           [ ifnet interface function ]
    1083             :  *
    1084             :  *      Initialize the interface.  Must be called at splnet().
    1085             :  */
    1086             : int
    1087           0 : stge_init(struct ifnet *ifp)
    1088             : {
    1089           0 :         struct stge_softc *sc = ifp->if_softc;
    1090             :         struct stge_descsoft *ds;
    1091             :         int i, error = 0;
    1092             : 
    1093             :         /*
    1094             :          * Cancel any pending I/O.
    1095             :          */
    1096           0 :         stge_stop(ifp, 0);
    1097             : 
    1098             :         /*
    1099             :          * Reset the chip to a known state.
    1100             :          */
    1101           0 :         stge_reset(sc);
    1102             : 
    1103             :         /*
    1104             :          * Initialize the transmit descriptor ring.
    1105             :          */
    1106           0 :         memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
    1107           0 :         for (i = 0; i < STGE_NTXDESC; i++) {
    1108           0 :                 sc->sc_txdescs[i].tfd_next = htole64(
    1109             :                     STGE_CDTXADDR(sc, STGE_NEXTTX(i)));
    1110           0 :                 sc->sc_txdescs[i].tfd_control = htole64(TFD_TFDDone);
    1111             :         }
    1112           0 :         sc->sc_txpending = 0;
    1113           0 :         sc->sc_txdirty = 0;
    1114           0 :         sc->sc_txlast = STGE_NTXDESC - 1;
    1115             : 
    1116             :         /*
    1117             :          * Initialize the receive descriptor and receive job
    1118             :          * descriptor rings.
    1119             :          */
    1120           0 :         for (i = 0; i < STGE_NRXDESC; i++) {
    1121           0 :                 ds = &sc->sc_rxsoft[i];
    1122           0 :                 if (ds->ds_mbuf == NULL) {
    1123           0 :                         if ((error = stge_add_rxbuf(sc, i)) != 0) {
    1124           0 :                                 printf("%s: unable to allocate or map rx "
    1125             :                                     "buffer %d, error = %d\n",
    1126           0 :                                     sc->sc_dev.dv_xname, i, error);
    1127             :                                 /*
    1128             :                                  * XXX Should attempt to run with fewer receive
    1129             :                                  * XXX buffers instead of just failing.
    1130             :                                  */
    1131           0 :                                 stge_rxdrain(sc);
    1132           0 :                                 goto out;
    1133             :                         }
    1134             :                 } else
    1135           0 :                         STGE_INIT_RXDESC(sc, i);
    1136             :         }
    1137           0 :         sc->sc_rxptr = 0;
    1138           0 :         sc->sc_rxdiscard = 0;
    1139           0 :         STGE_RXCHAIN_RESET(sc);
    1140             : 
    1141             :         /* Set the station address. */
    1142           0 :         if (sc->sc_stge1023) {
    1143           0 :                 CSR_WRITE_2(sc, STGE_StationAddress0,
    1144             :                     sc->sc_arpcom.ac_enaddr[0] | sc->sc_arpcom.ac_enaddr[1] << 8);
    1145           0 :                 CSR_WRITE_2(sc, STGE_StationAddress1,
    1146             :                     sc->sc_arpcom.ac_enaddr[2] | sc->sc_arpcom.ac_enaddr[3] << 8);
    1147           0 :                 CSR_WRITE_2(sc, STGE_StationAddress2,
    1148             :                     sc->sc_arpcom.ac_enaddr[4] | sc->sc_arpcom.ac_enaddr[5] << 8);
    1149           0 :         } else {
    1150           0 :                 for (i = 0; i < ETHER_ADDR_LEN; i++)
    1151           0 :                         CSR_WRITE_1(sc, STGE_StationAddress0 + i,
    1152             :                             sc->sc_arpcom.ac_enaddr[i]);
    1153             :         }
    1154             : 
    1155             :         /*
    1156             :          * Set the statistics masks.  Disable all the RMON stats,
    1157             :          * and disable selected stats in the non-RMON stats registers.
    1158             :          */
    1159           0 :         CSR_WRITE_4(sc, STGE_RMONStatisticsMask, 0xffffffff);
    1160           0 :         CSR_WRITE_4(sc, STGE_StatisticsMask,
    1161             :             (1U << 1) | (1U << 2) | (1U << 3) | (1U << 4) | (1U << 5) |
    1162             :             (1U << 6) | (1U << 7) | (1U << 8) | (1U << 9) | (1U << 10) |
    1163             :             (1U << 13) | (1U << 14) | (1U << 15) | (1U << 19) | (1U << 20) |
    1164             :             (1U << 21));
    1165             : 
    1166             :         /* Program promiscuous mode and multicast filters. */
    1167           0 :         stge_iff(sc);
    1168             : 
    1169             :         /*
    1170             :          * Give the transmit and receive ring to the chip.
    1171             :          */
    1172           0 :         CSR_WRITE_4(sc, STGE_TFDListPtrHi, 0); /* NOTE: 32-bit DMA */
    1173           0 :         CSR_WRITE_4(sc, STGE_TFDListPtrLo,
    1174             :             STGE_CDTXADDR(sc, sc->sc_txdirty));
    1175             : 
    1176           0 :         CSR_WRITE_4(sc, STGE_RFDListPtrHi, 0); /* NOTE: 32-bit DMA */
    1177           0 :         CSR_WRITE_4(sc, STGE_RFDListPtrLo,
    1178             :             STGE_CDRXADDR(sc, sc->sc_rxptr));
    1179             : 
    1180             :         /*
    1181             :          * Initialize the Tx auto-poll period.  It's OK to make this number
    1182             :          * large (255 is the max, but we use 127) -- we explicitly kick the
    1183             :          * transmit engine when there's actually a packet.
    1184             :          */
    1185           0 :         CSR_WRITE_1(sc, STGE_TxDMAPollPeriod, 127);
    1186             : 
    1187             :         /* ..and the Rx auto-poll period. */
    1188           0 :         CSR_WRITE_1(sc, STGE_RxDMAPollPeriod, 64);
    1189             : 
    1190             :         /* Initialize the Tx start threshold. */
    1191           0 :         CSR_WRITE_2(sc, STGE_TxStartThresh, sc->sc_txthresh);
    1192             : 
    1193             :         /* RX DMA thresholds, from linux */
    1194           0 :         CSR_WRITE_1(sc, STGE_RxDMABurstThresh, 0x30);
    1195           0 :         CSR_WRITE_1(sc, STGE_RxDMAUrgentThresh, 0x30);
    1196             : 
    1197             :         /* Rx early threhold, from Linux */
    1198           0 :         CSR_WRITE_2(sc, STGE_RxEarlyThresh, 0x7ff);
    1199             : 
    1200             :         /* Tx DMA thresholds, from Linux */
    1201           0 :         CSR_WRITE_1(sc, STGE_TxDMABurstThresh, 0x30);
    1202           0 :         CSR_WRITE_1(sc, STGE_TxDMAUrgentThresh, 0x04);
    1203             : 
    1204             :         /*
    1205             :          * Initialize the Rx DMA interrupt control register.  We
    1206             :          * request an interrupt after every incoming packet, but
    1207             :          * defer it for 32us (64 * 512 ns).  When the number of
    1208             :          * interrupts pending reaches 8, we stop deferring the
    1209             :          * interrupt, and signal it immediately.
    1210             :          */
    1211           0 :         CSR_WRITE_4(sc, STGE_RxDMAIntCtrl,
    1212             :             RDIC_RxFrameCount(8) | RDIC_RxDMAWaitTime(512));
    1213             : 
    1214             :         /*
    1215             :          * Initialize the interrupt mask.
    1216             :          */
    1217           0 :         sc->sc_IntEnable = IS_HostError | IS_TxComplete | IS_UpdateStats |
    1218             :             IS_TxDMAComplete | IS_RxDMAComplete | IS_RFDListEnd;
    1219           0 :         CSR_WRITE_2(sc, STGE_IntStatus, 0xffff);
    1220           0 :         CSR_WRITE_2(sc, STGE_IntEnable, sc->sc_IntEnable);
    1221             : 
    1222             :         /*
    1223             :          * Configure the DMA engine.
    1224             :          * XXX Should auto-tune TxBurstLimit.
    1225             :          */
    1226           0 :         CSR_WRITE_4(sc, STGE_DMACtrl, sc->sc_DMACtrl |
    1227             :             DMAC_TxBurstLimit(3));
    1228             : 
    1229             :         /*
    1230             :          * Send a PAUSE frame when we reach 29,696 bytes in the Rx
    1231             :          * FIFO, and send an un-PAUSE frame when we reach 3056 bytes
    1232             :          * in the Rx FIFO.
    1233             :          */
    1234           0 :         CSR_WRITE_2(sc, STGE_FlowOnTresh, 29696 / 16);
    1235           0 :         CSR_WRITE_2(sc, STGE_FlowOffThresh, 3056 / 16);
    1236             : 
    1237             :         /*
    1238             :          * Set the maximum frame size.
    1239             :          */
    1240             : #ifdef STGE_JUMBO
    1241             :         CSR_WRITE_2(sc, STGE_MaxFrameSize, STGE_JUMBO_FRAMELEN);
    1242             : #else
    1243           0 :         CSR_WRITE_2(sc, STGE_MaxFrameSize, ETHER_MAX_LEN);
    1244             : #endif
    1245             : 
    1246             :         /*
    1247             :          * Initialize MacCtrl -- do it before setting the media,
    1248             :          * as setting the media will actually program the register.
    1249             :          *
    1250             :          * Note: We have to poke the IFS value before poking
    1251             :          * anything else.
    1252             :          */
    1253           0 :         sc->sc_MACCtrl = MC_IFSSelect(0);
    1254           0 :         CSR_WRITE_4(sc, STGE_MACCtrl, sc->sc_MACCtrl);
    1255             : 
    1256           0 :         if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
    1257           0 :                 sc->sc_MACCtrl |= MC_AutoVLANuntagging;
    1258             : 
    1259           0 :         sc->sc_MACCtrl |= MC_StatisticsEnable | MC_TxEnable | MC_RxEnable;
    1260             : 
    1261           0 :         if (sc->sc_rev >= 6) {            /* >= B.2 */
    1262             :                 /* Multi-frag frame bug work-around. */
    1263           0 :                 CSR_WRITE_2(sc, STGE_DebugCtrl,
    1264             :                     CSR_READ_2(sc, STGE_DebugCtrl) | 0x0200);
    1265             : 
    1266             :                 /* Tx Poll Now bug work-around. */
    1267           0 :                 CSR_WRITE_2(sc, STGE_DebugCtrl,
    1268             :                     CSR_READ_2(sc, STGE_DebugCtrl) | 0x0010);
    1269             : 
    1270             :                 /* Rx Poll Now bug work-around. */
    1271           0 :                 CSR_WRITE_2(sc, STGE_DebugCtrl,
    1272             :                     CSR_READ_2(sc, STGE_DebugCtrl) | 0x0020);
    1273           0 :         }
    1274             : 
    1275             :         /*
    1276             :          * Set the current media.
    1277             :          */
    1278           0 :         mii_mediachg(&sc->sc_mii);
    1279             : 
    1280             :         /*
    1281             :          * Start the one second MII clock.
    1282             :          */
    1283           0 :         timeout_add_sec(&sc->sc_timeout, 1);
    1284             : 
    1285             :         /*
    1286             :          * ...all done!
    1287             :          */
    1288           0 :         ifp->if_flags |= IFF_RUNNING;
    1289           0 :         ifq_clr_oactive(&ifp->if_snd);
    1290             : 
    1291             :  out:
    1292           0 :         if (error)
    1293           0 :                 printf("%s: interface not running\n", sc->sc_dev.dv_xname);
    1294           0 :         return (error);
    1295             : }
    1296             : 
    1297             : /*
    1298             :  * stge_drain:
    1299             :  *
    1300             :  *      Drain the receive queue.
    1301             :  */
    1302             : void
    1303           0 : stge_rxdrain(struct stge_softc *sc)
    1304             : {
    1305             :         struct stge_descsoft *ds;
    1306             :         int i;
    1307             : 
    1308           0 :         for (i = 0; i < STGE_NRXDESC; i++) {
    1309           0 :                 ds = &sc->sc_rxsoft[i];
    1310           0 :                 if (ds->ds_mbuf != NULL) {
    1311           0 :                         bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
    1312           0 :                         ds->ds_mbuf->m_next = NULL;
    1313           0 :                         m_freem(ds->ds_mbuf);
    1314           0 :                         ds->ds_mbuf = NULL;
    1315           0 :                 }
    1316             :         }
    1317           0 : }
    1318             : 
    1319             : /*
    1320             :  * stge_stop:           [ ifnet interface function ]
    1321             :  *
    1322             :  *      Stop transmission on the interface.
    1323             :  */
    1324             : void
    1325           0 : stge_stop(struct ifnet *ifp, int disable)
    1326             : {
    1327           0 :         struct stge_softc *sc = ifp->if_softc;
    1328             :         struct stge_descsoft *ds;
    1329             :         int i;
    1330             : 
    1331             :         /*
    1332             :          * Stop the one second clock.
    1333             :          */
    1334           0 :         timeout_del(&sc->sc_timeout);
    1335             : 
    1336             :         /*
    1337             :          * Mark the interface down and cancel the watchdog timer.
    1338             :          */
    1339           0 :         ifp->if_flags &= ~IFF_RUNNING;
    1340           0 :         ifq_clr_oactive(&ifp->if_snd);
    1341           0 :         ifp->if_timer = 0;
    1342             : 
    1343             :         /* Down the MII. */
    1344           0 :         mii_down(&sc->sc_mii);
    1345             : 
    1346             :         /*
    1347             :          * Disable interrupts.
    1348             :          */
    1349           0 :         CSR_WRITE_2(sc, STGE_IntEnable, 0);
    1350             : 
    1351             :         /*
    1352             :          * Stop receiver, transmitter, and stats update.
    1353             :          */
    1354           0 :         CSR_WRITE_4(sc, STGE_MACCtrl,
    1355             :             MC_StatisticsDisable | MC_TxDisable | MC_RxDisable);
    1356             : 
    1357             :         /*
    1358             :          * Stop the transmit and receive DMA.
    1359             :          */
    1360           0 :         stge_dma_wait(sc);
    1361           0 :         CSR_WRITE_4(sc, STGE_TFDListPtrHi, 0);
    1362           0 :         CSR_WRITE_4(sc, STGE_TFDListPtrLo, 0);
    1363           0 :         CSR_WRITE_4(sc, STGE_RFDListPtrHi, 0);
    1364           0 :         CSR_WRITE_4(sc, STGE_RFDListPtrLo, 0);
    1365             : 
    1366             :         /*
    1367             :          * Release any queued transmit buffers.
    1368             :          */
    1369           0 :         for (i = 0; i < STGE_NTXDESC; i++) {
    1370           0 :                 ds = &sc->sc_txsoft[i];
    1371           0 :                 if (ds->ds_mbuf != NULL) {
    1372           0 :                         bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
    1373           0 :                         m_freem(ds->ds_mbuf);
    1374           0 :                         ds->ds_mbuf = NULL;
    1375           0 :                 }
    1376             :         }
    1377             : 
    1378           0 :         if (disable)
    1379           0 :                 stge_rxdrain(sc);
    1380           0 : }
    1381             : 
    1382             : static int
    1383           0 : stge_eeprom_wait(struct stge_softc *sc)
    1384             : {
    1385             :         int i;
    1386             : 
    1387           0 :         for (i = 0; i < STGE_TIMEOUT; i++) {
    1388           0 :                 delay(1000);
    1389           0 :                 if ((CSR_READ_2(sc, STGE_EepromCtrl) & EC_EepromBusy) == 0)
    1390           0 :                         return (0);
    1391             :         }
    1392           0 :         return (1);
    1393           0 : }
    1394             : 
    1395             : /*
    1396             :  * stge_read_eeprom:
    1397             :  *
    1398             :  *      Read data from the serial EEPROM.
    1399             :  */
    1400             : void
    1401           0 : stge_read_eeprom(struct stge_softc *sc, int offset, uint16_t *data)
    1402             : {
    1403             : 
    1404           0 :         if (stge_eeprom_wait(sc))
    1405           0 :                 printf("%s: EEPROM failed to come ready\n",
    1406           0 :                     sc->sc_dev.dv_xname);
    1407             : 
    1408           0 :         CSR_WRITE_2(sc, STGE_EepromCtrl,
    1409             :             EC_EepromAddress(offset) | EC_EepromOpcode(EC_OP_RR));
    1410           0 :         if (stge_eeprom_wait(sc))
    1411           0 :                 printf("%s: EEPROM read timed out\n",
    1412           0 :                     sc->sc_dev.dv_xname);
    1413           0 :         *data = CSR_READ_2(sc, STGE_EepromData);
    1414           0 : }
    1415             : 
    1416             : /*
    1417             :  * stge_add_rxbuf:
    1418             :  *
    1419             :  *      Add a receive buffer to the indicated descriptor.
    1420             :  */
    1421             : int
    1422           0 : stge_add_rxbuf(struct stge_softc *sc, int idx)
    1423             : {
    1424           0 :         struct stge_descsoft *ds = &sc->sc_rxsoft[idx];
    1425             :         struct mbuf *m;
    1426             :         int error;
    1427             : 
    1428           0 :         MGETHDR(m, M_DONTWAIT, MT_DATA);
    1429           0 :         if (m == NULL)
    1430           0 :                 return (ENOBUFS);
    1431             : 
    1432           0 :         MCLGET(m, M_DONTWAIT);
    1433           0 :         if ((m->m_flags & M_EXT) == 0) {
    1434           0 :                 m_freem(m);
    1435           0 :                 return (ENOBUFS);
    1436             :         }
    1437             : 
    1438           0 :         m->m_data = m->m_ext.ext_buf + 2;
    1439           0 :         m->m_len = MCLBYTES - 2;
    1440             : 
    1441           0 :         if (ds->ds_mbuf != NULL)
    1442           0 :                 bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
    1443             : 
    1444           0 :         ds->ds_mbuf = m;
    1445             : 
    1446           0 :         error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
    1447             :             m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
    1448           0 :         if (error) {
    1449           0 :                 printf("%s: can't load rx DMA map %d, error = %d\n",
    1450           0 :                     sc->sc_dev.dv_xname, idx, error);
    1451           0 :                 panic("stge_add_rxbuf");      /* XXX */
    1452             :         }
    1453             : 
    1454           0 :         bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
    1455             :             ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
    1456             : 
    1457           0 :         STGE_INIT_RXDESC(sc, idx);
    1458             : 
    1459           0 :         return (0);
    1460           0 : }
    1461             : 
    1462             : /*
    1463             :  * stge_iff:
    1464             :  *
    1465             :  *      Set up the receive filter.
    1466             :  */
    1467             : void
    1468           0 : stge_iff(struct stge_softc *sc)
    1469             : {
    1470           0 :         struct arpcom *ac = &sc->sc_arpcom;
    1471           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1472             :         struct ether_multi *enm;
    1473             :         struct ether_multistep step;
    1474             :         uint32_t crc;
    1475           0 :         uint32_t mchash[2];
    1476             : 
    1477           0 :         memset(mchash, 0, sizeof(mchash));
    1478           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
    1479             : 
    1480             :         /*
    1481             :          * Always accept broadcast packets.
    1482             :          * Always accept frames destined to our station address.
    1483             :          */
    1484           0 :         sc->sc_ReceiveMode = RM_ReceiveBroadcast | RM_ReceiveUnicast;
    1485             : 
    1486           0 :         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
    1487           0 :                 ifp->if_flags |= IFF_ALLMULTI;
    1488           0 :                 if (ifp->if_flags & IFF_PROMISC)
    1489           0 :                         sc->sc_ReceiveMode |= RM_ReceiveAllFrames;
    1490             :                 else
    1491           0 :                         sc->sc_ReceiveMode |= RM_ReceiveMulticast;
    1492             :         } else {
    1493             :                 /*
    1494             :                  * Set up the multicast address filter by passing all
    1495             :                  * multicast addresses through a CRC generator, and then
    1496             :                  * using the low-order 6 bits as an index into the 64 bit
    1497             :                  * multicast hash table.  The high order bits select the
    1498             :                  * register, while the rest of the bits select the bit
    1499             :                  * within the register.
    1500             :                  */
    1501           0 :                 sc->sc_ReceiveMode |= RM_ReceiveMulticastHash;
    1502             : 
    1503           0 :                 ETHER_FIRST_MULTI(step, ac, enm);
    1504           0 :                 while (enm != NULL) {
    1505           0 :                         crc = ether_crc32_be(enm->enm_addrlo,
    1506             :                             ETHER_ADDR_LEN);
    1507             : 
    1508             :                         /* Just want the 6 least significant bits. */
    1509           0 :                         crc &= 0x3f;
    1510             : 
    1511             :                         /* Set the corresponding bit in the hash table. */
    1512           0 :                         mchash[crc >> 5] |= 1 << (crc & 0x1f);
    1513             : 
    1514           0 :                         ETHER_NEXT_MULTI(step, enm);
    1515             :                 }
    1516             :         }
    1517             : 
    1518           0 :         CSR_WRITE_4(sc, STGE_HashTable0, mchash[0]);
    1519           0 :         CSR_WRITE_4(sc, STGE_HashTable1, mchash[1]);
    1520           0 :         CSR_WRITE_2(sc, STGE_ReceiveMode, sc->sc_ReceiveMode);
    1521           0 : }
    1522             : 
    1523             : /*
    1524             :  * stge_mii_readreg:    [mii interface function]
    1525             :  *
    1526             :  *      Read a PHY register on the MII of the TC9021.
    1527             :  */
    1528             : int
    1529           0 : stge_mii_readreg(struct device *self, int phy, int reg)
    1530             : {
    1531             : 
    1532           0 :         return (mii_bitbang_readreg(self, &stge_mii_bitbang_ops, phy, reg));
    1533             : }
    1534             : 
    1535             : /*
    1536             :  * stge_mii_writereg:   [mii interface function]
    1537             :  *
    1538             :  *      Write a PHY register on the MII of the TC9021.
    1539             :  */
    1540             : void
    1541           0 : stge_mii_writereg(struct device *self, int phy, int reg, int val)
    1542             : {
    1543             : 
    1544           0 :         mii_bitbang_writereg(self, &stge_mii_bitbang_ops, phy, reg, val);
    1545           0 : }
    1546             : 
    1547             : /*
    1548             :  * stge_mii_statchg:    [mii interface function]
    1549             :  *
    1550             :  *      Callback from MII layer when media changes.
    1551             :  */
    1552             : void
    1553           0 : stge_mii_statchg(struct device *self)
    1554             : {
    1555           0 :         struct stge_softc *sc = (struct stge_softc *) self;
    1556           0 :         struct mii_data *mii = &sc->sc_mii;
    1557             : 
    1558           0 :         sc->sc_MACCtrl &= ~(MC_DuplexSelect | MC_RxFlowControlEnable |
    1559             :             MC_TxFlowControlEnable);
    1560             : 
    1561           0 :         if (((mii->mii_media_active & IFM_GMASK) & IFM_FDX) != 0)
    1562           0 :                 sc->sc_MACCtrl |= MC_DuplexSelect;
    1563             : 
    1564           0 :         if (((mii->mii_media_active & IFM_GMASK) & IFM_ETH_RXPAUSE) != 0)
    1565           0 :                 sc->sc_MACCtrl |= MC_RxFlowControlEnable;
    1566           0 :         if (((mii->mii_media_active & IFM_GMASK) & IFM_ETH_TXPAUSE) != 0)
    1567           0 :                 sc->sc_MACCtrl |= MC_TxFlowControlEnable;
    1568             : 
    1569           0 :         CSR_WRITE_4(sc, STGE_MACCtrl, sc->sc_MACCtrl);
    1570           0 : }
    1571             : 
    1572             : /*
    1573             :  * sste_mii_bitbang_read: [mii bit-bang interface function]
    1574             :  *
    1575             :  *      Read the MII serial port for the MII bit-bang module.
    1576             :  */
    1577             : uint32_t
    1578           0 : stge_mii_bitbang_read(struct device *self)
    1579             : {
    1580           0 :         struct stge_softc *sc = (void *) self;
    1581             : 
    1582           0 :         return (CSR_READ_1(sc, STGE_PhyCtrl));
    1583             : }
    1584             : 
    1585             : /*
    1586             :  * stge_mii_bitbang_write: [mii big-bang interface function]
    1587             :  *
    1588             :  *      Write the MII serial port for the MII bit-bang module.
    1589             :  */
    1590             : void
    1591           0 : stge_mii_bitbang_write(struct device *self, uint32_t val)
    1592             : {
    1593           0 :         struct stge_softc *sc = (void *) self;
    1594             : 
    1595           0 :         CSR_WRITE_1(sc, STGE_PhyCtrl, val | sc->sc_PhyCtrl);
    1596           0 : }
    1597             : 
    1598             : /*
    1599             :  * stge_mediastatus:    [ifmedia interface function]
    1600             :  *
    1601             :  *      Get the current interface media status.
    1602             :  */
    1603             : void
    1604           0 : stge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
    1605             : {
    1606           0 :         struct stge_softc *sc = ifp->if_softc;
    1607             : 
    1608           0 :         mii_pollstat(&sc->sc_mii);
    1609           0 :         ifmr->ifm_status = sc->sc_mii.mii_media_status;
    1610           0 :         ifmr->ifm_active = sc->sc_mii.mii_media_active;
    1611           0 : }
    1612             : 
    1613             : /*
    1614             :  * stge_mediachange:    [ifmedia interface function]
    1615             :  *
    1616             :  *      Set hardware to newly-selected media.
    1617             :  */
    1618             : int
    1619           0 : stge_mediachange(struct ifnet *ifp)
    1620             : {
    1621           0 :         struct stge_softc *sc = ifp->if_softc;
    1622             : 
    1623           0 :         if (ifp->if_flags & IFF_UP)
    1624           0 :                 mii_mediachg(&sc->sc_mii);
    1625           0 :         return (0);
    1626             : }

Generated by: LCOV version 1.13