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