Home | History | Annotate | Line # | Download | only in ic
dwc_gmac.c revision 1.45
      1 /* $NetBSD: dwc_gmac.c,v 1.45 2017/12/21 12:09:43 martin 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 #include <sys/cdefs.h>
     43 
     44 __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.45 2017/12/21 12:09:43 martin Exp $");
     45 
     46 /* #define	DWC_GMAC_DEBUG	1 */
     47 
     48 #ifdef _KERNEL_OPT
     49 #include "opt_inet.h"
     50 #include "opt_net_mpsafe.h"
     51 #endif
     52 
     53 #include <sys/param.h>
     54 #include <sys/bus.h>
     55 #include <sys/device.h>
     56 #include <sys/intr.h>
     57 #include <sys/systm.h>
     58 #include <sys/sockio.h>
     59 #include <sys/cprng.h>
     60 
     61 #include <net/if.h>
     62 #include <net/if_ether.h>
     63 #include <net/if_media.h>
     64 #include <net/bpf.h>
     65 #ifdef INET
     66 #include <netinet/if_inarp.h>
     67 #endif
     68 
     69 #include <dev/mii/miivar.h>
     70 
     71 #include <dev/ic/dwc_gmac_reg.h>
     72 #include <dev/ic/dwc_gmac_var.h>
     73 
     74 static int dwc_gmac_miibus_read_reg(device_t, int, int);
     75 static void dwc_gmac_miibus_write_reg(device_t, int, int, int);
     76 static void dwc_gmac_miibus_statchg(struct ifnet *);
     77 
     78 static int dwc_gmac_reset(struct dwc_gmac_softc *sc);
     79 static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc,
     80 			 uint8_t enaddr[ETHER_ADDR_LEN]);
     81 static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc);
     82 static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc);
     83 static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
     84 static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
     85 static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *);
     86 static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
     87 static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
     88 static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
     89 static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops);
     90 static int dwc_gmac_init(struct ifnet *ifp);
     91 static int dwc_gmac_init_locked(struct ifnet *ifp);
     92 static void dwc_gmac_stop(struct ifnet *ifp, int disable);
     93 static void dwc_gmac_stop_locked(struct ifnet *ifp, int disable);
     94 static void dwc_gmac_start(struct ifnet *ifp);
     95 static void dwc_gmac_start_locked(struct ifnet *ifp);
     96 static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0);
     97 static int dwc_gmac_ioctl(struct ifnet *, u_long, void *);
     98 static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc);
     99 static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc);
    100 static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc);
    101 static int dwc_gmac_ifflags_cb(struct ethercom *);
    102 static uint32_t	bitrev32(uint32_t x);
    103 
    104 #define	TX_DESC_OFFSET(N)	((AWGE_RX_RING_COUNT+(N)) \
    105 				    *sizeof(struct dwc_gmac_dev_dmadesc))
    106 #define	TX_NEXT(N)		(((N)+1) & (AWGE_TX_RING_COUNT-1))
    107 
    108 #define RX_DESC_OFFSET(N)	((N)*sizeof(struct dwc_gmac_dev_dmadesc))
    109 #define	RX_NEXT(N)		(((N)+1) & (AWGE_RX_RING_COUNT-1))
    110 
    111 
    112 
    113 #define	GMAC_DEF_DMA_INT_MASK	(GMAC_DMA_INT_TIE|GMAC_DMA_INT_RIE| \
    114 				GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE| \
    115 				GMAC_DMA_INT_FBE|GMAC_DMA_INT_UNE)
    116 
    117 #define	GMAC_DMA_INT_ERRORS	(GMAC_DMA_INT_AIE|GMAC_DMA_INT_ERE| \
    118 				GMAC_DMA_INT_FBE|	\
    119 				GMAC_DMA_INT_RWE|GMAC_DMA_INT_RUE| \
    120 				GMAC_DMA_INT_UNE|GMAC_DMA_INT_OVE| \
    121 				GMAC_DMA_INT_TJE)
    122 
    123 #define	AWIN_DEF_MAC_INTRMASK	\
    124 	(AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG |	\
    125 	AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII)
    126 
    127 
    128 #ifdef DWC_GMAC_DEBUG
    129 static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc);
    130 static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc);
    131 static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc);
    132 static void dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg);
    133 static void dwc_dump_status(struct dwc_gmac_softc *sc);
    134 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt);
    135 #endif
    136 
    137 #ifdef NET_MPSAFE
    138 #define DWCGMAC_MPSAFE	1
    139 #endif
    140 
    141 void
    142 dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk)
    143 {
    144 	uint8_t enaddr[ETHER_ADDR_LEN];
    145 	uint32_t maclo, machi;
    146 	struct mii_data * const mii = &sc->sc_mii;
    147 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
    148 	prop_dictionary_t dict;
    149 	int rv;
    150 
    151 	mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET);
    152 	sc->sc_mii_clk = mii_clk & 7;
    153 
    154 	dict = device_properties(sc->sc_dev);
    155 	prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL;
    156 	if (ea != NULL) {
    157 		/*
    158 		 * If the MAC address is overriden by a device property,
    159 		 * use that.
    160 		 */
    161 		KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
    162 		KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
    163 		memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN);
    164 	} else {
    165 		/*
    166 		 * If we did not get an externaly configure address,
    167 		 * try to read one from the current filter setup,
    168 		 * before resetting the chip.
    169 		 */
    170 		maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    171 		    AWIN_GMAC_MAC_ADDR0LO);
    172 		machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    173 		    AWIN_GMAC_MAC_ADDR0HI);
    174 
    175 		if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) {
    176 			/* fake MAC address */
    177 			maclo = 0x00f2 | (cprng_strong32() << 16);
    178 			machi = cprng_strong32();
    179 		}
    180 
    181 		enaddr[0] = maclo & 0x0ff;
    182 		enaddr[1] = (maclo >> 8) & 0x0ff;
    183 		enaddr[2] = (maclo >> 16) & 0x0ff;
    184 		enaddr[3] = (maclo >> 24) & 0x0ff;
    185 		enaddr[4] = machi & 0x0ff;
    186 		enaddr[5] = (machi >> 8) & 0x0ff;
    187 	}
    188 
    189 	/*
    190 	 * Init chip and do initial setup
    191 	 */
    192 	if (dwc_gmac_reset(sc) != 0)
    193 		return;	/* not much to cleanup, haven't attached yet */
    194 	dwc_gmac_write_hwaddr(sc, enaddr);
    195 	aprint_normal_dev(sc->sc_dev, "Ethernet address: %s\n",
    196 	    ether_sprintf(enaddr));
    197 
    198 	/*
    199 	 * Allocate Tx and Rx rings
    200 	 */
    201 	if (dwc_gmac_alloc_dma_rings(sc) != 0) {
    202 		aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n");
    203 		goto fail;
    204 	}
    205 
    206 	if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) {
    207 		aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n");
    208 		goto fail;
    209 	}
    210 
    211 	if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) {
    212 		aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n");
    213 		goto fail;
    214 	}
    215 
    216 	sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
    217 	mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET);
    218 	mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
    219 
    220 	/*
    221 	 * Prepare interface data
    222 	 */
    223 	ifp->if_softc = sc;
    224 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    225 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    226 #ifdef DWCGMAC_MPSAFE
    227 	ifp->if_extflags = IFEF_MPSAFE;
    228 #endif
    229 	ifp->if_ioctl = dwc_gmac_ioctl;
    230 	ifp->if_start = dwc_gmac_start;
    231 	ifp->if_init = dwc_gmac_init;
    232 	ifp->if_stop = dwc_gmac_stop;
    233 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    234 	IFQ_SET_READY(&ifp->if_snd);
    235 
    236 	/*
    237 	 * Attach MII subdevices
    238 	 */
    239 	sc->sc_ec.ec_mii = &sc->sc_mii;
    240 	ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
    241         mii->mii_ifp = ifp;
    242         mii->mii_readreg = dwc_gmac_miibus_read_reg;
    243         mii->mii_writereg = dwc_gmac_miibus_write_reg;
    244         mii->mii_statchg = dwc_gmac_miibus_statchg;
    245         mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
    246 	    MIIF_DOPAUSE);
    247 
    248         if (LIST_EMPTY(&mii->mii_phys)) {
    249                 aprint_error_dev(sc->sc_dev, "no PHY found!\n");
    250                 ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
    251                 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL);
    252         } else {
    253                 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);
    254         }
    255 
    256 	/*
    257 	 * We can support 802.1Q VLAN-sized frames.
    258 	 */
    259 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
    260 
    261 	/*
    262 	 * Ready, attach interface
    263 	 */
    264 	/* Attach the interface. */
    265 	rv = if_initialize(ifp);
    266 	if (rv != 0)
    267 		goto fail_2;
    268 	sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
    269 	if_deferred_start_init(ifp, NULL);
    270 	ether_ifattach(ifp, enaddr);
    271 	ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb);
    272 	if_register(ifp);
    273 
    274 	/*
    275 	 * Enable interrupts
    276 	 */
    277 	mutex_enter(sc->sc_lock);
    278 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK,
    279 	    AWIN_DEF_MAC_INTRMASK);
    280 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE,
    281 	    GMAC_DEF_DMA_INT_MASK);
    282 	mutex_exit(sc->sc_lock);
    283 
    284 	return;
    285 fail_2:
    286 	ifmedia_removeall(&mii->mii_media);
    287 	mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY);
    288 	mutex_destroy(&sc->sc_txq.t_mtx);
    289 	mutex_destroy(&sc->sc_rxq.r_mtx);
    290 	mutex_obj_free(sc->sc_lock);
    291 fail:
    292 	dwc_gmac_free_rx_ring(sc, &sc->sc_rxq);
    293 	dwc_gmac_free_tx_ring(sc, &sc->sc_txq);
    294 	dwc_gmac_free_dma_rings(sc);
    295 	mutex_destroy(&sc->sc_mdio_lock);
    296 }
    297 
    298 
    299 
    300 static int
    301 dwc_gmac_reset(struct dwc_gmac_softc *sc)
    302 {
    303 	size_t cnt;
    304 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
    305 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) | GMAC_BUSMODE_RESET);
    306 	for (cnt = 0; cnt < 3000; cnt++) {
    307 		if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)
    308 		    & GMAC_BUSMODE_RESET) == 0)
    309 			return 0;
    310 		delay(10);
    311 	}
    312 
    313 	aprint_error_dev(sc->sc_dev, "reset timed out\n");
    314 	return EIO;
    315 }
    316 
    317 static void
    318 dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc,
    319     uint8_t enaddr[ETHER_ADDR_LEN])
    320 {
    321 	uint32_t lo, hi;
    322 
    323 	lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16)
    324 	    | (enaddr[3] << 24);
    325 	hi = enaddr[4] | (enaddr[5] << 8);
    326 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo);
    327 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi);
    328 }
    329 
    330 static int
    331 dwc_gmac_miibus_read_reg(device_t self, int phy, int reg)
    332 {
    333 	struct dwc_gmac_softc * const sc = device_private(self);
    334 	uint16_t mii;
    335 	size_t cnt;
    336 	int rv = 0;
    337 
    338 	mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK)
    339 	    | __SHIFTIN(reg,GMAC_MII_REG_MASK)
    340 	    | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK)
    341 	    | GMAC_MII_BUSY;
    342 
    343 	mutex_enter(&sc->sc_mdio_lock);
    344 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
    345 
    346 	for (cnt = 0; cnt < 1000; cnt++) {
    347 		if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    348 		    AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) {
    349 			rv = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    350 			    AWIN_GMAC_MAC_MIIDATA);
    351 			break;
    352 		}
    353 		delay(10);
    354 	}
    355 
    356 	mutex_exit(&sc->sc_mdio_lock);
    357 
    358 	return rv;
    359 }
    360 
    361 static void
    362 dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, int val)
    363 {
    364 	struct dwc_gmac_softc * const sc = device_private(self);
    365 	uint16_t mii;
    366 	size_t cnt;
    367 
    368 	mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK)
    369 	    | __SHIFTIN(reg,GMAC_MII_REG_MASK)
    370 	    | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK)
    371 	    | GMAC_MII_BUSY | GMAC_MII_WRITE;
    372 
    373 	mutex_enter(&sc->sc_mdio_lock);
    374 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val);
    375 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii);
    376 
    377 	for (cnt = 0; cnt < 1000; cnt++) {
    378 		if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    379 		    AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY))
    380 			break;
    381 		delay(10);
    382 	}
    383 
    384 	mutex_exit(&sc->sc_mdio_lock);
    385 }
    386 
    387 static int
    388 dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc,
    389 	struct dwc_gmac_rx_ring *ring)
    390 {
    391 	struct dwc_gmac_rx_data *data;
    392 	bus_addr_t physaddr;
    393 	const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc);
    394 	int error, i, next;
    395 
    396 	ring->r_cur = ring->r_next = 0;
    397 	memset(ring->r_desc, 0, descsize);
    398 
    399 	/*
    400 	 * Pre-allocate Rx buffers and populate Rx ring.
    401 	 */
    402 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    403 		struct dwc_gmac_dev_dmadesc *desc;
    404 
    405 		data = &sc->sc_rxq.r_data[i];
    406 
    407 		MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA);
    408 		if (data->rd_m == NULL) {
    409 			aprint_error_dev(sc->sc_dev,
    410 			    "could not allocate rx mbuf #%d\n", i);
    411 			error = ENOMEM;
    412 			goto fail;
    413 		}
    414 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
    415 		    MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map);
    416 		if (error != 0) {
    417 			aprint_error_dev(sc->sc_dev,
    418 			    "could not create DMA map\n");
    419 			data->rd_map = NULL;
    420 			goto fail;
    421 		}
    422 		MCLGET(data->rd_m, M_DONTWAIT);
    423 		if (!(data->rd_m->m_flags & M_EXT)) {
    424 			aprint_error_dev(sc->sc_dev,
    425 			    "could not allocate mbuf cluster #%d\n", i);
    426 			error = ENOMEM;
    427 			goto fail;
    428 		}
    429 
    430 		error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
    431 		    mtod(data->rd_m, void *), MCLBYTES, NULL,
    432 		    BUS_DMA_READ | BUS_DMA_NOWAIT);
    433 		if (error != 0) {
    434 			aprint_error_dev(sc->sc_dev,
    435 			    "could not load rx buf DMA map #%d", i);
    436 			goto fail;
    437 		}
    438 		physaddr = data->rd_map->dm_segs[0].ds_addr;
    439 
    440 		desc = &sc->sc_rxq.r_desc[i];
    441 		desc->ddesc_data = htole32(physaddr);
    442 		next = RX_NEXT(i);
    443 		desc->ddesc_next = htole32(ring->r_physaddr
    444 		    + next * sizeof(*desc));
    445 		desc->ddesc_cntl = htole32(
    446 		    __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
    447 		    DDESC_CNTL_RXCHAIN);
    448 		desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
    449 	}
    450 
    451 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
    452 	    AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
    453 	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
    454 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    455 	    ring->r_physaddr);
    456 
    457 	return 0;
    458 
    459 fail:
    460 	dwc_gmac_free_rx_ring(sc, ring);
    461 	return error;
    462 }
    463 
    464 static void
    465 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc,
    466 	struct dwc_gmac_rx_ring *ring)
    467 {
    468 	struct dwc_gmac_dev_dmadesc *desc;
    469 	int i;
    470 
    471 	mutex_enter(&ring->r_mtx);
    472 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    473 		desc = &sc->sc_rxq.r_desc[i];
    474 		desc->ddesc_cntl = htole32(
    475 		    __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
    476 		    DDESC_CNTL_RXCHAIN);
    477 		desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
    478 	}
    479 
    480 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
    481 	    AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
    482 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    483 
    484 	ring->r_cur = ring->r_next = 0;
    485 	/* reset DMA address to start of ring */
    486 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    487 	    sc->sc_rxq.r_physaddr);
    488 	mutex_exit(&ring->r_mtx);
    489 }
    490 
    491 static int
    492 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc)
    493 {
    494 	const size_t descsize = AWGE_TOTAL_RING_COUNT *
    495 		sizeof(struct dwc_gmac_dev_dmadesc);
    496 	int error, nsegs;
    497 	void *rings;
    498 
    499 	error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0,
    500 	    BUS_DMA_NOWAIT, &sc->sc_dma_ring_map);
    501 	if (error != 0) {
    502 		aprint_error_dev(sc->sc_dev,
    503 		    "could not create desc DMA map\n");
    504 		sc->sc_dma_ring_map = NULL;
    505 		goto fail;
    506 	}
    507 
    508 	error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0,
    509 	    &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
    510 	if (error != 0) {
    511 		aprint_error_dev(sc->sc_dev,
    512 		    "could not map DMA memory\n");
    513 		goto fail;
    514 	}
    515 
    516 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs,
    517 	    descsize, &rings, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
    518 	if (error != 0) {
    519 		aprint_error_dev(sc->sc_dev,
    520 		    "could not allocate DMA memory\n");
    521 		goto fail;
    522 	}
    523 
    524 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings,
    525 	    descsize, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
    526 	if (error != 0) {
    527 		aprint_error_dev(sc->sc_dev,
    528 		    "could not load desc DMA map\n");
    529 		goto fail;
    530 	}
    531 
    532 	/* give first AWGE_RX_RING_COUNT to the RX side */
    533 	sc->sc_rxq.r_desc = rings;
    534 	sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr;
    535 
    536 	/* and next rings to the TX side */
    537 	sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT;
    538 	sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr +
    539 	    AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc);
    540 
    541 	return 0;
    542 
    543 fail:
    544 	dwc_gmac_free_dma_rings(sc);
    545 	return error;
    546 }
    547 
    548 static void
    549 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc)
    550 {
    551 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
    552 	    sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    553 	bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map);
    554 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc,
    555 	    AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc));
    556 	bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1);
    557 }
    558 
    559 static void
    560 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring)
    561 {
    562 	struct dwc_gmac_rx_data *data;
    563 	int i;
    564 
    565 	if (ring->r_desc == NULL)
    566 		return;
    567 
    568 
    569 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
    570 		data = &ring->r_data[i];
    571 
    572 		if (data->rd_map != NULL) {
    573 			bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
    574 			    AWGE_RX_RING_COUNT
    575 				*sizeof(struct dwc_gmac_dev_dmadesc),
    576 			    BUS_DMASYNC_POSTREAD);
    577 			bus_dmamap_unload(sc->sc_dmat, data->rd_map);
    578 			bus_dmamap_destroy(sc->sc_dmat, data->rd_map);
    579 		}
    580 		if (data->rd_m != NULL)
    581 			m_freem(data->rd_m);
    582 	}
    583 }
    584 
    585 static int
    586 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc,
    587 	struct dwc_gmac_tx_ring *ring)
    588 {
    589 	int i, error = 0;
    590 
    591 	ring->t_queued = 0;
    592 	ring->t_cur = ring->t_next = 0;
    593 
    594 	memset(ring->t_desc, 0, AWGE_TX_RING_COUNT*sizeof(*ring->t_desc));
    595 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    596 	    TX_DESC_OFFSET(0),
    597 	    AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
    598 	    BUS_DMASYNC_POSTWRITE);
    599 
    600 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    601 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    602 		    AWGE_TX_RING_COUNT, MCLBYTES, 0,
    603 		    BUS_DMA_NOWAIT|BUS_DMA_COHERENT,
    604 		    &ring->t_data[i].td_map);
    605 		if (error != 0) {
    606 			aprint_error_dev(sc->sc_dev,
    607 			    "could not create TX DMA map #%d\n", i);
    608 			ring->t_data[i].td_map = NULL;
    609 			goto fail;
    610 		}
    611 		ring->t_desc[i].ddesc_next = htole32(
    612 		    ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc)
    613 		    *TX_NEXT(i));
    614 	}
    615 
    616 	return 0;
    617 
    618 fail:
    619 	dwc_gmac_free_tx_ring(sc, ring);
    620 	return error;
    621 }
    622 
    623 static void
    624 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops)
    625 {
    626 	/* 'end' is pointing one descriptor beyound the last we want to sync */
    627 	if (end > start) {
    628 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    629 		    TX_DESC_OFFSET(start),
    630 		    TX_DESC_OFFSET(end)-TX_DESC_OFFSET(start),
    631 		    ops);
    632 		return;
    633 	}
    634 	/* sync from 'start' to end of ring */
    635 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    636 	    TX_DESC_OFFSET(start),
    637 	    TX_DESC_OFFSET(AWGE_TX_RING_COUNT)-TX_DESC_OFFSET(start),
    638 	    ops);
    639 	/* sync from start of ring to 'end' */
    640 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    641 	    TX_DESC_OFFSET(0),
    642 	    TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0),
    643 	    ops);
    644 }
    645 
    646 static void
    647 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc,
    648 	struct dwc_gmac_tx_ring *ring)
    649 {
    650 	int i;
    651 
    652 	mutex_enter(&ring->t_mtx);
    653 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    654 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    655 
    656 		if (data->td_m != NULL) {
    657 			bus_dmamap_sync(sc->sc_dmat, data->td_active,
    658 			    0, data->td_active->dm_mapsize,
    659 			    BUS_DMASYNC_POSTWRITE);
    660 			bus_dmamap_unload(sc->sc_dmat, data->td_active);
    661 			m_freem(data->td_m);
    662 			data->td_m = NULL;
    663 		}
    664 	}
    665 
    666 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
    667 	    TX_DESC_OFFSET(0),
    668 	    AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc),
    669 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    670 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
    671 	    sc->sc_txq.t_physaddr);
    672 
    673 	ring->t_queued = 0;
    674 	ring->t_cur = ring->t_next = 0;
    675 	mutex_exit(&ring->t_mtx);
    676 }
    677 
    678 static void
    679 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc,
    680 	struct dwc_gmac_tx_ring *ring)
    681 {
    682 	int i;
    683 
    684 	/* unload the maps */
    685 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    686 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    687 
    688 		if (data->td_m != NULL) {
    689 			bus_dmamap_sync(sc->sc_dmat, data->td_active,
    690 			    0, data->td_map->dm_mapsize,
    691 			    BUS_DMASYNC_POSTWRITE);
    692 			bus_dmamap_unload(sc->sc_dmat, data->td_active);
    693 			m_freem(data->td_m);
    694 			data->td_m = NULL;
    695 		}
    696 	}
    697 
    698 	/* and actually free them */
    699 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
    700 		struct dwc_gmac_tx_data *data = &ring->t_data[i];
    701 
    702 		bus_dmamap_destroy(sc->sc_dmat, data->td_map);
    703 	}
    704 }
    705 
    706 static void
    707 dwc_gmac_miibus_statchg(struct ifnet *ifp)
    708 {
    709 	struct dwc_gmac_softc * const sc = ifp->if_softc;
    710 	struct mii_data * const mii = &sc->sc_mii;
    711 	uint32_t conf, flow;
    712 
    713 	/*
    714 	 * Set MII or GMII interface based on the speed
    715 	 * negotiated by the PHY.
    716 	 */
    717 	conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF);
    718 	conf &= ~(AWIN_GMAC_MAC_CONF_FES100|AWIN_GMAC_MAC_CONF_MIISEL
    719 	    |AWIN_GMAC_MAC_CONF_FULLDPLX);
    720 	conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST
    721 	    | AWIN_GMAC_MAC_CONF_DISABLERXOWN
    722 	    | AWIN_GMAC_MAC_CONF_DISABLEJABBER
    723 	    | AWIN_GMAC_MAC_CONF_ACS
    724 	    | AWIN_GMAC_MAC_CONF_RXENABLE
    725 	    | AWIN_GMAC_MAC_CONF_TXENABLE;
    726 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
    727 	case IFM_10_T:
    728 		conf |= AWIN_GMAC_MAC_CONF_MIISEL;
    729 		break;
    730 	case IFM_100_TX:
    731 		conf |= AWIN_GMAC_MAC_CONF_FES100 |
    732 			AWIN_GMAC_MAC_CONF_MIISEL;
    733 		break;
    734 	case IFM_1000_T:
    735 		break;
    736 	}
    737 
    738 	flow = 0;
    739 	if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
    740 		conf |= AWIN_GMAC_MAC_CONF_FULLDPLX;
    741 		flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE);
    742 	}
    743 	if (mii->mii_media_active & IFM_ETH_TXPAUSE) {
    744 		flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE;
    745 	}
    746 	if (mii->mii_media_active & IFM_ETH_RXPAUSE) {
    747 		flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE;
    748 	}
    749 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    750 	    AWIN_GMAC_MAC_FLOWCTRL, flow);
    751 
    752 #ifdef DWC_GMAC_DEBUG
    753 	aprint_normal_dev(sc->sc_dev,
    754 	    "setting MAC conf register: %08x\n", conf);
    755 #endif
    756 
    757 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    758 	    AWIN_GMAC_MAC_CONF, conf);
    759 }
    760 
    761 static int
    762 dwc_gmac_init(struct ifnet *ifp)
    763 {
    764 	struct dwc_gmac_softc *sc = ifp->if_softc;
    765 
    766 	mutex_enter(sc->sc_lock);
    767 	int ret = dwc_gmac_init_locked(ifp);
    768 	mutex_exit(sc->sc_lock);
    769 
    770 	return ret;
    771 }
    772 
    773 static int
    774 dwc_gmac_init_locked(struct ifnet *ifp)
    775 {
    776 	struct dwc_gmac_softc *sc = ifp->if_softc;
    777 	uint32_t ffilt;
    778 
    779 	if (ifp->if_flags & IFF_RUNNING)
    780 		return 0;
    781 
    782 	dwc_gmac_stop_locked(ifp, 0);
    783 
    784 	/*
    785 	 * Configure DMA burst/transfer mode and RX/TX priorities.
    786 	 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented.
    787 	 */
    788 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE,
    789 	    GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL |
    790 	    __SHIFTIN(2, GMAC_BUSMODE_RPBL) |
    791 	    __SHIFTIN(2, GMAC_BUSMODE_PBL));
    792 
    793 	/*
    794 	 * Set up address filter
    795 	 */
    796 	ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
    797 	if (ifp->if_flags & IFF_PROMISC) {
    798 		ffilt |= AWIN_GMAC_MAC_FFILT_PR;
    799 	} else {
    800 		ffilt &= ~AWIN_GMAC_MAC_FFILT_PR;
    801 	}
    802 	if (ifp->if_flags & IFF_BROADCAST) {
    803 		ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF;
    804 	} else {
    805 		ffilt |= AWIN_GMAC_MAC_FFILT_DBF;
    806 	}
    807 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
    808 
    809 	/*
    810 	 * Set up multicast filter
    811 	 */
    812 	dwc_gmac_setmulti(sc);
    813 
    814 	/*
    815 	 * Set up dma pointer for RX and TX ring
    816 	 */
    817 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
    818 	    sc->sc_rxq.r_physaddr);
    819 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR,
    820 	    sc->sc_txq.t_physaddr);
    821 
    822 	/*
    823 	 * Start RX/TX part
    824 	 */
    825 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    826 	    AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART |
    827 	    GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD);
    828 
    829 	sc->sc_stopping = false;
    830 
    831 	ifp->if_flags |= IFF_RUNNING;
    832 	ifp->if_flags &= ~IFF_OACTIVE;
    833 
    834 	return 0;
    835 }
    836 
    837 static void
    838 dwc_gmac_start(struct ifnet *ifp)
    839 {
    840 	struct dwc_gmac_softc *sc = ifp->if_softc;
    841 #ifdef DWCGMAC_MPSAFE
    842 	KASSERT(if_is_mpsafe(ifp));
    843 #endif
    844 
    845 	mutex_enter(sc->sc_lock);
    846 	if (!sc->sc_stopping) {
    847 		mutex_enter(&sc->sc_txq.t_mtx);
    848 		dwc_gmac_start_locked(ifp);
    849 		mutex_exit(&sc->sc_txq.t_mtx);
    850 	}
    851 	mutex_exit(sc->sc_lock);
    852 }
    853 
    854 static void
    855 dwc_gmac_start_locked(struct ifnet *ifp)
    856 {
    857 	struct dwc_gmac_softc *sc = ifp->if_softc;
    858 	int old = sc->sc_txq.t_queued;
    859 	int start = sc->sc_txq.t_cur;
    860 	struct mbuf *m0;
    861 
    862 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
    863 		return;
    864 
    865 	for (;;) {
    866 		IFQ_POLL(&ifp->if_snd, m0);
    867 		if (m0 == NULL)
    868 			break;
    869 		if (dwc_gmac_queue(sc, m0) != 0) {
    870 			ifp->if_flags |= IFF_OACTIVE;
    871 			break;
    872 		}
    873 		IFQ_DEQUEUE(&ifp->if_snd, m0);
    874 		bpf_mtap(ifp, m0);
    875 		if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) {
    876 			ifp->if_flags |= IFF_OACTIVE;
    877 			break;
    878 		}
    879 	}
    880 
    881 	if (sc->sc_txq.t_queued != old) {
    882 		/* packets have been queued, kick it off */
    883 		dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
    884 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    885 
    886 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    887 		    AWIN_GMAC_DMA_TXPOLL, ~0U);
    888 #ifdef DWC_GMAC_DEBUG
    889 		dwc_dump_status(sc);
    890 #endif
    891 	}
    892 }
    893 
    894 static void
    895 dwc_gmac_stop(struct ifnet *ifp, int disable)
    896 {
    897 	struct dwc_gmac_softc *sc = ifp->if_softc;
    898 
    899 	mutex_enter(sc->sc_lock);
    900 	dwc_gmac_stop_locked(ifp, disable);
    901 	mutex_exit(sc->sc_lock);
    902 }
    903 
    904 static void
    905 dwc_gmac_stop_locked(struct ifnet *ifp, int disable)
    906 {
    907 	struct dwc_gmac_softc *sc = ifp->if_softc;
    908 
    909 	sc->sc_stopping = true;
    910 
    911 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    912 	    AWIN_GMAC_DMA_OPMODE,
    913 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    914 	        AWIN_GMAC_DMA_OPMODE)
    915 		& ~(GMAC_DMA_OP_TXSTART|GMAC_DMA_OP_RXSTART));
    916 	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
    917 	    AWIN_GMAC_DMA_OPMODE,
    918 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    919 	        AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX);
    920 
    921 	mii_down(&sc->sc_mii);
    922 	dwc_gmac_reset_tx_ring(sc, &sc->sc_txq);
    923 	dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq);
    924 }
    925 
    926 /*
    927  * Add m0 to the TX ring
    928  */
    929 static int
    930 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
    931 {
    932 	struct dwc_gmac_dev_dmadesc *desc = NULL;
    933 	struct dwc_gmac_tx_data *data = NULL;
    934 	bus_dmamap_t map;
    935 	uint32_t flags, len, status;
    936 	int error, i, first;
    937 
    938 #ifdef DWC_GMAC_DEBUG
    939 	aprint_normal_dev(sc->sc_dev,
    940 	    "dwc_gmac_queue: adding mbuf chain %p\n", m0);
    941 #endif
    942 
    943 	first = sc->sc_txq.t_cur;
    944 	map = sc->sc_txq.t_data[first].td_map;
    945 
    946 	error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0,
    947 	    BUS_DMA_WRITE|BUS_DMA_NOWAIT);
    948 	if (error != 0) {
    949 		aprint_error_dev(sc->sc_dev, "could not map mbuf "
    950 		    "(len: %d, error %d)\n", m0->m_pkthdr.len, error);
    951 		return error;
    952 	}
    953 
    954 	if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) {
    955 		bus_dmamap_unload(sc->sc_dmat, map);
    956 		return ENOBUFS;
    957 	}
    958 
    959 	flags = DDESC_CNTL_TXFIRST|DDESC_CNTL_TXCHAIN;
    960 	status = 0;
    961 	for (i = 0; i < map->dm_nsegs; i++) {
    962 		data = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
    963 		desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
    964 
    965 		desc->ddesc_data = htole32(map->dm_segs[i].ds_addr);
    966 		len = __SHIFTIN(map->dm_segs[i].ds_len, DDESC_CNTL_SIZE1MASK);
    967 
    968 #ifdef DWC_GMAC_DEBUG
    969 		aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx "
    970 		    "len %lu (flags: %08x, len: %08x)\n", sc->sc_txq.t_cur,
    971 		    (unsigned long)map->dm_segs[i].ds_addr,
    972 		    (unsigned long)map->dm_segs[i].ds_len,
    973 		    flags, len);
    974 #endif
    975 
    976 		desc->ddesc_cntl = htole32(len|flags);
    977 		flags &= ~DDESC_CNTL_TXFIRST;
    978 
    979 		/*
    980 		 * Defer passing ownership of the first descriptor
    981 		 * until we are done.
    982 		 */
    983 		desc->ddesc_status = htole32(status);
    984 		status |= DDESC_STATUS_OWNEDBYDEV;
    985 
    986 		sc->sc_txq.t_queued++;
    987 		sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur);
    988 	}
    989 
    990 	desc->ddesc_cntl |= htole32(DDESC_CNTL_TXLAST|DDESC_CNTL_TXINT);
    991 
    992 	data->td_m = m0;
    993 	data->td_active = map;
    994 
    995 	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
    996 	    BUS_DMASYNC_PREWRITE);
    997 
    998 	/* Pass first to device */
    999 	sc->sc_txq.t_desc[first].ddesc_status =
   1000 	    htole32(DDESC_STATUS_OWNEDBYDEV);
   1001 
   1002 	return 0;
   1003 }
   1004 
   1005 /*
   1006  * If the interface is up and running, only modify the receive
   1007  * filter when setting promiscuous or debug mode.  Otherwise fall
   1008  * through to ether_ioctl, which will reset the chip.
   1009  */
   1010 static int
   1011 dwc_gmac_ifflags_cb(struct ethercom *ec)
   1012 {
   1013 	struct ifnet *ifp = &ec->ec_if;
   1014 	struct dwc_gmac_softc *sc = ifp->if_softc;
   1015 	int ret = 0;
   1016 
   1017 	mutex_enter(sc->sc_lock);
   1018 	int change = ifp->if_flags ^ sc->sc_if_flags;
   1019 	sc->sc_if_flags = ifp->if_flags;
   1020 
   1021 	if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0) {
   1022 		ret = ENETRESET;
   1023 		goto out;
   1024 	}
   1025 	if ((change & IFF_PROMISC) != 0) {
   1026 		dwc_gmac_setmulti(sc);
   1027 	}
   1028 out:
   1029 	mutex_exit(sc->sc_lock);
   1030 
   1031 	return ret;
   1032 }
   1033 
   1034 static int
   1035 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1036 {
   1037 	struct dwc_gmac_softc *sc = ifp->if_softc;
   1038 	int error = 0;
   1039 
   1040 	int s = splnet();
   1041 	error = ether_ioctl(ifp, cmd, data);
   1042 
   1043 #ifdef DWCGMAC_MPSAFE
   1044 	splx(s);
   1045 #endif
   1046 
   1047 	if (error == ENETRESET) {
   1048 		error = 0;
   1049 		if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
   1050 			;
   1051 		else if (ifp->if_flags & IFF_RUNNING) {
   1052 			/*
   1053 			 * Multicast list has changed; set the hardware filter
   1054 			 * accordingly.
   1055 			 */
   1056 			mutex_enter(sc->sc_lock);
   1057 			dwc_gmac_setmulti(sc);
   1058 			mutex_exit(sc->sc_lock);
   1059 		}
   1060 	}
   1061 
   1062 	/* Try to get things going again */
   1063 	if (ifp->if_flags & IFF_UP)
   1064 		dwc_gmac_start(ifp);
   1065 	sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
   1066 
   1067 #ifndef DWCGMAC_MPSAFE
   1068 	splx(s);
   1069 #endif
   1070 
   1071 	return error;
   1072 }
   1073 
   1074 static void
   1075 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
   1076 {
   1077 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1078 	struct dwc_gmac_tx_data *data;
   1079 	struct dwc_gmac_dev_dmadesc *desc;
   1080 	uint32_t status;
   1081 	int i, nsegs;
   1082 
   1083 	mutex_enter(&sc->sc_txq.t_mtx);
   1084 
   1085 	for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) {
   1086 #ifdef DWC_GMAC_DEBUG
   1087 		aprint_normal_dev(sc->sc_dev,
   1088 		    "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n",
   1089 		    i, sc->sc_txq.t_queued);
   1090 #endif
   1091 
   1092 		/*
   1093 		 * i+1 does not need to be a valid descriptor,
   1094 		 * this is just a special notion to just sync
   1095 		 * a single tx descriptor (i)
   1096 		 */
   1097 		dwc_gmac_txdesc_sync(sc, i, i+1,
   1098 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1099 
   1100 		desc = &sc->sc_txq.t_desc[i];
   1101 		status = le32toh(desc->ddesc_status);
   1102 		if (status & DDESC_STATUS_OWNEDBYDEV)
   1103 			break;
   1104 
   1105 		data = &sc->sc_txq.t_data[i];
   1106 		if (data->td_m == NULL)
   1107 			continue;
   1108 
   1109 		ifp->if_opackets++;
   1110 		nsegs = data->td_active->dm_nsegs;
   1111 		bus_dmamap_sync(sc->sc_dmat, data->td_active, 0,
   1112 		    data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1113 		bus_dmamap_unload(sc->sc_dmat, data->td_active);
   1114 
   1115 #ifdef DWC_GMAC_DEBUG
   1116 		aprint_normal_dev(sc->sc_dev,
   1117 		    "dwc_gmac_tx_intr: done with packet at desc #%d, "
   1118 		    "freeing mbuf %p\n", i, data->td_m);
   1119 #endif
   1120 
   1121 		m_freem(data->td_m);
   1122 		data->td_m = NULL;
   1123 
   1124 		sc->sc_txq.t_queued -= nsegs;
   1125 	}
   1126 
   1127 	sc->sc_txq.t_next = i;
   1128 
   1129 	if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) {
   1130 		ifp->if_flags &= ~IFF_OACTIVE;
   1131 	}
   1132 	mutex_exit(&sc->sc_txq.t_mtx);
   1133 }
   1134 
   1135 static void
   1136 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
   1137 {
   1138 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1139 	struct dwc_gmac_dev_dmadesc *desc;
   1140 	struct dwc_gmac_rx_data *data;
   1141 	bus_addr_t physaddr;
   1142 	uint32_t status;
   1143 	struct mbuf *m, *mnew;
   1144 	int i, len, error;
   1145 
   1146 	mutex_enter(&sc->sc_rxq.r_mtx);
   1147 	for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) {
   1148 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1149 		    RX_DESC_OFFSET(i), sizeof(*desc),
   1150 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1151 		desc = &sc->sc_rxq.r_desc[i];
   1152 		data = &sc->sc_rxq.r_data[i];
   1153 
   1154 		status = le32toh(desc->ddesc_status);
   1155 		if (status & DDESC_STATUS_OWNEDBYDEV)
   1156 			break;
   1157 
   1158 		if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) {
   1159 #ifdef DWC_GMAC_DEBUG
   1160 			aprint_normal_dev(sc->sc_dev,
   1161 			    "RX error: descriptor status %08x, skipping\n",
   1162 			    status);
   1163 #endif
   1164 			ifp->if_ierrors++;
   1165 			goto skip;
   1166 		}
   1167 
   1168 		len = __SHIFTOUT(status, DDESC_STATUS_FRMLENMSK);
   1169 
   1170 #ifdef DWC_GMAC_DEBUG
   1171 		aprint_normal_dev(sc->sc_dev,
   1172 		    "rx int: device is done with descriptor #%d, len: %d\n",
   1173 		    i, len);
   1174 #endif
   1175 
   1176 		/*
   1177 		 * Try to get a new mbuf before passing this one
   1178 		 * up, if that fails, drop the packet and reuse
   1179 		 * the existing one.
   1180 		 */
   1181 		MGETHDR(mnew, M_DONTWAIT, MT_DATA);
   1182 		if (mnew == NULL) {
   1183 			ifp->if_ierrors++;
   1184 			goto skip;
   1185 		}
   1186 		MCLGET(mnew, M_DONTWAIT);
   1187 		if ((mnew->m_flags & M_EXT) == 0) {
   1188 			m_freem(mnew);
   1189 			ifp->if_ierrors++;
   1190 			goto skip;
   1191 		}
   1192 
   1193 		/* unload old DMA map */
   1194 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
   1195 		    data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1196 		bus_dmamap_unload(sc->sc_dmat, data->rd_map);
   1197 
   1198 		/* and reload with new mbuf */
   1199 		error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
   1200 		    mtod(mnew, void*), MCLBYTES, NULL,
   1201 		    BUS_DMA_READ | BUS_DMA_NOWAIT);
   1202 		if (error != 0) {
   1203 			m_freem(mnew);
   1204 			/* try to reload old mbuf */
   1205 			error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
   1206 			    mtod(data->rd_m, void*), MCLBYTES, NULL,
   1207 			    BUS_DMA_READ | BUS_DMA_NOWAIT);
   1208 			if (error != 0) {
   1209 				panic("%s: could not load old rx mbuf",
   1210 				    device_xname(sc->sc_dev));
   1211 			}
   1212 			ifp->if_ierrors++;
   1213 			goto skip;
   1214 		}
   1215 		physaddr = data->rd_map->dm_segs[0].ds_addr;
   1216 
   1217 		/*
   1218 		 * New mbuf loaded, update RX ring and continue
   1219 		 */
   1220 		m = data->rd_m;
   1221 		data->rd_m = mnew;
   1222 		desc->ddesc_data = htole32(physaddr);
   1223 
   1224 		/* finalize mbuf */
   1225 		m->m_pkthdr.len = m->m_len = len;
   1226 		m_set_rcvif(m, ifp);
   1227 		m->m_flags |= M_HASFCS;
   1228 
   1229 		if_percpuq_enqueue(sc->sc_ipq, m);
   1230 
   1231 skip:
   1232 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
   1233 		    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
   1234 		desc->ddesc_cntl = htole32(
   1235 		    __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
   1236 		    DDESC_CNTL_RXCHAIN);
   1237 		desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
   1238 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
   1239 		    RX_DESC_OFFSET(i), sizeof(*desc),
   1240 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1241 	}
   1242 
   1243 	/* update RX pointer */
   1244 	sc->sc_rxq.r_cur = i;
   1245 
   1246 	mutex_exit(&sc->sc_rxq.r_mtx);
   1247 }
   1248 
   1249 /*
   1250  * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal
   1251  */
   1252 static uint32_t
   1253 bitrev32(uint32_t x)
   1254 {
   1255 	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
   1256 	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
   1257 	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
   1258 	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
   1259 
   1260 	return (x >> 16) | (x << 16);
   1261 }
   1262 
   1263 static void
   1264 dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
   1265 {
   1266 	struct ifnet * const ifp = &sc->sc_ec.ec_if;
   1267 	struct ether_multi *enm;
   1268 	struct ether_multistep step;
   1269 	uint32_t hashes[2] = { 0, 0 };
   1270 	uint32_t ffilt, h;
   1271 	int mcnt;
   1272 
   1273 	KASSERT(mutex_owned(sc->sc_lock));
   1274 
   1275 	ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
   1276 
   1277 	if (ifp->if_flags & IFF_PROMISC) {
   1278 		ffilt |= AWIN_GMAC_MAC_FFILT_PR;
   1279 		goto special_filter;
   1280 	}
   1281 
   1282 	ifp->if_flags &= ~IFF_ALLMULTI;
   1283 	ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR);
   1284 
   1285 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0);
   1286 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0);
   1287 
   1288 	ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
   1289 	mcnt = 0;
   1290 	while (enm != NULL) {
   1291 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1292 		    ETHER_ADDR_LEN) != 0) {
   1293 			ffilt |= AWIN_GMAC_MAC_FFILT_PM;
   1294 			ifp->if_flags |= IFF_ALLMULTI;
   1295 			goto special_filter;
   1296 		}
   1297 
   1298 		h = bitrev32(
   1299 			~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN)
   1300 		    ) >> 26;
   1301 		hashes[h >> 5] |= (1 << (h & 0x1f));
   1302 
   1303 		mcnt++;
   1304 		ETHER_NEXT_MULTI(step, enm);
   1305 	}
   1306 
   1307 	if (mcnt)
   1308 		ffilt |= AWIN_GMAC_MAC_FFILT_HMC;
   1309 	else
   1310 		ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC;
   1311 
   1312 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
   1313 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
   1314 	    hashes[0]);
   1315 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
   1316 	    hashes[1]);
   1317 	sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
   1318 
   1319 #ifdef DWC_GMAC_DEBUG
   1320 	dwc_gmac_dump_ffilt(sc, ffilt);
   1321 #endif
   1322 	return;
   1323 
   1324 special_filter:
   1325 #ifdef DWC_GMAC_DEBUG
   1326 	dwc_gmac_dump_ffilt(sc, ffilt);
   1327 #endif
   1328 	/* no MAC hashes, ALLMULTI or PROMISC */
   1329 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT,
   1330 	    ffilt);
   1331 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
   1332 	    0xffffffff);
   1333 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
   1334 	    0xffffffff);
   1335 	sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
   1336 }
   1337 
   1338 int
   1339 dwc_gmac_intr(struct dwc_gmac_softc *sc)
   1340 {
   1341 	uint32_t status, dma_status;
   1342 	int rv = 0;
   1343 
   1344 	if (sc->sc_stopping)
   1345 		return 0;
   1346 
   1347 	status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR);
   1348 	if (status & AWIN_GMAC_MII_IRQ) {
   1349 		(void)bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1350 		    AWIN_GMAC_MII_STATUS);
   1351 		rv = 1;
   1352 		mii_pollstat(&sc->sc_mii);
   1353 	}
   1354 
   1355 	dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1356 	    AWIN_GMAC_DMA_STATUS);
   1357 
   1358 	if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE))
   1359 		rv = 1;
   1360 
   1361 	if (dma_status & GMAC_DMA_INT_TIE)
   1362 		dwc_gmac_tx_intr(sc);
   1363 
   1364 	if (dma_status & GMAC_DMA_INT_RIE)
   1365 		dwc_gmac_rx_intr(sc);
   1366 
   1367 	/*
   1368 	 * Check error conditions
   1369 	 */
   1370 	if (dma_status & GMAC_DMA_INT_ERRORS) {
   1371 		sc->sc_ec.ec_if.if_oerrors++;
   1372 #ifdef DWC_GMAC_DEBUG
   1373 		dwc_dump_and_abort(sc, "interrupt error condition");
   1374 #endif
   1375 	}
   1376 
   1377 	/* ack interrupt */
   1378 	if (dma_status)
   1379 		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
   1380 		    AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK);
   1381 
   1382 	/*
   1383 	 * Get more packets
   1384 	 */
   1385 	if (rv)
   1386 		if_schedule_deferred_start(&sc->sc_ec.ec_if);
   1387 
   1388 	return rv;
   1389 }
   1390 
   1391 #ifdef DWC_GMAC_DEBUG
   1392 static void
   1393 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc)
   1394 {
   1395 	aprint_normal_dev(sc->sc_dev, "busmode: %08x\n",
   1396 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE));
   1397 	aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n",
   1398 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL));
   1399 	aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n",
   1400 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL));
   1401 	aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n",
   1402 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR));
   1403 	aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n",
   1404 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR));
   1405 	aprint_normal_dev(sc->sc_dev, "status: %08x\n",
   1406 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS));
   1407 	aprint_normal_dev(sc->sc_dev, "op mode: %08x\n",
   1408 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE));
   1409 	aprint_normal_dev(sc->sc_dev, "int enable: %08x\n",
   1410 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE));
   1411 	aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n",
   1412 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC));
   1413 	aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n",
   1414 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC));
   1415 	aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n",
   1416 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR));
   1417 	aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n",
   1418 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR));
   1419 }
   1420 
   1421 static void
   1422 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
   1423 {
   1424 	int i;
   1425 
   1426 	aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n",
   1427 	    sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued);
   1428 	aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n");
   1429 	for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
   1430 		struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i];
   1431 		aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
   1432 		    "data: %08x next: %08x\n",
   1433 		    i, sc->sc_txq.t_physaddr +
   1434 			i*sizeof(struct dwc_gmac_dev_dmadesc),
   1435 		    le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
   1436 		    le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
   1437 	}
   1438 }
   1439 
   1440 static void
   1441 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
   1442 {
   1443 	int i;
   1444 
   1445 	aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n",
   1446 	    sc->sc_rxq.r_cur, sc->sc_rxq.r_next);
   1447 	aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n");
   1448 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
   1449 		struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i];
   1450 		aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
   1451 		    "data: %08x next: %08x\n",
   1452 		    i, sc->sc_rxq.r_physaddr +
   1453 			i*sizeof(struct dwc_gmac_dev_dmadesc),
   1454 		    le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
   1455 		    le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
   1456 	}
   1457 }
   1458 
   1459 static void
   1460 dwc_dump_status(struct dwc_gmac_softc *sc)
   1461 {
   1462 	uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1463 	     AWIN_GMAC_MAC_INTR);
   1464 	uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
   1465 	     AWIN_GMAC_DMA_STATUS);
   1466 	char buf[200];
   1467 
   1468 	/* print interrupt state */
   1469 	snprintb(buf, sizeof(buf), "\177\20"
   1470 	    "b\x10""NI\0"
   1471 	    "b\x0f""AI\0"
   1472 	    "b\x0e""ER\0"
   1473 	    "b\x0d""FB\0"
   1474 	    "b\x0a""ET\0"
   1475 	    "b\x09""RW\0"
   1476 	    "b\x08""RS\0"
   1477 	    "b\x07""RU\0"
   1478 	    "b\x06""RI\0"
   1479 	    "b\x05""UN\0"
   1480 	    "b\x04""OV\0"
   1481 	    "b\x03""TJ\0"
   1482 	    "b\x02""TU\0"
   1483 	    "b\x01""TS\0"
   1484 	    "b\x00""TI\0"
   1485 	    "\0", dma_status);
   1486 	aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n",
   1487 	    status, buf);
   1488 }
   1489 
   1490 static void
   1491 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg)
   1492 {
   1493 	dwc_dump_status(sc);
   1494 	dwc_gmac_dump_ffilt(sc,
   1495 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT));
   1496 	dwc_gmac_dump_dma(sc);
   1497 	dwc_gmac_dump_tx_desc(sc);
   1498 	dwc_gmac_dump_rx_desc(sc);
   1499 
   1500 	panic("%s", msg);
   1501 }
   1502 
   1503 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt)
   1504 {
   1505 	char buf[200];
   1506 
   1507 	/* print filter setup */
   1508 	snprintb(buf, sizeof(buf), "\177\20"
   1509 	    "b\x1f""RA\0"
   1510 	    "b\x0a""HPF\0"
   1511 	    "b\x09""SAF\0"
   1512 	    "b\x08""SAIF\0"
   1513 	    "b\x05""DBF\0"
   1514 	    "b\x04""PM\0"
   1515 	    "b\x03""DAIF\0"
   1516 	    "b\x02""HMC\0"
   1517 	    "b\x01""HUC\0"
   1518 	    "b\x00""PR\0"
   1519 	    "\0", ffilt);
   1520 	aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf);
   1521 }
   1522 #endif
   1523