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