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