Home | History | Annotate | Line # | Download | only in ic
      1 /* $NetBSD: dwc_gmac.c,v 1.102 2026/06/22 20:26:34 jakllsch Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Matt Thomas of 3am Software Foundry and Martin Husemann.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * This driver supports the Synopsis Designware GMAC core, as found
     34  * on Allwinner A20 cores and others.
     35  *
     36  * Real documentation seems to not be available, the marketing product
     37  * documents could be found here:
     38  *
     39  *  http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive
     40  */
     41 
     42 /*
     43  * Lock order:
     44  *
     45  *	IFNET_LOCK -> sc_mcast_lock
     46  *	IFNET_LOCK -> sc_intr_lock -> {sc_txq.t_mtx, sc_rxq.r_mtx}
     47  */
     48 
     49 #include <sys/cdefs.h>
     50 
     51 __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.102 2026/06/22 20:26:34 jakllsch Exp $");
     52 
     53 /* #define	DWC_GMAC_DEBUG	1 */
     54 
     55 #ifdef _KERNEL_OPT
     56 #include "opt_inet.h"
     57 #endif
     58 
     59 #include <sys/param.h>
     60 #include <sys/bus.h>
     61 #include <sys/device.h>
     62 #include <sys/intr.h>
     63 #include <sys/systm.h>
     64 #include <sys/sockio.h>
     65 #include <sys/cprng.h>
     66 #include <sys/rndsource.h>
     67 
     68 #include <net/if.h>
     69 #include <net/if_ether.h>
     70 #include <net/if_media.h>
     71 #include <net/bpf.h>
     72 #ifdef INET
     73 #include <netinet/if_inarp.h>
     74 #endif
     75 
     76 #include <dev/mii/miivar.h>
     77 
     78 #include <dev/ic/dwc_gmac_reg.h>
     79 #include <dev/ic/dwc_gmac_var.h>
     80 
     81 static int dwc_gmac_miibus_read_reg(device_t, int, int, uint16_t *);
     82 static int dwc_gmac_miibus_write_reg(device_t, int, int, uint16_t);
     83 static void dwc_gmac_miibus_statchg(struct ifnet *);
     84 
     85 static int dwc_gmac_reset(struct dwc_gmac_softc *);
     86 static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *, uint8_t[ETHER_ADDR_LEN]);
     87 static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *);
     88 static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *);
     89 static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
     90 static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
     91 static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *, struct dwc_gmac_rx_ring *);
     92 static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
     93 static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
     94 static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *, struct dwc_gmac_tx_ring *);
     95 static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *, int, int, int);
     96 static int dwc_gmac_init(struct ifnet *);
     97 static void dwc_gmac_stop(struct ifnet *, int);
     98 static void dwc_gmac_start(struct ifnet *);
     99 static void dwc_gmac_start_locked(struct ifnet *);
    100 static int dwc_gmac_queue(struct dwc_gmac_softc *, struct mbuf *);
    101 static int dwc_gmac_ioctl(struct ifnet *, u_long, void *);
    102 static void dwc_gmac_tx_intr(struct dwc_gmac_softc *);
    103 static void dwc_gmac_rx_intr(struct dwc_gmac_softc *);
    104 static void dwc_gmac_setmulti(struct dwc_gmac_softc *);
    105 static int dwc_gmac_ifflags_cb(struct ethercom *);
    106 static void dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
    107 static int  dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
    108 static void dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *, int);
    109 static uint32_t dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *);
    110 static void dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
    111 static void dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
    112 static void dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
    113 static void dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
    114 static int  dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *);
    115 static void dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *, int);
    116 static uint32_t dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *);
    117 static void dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
    118 static void dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
    119 static void dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
    120 static void dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
    121 static int  dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *);
    122 
    123 static const struct dwc_gmac_desc_methods desc_methods_standard = {
    124 	.tx_init_flags = dwc_gmac_desc_std_tx_init_flags,
    125 	.tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
    126 	.tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
    127 	.tx_set_len = dwc_gmac_desc_std_set_len,
    128 	.tx_set_first_frag = dwc_gmac_desc_std_tx_set_first_frag,
    129 	.tx_set_last_frag = dwc_gmac_desc_std_tx_set_last_frag,
    130 	.rx_init_flags = dwc_gmac_desc_std_rx_init_flags,
    131 	.rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
    132 	.rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
    133 	.rx_set_len = dwc_gmac_desc_std_set_len,
    134 	.rx_get_len = dwc_gmac_desc_std_get_len,
    135 	.rx_has_error = dwc_gmac_desc_std_rx_has_error
    136 };
    137 
    138 static const struct dwc_gmac_desc_methods desc_methods_enhanced = {
    139 	.tx_init_flags = dwc_gmac_desc_enh_tx_init_flags,
    140 	.tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
    141 	.tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
    142 	.tx_set_len = dwc_gmac_desc_enh_set_len,
    143 	.tx_set_first_frag = dwc_gmac_desc_enh_tx_set_first_frag,
    144 	.tx_set_last_frag = dwc_gmac_desc_enh_tx_set_last_frag,
    145 	.rx_init_flags = dwc_gmac_desc_enh_rx_init_flags,
    146 	.rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
    147 	.rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
    148 	.rx_set_len = dwc_gmac_desc_enh_set_len,
    149 	.rx_get_len = dwc_gmac_desc_enh_get_len,
    150 	.rx_has_error = dwc_gmac_desc_enh_rx_has_error
    151 };
    152 
    153 
    154 #define	TX_DESC_OFFSET(N)	((AWGE_RX_RING_COUNT + (N)) \
    155 				    * sizeof(struct dwc_gmac_dev_dmadesc))
    156 #define	TX_NEXT(N)		(((N) + 1) & (AWGE_TX_RING_COUNT - 1))
    157 
    158 #define RX_DESC_OFFSET(N)	((N) * sizeof(struct dwc_gmac_dev_dmadesc))
    159 #define	RX_NEXT(N)		(((N) + 1) & (AWGE_RX_RING_COUNT - 1))
    160 
    161 
    162 
    163 #define	GMAC_DEF_DMA_INT_MASK	(GMAC_DMA_INT_TIE | GMAC_DMA_INT_RIE | \
    164 				GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE | \
    165 				GMAC_DMA_INT_FBE | GMAC_DMA_INT_UNE)
    166 
    167 #define	GMAC_DMA_INT_ERRORS	(GMAC_DMA_INT_AIE | GMAC_DMA_INT_ERE | \
    168 				GMAC_DMA_INT_FBE |	\
    169 				GMAC_DMA_INT_RWE | GMAC_DMA_INT_RUE | \
    170 				GMAC_DMA_INT_UNE | GMAC_DMA_INT_OVE | \
    171 				GMAC_DMA_INT_TJE)
    172 
    173 #define	AWIN_DEF_MAC_INTRMASK	\
    174 	(AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG |	\
    175 	AWIN_GMAC_MAC_INT_LINKCHG)
    176 
    177 #define	DWC_GMAC_DEFAULT_PBL 8
    178 
    179 #ifdef DWC_GMAC_DEBUG
    180 static void dwc_gmac_dump_dma(struct dwc_gmac_softc *);
    181 static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *);
    182 static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *);
    183 static void dwc_dump_and_abort(struct dwc_gmac_softc *, const char *);
    184 static void dwc_dump_status(struct dwc_gmac_softc *);
    185 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *, uint32_t);
    186 #endif
    187 
    188 int
    189 dwc_gmac_attach(struct dwc_gmac_softc *sc, int phy_id, uint32_t mii_clk)
    190 {
    191 	uint8_t enaddr[ETHER_ADDR_LEN];
    192 	uint32_t maclo, machi, hwft;
    193 	struct mii_data * const mii = &sc->sc_mii;
    194 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
    195 
    196 	mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET);
    197 	sc->sc_mii_clk = mii_clk & 7;
    198 
    199 	if (! ether_getaddr(sc->sc_dev, enaddr)) {
    200 		/*
    201 		 * If we did not get an externally configured address,
    202 		 * try to read one from the current filter setup,
    203 		 * before resetting the chip.
    204 		 */
    205 		maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    206 		    AWIN_GMAC_MAC_ADDR0LO);
    207 		machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    208 		    AWIN_GMAC_MAC_ADDR0HI);
    209 
    210 		if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) {
    211 			/* fake MAC address */
    212 			maclo = 0x00f2 | (cprng_strong32() << 16);
    213 			machi = cprng_strong32();
    214 		}
    215 
    216 		enaddr[0] = maclo & 0x0ff;
    217 		enaddr[1] = (maclo >> 8) & 0x0ff;
    218 		enaddr[2] = (maclo >> 16) & 0x0ff;
    219 		enaddr[3] = (maclo >> 24) & 0x0ff;
    220 		enaddr[4] = machi & 0x0ff;
    221 		enaddr[5] = (machi >> 8) & 0x0ff;
    222 	}
    223 
    224 	const uint32_t ver =
    225 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_VERSION);
    226 	const uint32_t snpsver =
    227 	    __SHIFTOUT(ver, AWIN_GMAC_MAC_VERSION_SNPSVER_MASK);
    228 	aprint_normal_dev(sc->sc_dev, "Core version: %08x\n", snpsver);
    229 
    230 	/*
    231 	 * Init chip and do initial setup
    232 	 */
    233 	if (dwc_gmac_reset(sc) != 0)
    234 		return ENXIO;	/* not much to cleanup, haven't attached yet */
    235 	dwc_gmac_write_hwaddr(sc, enaddr);
    236 	aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
    237 	    ether_sprintf(enaddr));
    238 
    239 	hwft = 0;
    240 	if (snpsver >= 0x35) {
    241 		hwft = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    242 		    AWIN_GMAC_DMA_HWFEATURES);
    243 		aprint_normal_dev(sc->sc_dev,
    244 		    "HW feature mask: %x\n", hwft);
    245 	}
    246 
    247 	if (sizeof(bus_addr_t) > 4) {
    248 		int error = bus_dmatag_subregion(sc->sc_dmat, 0, __MASK(32),
    249 		    &sc->sc_dmat, BUS_DMA_WAITOK);
    250 		if (error != 0) {
    251 			aprint_error_dev(sc->sc_dev,
    252 			    "failed to create DMA subregion\n");
    253 			return ENOMEM;
    254 		}
    255 	}
    256 
    257 	if (hwft & GMAC_DMA_FEAT_ENHANCED_DESC) {
    258 		aprint_normal_dev(sc->sc_dev,
    259 		    "Using enhanced descriptor format\n");
    260 		sc->sc_descm = &desc_methods_enhanced;
    261 	} else {
    262 		sc->sc_descm = &desc_methods_standard;
    263 	}
    264 	if (hwft & GMAC_DMA_FEAT_RMON) {
    265 		uint32_t val;
    266 
    267 		/* Mask all MMC interrupts */
    268 		val = 0xffffffff;
    269 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    270 		    GMAC_MMC_RX_INT_MSK, val);
    271 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    272 		    GMAC_MMC_TX_INT_MSK, val);
    273 	}
    274 
    275 	if (!sc->sc_txpbl)
    276 		sc->sc_txpbl = DWC_GMAC_DEFAULT_PBL;
    277 	if (!sc->sc_rxpbl)
    278 		sc->sc_rxpbl = DWC_GMAC_DEFAULT_PBL;
    279 
    280 	/*
    281 	 * Allocate Tx and Rx rings
    282 	 */
    283 	if (dwc_gmac_alloc_dma_rings(sc) != 0) {
    284 		aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n");
    285 		goto fail;
    286 	}
    287 
    288 	if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) {
    289 		aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n");
    290 		goto fail;
    291 	}
    292 
    293 	if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) {
    294 		aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n");
    295 		goto fail;
    296 	}
    297 
    298 	sc->sc_stopping = false;
    299 	sc->sc_txbusy = false;
    300 
    301 	sc->sc_mcast_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
    302 	sc->sc_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
    303 	mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET);
    304 	mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
    305 
    306 	/*
    307 	 * Prepare interface data
    308 	 */
    309 	ifp->if_softc = sc;
    310 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    311 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    312 	ifp->if_extflags = IFEF_MPSAFE;
    313 	ifp->if_ioctl = dwc_gmac_ioctl;
    314 	ifp->if_start = dwc_gmac_start;
    315 	ifp->if_init = dwc_gmac_init;
    316 	ifp->if_stop = dwc_gmac_stop;
    317 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    318 	IFQ_SET_READY(&ifp->if_snd);
    319 
    320 	/*
    321 	 * Attach MII subdevices
    322 	 */
    323 	sc->sc_ec.ec_mii = &sc->sc_mii;
    324 	ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
    325 	mii->mii_ifp = ifp;
    326 	mii->mii_readreg = dwc_gmac_miibus_read_reg;
    327 	mii->mii_writereg = dwc_gmac_miibus_write_reg;
    328 	mii->mii_statchg = dwc_gmac_miibus_statchg;
    329 	mii_attach(sc->sc_dev, mii, 0xffffffff, phy_id, MII_OFFSET_ANY,
    330 	    MIIF_DOPAUSE);
    331 
    332 	if (LIST_EMPTY(&mii->mii_phys)) {
    333 		aprint_error_dev(sc->sc_dev, "no PHY found!\n");
    334 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
    335 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_MANUAL);
    336 	} else {
    337 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
    338 	}
    339 
    340 	/*
    341 	 * We can support 802.1Q VLAN-sized frames.
    342 	 */
    343 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
    344 
    345 	/*
    346 	 * Ready, attach interface
    347 	 */
    348 	/* Attach the interface. */
    349 	if_initialize(ifp);
    350 	sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
    351 	if_deferred_start_init(ifp, NULL);
    352 	ether_ifattach(ifp, enaddr);
    353 	ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb);
    354 	if_register(ifp);
    355 	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
    356 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
    357 
    358 	/*
    359 	 * Enable interrupts
    360 	 */
    361 	mutex_enter(sc->sc_intr_lock);
    362 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK,
    363 	    AWIN_DEF_MAC_INTRMASK);
    364 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE,
    365 	    GMAC_DEF_DMA_INT_MASK);
    366 	mutex_exit(sc->sc_intr_lock);
    367 
    368 	return 0;
    369 
    370 fail:
    371 	dwc_gmac_free_rx_ring(sc, &sc->sc_rxq);
    372 	dwc_gmac_free_tx_ring(sc, &sc->sc_txq);
    373 	dwc_gmac_free_dma_rings(sc);
    374 	mutex_destroy(&sc->sc_mdio_lock);
    375 
    376 	return ENXIO;
    377 }
    378 
    379 
    380 
    381 static int
    382 dwc_gmac_reset(struct dwc_gmac_softc *sc)
    383 {
    384 	size_t cnt;
    385 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
    386 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)
    387 	    | GMAC_BUSMODE_RESET);
    388 	for (cnt = 0; cnt < 30000; cnt++) {
    389 		if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)
    390 		    & GMAC_BUSMODE_RESET) == 0)
    391 			return 0;
    392 		delay(10);
    393 	}
    394 
    395 	aprint_error_dev(sc->sc_dev, "reset timed out\n");
    396 	return EIO;
    397 }
    398 
    399 static void
    400 dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc,
    401     uint8_t enaddr[ETHER_ADDR_LEN])
    402 {
    403 	uint32_t hi, lo;
    404 
    405 	hi = enaddr[4] | (enaddr[5] << 8);
    406 	lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16)
    407 	    | ((uint32_t)enaddr[3] << 24);
    408 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi);
    409 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo);
    410 }
    411 
    412 static int
    413 dwc_gmac_miibus_read_reg(device_t self, int phy, int reg, uint16_t *val)
    414 {
    415 	struct dwc_gmac_softc * const sc = device_private(self);
    416 	uint16_t mii;
    417 	size_t cnt;
    418 
    419 	mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK)
    420 	    | __SHIFTIN(reg, GMAC_MII_REG_MASK)
    421 	    | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK)
    422 	    | GMAC_MII_BUSY;
    423 
    424 	mutex_enter(&sc->sc_mdio_lock);
    425 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
    426 
    427 	for (cnt = 0; cnt < 1000; cnt++) {
    428 		if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    429 		    AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) {
    430 			*val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    431 			    AWIN_GMAC_MAC_MIIDATA);
    432 			break;
    433 		}
    434 		delay(10);
    435 	}
    436 
    437 	mutex_exit(&sc->sc_mdio_lock);
    438 
    439 	if (cnt >= 1000)
    440 		return ETIMEDOUT;
    441 
    442 	return 0;
    443 }
    444 
    445 static int
    446 dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, uint16_t val)
    447 {
    448 	struct dwc_gmac_softc * const sc = device_private(self);
    449 	uint16_t mii;
    450 	size_t cnt;
    451 
    452 	mii = __SHIFTIN(phy, GMAC_MII_PHY_MASK)
    453 	    | __SHIFTIN(reg, GMAC_MII_REG_MASK)
    454 	    | __SHIFTIN(sc->sc_mii_clk, GMAC_MII_CLKMASK)
    455 	    | GMAC_MII_BUSY | GMAC_MII_WRITE;
    456 
    457 	mutex_enter(&sc->sc_mdio_lock);
    458 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val);
    459 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
    460 
    461 	for (cnt = 0; cnt < 1000; cnt++) {
    462 		if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    463 		    AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY))
    464 			break;
    465 		delay(10);
    466 	}
    467 
    468 	mutex_exit(&sc->sc_mdio_lock);
    469 
    470 	if (cnt >= 1000)
    471 		return ETIMEDOUT;
    472 
    473 	return 0;
    474 }
    475 
    476 static int
    477 dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc,
    478 	struct dwc_gmac_rx_ring *ring)
    479 {
    480 	struct dwc_gmac_rx_data *data;
    481 	bus_addr_t physaddr;
    482 	const size_t rxringsz = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc);
    483 	int error, i, next;
    484 
    485 	ring->r_cur = ring->r_next = 0;
    486 	memset(ring->r_desc, 0, rxringsz);
    487 
    488 	/*
    489 	 * Pre-allocate Rx buffers and populate Rx ring.
    490 	 */
    491 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    492 		struct dwc_gmac_dev_dmadesc *desc;
    493 
    494 		data = &sc->sc_rxq.r_data[i];
    495 
    496 		MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA);
    497 		if (data->rd_m == NULL) {
    498 			aprint_error_dev(sc->sc_dev,
    499 			    "could not allocate rx mbuf #%d\n", i);
    500 			error = ENOMEM;
    501 			goto fail;
    502 		}
    503 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
    504 		    MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map);
    505 		if (error != 0) {
    506 			aprint_error_dev(sc->sc_dev,
    507 			    "could not create DMA map\n");
    508 			data->rd_map = NULL;
    509 			goto fail;
    510 		}
    511 		MCLGET(data->rd_m, M_DONTWAIT);
    512 		if (!(data->rd_m->m_flags & M_EXT)) {
    513 			aprint_error_dev(sc->sc_dev,
    514 			    "could not allocate mbuf cluster #%d\n", i);
    515 			error = ENOMEM;
    516 			goto fail;
    517 		}
    518 		data->rd_m->m_len = data->rd_m->m_pkthdr.len
    519 		    = data->rd_m->m_ext.ext_size;
    520 		m_adj(data->rd_m, ETHER_ALIGN);
    521 		if (data->rd_m->m_len > AWGE_MAX_PACKET) {
    522 			data->rd_m->m_len = data->rd_m->m_pkthdr.len
    523 			    = AWGE_MAX_PACKET;
    524 		}
    525 
    526 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
    527 		    data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
    528 		if (error != 0) {
    529 			aprint_error_dev(sc->sc_dev,
    530 			    "could not load rx buf DMA map #%d", i);
    531 			goto fail;
    532 		}
    533 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
    534 		    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
    535 		physaddr = data->rd_map->dm_segs[0].ds_addr;
    536 
    537 		desc = &sc->sc_rxq.r_desc[i];
    538 		desc->ddesc_data = htole32(physaddr);
    539 		next = RX_NEXT(i);
    540 		desc->ddesc_next = htole32(ring->r_physaddr
    541 		    + next * sizeof(*desc));
    542 		sc->sc_descm->rx_init_flags(desc);
    543 		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
    544 		sc->sc_descm->rx_set_owned_by_dev(desc);
    545 	}
    546 
    547 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    548 	    RX_DESC_OFFSET(0),
    549 	    AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
    550 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    551 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    552 	    ring->r_physaddr);
    553 
    554 	return 0;
    555 
    556 fail:
    557 	dwc_gmac_free_rx_ring(sc, ring);
    558 	return error;
    559 }
    560 
    561 static void
    562 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc,
    563 	struct dwc_gmac_rx_ring *ring)
    564 {
    565 	struct dwc_gmac_dev_dmadesc *desc;
    566 	struct dwc_gmac_rx_data *data;
    567 	int i;
    568 
    569 	mutex_enter(&ring->r_mtx);
    570 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    571 		desc = &sc->sc_rxq.r_desc[i];
    572 		data = &sc->sc_rxq.r_data[i];
    573 		sc->sc_descm->rx_init_flags(desc);
    574 		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
    575 		sc->sc_descm->rx_set_owned_by_dev(desc);
    576 	}
    577 
    578 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
    579 	    AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
    580 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    581 
    582 	ring->r_cur = ring->r_next = 0;
    583 	/* reset DMA address to start of ring */
    584 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    585 	    sc->sc_rxq.r_physaddr);
    586 	mutex_exit(&ring->r_mtx);
    587 }
    588 
    589 static int
    590 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc)
    591 {
    592 	const size_t ringsize = AWGE_TOTAL_RING_COUNT *
    593 		sizeof(struct dwc_gmac_dev_dmadesc);
    594 	int error, nsegs;
    595 	void *rings;
    596 
    597 	error = bus_dmamap_create(sc->sc_dmat, ringsize, 1, ringsize, 0,
    598 	    BUS_DMA_NOWAIT, &sc->sc_dma_ring_map);
    599 	if (error != 0) {
    600 		aprint_error_dev(sc->sc_dev,
    601 		    "could not create desc DMA map\n");
    602 		sc->sc_dma_ring_map = NULL;
    603 		goto fail;
    604 	}
    605 
    606 	error = bus_dmamem_alloc(sc->sc_dmat, ringsize, PAGE_SIZE, 0,
    607 	    &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT);
    608 	if (error != 0) {
    609 		aprint_error_dev(sc->sc_dev,
    610 		    "could not map DMA memory\n");
    611 		goto fail;
    612 	}
    613 
    614 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs,
    615 	    ringsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
    616 	if (error != 0) {
    617 		aprint_error_dev(sc->sc_dev,
    618 		    "could not allocate DMA memory\n");
    619 		goto fail;
    620 	}
    621 
    622 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings,
    623 	    ringsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
    624 	if (error != 0) {
    625 		aprint_error_dev(sc->sc_dev,
    626 		    "could not load desc DMA map\n");
    627 		goto fail;
    628 	}
    629 
    630 	/* give first AWGE_RX_RING_COUNT to the RX side */
    631 	sc->sc_rxq.r_desc = rings;
    632 	sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr;
    633 
    634 	/* and next rings to the TX side */
    635 	sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT;
    636 	sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr +
    637 	    AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc);
    638 
    639 	return 0;
    640 
    641 fail:
    642 	dwc_gmac_free_dma_rings(sc);
    643 	return error;
    644 }
    645 
    646 static void
    647 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc)
    648 {
    649 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
    650 	    sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    651 	bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map);
    652 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc,
    653 	    AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc));
    654 	bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1);
    655 }
    656 
    657 static void
    658 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring)
    659 {
    660 	struct dwc_gmac_rx_data *data;
    661 	int i;
    662 
    663 	if (ring->r_desc == NULL)
    664 		return;
    665 
    666 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    667 		data = &ring->r_data[i];
    668 
    669 		if (data->rd_map != NULL) {
    670 			bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
    671 			    AWGE_RX_RING_COUNT
    672 				* sizeof(struct dwc_gmac_dev_dmadesc),
    673 			    BUS_DMASYNC_POSTREAD);
    674 			bus_dmamap_unload(sc->sc_dmat, data->rd_map);
    675 			bus_dmamap_destroy(sc->sc_dmat, data->rd_map);
    676 		}
    677 		m_freem(data->rd_m);
    678 	}
    679 }
    680 
    681 static int
    682 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc,
    683 	struct dwc_gmac_tx_ring *ring)
    684 {
    685 	int i, error = 0;
    686 
    687 	ring->t_queued = 0;
    688 	ring->t_cur = ring->t_next = 0;
    689 
    690 	memset(ring->t_desc, 0, AWGE_TX_RING_COUNT * sizeof(*ring->t_desc));
    691 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    692 	    TX_DESC_OFFSET(0),
    693 	    AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
    694 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    695 
    696 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    697 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    698 		    AWGE_TX_RING_COUNT, MCLBYTES, 0,
    699 		    BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
    700 		    &ring->t_data[i].td_map);
    701 		if (error != 0) {
    702 			aprint_error_dev(sc->sc_dev,
    703 			    "could not create TX DMA map #%d\n", i);
    704 			ring->t_data[i].td_map = NULL;
    705 			goto fail;
    706 		}
    707 		ring->t_desc[i].ddesc_next = htole32(
    708 		    ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc)
    709 		    * TX_NEXT(i));
    710 	}
    711 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    712 	    TX_DESC_OFFSET(0),
    713 	    AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
    714 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    715 
    716 	return 0;
    717 
    718 fail:
    719 	dwc_gmac_free_tx_ring(sc, ring);
    720 	return error;
    721 }
    722 
    723 static void
    724 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops)
    725 {
    726 	/* 'end' is pointing one descriptor beyond the last we want to sync */
    727 	if (end > start) {
    728 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    729 		    TX_DESC_OFFSET(start),
    730 		    TX_DESC_OFFSET(end) - TX_DESC_OFFSET(start),
    731 		    ops);
    732 		return;
    733 	}
    734 	/* sync from 'start' to end of ring */
    735 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    736 	    TX_DESC_OFFSET(start),
    737 	    TX_DESC_OFFSET(AWGE_TX_RING_COUNT) - TX_DESC_OFFSET(start),
    738 	    ops);
    739 	if (TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0) > 0) {
    740 		/* sync from start of ring to 'end' */
    741 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    742 		    TX_DESC_OFFSET(0),
    743 		    TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0),
    744 		    ops);
    745 	}
    746 }
    747 
    748 static void
    749 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc,
    750 	struct dwc_gmac_tx_ring *ring)
    751 {
    752 	int i;
    753 
    754 	mutex_enter(&ring->t_mtx);
    755 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    756 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    757 
    758 		if (data->td_m != NULL) {
    759 			bus_dmamap_sync(sc->sc_dmat, data->td_active,
    760 			    0, data->td_active->dm_mapsize,
    761 			    BUS_DMASYNC_POSTWRITE);
    762 			bus_dmamap_unload(sc->sc_dmat, data->td_active);
    763 			m_freem(data->td_m);
    764 			data->td_m = NULL;
    765 		}
    766 	}
    767 
    768 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    769 	    TX_DESC_OFFSET(0),
    770 	    AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
    771 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    772 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
    773 	    sc->sc_txq.t_physaddr);
    774 
    775 	ring->t_queued = 0;
    776 	ring->t_cur = ring->t_next = 0;
    777 	mutex_exit(&ring->t_mtx);
    778 }
    779 
    780 static void
    781 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc,
    782 	struct dwc_gmac_tx_ring *ring)
    783 {
    784 	int i;
    785 
    786 	/* unload the maps */
    787 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    788 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    789 
    790 		if (data->td_m != NULL) {
    791 			bus_dmamap_sync(sc->sc_dmat, data->td_active,
    792 			    0, data->td_map->dm_mapsize,
    793 			    BUS_DMASYNC_POSTWRITE);
    794 			bus_dmamap_unload(sc->sc_dmat, data->td_active);
    795 			m_freem(data->td_m);
    796 			data->td_m = NULL;
    797 		}
    798 	}
    799 
    800 	/* and actually free them */
    801 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    802 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    803 
    804 		bus_dmamap_destroy(sc->sc_dmat, data->td_map);
    805 	}
    806 }
    807 
    808 static void
    809 dwc_gmac_miibus_statchg(struct ifnet *ifp)
    810 {
    811 	struct dwc_gmac_softc * const sc = ifp->if_softc;
    812 	struct mii_data * const mii = &sc->sc_mii;
    813 	uint32_t conf, flow;
    814 
    815 	/*
    816 	 * Set MII or GMII interface based on the speed
    817 	 * negotiated by the PHY.
    818 	 */
    819 	conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF);
    820 	conf &= ~(AWIN_GMAC_MAC_CONF_FES100 | AWIN_GMAC_MAC_CONF_MIISEL
    821 	    | AWIN_GMAC_MAC_CONF_FULLDPLX);
    822 	conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST
    823 	    | AWIN_GMAC_MAC_CONF_DISABLERXOWN
    824 	    | AWIN_GMAC_MAC_CONF_DISABLEJABBER
    825 	    | AWIN_GMAC_MAC_CONF_RXENABLE
    826 	    | AWIN_GMAC_MAC_CONF_TXENABLE;
    827 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
    828 	case IFM_10_T:
    829 		conf |= AWIN_GMAC_MAC_CONF_MIISEL;
    830 		break;
    831 	case IFM_100_TX:
    832 		conf |= AWIN_GMAC_MAC_CONF_FES100 |
    833 			AWIN_GMAC_MAC_CONF_MIISEL;
    834 		break;
    835 	case IFM_1000_T:
    836 		break;
    837 	}
    838 	if (sc->sc_set_speed)
    839 		sc->sc_set_speed(sc, IFM_SUBTYPE(mii->mii_media_active));
    840 
    841 	flow = AWIN_GMAC_MAC_FLOWCTRL_UPE;
    842 	if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
    843 		conf |= AWIN_GMAC_MAC_CONF_FULLDPLX;
    844 		flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE);
    845 	}
    846 	if (mii->mii_media_active & IFM_ETH_TXPAUSE) {
    847 		flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE;
    848 	}
    849 	if (mii->mii_media_active & IFM_ETH_RXPAUSE) {
    850 		flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE;
    851 	}
    852 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    853 	    AWIN_GMAC_MAC_FLOWCTRL, flow);
    854 
    855 #ifdef DWC_GMAC_DEBUG
    856 	aprint_normal_dev(sc->sc_dev,
    857 	    "setting MAC conf register: %08x\n", conf);
    858 #endif
    859 
    860 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    861 	    AWIN_GMAC_MAC_CONF, conf);
    862 }
    863 
    864 static int
    865 dwc_gmac_init(struct ifnet *ifp)
    866 {
    867 	struct dwc_gmac_softc * const sc = ifp->if_softc;
    868 	uint32_t ffilt;
    869 
    870 	ASSERT_SLEEPABLE();
    871 	KASSERT(IFNET_LOCKED(ifp));
    872 	KASSERT(ifp == &sc->sc_ec.ec_if);
    873 
    874 	dwc_gmac_stop(ifp, 0);
    875 
    876 	/*
    877 	 * Configure DMA burst/transfer mode and RX/TX priorities.
    878 	 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented.
    879 	 */
    880 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
    881 	    ((sc->sc_flags & DWC_GMAC_FIXED_BURST) ? GMAC_BUSMODE_FIXEDBURST :
    882 	    0) | GMAC_BUSMODE_4PBL | GMAC_BUSMODE_USP |
    883 	    __SHIFTIN(sc->sc_rxpbl, GMAC_BUSMODE_RPBL) |
    884 	    __SHIFTIN(sc->sc_txpbl, GMAC_BUSMODE_PBL));
    885 
    886 	/*
    887 	 * Set up address filter
    888 	 */
    889 	ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
    890 	if (ifp->if_flags & IFF_PROMISC) {
    891 		ffilt |= AWIN_GMAC_MAC_FFILT_PR;
    892 	} else {
    893 		ffilt &= ~AWIN_GMAC_MAC_FFILT_PR;
    894 	}
    895 	if (ifp->if_flags & IFF_BROADCAST) {
    896 		ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF;
    897 	} else {
    898 		ffilt |= AWIN_GMAC_MAC_FFILT_DBF;
    899 	}
    900 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
    901 
    902 	/*
    903 	 * Set up multicast filter
    904 	 */
    905 	mutex_enter(sc->sc_mcast_lock);
    906 	dwc_gmac_setmulti(sc);
    907 	mutex_exit(sc->sc_mcast_lock);
    908 
    909 	/*
    910 	 * Set up dma pointer for RX and TX ring
    911 	 */
    912 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    913 	    sc->sc_rxq.r_physaddr);
    914 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
    915 	    sc->sc_txq.t_physaddr);
    916 
    917 	/*
    918 	 * Start RX/TX part
    919 	 */
    920 	uint32_t opmode = GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART;
    921 	if ((sc->sc_flags & DWC_GMAC_FORCE_THRESH_DMA_MODE) == 0) {
    922 		opmode |= GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD;
    923 		opmode |= GMAC_DMA_OP_EFC; /* requires 4KiB+ RX FIFO */
    924 	}
    925 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, opmode);
    926 #ifdef DWC_GMAC_DEBUG
    927 	aprint_normal_dev(sc->sc_dev,
    928 	    "setting DMA opmode register: %08x\n", opmode);
    929 #endif
    930 
    931 	ifp->if_flags |= IFF_RUNNING;
    932 	sc->sc_if_flags = ifp->if_flags;
    933 
    934 	mutex_enter(sc->sc_intr_lock);
    935 	sc->sc_stopping = false;
    936 	mutex_exit(sc->sc_intr_lock);
    937 
    938 	mutex_enter(&sc->sc_txq.t_mtx);
    939 	sc->sc_txbusy = false;
    940 	mutex_exit(&sc->sc_txq.t_mtx);
    941 
    942 	return 0;
    943 }
    944 
    945 static void
    946 dwc_gmac_start(struct ifnet *ifp)
    947 {
    948 	struct dwc_gmac_softc * const sc = ifp->if_softc;
    949 	KASSERT(if_is_mpsafe(ifp));
    950 
    951 	mutex_enter(sc->sc_intr_lock);
    952 	if (!sc->sc_stopping) {
    953 		dwc_gmac_start_locked(ifp);
    954 	}
    955 	mutex_exit(sc->sc_intr_lock);
    956 }
    957 
    958 static void
    959 dwc_gmac_start_locked(struct ifnet *ifp)
    960 {
    961 	struct dwc_gmac_softc * const sc = ifp->if_softc;
    962 	int old = sc->sc_txq.t_queued;
    963 	int start = sc->sc_txq.t_cur;
    964 	struct mbuf *m0;
    965 
    966 	KASSERT(mutex_owned(sc->sc_intr_lock));
    967 
    968 	mutex_enter(&sc->sc_txq.t_mtx);
    969 	if (sc->sc_txbusy) {
    970 		mutex_exit(&sc->sc_txq.t_mtx);
    971 		return;
    972 	}
    973 
    974 	for (;;) {
    975 		IFQ_POLL(&ifp->if_snd, m0);
    976 		if (m0 == NULL)
    977 			break;
    978 		if (dwc_gmac_queue(sc, m0) != 0) {
    979 			sc->sc_txbusy = true;
    980 			break;
    981 		}
    982 		IFQ_DEQUEUE(&ifp->if_snd, m0);
    983 		bpf_mtap(ifp, m0, BPF_D_OUT);
    984 		if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) {
    985 			sc->sc_txbusy = true;
    986 			break;
    987 		}
    988 	}
    989 
    990 	if (sc->sc_txq.t_queued != old) {
    991 		/* packets have been queued, kick it off */
    992 		dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
    993 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    994 
    995 #ifdef DWC_GMAC_DEBUG
    996 		dwc_dump_status(sc);
    997 #endif
    998 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    999 		    AWIN_GMAC_DMA_TXPOLL, ~0U);
   1000 	}
   1001 	mutex_exit(&sc->sc_txq.t_mtx);
   1002 }
   1003 
   1004 static void
   1005 dwc_gmac_stop(struct ifnet *ifp, int disable)
   1006 {
   1007 	struct dwc_gmac_softc * const sc = ifp->if_softc;
   1008 
   1009 	ASSERT_SLEEPABLE();
   1010 	KASSERT(IFNET_LOCKED(ifp));
   1011 
   1012 	ifp->if_flags &= ~IFF_RUNNING;
   1013 
   1014 	mutex_enter(sc->sc_mcast_lock);
   1015 	sc->sc_if_flags = ifp->if_flags;
   1016 	mutex_exit(sc->sc_mcast_lock);
   1017 
   1018 	mutex_enter(sc->sc_intr_lock);
   1019 	sc->sc_stopping = true;
   1020 	mutex_exit(sc->sc_intr_lock);
   1021 
   1022 	mutex_enter(&sc->sc_txq.t_mtx);
   1023 	sc->sc_txbusy = false;
   1024 	mutex_exit(&sc->sc_txq.t_mtx);
   1025 
   1026 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
   1027 	    AWIN_GMAC_DMA_OPMODE,
   1028 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1029 		AWIN_GMAC_DMA_OPMODE)
   1030 		& ~(GMAC_DMA_OP_TXSTART | GMAC_DMA_OP_RXSTART));
   1031 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
   1032 	    AWIN_GMAC_DMA_OPMODE,
   1033 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1034 		AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX);
   1035 
   1036 	mii_down(&sc->sc_mii);
   1037 	dwc_gmac_reset_tx_ring(sc, &sc->sc_txq);
   1038 	dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq);
   1039 }
   1040 
   1041 /*
   1042  * Add m0 to the TX ring
   1043  */
   1044 static int
   1045 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
   1046 {
   1047 	struct dwc_gmac_dev_dmadesc *desc = NULL;
   1048 	struct dwc_gmac_tx_data *data = NULL;
   1049 	bus_dmamap_t map;
   1050 	int error, i, first;
   1051 
   1052 #ifdef DWC_GMAC_DEBUG
   1053 	aprint_normal_dev(sc->sc_dev,
   1054 	    "dwc_gmac_queue: adding mbuf chain %p\n", m0);
   1055 #endif
   1056 
   1057 	first = sc->sc_txq.t_cur;
   1058 	map = sc->sc_txq.t_data[first].td_map;
   1059 
   1060 	error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0,
   1061 	    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1062 	if (error != 0) {
   1063 		aprint_error_dev(sc->sc_dev, "could not map mbuf "
   1064 		    "(len: %d, error %d)\n", m0->m_pkthdr.len, error);
   1065 		return error;
   1066 	}
   1067 
   1068 	if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) {
   1069 		bus_dmamap_unload(sc->sc_dmat, map);
   1070 		return ENOBUFS;
   1071 	}
   1072 
   1073 	for (i = 0; i < map->dm_nsegs; i++) {
   1074 		data = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
   1075 		desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
   1076 
   1077 		desc->ddesc_data = htole32(map->dm_segs[i].ds_addr);
   1078 
   1079 #ifdef DWC_GMAC_DEBUG
   1080 		aprint_normal_dev(sc->sc_dev, "enqueuing desc #%d data %08lx "
   1081 		    "len %lu\n", sc->sc_txq.t_cur,
   1082 		    (unsigned long)map->dm_segs[i].ds_addr,
   1083 		    (unsigned long)map->dm_segs[i].ds_len);
   1084 #endif
   1085 
   1086 		sc->sc_descm->tx_init_flags(desc);
   1087 		sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len);
   1088 
   1089 		if (i == 0)
   1090 			sc->sc_descm->tx_set_first_frag(desc);
   1091 
   1092 		/*
   1093 		 * Defer passing ownership of the first descriptor
   1094 		 * until we are done.
   1095 		 */
   1096 		if (i != 0)
   1097 			sc->sc_descm->tx_set_owned_by_dev(desc);
   1098 
   1099 		sc->sc_txq.t_queued++;
   1100 		sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur);
   1101 	}
   1102 
   1103 	sc->sc_descm->tx_set_last_frag(desc);
   1104 
   1105 	data->td_m = m0;
   1106 	data->td_active = map;
   1107 
   1108 	/* sync the packet buffer */
   1109 	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   1110 	    BUS_DMASYNC_PREWRITE);
   1111 
   1112 	/* sync the new descriptors - ownership not transferred yet */
   1113 	dwc_gmac_txdesc_sync(sc, first, sc->sc_txq.t_cur,
   1114 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1115 
   1116 	/* Pass first to device */
   1117 	sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]);
   1118 
   1119 	return 0;
   1120 }
   1121 
   1122 /*
   1123  * If the interface is up and running, only modify the receive
   1124  * filter when setting promiscuous or debug mode.  Otherwise fall
   1125  * through to ether_ioctl, which will reset the chip.
   1126  */
   1127 static int
   1128 dwc_gmac_ifflags_cb(struct ethercom *ec)
   1129 {
   1130 	struct ifnet * const ifp = &ec->ec_if;
   1131 	struct dwc_gmac_softc * const sc = ifp->if_softc;
   1132 	int ret = 0;
   1133 
   1134 	KASSERT(IFNET_LOCKED(ifp));
   1135 	mutex_enter(sc->sc_mcast_lock);
   1136 
   1137 	u_short change = ifp->if_flags ^ sc->sc_if_flags;
   1138 	sc->sc_if_flags = ifp->if_flags;
   1139 
   1140 	if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
   1141 		ret = ENETRESET;
   1142 	} else  if ((change & IFF_PROMISC) != 0) {
   1143 		dwc_gmac_setmulti(sc);
   1144 	}
   1145 
   1146 	mutex_exit(sc->sc_mcast_lock);
   1147 
   1148 	return ret;
   1149 }
   1150 
   1151 static int
   1152 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1153 {
   1154 	struct dwc_gmac_softc * const sc = ifp->if_softc;
   1155 	int error = 0;
   1156 
   1157 	switch (cmd) {
   1158 	case SIOCADDMULTI:
   1159 	case SIOCDELMULTI:
   1160 		break;
   1161 	default:
   1162 		KASSERT(IFNET_LOCKED(ifp));
   1163 	}
   1164 
   1165 	const int s = splnet();
   1166 	error = ether_ioctl(ifp, cmd, data);
   1167 	splx(s);
   1168 
   1169 	if (error == ENETRESET) {
   1170 		error = 0;
   1171 		if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) {
   1172 			mutex_enter(sc->sc_mcast_lock);
   1173 			if (sc->sc_if_flags & IFF_RUNNING) {
   1174 				/*
   1175 				 * Multicast list has changed; set the hardware
   1176 				 * filter accordingly.
   1177 				 */
   1178 				dwc_gmac_setmulti(sc);
   1179 			}
   1180 			mutex_exit(sc->sc_mcast_lock);
   1181 		}
   1182 	}
   1183 
   1184 	return error;
   1185 }
   1186 
   1187 static void
   1188 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
   1189 {
   1190 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
   1191 	struct dwc_gmac_tx_data *data;
   1192 	struct dwc_gmac_dev_dmadesc *desc;
   1193 	int i, nsegs;
   1194 
   1195 	mutex_enter(&sc->sc_txq.t_mtx);
   1196 
   1197 	for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) {
   1198 #ifdef DWC_GMAC_DEBUG
   1199 		aprint_normal_dev(sc->sc_dev,
   1200 		    "%s: checking desc #%d (t_queued: %d)\n", __func__,
   1201 		    i, sc->sc_txq.t_queued);
   1202 #endif
   1203 
   1204 		/*
   1205 		 * i + 1 does not need to be a valid descriptor,
   1206 		 * this is just a special notion to just sync
   1207 		 * a single tx descriptor (i)
   1208 		 */
   1209 		dwc_gmac_txdesc_sync(sc, i, i + 1,
   1210 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1211 
   1212 		desc = &sc->sc_txq.t_desc[i];
   1213 		if (sc->sc_descm->tx_is_owned_by_dev(desc))
   1214 			break;
   1215 
   1216 		data = &sc->sc_txq.t_data[i];
   1217 		if (data->td_m == NULL)
   1218 			continue;
   1219 
   1220 		if_statinc(ifp, if_opackets);
   1221 		nsegs = data->td_active->dm_nsegs;
   1222 		bus_dmamap_sync(sc->sc_dmat, data->td_active, 0,
   1223 		    data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1224 		bus_dmamap_unload(sc->sc_dmat, data->td_active);
   1225 
   1226 #ifdef DWC_GMAC_DEBUG
   1227 		aprint_normal_dev(sc->sc_dev,
   1228 		    "%s: done with packet at desc #%d, freeing mbuf %p\n",
   1229 		    __func__, i, data->td_m);
   1230 #endif
   1231 
   1232 		m_freem(data->td_m);
   1233 		data->td_m = NULL;
   1234 
   1235 		sc->sc_txq.t_queued -= nsegs;
   1236 	}
   1237 
   1238 	sc->sc_txq.t_next = i;
   1239 
   1240 	if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) {
   1241 		sc->sc_txbusy = false;
   1242 	}
   1243 	mutex_exit(&sc->sc_txq.t_mtx);
   1244 }
   1245 
   1246 static void
   1247 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
   1248 {
   1249 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
   1250 	struct dwc_gmac_dev_dmadesc *desc;
   1251 	struct dwc_gmac_rx_data *data;
   1252 	bus_addr_t physaddr;
   1253 	struct mbuf *m, *mnew;
   1254 	int i, len, error;
   1255 
   1256 	mutex_enter(&sc->sc_rxq.r_mtx);
   1257 	for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) {
   1258 #ifdef DWC_GMAC_DEBUG
   1259 		aprint_normal_dev(sc->sc_dev, "%s: checking desc #%d\n",
   1260 		    __func__, i);
   1261 #endif
   1262 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1263 		    RX_DESC_OFFSET(i), sizeof(*desc),
   1264 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1265 		desc = &sc->sc_rxq.r_desc[i];
   1266 		data = &sc->sc_rxq.r_data[i];
   1267 
   1268 		if (sc->sc_descm->rx_is_owned_by_dev(desc))
   1269 			break;
   1270 
   1271 		if (sc->sc_descm->rx_has_error(desc)) {
   1272 #ifdef DWC_GMAC_DEBUG
   1273 			aprint_normal_dev(sc->sc_dev,
   1274 			    "%s: RX error: status %08x, skipping\n",
   1275 			    __func__, le32toh(desc->ddesc_status0));
   1276 #endif
   1277 			if_statinc(ifp, if_ierrors);
   1278 			goto skip;
   1279 		}
   1280 
   1281 		len = sc->sc_descm->rx_get_len(desc);
   1282 
   1283 #ifdef DWC_GMAC_DEBUG
   1284 		aprint_normal_dev(sc->sc_dev,
   1285 		    "%s: device is done with descriptor #%d, len: %d\n",
   1286 		    __func__, i, len);
   1287 #endif
   1288 
   1289 		/*
   1290 		 * Try to get a new mbuf before passing this one
   1291 		 * up, if that fails, drop the packet and reuse
   1292 		 * the existing one.
   1293 		 */
   1294 		MGETHDR(mnew, M_DONTWAIT, MT_DATA);
   1295 		if (mnew == NULL) {
   1296 			if_statinc(ifp, if_ierrors);
   1297 			goto skip;
   1298 		}
   1299 		MCLGET(mnew, M_DONTWAIT);
   1300 		if ((mnew->m_flags & M_EXT) == 0) {
   1301 			m_freem(mnew);
   1302 			if_statinc(ifp, if_ierrors);
   1303 			goto skip;
   1304 		}
   1305 		mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size;
   1306 		m_adj(mnew, ETHER_ALIGN);
   1307 		if (mnew->m_len > AWGE_MAX_PACKET) {
   1308 			mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET;
   1309 		}
   1310 
   1311 		/* unload old DMA map */
   1312 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
   1313 		    data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1314 		bus_dmamap_unload(sc->sc_dmat, data->rd_map);
   1315 
   1316 		/* and reload with new mbuf */
   1317 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
   1318 		    mnew, BUS_DMA_READ | BUS_DMA_NOWAIT);
   1319 		if (error != 0) {
   1320 			m_freem(mnew);
   1321 			/* try to reload old mbuf */
   1322 			error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
   1323 			    data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
   1324 			if (error != 0) {
   1325 				panic("%s: could not load old rx mbuf",
   1326 				    device_xname(sc->sc_dev));
   1327 			}
   1328 			if_statinc(ifp, if_ierrors);
   1329 			goto skip;
   1330 		}
   1331 		physaddr = data->rd_map->dm_segs[0].ds_addr;
   1332 
   1333 #ifdef DWC_GMAC_DEBUG
   1334 		aprint_normal_dev(sc->sc_dev,
   1335 		    "%s: receiving packet at desc #%d,   using mbuf %p\n",
   1336 		    __func__, i, data->rd_m);
   1337 #endif
   1338 		/*
   1339 		 * New mbuf loaded, update RX ring and continue
   1340 		 */
   1341 		m = data->rd_m;
   1342 		data->rd_m = mnew;
   1343 		desc->ddesc_data = htole32(physaddr);
   1344 
   1345 		/* finalize mbuf */
   1346 		m->m_pkthdr.len = m->m_len = len;
   1347 		m_set_rcvif(m, ifp);
   1348 		m->m_flags |= M_HASFCS;
   1349 
   1350 		if_percpuq_enqueue(sc->sc_ipq, m);
   1351 
   1352 skip:
   1353 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
   1354 		    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
   1355 
   1356 		sc->sc_descm->rx_init_flags(desc);
   1357 		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
   1358 
   1359 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1360 		    RX_DESC_OFFSET(i), sizeof(*desc),
   1361 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1362 
   1363 		sc->sc_descm->rx_set_owned_by_dev(desc);
   1364 
   1365 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1366 		    RX_DESC_OFFSET(i), sizeof(*desc),
   1367 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1368 	}
   1369 
   1370 	/* update RX pointer */
   1371 	sc->sc_rxq.r_cur = i;
   1372 
   1373 	mutex_exit(&sc->sc_rxq.r_mtx);
   1374 }
   1375 
   1376 static void
   1377 dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
   1378 {
   1379 	struct ether_multi *enm;
   1380 	struct ether_multistep step;
   1381 	struct ethercom *ec = &sc->sc_ec;
   1382 	uint32_t hashes[2] = { 0, 0 };
   1383 	uint32_t ffilt, h;
   1384 	int mcnt;
   1385 
   1386 	KASSERT(mutex_owned(sc->sc_mcast_lock));
   1387 
   1388 	ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
   1389 
   1390 	if (sc->sc_if_flags & IFF_PROMISC) {
   1391 		ffilt |= AWIN_GMAC_MAC_FFILT_PR;
   1392 		goto special_filter;
   1393 	}
   1394 
   1395 	ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM | AWIN_GMAC_MAC_FFILT_PR);
   1396 
   1397 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0);
   1398 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0);
   1399 
   1400 	ETHER_LOCK(ec);
   1401 	ec->ec_flags &= ~ETHER_F_ALLMULTI;
   1402 	ETHER_FIRST_MULTI(step, ec, enm);
   1403 	mcnt = 0;
   1404 	while (enm != NULL) {
   1405 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1406 		    ETHER_ADDR_LEN) != 0) {
   1407 			ffilt |= AWIN_GMAC_MAC_FFILT_PM;
   1408 			ec->ec_flags |= ETHER_F_ALLMULTI;
   1409 			ETHER_UNLOCK(ec);
   1410 			goto special_filter;
   1411 		}
   1412 
   1413 		h = ~ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
   1414 		hashes[h >> 5] |= (1 << (h & 0x1f));
   1415 
   1416 		mcnt++;
   1417 		ETHER_NEXT_MULTI(step, enm);
   1418 	}
   1419 	ETHER_UNLOCK(ec);
   1420 
   1421 	if (mcnt)
   1422 		ffilt |= AWIN_GMAC_MAC_FFILT_HMC;
   1423 	else
   1424 		ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC;
   1425 
   1426 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
   1427 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
   1428 	    hashes[0]);
   1429 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
   1430 	    hashes[1]);
   1431 
   1432 #ifdef DWC_GMAC_DEBUG
   1433 	dwc_gmac_dump_ffilt(sc, ffilt);
   1434 #endif
   1435 	return;
   1436 
   1437 special_filter:
   1438 #ifdef DWC_GMAC_DEBUG
   1439 	dwc_gmac_dump_ffilt(sc, ffilt);
   1440 #endif
   1441 	/* no MAC hashes, ALLMULTI or PROMISC */
   1442 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT,
   1443 	    ffilt);
   1444 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
   1445 	    0xffffffff);
   1446 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
   1447 	    0xffffffff);
   1448 }
   1449 
   1450 int
   1451 dwc_gmac_intr(struct dwc_gmac_softc *sc)
   1452 {
   1453 	uint32_t status, dma_status;
   1454 	int rv = 0;
   1455 
   1456 	mutex_enter(sc->sc_intr_lock);
   1457 	if (sc->sc_stopping) {
   1458 		mutex_exit(sc->sc_intr_lock);
   1459 		return 0;
   1460 	}
   1461 
   1462 	status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR);
   1463 	if (status & AWIN_GMAC_MII_IRQ) {
   1464 		(void)bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1465 		    AWIN_GMAC_MII_STATUS);
   1466 		rv = 1;
   1467 		mii_pollstat(&sc->sc_mii);
   1468 	}
   1469 
   1470 	dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1471 	    AWIN_GMAC_DMA_STATUS);
   1472 
   1473 	if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE))
   1474 		rv = 1;
   1475 
   1476 	if (dma_status & GMAC_DMA_INT_TIE)
   1477 		dwc_gmac_tx_intr(sc);
   1478 
   1479 	if (dma_status & GMAC_DMA_INT_RIE)
   1480 		dwc_gmac_rx_intr(sc);
   1481 
   1482 	/*
   1483 	 * Check error conditions
   1484 	 */
   1485 	if (dma_status & GMAC_DMA_INT_ERRORS) {
   1486 		if_statinc(&sc->sc_ec.ec_if, if_oerrors);
   1487 #ifdef DWC_GMAC_DEBUG
   1488 		dwc_dump_and_abort(sc, "interrupt error condition");
   1489 #endif
   1490 	}
   1491 
   1492 	rnd_add_uint32(&sc->rnd_source, dma_status);
   1493 
   1494 	/* ack interrupt */
   1495 	if (dma_status)
   1496 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
   1497 		    AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK);
   1498 
   1499 	/*
   1500 	 * Get more packets
   1501 	 */
   1502 	if (rv)
   1503 		if_schedule_deferred_start(&sc->sc_ec.ec_if);
   1504 
   1505 	mutex_exit(sc->sc_intr_lock);
   1506 
   1507 	return rv;
   1508 }
   1509 
   1510 static void
   1511 dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc)
   1512 {
   1513 
   1514 	desc->ddesc_status0 |= htole32(DDESC_STATUS_OWNEDBYDEV);
   1515 }
   1516 
   1517 static int
   1518 dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc)
   1519 {
   1520 
   1521 	return !!(le32toh(desc->ddesc_status0) & DDESC_STATUS_OWNEDBYDEV);
   1522 }
   1523 
   1524 static void
   1525 dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len)
   1526 {
   1527 	uint32_t cntl = le32toh(desc->ddesc_cntl1);
   1528 
   1529 	desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) |
   1530 		__SHIFTIN(len, DDESC_CNTL_SIZE1MASK));
   1531 }
   1532 
   1533 static uint32_t
   1534 dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc)
   1535 {
   1536 
   1537 	return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK);
   1538 }
   1539 
   1540 static void
   1541 dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
   1542 {
   1543 
   1544 	desc->ddesc_status0 = 0;
   1545 	desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN);
   1546 }
   1547 
   1548 static void
   1549 dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc)
   1550 {
   1551 	uint32_t cntl = le32toh(desc->ddesc_cntl1);
   1552 
   1553 	desc->ddesc_cntl1 = htole32(cntl | DDESC_CNTL_TXFIRST);
   1554 }
   1555 
   1556 static void
   1557 dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc)
   1558 {
   1559 	uint32_t cntl = le32toh(desc->ddesc_cntl1);
   1560 
   1561 	desc->ddesc_cntl1 = htole32(cntl |
   1562 		DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT);
   1563 }
   1564 
   1565 static void
   1566 dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
   1567 {
   1568 
   1569 	desc->ddesc_status0 = 0;
   1570 	desc->ddesc_cntl1 = htole32(DDESC_CNTL_RXCHAIN);
   1571 }
   1572 
   1573 static int
   1574 dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) {
   1575 	return !!(le32toh(desc->ddesc_status0) &
   1576 		(DDESC_STATUS_RXERROR | DDESC_STATUS_RXTRUNCATED));
   1577 }
   1578 
   1579 static void
   1580 dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *desc, int len)
   1581 {
   1582 	uint32_t tdes1 = le32toh(desc->ddesc_cntl1);
   1583 
   1584 	desc->ddesc_cntl1 = htole32((tdes1 & ~DDESC_DES1_SIZE1MASK) |
   1585 		__SHIFTIN(len, DDESC_DES1_SIZE1MASK));
   1586 }
   1587 
   1588 static uint32_t
   1589 dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *desc)
   1590 {
   1591 
   1592 	return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_RDES0_FL);
   1593 }
   1594 
   1595 static void
   1596 dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
   1597 {
   1598 
   1599 	desc->ddesc_status0 = htole32(DDESC_TDES0_TCH);
   1600 	desc->ddesc_cntl1 = 0;
   1601 }
   1602 
   1603 static void
   1604 dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc)
   1605 {
   1606 	uint32_t tdes0 = le32toh(desc->ddesc_status0);
   1607 
   1608 	desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_FS);
   1609 }
   1610 
   1611 static void
   1612 dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc)
   1613 {
   1614 	uint32_t tdes0 = le32toh(desc->ddesc_status0);
   1615 
   1616 	desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_LS | DDESC_TDES0_IC);
   1617 }
   1618 
   1619 static void
   1620 dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc)
   1621 {
   1622 
   1623 	desc->ddesc_status0 = 0;
   1624 	desc->ddesc_cntl1 = htole32(DDESC_RDES1_RCH);
   1625 }
   1626 
   1627 static int
   1628 dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *desc)
   1629 {
   1630 
   1631 	return !!(le32toh(desc->ddesc_status0) &
   1632 		(DDESC_RDES0_ES | DDESC_RDES0_LE));
   1633 }
   1634 
   1635 #ifdef DWC_GMAC_DEBUG
   1636 static void
   1637 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc)
   1638 {
   1639 	aprint_normal_dev(sc->sc_dev, "busmode: %08x\n",
   1640 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE));
   1641 	aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n",
   1642 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL));
   1643 	aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n",
   1644 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL));
   1645 	aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n",
   1646 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR));
   1647 	aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n",
   1648 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR));
   1649 	aprint_normal_dev(sc->sc_dev, " status: %08x\n",
   1650 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS));
   1651 	aprint_normal_dev(sc->sc_dev, "op mode: %08x\n",
   1652 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE));
   1653 	aprint_normal_dev(sc->sc_dev, "int en.: %08x\n",
   1654 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE));
   1655 	aprint_normal_dev(sc->sc_dev, " cur tx: %08x\n",
   1656 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC));
   1657 	aprint_normal_dev(sc->sc_dev, " cur rx: %08x\n",
   1658 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC));
   1659 	aprint_normal_dev(sc->sc_dev, "cur txb: %08x\n",
   1660 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR));
   1661 	aprint_normal_dev(sc->sc_dev, "cur rxb: %08x\n",
   1662 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR));
   1663 }
   1664 
   1665 static void
   1666 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
   1667 {
   1668 	const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc);
   1669 
   1670 	aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n",
   1671 	    sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued);
   1672 	aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n");
   1673 
   1674 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1675 	    TX_DESC_OFFSET(0), AWGE_TX_RING_COUNT * descsz,
   1676 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1677 
   1678 	for (size_t i = 0; i < AWGE_TX_RING_COUNT; i++) {
   1679 		struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i];
   1680 		aprint_normal("#%3zu (%08lx): status: %08x cntl: %08x "
   1681 		    "data: %08x next: %08x\n",
   1682 		    i, sc->sc_txq.t_physaddr + i * descsz,
   1683 		    le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
   1684 		    le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
   1685 	}
   1686 }
   1687 
   1688 static void
   1689 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
   1690 {
   1691 	const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc);
   1692 
   1693 	aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n",
   1694 	    sc->sc_rxq.r_cur, sc->sc_rxq.r_next);
   1695 	aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n");
   1696 
   1697 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1698 	    RX_DESC_OFFSET(0), AWGE_RX_RING_COUNT * descsz,
   1699 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1700 
   1701 	for (size_t i = 0; i < AWGE_RX_RING_COUNT; i++) {
   1702 		struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i];
   1703 		char buf[200];
   1704 
   1705 		if (!sc->sc_descm->rx_is_owned_by_dev(desc)) {
   1706 			/* print interrupt state */
   1707 			snprintb(buf, sizeof(buf),
   1708 			    "\177\20"
   1709 			    "b\x1e"	"daff\0"
   1710 			    "f\x10\xe"	"frlen\0"
   1711 			    "b\x0f"	"error\0"
   1712 			    "b\x0e"	"rxtrunc\0"	/* descriptor error? */
   1713 			    "b\x0d"	"saff\0"
   1714 			    "b\x0c"	"giantframe\0"	/* length error? */
   1715 			    "b\x0b"	"damaged\0"
   1716 			    "b\x0a"	"vlan\0"
   1717 			    "b\x09"	"first\0"
   1718 			    "b\x08"	"last\0"
   1719 			    "b\x07"	"giant\0"
   1720 			    "b\x06"	"collision\0"
   1721 			    "b\x05"	"ether\0"
   1722 			    "b\x04"	"watchdog\0"
   1723 			    "b\x03"	"miierror\0"
   1724 			    "b\x02"	"dribbling\0"
   1725 			    "b\x01"	"crc\0"
   1726 			    "\0", le32toh(desc->ddesc_status0));
   1727 		}
   1728 
   1729 		aprint_normal("#%3zu (%08lx): status: %08x cntl: %08x "
   1730 		    "data: %08x next: %08x %s\n",
   1731 		    i, sc->sc_rxq.r_physaddr + i * descsz,
   1732 		    le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
   1733 		    le32toh(desc->ddesc_data), le32toh(desc->ddesc_next),
   1734 		    sc->sc_descm->rx_is_owned_by_dev(desc) ? "" : buf);
   1735 	}
   1736 }
   1737 
   1738 static void
   1739 dwc_dump_status(struct dwc_gmac_softc *sc)
   1740 {
   1741 	uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1742 	    AWIN_GMAC_MAC_INTR);
   1743 	uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1744 	    AWIN_GMAC_DMA_STATUS);
   1745 	char buf[200];
   1746 
   1747 	/* print interrupt state */
   1748 	snprintb(buf, sizeof(buf),
   1749 	    "\177\20"
   1750 	    "b\x1c"	"GPI\0"
   1751 	    "b\x1b"	"GMC\0"
   1752 	    "b\x1a"	"GLI\0"
   1753 	    "f\x17\x3"	"EB\0"
   1754 	    "f\x14\x3"	"TPS\0"
   1755 	    "f\x11\x3"	"RPS\0"
   1756 	    "b\x10"	"NI\0"
   1757 	    "b\x0f"	"AI\0"
   1758 	    "b\x0e"	"ER\0"
   1759 	    "b\x0d"	"FB\0"
   1760 	    "b\x0a"	"ET\0"
   1761 	    "b\x09"	"RW\0"
   1762 	    "b\x08"	"RS\0"
   1763 	    "b\x07"	"RU\0"
   1764 	    "b\x06"	"RI\0"
   1765 	    "b\x05"	"UN\0"
   1766 	    "b\x04"	"OV\0"
   1767 	    "b\x03"	"TJ\0"
   1768 	    "b\x02"	"TU\0"
   1769 	    "b\x01"	"TS\0"
   1770 	    "b\x00"	"TI\0"
   1771 	    "\0", dma_status);
   1772 	aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n",
   1773 	    status, buf);
   1774 }
   1775 
   1776 static void
   1777 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg)
   1778 {
   1779 	dwc_dump_status(sc);
   1780 	dwc_gmac_dump_ffilt(sc,
   1781 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT));
   1782 	dwc_gmac_dump_dma(sc);
   1783 	dwc_gmac_dump_tx_desc(sc);
   1784 	dwc_gmac_dump_rx_desc(sc);
   1785 
   1786 	panic("%s", msg);
   1787 }
   1788 
   1789 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt)
   1790 {
   1791 	char buf[200];
   1792 
   1793 	/* print filter setup */
   1794 	snprintb(buf, sizeof(buf), "\177\20"
   1795 	    "b\x1f""RA\0"
   1796 	    "b\x0a""HPF\0"
   1797 	    "b\x09""SAF\0"
   1798 	    "b\x08""SAIF\0"
   1799 	    "b\x05""DBF\0"
   1800 	    "b\x04""PM\0"
   1801 	    "b\x03""DAIF\0"
   1802 	    "b\x02""HMC\0"
   1803 	    "b\x01""HUC\0"
   1804 	    "b\x00""PR\0"
   1805 	    "\0", ffilt);
   1806 	aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf);
   1807 }
   1808 #endif
   1809