dwc_gmac.c revision 1.28.2.11 1 /* $NetBSD: dwc_gmac.c,v 1.28.2.11 2017/02/05 13:40:27 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry and Martin Husemann.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * This driver supports the Synopsis Designware GMAC core, as found
34 * on Allwinner A20 cores and others.
35 *
36 * Real documentation seems to not be available, the marketing product
37 * documents could be found here:
38 *
39 * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive
40 */
41
42 #include <sys/cdefs.h>
43
44 __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.28.2.11 2017/02/05 13:40:27 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 mutex_exit(&sc->sc_rxq.r_mtx);
1215
1216 if_percpuq_enqueue(sc->sc_ipq, m);
1217
1218 mutex_enter(&sc->sc_rxq.r_mtx);
1219
1220 skip:
1221 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
1222 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
1223 desc->ddesc_cntl = htole32(
1224 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
1225 DDESC_CNTL_RXCHAIN);
1226 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
1227 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
1228 RX_DESC_OFFSET(i), sizeof(*desc),
1229 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1230 }
1231
1232 /* update RX pointer */
1233 sc->sc_rxq.r_cur = i;
1234
1235 mutex_exit(&sc->sc_rxq.r_mtx);
1236 }
1237
1238 /*
1239 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal
1240 */
1241 static uint32_t
1242 bitrev32(uint32_t x)
1243 {
1244 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
1245 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
1246 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
1247 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
1248
1249 return (x >> 16) | (x << 16);
1250 }
1251
1252 static void
1253 dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
1254 {
1255 struct ifnet * const ifp = &sc->sc_ec.ec_if;
1256 struct ether_multi *enm;
1257 struct ether_multistep step;
1258 uint32_t hashes[2] = { 0, 0 };
1259 uint32_t ffilt, h;
1260 int mcnt;
1261
1262 KASSERT(mutex_owned(sc->sc_lock));
1263
1264 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
1265
1266 if (ifp->if_flags & IFF_PROMISC) {
1267 ffilt |= AWIN_GMAC_MAC_FFILT_PR;
1268 goto special_filter;
1269 }
1270
1271 ifp->if_flags &= ~IFF_ALLMULTI;
1272 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR);
1273
1274 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0);
1275 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0);
1276
1277 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
1278 mcnt = 0;
1279 while (enm != NULL) {
1280 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1281 ETHER_ADDR_LEN) != 0) {
1282 ffilt |= AWIN_GMAC_MAC_FFILT_PM;
1283 ifp->if_flags |= IFF_ALLMULTI;
1284 goto special_filter;
1285 }
1286
1287 h = bitrev32(
1288 ~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN)
1289 ) >> 26;
1290 hashes[h >> 5] |= (1 << (h & 0x1f));
1291
1292 mcnt++;
1293 ETHER_NEXT_MULTI(step, enm);
1294 }
1295
1296 if (mcnt)
1297 ffilt |= AWIN_GMAC_MAC_FFILT_HMC;
1298 else
1299 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC;
1300
1301 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
1302 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1303 hashes[0]);
1304 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1305 hashes[1]);
1306 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1307
1308 #ifdef DWC_GMAC_DEBUG
1309 dwc_gmac_dump_ffilt(sc, ffilt);
1310 #endif
1311 return;
1312
1313 special_filter:
1314 #ifdef DWC_GMAC_DEBUG
1315 dwc_gmac_dump_ffilt(sc, ffilt);
1316 #endif
1317 /* no MAC hashes, ALLMULTI or PROMISC */
1318 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT,
1319 ffilt);
1320 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW,
1321 0xffffffff);
1322 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH,
1323 0xffffffff);
1324 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags;
1325 }
1326
1327 int
1328 dwc_gmac_intr(struct dwc_gmac_softc *sc)
1329 {
1330 uint32_t status, dma_status;
1331 int rv = 0;
1332
1333 if (sc->sc_stopping)
1334 return 0;
1335
1336 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR);
1337 if (status & AWIN_GMAC_MII_IRQ) {
1338 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1339 AWIN_GMAC_MII_STATUS);
1340 rv = 1;
1341 mii_pollstat(&sc->sc_mii);
1342 }
1343
1344 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1345 AWIN_GMAC_DMA_STATUS);
1346
1347 if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE))
1348 rv = 1;
1349
1350 if (dma_status & GMAC_DMA_INT_TIE)
1351 dwc_gmac_tx_intr(sc);
1352
1353 if (dma_status & GMAC_DMA_INT_RIE)
1354 dwc_gmac_rx_intr(sc);
1355
1356 /*
1357 * Check error conditions
1358 */
1359 if (dma_status & GMAC_DMA_INT_ERRORS) {
1360 sc->sc_ec.ec_if.if_oerrors++;
1361 #ifdef DWC_GMAC_DEBUG
1362 dwc_dump_and_abort(sc, "interrupt error condition");
1363 #endif
1364 }
1365
1366 /* ack interrupt */
1367 if (dma_status)
1368 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
1369 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK);
1370
1371 /*
1372 * Get more packets
1373 */
1374 if (rv)
1375 sc->sc_ec.ec_if.if_start(&sc->sc_ec.ec_if);
1376
1377 return rv;
1378 }
1379
1380 #ifdef DWC_GMAC_DEBUG
1381 static void
1382 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc)
1383 {
1384 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n",
1385 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE));
1386 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n",
1387 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL));
1388 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n",
1389 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL));
1390 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n",
1391 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR));
1392 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n",
1393 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR));
1394 aprint_normal_dev(sc->sc_dev, "status: %08x\n",
1395 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS));
1396 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n",
1397 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE));
1398 aprint_normal_dev(sc->sc_dev, "int enable: %08x\n",
1399 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE));
1400 aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n",
1401 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC));
1402 aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n",
1403 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC));
1404 aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n",
1405 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR));
1406 aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n",
1407 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR));
1408 }
1409
1410 static void
1411 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
1412 {
1413 int i;
1414
1415 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n",
1416 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued);
1417 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n");
1418 for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
1419 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i];
1420 aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
1421 "data: %08x next: %08x\n",
1422 i, sc->sc_txq.t_physaddr +
1423 i*sizeof(struct dwc_gmac_dev_dmadesc),
1424 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
1425 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
1426 }
1427 }
1428
1429 static void
1430 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
1431 {
1432 int i;
1433
1434 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n",
1435 sc->sc_rxq.r_cur, sc->sc_rxq.r_next);
1436 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n");
1437 for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
1438 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i];
1439 aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
1440 "data: %08x next: %08x\n",
1441 i, sc->sc_rxq.r_physaddr +
1442 i*sizeof(struct dwc_gmac_dev_dmadesc),
1443 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
1444 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
1445 }
1446 }
1447
1448 static void
1449 dwc_dump_status(struct dwc_gmac_softc *sc)
1450 {
1451 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1452 AWIN_GMAC_MAC_INTR);
1453 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
1454 AWIN_GMAC_DMA_STATUS);
1455 char buf[200];
1456
1457 /* print interrupt state */
1458 snprintb(buf, sizeof(buf), "\177\20"
1459 "b\x10""NI\0"
1460 "b\x0f""AI\0"
1461 "b\x0e""ER\0"
1462 "b\x0d""FB\0"
1463 "b\x0a""ET\0"
1464 "b\x09""RW\0"
1465 "b\x08""RS\0"
1466 "b\x07""RU\0"
1467 "b\x06""RI\0"
1468 "b\x05""UN\0"
1469 "b\x04""OV\0"
1470 "b\x03""TJ\0"
1471 "b\x02""TU\0"
1472 "b\x01""TS\0"
1473 "b\x00""TI\0"
1474 "\0", dma_status);
1475 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n",
1476 status, buf);
1477 }
1478
1479 static void
1480 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg)
1481 {
1482 dwc_dump_status(sc);
1483 dwc_gmac_dump_ffilt(sc,
1484 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT));
1485 dwc_gmac_dump_dma(sc);
1486 dwc_gmac_dump_tx_desc(sc);
1487 dwc_gmac_dump_rx_desc(sc);
1488
1489 panic("%s", msg);
1490 }
1491
1492 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt)
1493 {
1494 char buf[200];
1495
1496 /* print filter setup */
1497 snprintb(buf, sizeof(buf), "\177\20"
1498 "b\x1f""RA\0"
1499 "b\x0a""HPF\0"
1500 "b\x09""SAF\0"
1501 "b\x08""SAIF\0"
1502 "b\x05""DBF\0"
1503 "b\x04""PM\0"
1504 "b\x03""DAIF\0"
1505 "b\x02""HMC\0"
1506 "b\x01""HUC\0"
1507 "b\x00""PR\0"
1508 "\0", ffilt);
1509 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf);
1510 }
1511 #endif
1512