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