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