6479ff271b76efa322f2c13f3097fd432a2398dc
[openbsd] / sys / dev / ic / dwqe.c
1 /*      $OpenBSD: dwqe.c,v 1.6 2023/04/22 06:36:35 dlg Exp $    */
2 /*
3  * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
4  * Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 /*
20  * Driver for the Synopsys Designware ethernet controller.
21  */
22
23 #include "bpfilter.h"
24
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/device.h>
28 #include <sys/kernel.h>
29 #include <sys/malloc.h>
30 #include <sys/mbuf.h>
31 #include <sys/queue.h>
32 #include <sys/socket.h>
33 #include <sys/sockio.h>
34 #include <sys/timeout.h>
35
36 #include <machine/bus.h>
37 #include <machine/fdt.h>
38
39 #include <net/if.h>
40 #include <net/if_media.h>
41
42 #include <dev/ofw/openfirm.h>
43 #include <dev/ofw/ofw_clock.h>
44 #include <dev/ofw/ofw_gpio.h>
45 #include <dev/ofw/ofw_misc.h>
46 #include <dev/ofw/ofw_pinctrl.h>
47 #include <dev/ofw/ofw_regulator.h>
48 #include <dev/ofw/fdt.h>
49
50 #include <dev/mii/mii.h>
51 #include <dev/mii/miivar.h>
52
53 #if NBPFILTER > 0
54 #include <net/bpf.h>
55 #endif
56
57 #include <netinet/in.h>
58 #include <netinet/if_ether.h>
59
60 #include <dev/ic/dwqevar.h>
61 #include <dev/ic/dwqereg.h>
62
63 struct cfdriver dwqe_cd = {
64         NULL, "dwqe", DV_IFNET
65 };
66
67 uint32_t dwqe_read(struct dwqe_softc *, bus_addr_t);
68 void    dwqe_write(struct dwqe_softc *, bus_addr_t, uint32_t);
69
70 int     dwqe_ioctl(struct ifnet *, u_long, caddr_t);
71 void    dwqe_start(struct ifqueue *);
72 void    dwqe_watchdog(struct ifnet *);
73
74 int     dwqe_media_change(struct ifnet *);
75 void    dwqe_media_status(struct ifnet *, struct ifmediareq *);
76
77 int     dwqe_mii_readreg(struct device *, int, int);
78 void    dwqe_mii_writereg(struct device *, int, int, int);
79 void    dwqe_mii_statchg(struct device *);
80
81 void    dwqe_lladdr_read(struct dwqe_softc *, uint8_t *);
82 void    dwqe_lladdr_write(struct dwqe_softc *);
83
84 void    dwqe_tick(void *);
85 void    dwqe_rxtick(void *);
86
87 int     dwqe_intr(void *);
88 void    dwqe_tx_proc(struct dwqe_softc *);
89 void    dwqe_rx_proc(struct dwqe_softc *);
90
91 void    dwqe_up(struct dwqe_softc *);
92 void    dwqe_down(struct dwqe_softc *);
93 void    dwqe_iff(struct dwqe_softc *);
94 int     dwqe_encap(struct dwqe_softc *, struct mbuf *, int *, int *);
95
96 void    dwqe_reset(struct dwqe_softc *);
97
98 struct dwqe_dmamem *
99         dwqe_dmamem_alloc(struct dwqe_softc *, bus_size_t, bus_size_t);
100 void    dwqe_dmamem_free(struct dwqe_softc *, struct dwqe_dmamem *);
101 struct mbuf *dwqe_alloc_mbuf(struct dwqe_softc *, bus_dmamap_t);
102 void    dwqe_fill_rx_ring(struct dwqe_softc *);
103
104 int
105 dwqe_attach(struct dwqe_softc *sc)
106 {
107         struct ifnet *ifp;
108         uint32_t version, mode;
109         int mii_flags = 0;
110         int i;
111
112         version = dwqe_read(sc, GMAC_VERSION);
113         printf(": rev 0x%02x, address %s\n", version & GMAC_VERSION_SNPS_MASK,
114             ether_sprintf(sc->sc_lladdr));
115
116         for (i = 0; i < 4; i++)
117                 sc->sc_hw_feature[i] = dwqe_read(sc, GMAC_MAC_HW_FEATURE(i));
118
119         timeout_set(&sc->sc_tick, dwqe_tick, sc);
120         timeout_set(&sc->sc_rxto, dwqe_rxtick, sc);
121
122         ifp = &sc->sc_ac.ac_if;
123         ifp->if_softc = sc;
124         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
125         ifp->if_xflags = IFXF_MPSAFE;
126         ifp->if_ioctl = dwqe_ioctl;
127         ifp->if_qstart = dwqe_start;
128         ifp->if_watchdog = dwqe_watchdog;
129         ifq_set_maxlen(&ifp->if_snd, DWQE_NTXDESC - 1);
130         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
131
132         ifp->if_capabilities = IFCAP_VLAN_MTU;
133
134         sc->sc_mii.mii_ifp = ifp;
135         sc->sc_mii.mii_readreg = dwqe_mii_readreg;
136         sc->sc_mii.mii_writereg = dwqe_mii_writereg;
137         sc->sc_mii.mii_statchg = dwqe_mii_statchg;
138
139         ifmedia_init(&sc->sc_media, 0, dwqe_media_change, dwqe_media_status);
140
141         dwqe_reset(sc);
142
143         /* Configure DMA engine. */
144         mode = dwqe_read(sc, GMAC_SYS_BUS_MODE);
145         if (sc->sc_fixed_burst)
146                 mode |= GMAC_SYS_BUS_MODE_FB;
147         if (sc->sc_mixed_burst)
148                 mode |= GMAC_SYS_BUS_MODE_MB;
149         if (sc->sc_aal)
150                 mode |= GMAC_SYS_BUS_MODE_AAL;
151         dwqe_write(sc, GMAC_SYS_BUS_MODE, mode);
152
153         /* Configure channel 0. */
154         mode = dwqe_read(sc, GMAC_CHAN_CONTROL(0));
155         if (sc->sc_8xpbl)
156                 mode |= GMAC_CHAN_CONTROL_8XPBL;
157         dwqe_write(sc, GMAC_CHAN_CONTROL(0), mode);
158
159         mode = dwqe_read(sc, GMAC_CHAN_TX_CONTROL(0));
160         mode &= ~GMAC_CHAN_TX_CONTROL_PBL_MASK;
161         mode |= sc->sc_txpbl << GMAC_CHAN_TX_CONTROL_PBL_SHIFT;
162         mode |= GMAC_CHAN_TX_CONTROL_OSP;
163         dwqe_write(sc, GMAC_CHAN_TX_CONTROL(0), mode);
164         mode = dwqe_read(sc, GMAC_CHAN_RX_CONTROL(0));
165         mode &= ~GMAC_CHAN_RX_CONTROL_RPBL_MASK;
166         mode |= sc->sc_rxpbl << GMAC_CHAN_RX_CONTROL_RPBL_SHIFT;
167         dwqe_write(sc, GMAC_CHAN_RX_CONTROL(0), mode);
168
169         /* Configure AXI master. */
170         if (sc->sc_axi_config) {
171                 int i;
172
173                 mode = dwqe_read(sc, GMAC_SYS_BUS_MODE);
174
175                 mode &= ~GMAC_SYS_BUS_MODE_EN_LPI;
176                 if (sc->sc_lpi_en)
177                         mode |= GMAC_SYS_BUS_MODE_EN_LPI;
178                 mode &= ~GMAC_SYS_BUS_MODE_LPI_XIT_FRM;
179                 if (sc->sc_xit_frm)
180                         mode |= GMAC_SYS_BUS_MODE_LPI_XIT_FRM;
181
182                 mode &= ~GMAC_SYS_BUS_MODE_WR_OSR_LMT_MASK;
183                 mode |= (sc->sc_wr_osr_lmt << GMAC_SYS_BUS_MODE_WR_OSR_LMT_SHIFT);
184                 mode &= ~GMAC_SYS_BUS_MODE_RD_OSR_LMT_MASK;
185                 mode |= (sc->sc_rd_osr_lmt << GMAC_SYS_BUS_MODE_RD_OSR_LMT_SHIFT);
186
187                 for (i = 0; i < nitems(sc->sc_blen); i++) {
188                         switch (sc->sc_blen[i]) {
189                         case 256:
190                                 mode |= GMAC_SYS_BUS_MODE_BLEN_256;
191                                 break;
192                         case 128:
193                                 mode |= GMAC_SYS_BUS_MODE_BLEN_128;
194                                 break;
195                         case 64:
196                                 mode |= GMAC_SYS_BUS_MODE_BLEN_64;
197                                 break;
198                         case 32:
199                                 mode |= GMAC_SYS_BUS_MODE_BLEN_32;
200                                 break;
201                         case 16:
202                                 mode |= GMAC_SYS_BUS_MODE_BLEN_16;
203                                 break;
204                         case 8:
205                                 mode |= GMAC_SYS_BUS_MODE_BLEN_8;
206                                 break;
207                         case 4:
208                                 mode |= GMAC_SYS_BUS_MODE_BLEN_4;
209                                 break;
210                         }
211                 }
212
213                 dwqe_write(sc, GMAC_SYS_BUS_MODE, mode);
214         }
215
216         switch (sc->sc_phy_mode) {
217         case DWQE_PHY_MODE_RGMII:
218                 mii_flags |= MIIF_SETDELAY;
219                 break;
220         case DWQE_PHY_MODE_RGMII_ID:
221                 mii_flags |= MIIF_SETDELAY | MIIF_RXID | MIIF_TXID;
222                 break;
223         case DWQE_PHY_MODE_RGMII_RXID:
224                 mii_flags |= MIIF_SETDELAY | MIIF_RXID;
225                 break;
226         case DWQE_PHY_MODE_RGMII_TXID:
227                 mii_flags |= MIIF_SETDELAY | MIIF_TXID;
228                 break;
229         default:
230                 break;
231         }
232
233         mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, sc->sc_phyloc,
234             (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, mii_flags);
235         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
236                 printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
237                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
238                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
239         } else
240                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
241
242         if_attach(ifp);
243         ether_ifattach(ifp);
244
245         /* Disable interrupts. */
246         dwqe_write(sc, GMAC_INT_EN, 0);
247         dwqe_write(sc, GMAC_CHAN_INTR_ENA(0), 0);
248
249         return 0;
250 }
251
252 uint32_t
253 dwqe_read(struct dwqe_softc *sc, bus_addr_t addr)
254 {
255         return bus_space_read_4(sc->sc_iot, sc->sc_ioh, addr);
256 }
257
258 void
259 dwqe_write(struct dwqe_softc *sc, bus_addr_t addr, uint32_t data)
260 {
261         bus_space_write_4(sc->sc_iot, sc->sc_ioh, addr, data);
262 }
263
264 void
265 dwqe_lladdr_read(struct dwqe_softc *sc, uint8_t *lladdr)
266 {
267         uint32_t machi, maclo;
268
269         machi = dwqe_read(sc, GMAC_MAC_ADDR0_HI);
270         maclo = dwqe_read(sc, GMAC_MAC_ADDR0_LO);
271
272         if (machi || maclo) {
273                 lladdr[0] = (maclo >> 0) & 0xff;
274                 lladdr[1] = (maclo >> 8) & 0xff;
275                 lladdr[2] = (maclo >> 16) & 0xff;
276                 lladdr[3] = (maclo >> 24) & 0xff;
277                 lladdr[4] = (machi >> 0) & 0xff;
278                 lladdr[5] = (machi >> 8) & 0xff;
279         } else {
280                 ether_fakeaddr(&sc->sc_ac.ac_if);
281         }
282 }
283
284 void
285 dwqe_lladdr_write(struct dwqe_softc *sc)
286 {
287         dwqe_write(sc, GMAC_MAC_ADDR0_HI,
288             sc->sc_lladdr[5] << 8 | sc->sc_lladdr[4] << 0);
289         dwqe_write(sc, GMAC_MAC_ADDR0_LO,
290             sc->sc_lladdr[3] << 24 | sc->sc_lladdr[2] << 16 |
291             sc->sc_lladdr[1] << 8 | sc->sc_lladdr[0] << 0);
292 }
293
294 void
295 dwqe_start(struct ifqueue *ifq)
296 {
297         struct ifnet *ifp = ifq->ifq_if;
298         struct dwqe_softc *sc = ifp->if_softc;
299         struct mbuf *m;
300         int error, idx, left, used;
301
302         if (!(ifp->if_flags & IFF_RUNNING))
303                 return;
304         if (ifq_is_oactive(&ifp->if_snd))
305                 return;
306         if (ifq_empty(&ifp->if_snd))
307                 return;
308         if (!sc->sc_link)
309                 return;
310
311         idx = sc->sc_tx_prod;
312         left = sc->sc_tx_cons;
313         if (left <= idx)
314                 left += DWQE_NTXDESC;
315         left -= idx;
316         used = 0;
317
318         for (;;) {
319                 if (used + DWQE_NTXSEGS + 1 > left) {
320                         ifq_set_oactive(ifq);
321                         break;
322                 }
323
324                 m = ifq_dequeue(ifq);
325                 if (m == NULL)
326                         break;
327
328                 error = dwqe_encap(sc, m, &idx, &used);
329                 if (error == EFBIG) {
330                         m_freem(m); /* give up: drop it */
331                         ifp->if_oerrors++;
332                         continue;
333                 }
334
335 #if NBPFILTER > 0
336                 if (ifp->if_bpf)
337                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
338 #endif
339         }
340
341         if (sc->sc_tx_prod != idx) {
342                 sc->sc_tx_prod = idx;
343
344                 /* Set a timeout in case the chip goes out to lunch. */
345                 ifp->if_timer = 5;
346         }
347 }
348
349 int
350 dwqe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
351 {
352         struct dwqe_softc *sc = ifp->if_softc;
353         struct ifreq *ifr = (struct ifreq *)addr;
354         int error = 0, s;
355
356         s = splnet();
357
358         switch (cmd) {
359         case SIOCSIFADDR:
360                 ifp->if_flags |= IFF_UP;
361                 /* FALLTHROUGH */
362         case SIOCSIFFLAGS:
363                 if (ifp->if_flags & IFF_UP) {
364                         if (ifp->if_flags & IFF_RUNNING)
365                                 error = ENETRESET;
366                         else
367                                 dwqe_up(sc);
368                 } else {
369                         if (ifp->if_flags & IFF_RUNNING)
370                                 dwqe_down(sc);
371                 }
372                 break;
373
374         case SIOCGIFMEDIA:
375         case SIOCSIFMEDIA:
376                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
377                 break;
378
379         case SIOCGIFRXR:
380                 error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
381                     NULL, MCLBYTES, &sc->sc_rx_ring);
382                 break;
383
384         default:
385                 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
386                 break;
387         }
388
389         if (error == ENETRESET) {
390                 if (ifp->if_flags & IFF_RUNNING)
391                         dwqe_iff(sc);
392                 error = 0;
393         }
394
395         splx(s);
396         return (error);
397 }
398
399 void
400 dwqe_watchdog(struct ifnet *ifp)
401 {
402         printf("%s\n", __func__);
403 }
404
405 int
406 dwqe_media_change(struct ifnet *ifp)
407 {
408         struct dwqe_softc *sc = ifp->if_softc;
409
410         if (LIST_FIRST(&sc->sc_mii.mii_phys))
411                 mii_mediachg(&sc->sc_mii);
412
413         return (0);
414 }
415
416 void
417 dwqe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
418 {
419         struct dwqe_softc *sc = ifp->if_softc;
420
421         if (LIST_FIRST(&sc->sc_mii.mii_phys)) {
422                 mii_pollstat(&sc->sc_mii);
423                 ifmr->ifm_active = sc->sc_mii.mii_media_active;
424                 ifmr->ifm_status = sc->sc_mii.mii_media_status;
425         }
426 }
427
428 int
429 dwqe_mii_readreg(struct device *self, int phy, int reg)
430 {
431         struct dwqe_softc *sc = (void *)self;
432         int n;
433
434         dwqe_write(sc, GMAC_MAC_MDIO_ADDR,
435             sc->sc_clk << GMAC_MAC_MDIO_ADDR_CR_SHIFT |
436             (phy << GMAC_MAC_MDIO_ADDR_PA_SHIFT) |
437             (reg << GMAC_MAC_MDIO_ADDR_RDA_SHIFT) |
438             GMAC_MAC_MDIO_ADDR_GOC_READ |
439             GMAC_MAC_MDIO_ADDR_GB);
440
441         for (n = 0; n < 2000; n++) {
442                 delay(10);
443                 if ((dwqe_read(sc, GMAC_MAC_MDIO_ADDR) & GMAC_MAC_MDIO_ADDR_GB) == 0)
444                         return dwqe_read(sc, GMAC_MAC_MDIO_DATA);
445         }
446
447         printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
448         return (0);
449 }
450
451 void
452 dwqe_mii_writereg(struct device *self, int phy, int reg, int val)
453 {
454         struct dwqe_softc *sc = (void *)self;
455         int n;
456
457         dwqe_write(sc, GMAC_MAC_MDIO_DATA, val);
458         dwqe_write(sc, GMAC_MAC_MDIO_ADDR,
459             sc->sc_clk << GMAC_MAC_MDIO_ADDR_CR_SHIFT |
460             (phy << GMAC_MAC_MDIO_ADDR_PA_SHIFT) |
461             (reg << GMAC_MAC_MDIO_ADDR_RDA_SHIFT) |
462             GMAC_MAC_MDIO_ADDR_GOC_WRITE |
463             GMAC_MAC_MDIO_ADDR_GB);
464
465         for (n = 0; n < 2000; n++) {
466                 delay(10);
467                 if ((dwqe_read(sc, GMAC_MAC_MDIO_ADDR) & GMAC_MAC_MDIO_ADDR_GB) == 0)
468                         return;
469         }
470
471         printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
472 }
473
474 void
475 dwqe_mii_statchg(struct device *self)
476 {
477         struct dwqe_softc *sc = (void *)self;
478         struct ifnet *ifp = &sc->sc_ac.ac_if;
479         uint32_t conf;
480
481         conf = dwqe_read(sc, GMAC_MAC_CONF);
482         conf &= ~(GMAC_MAC_CONF_PS | GMAC_MAC_CONF_FES);
483
484         switch (ifp->if_baudrate) {
485         case IF_Mbps(1000):
486                 sc->sc_link = 1;
487                 break;
488         case IF_Mbps(100):
489                 conf |= GMAC_MAC_CONF_PS | GMAC_MAC_CONF_FES;
490                 sc->sc_link = 1;
491                 break;
492         case IF_Mbps(10):
493                 conf |= GMAC_MAC_CONF_PS;
494                 sc->sc_link = 1;
495                 break;
496         default:
497                 sc->sc_link = 0;
498                 return;
499         }
500
501         if (sc->sc_link == 0)
502                 return;
503
504         conf &= ~GMAC_MAC_CONF_DM;
505         if (ifp->if_link_state == LINK_STATE_FULL_DUPLEX)
506                 conf |= GMAC_MAC_CONF_DM;
507
508         dwqe_write(sc, GMAC_MAC_CONF, conf);
509 }
510
511 void
512 dwqe_tick(void *arg)
513 {
514         struct dwqe_softc *sc = arg;
515         int s;
516
517         s = splnet();
518         mii_tick(&sc->sc_mii);
519         splx(s);
520
521         timeout_add_sec(&sc->sc_tick, 1);
522 }
523
524 void
525 dwqe_rxtick(void *arg)
526 {
527         struct dwqe_softc *sc = arg;
528         int s;
529
530         s = splnet();
531
532         /* TODO: disable RXQ? */
533         printf("%s:%d\n", __func__, __LINE__);
534
535         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_rxring),
536             0, DWQE_DMA_LEN(sc->sc_rxring),
537             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
538
539         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR_HI(0), 0);
540         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR(0), 0);
541
542         sc->sc_rx_prod = sc->sc_rx_cons = 0;
543         dwqe_fill_rx_ring(sc);
544
545         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_rxring),
546             0, DWQE_DMA_LEN(sc->sc_rxring),
547             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
548
549         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR_HI(0), DWQE_DMA_DVA(sc->sc_rxring) >> 32);
550         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR(0), DWQE_DMA_DVA(sc->sc_rxring));
551
552         /* TODO: re-enable RXQ? */
553
554         splx(s);
555 }
556
557 int
558 dwqe_intr(void *arg)
559 {
560         struct dwqe_softc *sc = arg;
561         uint32_t reg;
562
563         reg = dwqe_read(sc, GMAC_INT_STATUS);
564         dwqe_write(sc, GMAC_INT_STATUS, reg);
565
566         reg = dwqe_read(sc, GMAC_CHAN_STATUS(0));
567         dwqe_write(sc, GMAC_CHAN_STATUS(0), reg);
568
569         if (reg & GMAC_CHAN_STATUS_RI)
570                 dwqe_rx_proc(sc);
571
572         if (reg & GMAC_CHAN_STATUS_TI)
573                 dwqe_tx_proc(sc);
574
575         return (1);
576 }
577
578 void
579 dwqe_tx_proc(struct dwqe_softc *sc)
580 {
581         struct ifnet *ifp = &sc->sc_ac.ac_if;
582         struct dwqe_desc *txd;
583         struct dwqe_buf *txb;
584         int idx, txfree;
585
586         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_txring), 0,
587             DWQE_DMA_LEN(sc->sc_txring),
588             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
589
590         txfree = 0;
591         while (sc->sc_tx_cons != sc->sc_tx_prod) {
592                 idx = sc->sc_tx_cons;
593                 KASSERT(idx < DWQE_NTXDESC);
594
595                 txd = &sc->sc_txdesc[idx];
596                 if (txd->sd_tdes3 & TDES3_OWN)
597                         break;
598
599                 txb = &sc->sc_txbuf[idx];
600                 if (txb->tb_m) {
601                         bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0,
602                             txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
603                         bus_dmamap_unload(sc->sc_dmat, txb->tb_map);
604
605                         m_freem(txb->tb_m);
606                         txb->tb_m = NULL;
607                 }
608
609                 txfree++;
610
611                 if (sc->sc_tx_cons == (DWQE_NTXDESC - 1))
612                         sc->sc_tx_cons = 0;
613                 else
614                         sc->sc_tx_cons++;
615
616                 txd->sd_tdes3 = 0;
617         }
618
619         if (sc->sc_tx_cons == sc->sc_tx_prod)
620                 ifp->if_timer = 0;
621
622         if (txfree) {
623                 if (ifq_is_oactive(&ifp->if_snd))
624                         ifq_restart(&ifp->if_snd);
625         }
626 }
627
628 void
629 dwqe_rx_proc(struct dwqe_softc *sc)
630 {
631         struct ifnet *ifp = &sc->sc_ac.ac_if;
632         struct dwqe_desc *rxd;
633         struct dwqe_buf *rxb;
634         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
635         struct mbuf *m;
636         int idx, len, cnt, put;
637
638         if ((ifp->if_flags & IFF_RUNNING) == 0)
639                 return;
640
641         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_rxring), 0,
642             DWQE_DMA_LEN(sc->sc_rxring),
643             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
644
645         cnt = if_rxr_inuse(&sc->sc_rx_ring);
646         put = 0;
647         while (put < cnt) {
648                 idx = sc->sc_rx_cons;
649                 KASSERT(idx < DWQE_NRXDESC);
650
651                 rxd = &sc->sc_rxdesc[idx];
652                 if (rxd->sd_tdes3 & RDES3_OWN)
653                         break;
654
655                 len = rxd->sd_tdes3 & RDES3_LENGTH;
656                 rxb = &sc->sc_rxbuf[idx];
657                 KASSERT(rxb->tb_m);
658
659                 bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0,
660                     len, BUS_DMASYNC_POSTREAD);
661                 bus_dmamap_unload(sc->sc_dmat, rxb->tb_map);
662
663                 /* Strip off CRC. */
664                 len -= ETHER_CRC_LEN;
665                 KASSERT(len > 0);
666
667                 m = rxb->tb_m;
668                 rxb->tb_m = NULL;
669                 m->m_pkthdr.len = m->m_len = len;
670
671                 ml_enqueue(&ml, m);
672
673                 put++;
674                 if (sc->sc_rx_cons == (DWQE_NRXDESC - 1))
675                         sc->sc_rx_cons = 0;
676                 else
677                         sc->sc_rx_cons++;
678         }
679
680         if_rxr_put(&sc->sc_rx_ring, put);
681         if (ifiq_input(&ifp->if_rcv, &ml))
682                 if_rxr_livelocked(&sc->sc_rx_ring);
683
684         dwqe_fill_rx_ring(sc);
685
686         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_rxring), 0,
687             DWQE_DMA_LEN(sc->sc_rxring),
688             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
689
690 }
691
692 void
693 dwqe_up(struct dwqe_softc *sc)
694 {
695         struct ifnet *ifp = &sc->sc_ac.ac_if;
696         struct dwqe_buf *txb, *rxb;
697         uint32_t mode, reg, tqs, rqs;
698         int i;
699
700         /* Allocate Tx descriptor ring. */
701         sc->sc_txring = dwqe_dmamem_alloc(sc,
702             DWQE_NTXDESC * sizeof(struct dwqe_desc), 8);
703         sc->sc_txdesc = DWQE_DMA_KVA(sc->sc_txring);
704
705         sc->sc_txbuf = malloc(sizeof(struct dwqe_buf) * DWQE_NTXDESC,
706             M_DEVBUF, M_WAITOK);
707         for (i = 0; i < DWQE_NTXDESC; i++) {
708                 txb = &sc->sc_txbuf[i];
709                 bus_dmamap_create(sc->sc_dmat, MCLBYTES, DWQE_NTXSEGS,
710                     MCLBYTES, 0, BUS_DMA_WAITOK, &txb->tb_map);
711                 txb->tb_m = NULL;
712         }
713
714         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_txring),
715             0, DWQE_DMA_LEN(sc->sc_txring), BUS_DMASYNC_PREWRITE);
716
717         sc->sc_tx_prod = sc->sc_tx_cons = 0;
718
719         dwqe_write(sc, GMAC_CHAN_TX_BASE_ADDR_HI(0), DWQE_DMA_DVA(sc->sc_txring) >> 32);
720         dwqe_write(sc, GMAC_CHAN_TX_BASE_ADDR(0), DWQE_DMA_DVA(sc->sc_txring));
721         dwqe_write(sc, GMAC_CHAN_TX_RING_LEN(0), DWQE_NTXDESC - 1);
722         dwqe_write(sc, GMAC_CHAN_TX_END_ADDR(0), DWQE_DMA_DVA(sc->sc_txring));
723
724         /* Allocate  descriptor ring. */
725         sc->sc_rxring = dwqe_dmamem_alloc(sc,
726             DWQE_NRXDESC * sizeof(struct dwqe_desc), 8);
727         sc->sc_rxdesc = DWQE_DMA_KVA(sc->sc_rxring);
728
729         sc->sc_rxbuf = malloc(sizeof(struct dwqe_buf) * DWQE_NRXDESC,
730             M_DEVBUF, M_WAITOK);
731
732         for (i = 0; i < DWQE_NRXDESC; i++) {
733                 rxb = &sc->sc_rxbuf[i];
734                 bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
735                     MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->tb_map);
736                 rxb->tb_m = NULL;
737         }
738
739         if_rxr_init(&sc->sc_rx_ring, 2, DWQE_NRXDESC);
740
741         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR_HI(0), DWQE_DMA_DVA(sc->sc_rxring) >> 32);
742         dwqe_write(sc, GMAC_CHAN_RX_BASE_ADDR(0), DWQE_DMA_DVA(sc->sc_rxring));
743         dwqe_write(sc, GMAC_CHAN_RX_RING_LEN(0), DWQE_NRXDESC - 1);
744
745         sc->sc_rx_prod = sc->sc_rx_cons = 0;
746         dwqe_fill_rx_ring(sc);
747
748         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_rxring),
749             0, DWQE_DMA_LEN(sc->sc_rxring),
750             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
751
752         dwqe_lladdr_write(sc);
753
754         /* Configure media. */
755         if (LIST_FIRST(&sc->sc_mii.mii_phys))
756                 mii_mediachg(&sc->sc_mii);
757
758         /* Program promiscuous mode and multicast filters. */
759         dwqe_iff(sc);
760
761         ifp->if_flags |= IFF_RUNNING;
762         ifq_clr_oactive(&ifp->if_snd);
763
764         dwqe_write(sc, GMAC_MAC_1US_TIC_CTR, (sc->sc_clk / 1000000) - 1);
765
766         /* Start receive DMA */
767         reg = dwqe_read(sc, GMAC_CHAN_RX_CONTROL(0));
768         reg |= GMAC_CHAN_RX_CONTROL_SR;
769         dwqe_write(sc, GMAC_CHAN_RX_CONTROL(0), reg);
770
771         /* Start transmit DMA */
772         reg = dwqe_read(sc, GMAC_CHAN_TX_CONTROL(0));
773         reg |= GMAC_CHAN_TX_CONTROL_ST;
774         dwqe_write(sc, GMAC_CHAN_TX_CONTROL(0), reg);
775
776         mode = dwqe_read(sc, GMAC_MTL_CHAN_RX_OP_MODE(0));
777         if (sc->sc_force_thresh_dma_mode) {
778                 mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RSF;
779                 mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RTC_MASK;
780                 mode |= GMAC_MTL_CHAN_RX_OP_MODE_RTC_128;
781         } else {
782                 mode |= GMAC_MTL_CHAN_RX_OP_MODE_RSF;
783         }
784         mode &= ~GMAC_MTL_CHAN_RX_OP_MODE_RQS_MASK;
785         rqs = (128 << GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(sc->sc_hw_feature[1]) /
786             256) - 1;
787         mode |= rqs << GMAC_MTL_CHAN_RX_OP_MODE_RQS_SHIFT;
788         dwqe_write(sc, GMAC_MTL_CHAN_RX_OP_MODE(0), mode);
789
790         mode = dwqe_read(sc, GMAC_MTL_CHAN_TX_OP_MODE(0));
791         if (sc->sc_force_thresh_dma_mode) {
792                 mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TSF;
793                 mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TTC_MASK;
794                 mode |= GMAC_MTL_CHAN_TX_OP_MODE_TTC_128;
795         } else {
796                 mode |= GMAC_MTL_CHAN_TX_OP_MODE_TSF;
797         }
798         mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TXQEN_MASK;
799         mode |= GMAC_MTL_CHAN_TX_OP_MODE_TXQEN;
800         mode &= ~GMAC_MTL_CHAN_TX_OP_MODE_TQS_MASK;
801         tqs = (128 << GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(sc->sc_hw_feature[1]) /
802             256) - 1;
803         mode |= tqs << GMAC_MTL_CHAN_TX_OP_MODE_TQS_SHIFT;
804         dwqe_write(sc, GMAC_MTL_CHAN_TX_OP_MODE(0), mode);
805
806         reg = dwqe_read(sc, GMAC_QX_TX_FLOW_CTRL(0));
807         reg |= 0xffffU << GMAC_QX_TX_FLOW_CTRL_PT_SHIFT;
808         reg |= GMAC_QX_TX_FLOW_CTRL_TFE;
809         dwqe_write(sc, GMAC_QX_TX_FLOW_CTRL(0), reg);
810         reg = dwqe_read(sc, GMAC_RX_FLOW_CTRL);
811         reg |= GMAC_RX_FLOW_CTRL_RFE;
812         dwqe_write(sc, GMAC_RX_FLOW_CTRL, reg);
813
814         dwqe_write(sc, GMAC_RXQ_CTRL0, GMAC_RXQ_CTRL0_DCB_QUEUE_EN(0));
815
816         dwqe_write(sc, GMAC_MAC_CONF, dwqe_read(sc, GMAC_MAC_CONF) |
817             GMAC_MAC_CONF_BE | GMAC_MAC_CONF_JD | GMAC_MAC_CONF_JE |
818             GMAC_MAC_CONF_DCRS | GMAC_MAC_CONF_TE | GMAC_MAC_CONF_RE);
819
820         dwqe_write(sc, GMAC_CHAN_INTR_ENA(0),
821             GMAC_CHAN_INTR_ENA_NIE |
822             GMAC_CHAN_INTR_ENA_AIE |
823             GMAC_CHAN_INTR_ENA_FBE |
824             GMAC_CHAN_INTR_ENA_RIE |
825             GMAC_CHAN_INTR_ENA_TIE);
826
827         timeout_add_sec(&sc->sc_tick, 1);
828 }
829
830 void
831 dwqe_down(struct dwqe_softc *sc)
832 {
833         struct ifnet *ifp = &sc->sc_ac.ac_if;
834         struct dwqe_buf *txb, *rxb;
835         uint32_t reg;
836         int i;
837
838         timeout_del(&sc->sc_rxto);
839         timeout_del(&sc->sc_tick);
840
841         ifp->if_flags &= ~IFF_RUNNING;
842         ifq_clr_oactive(&ifp->if_snd);
843         ifp->if_timer = 0;
844
845         /* Disable receiver */
846         reg = dwqe_read(sc, GMAC_MAC_CONF);
847         reg &= ~GMAC_MAC_CONF_RE;
848         dwqe_write(sc, GMAC_MAC_CONF, reg);
849
850         /* Stop receive DMA */
851         reg = dwqe_read(sc, GMAC_CHAN_RX_CONTROL(0));
852         reg &= ~GMAC_CHAN_RX_CONTROL_SR;
853         dwqe_write(sc, GMAC_CHAN_RX_CONTROL(0), reg);
854
855         /* Stop transmit DMA */
856         reg = dwqe_read(sc, GMAC_CHAN_TX_CONTROL(0));
857         reg &= ~GMAC_CHAN_TX_CONTROL_ST;
858         dwqe_write(sc, GMAC_CHAN_TX_CONTROL(0), reg);
859
860         /* Flush data in the TX FIFO */
861         reg = dwqe_read(sc, GMAC_MTL_CHAN_TX_OP_MODE(0));
862         reg |= GMAC_MTL_CHAN_TX_OP_MODE_FTQ;
863         dwqe_write(sc, GMAC_MTL_CHAN_TX_OP_MODE(0), reg);
864         /* Wait for flush to complete */
865         for (i = 10000; i > 0; i--) {
866                 reg = dwqe_read(sc, GMAC_MTL_CHAN_TX_OP_MODE(0));
867                 if ((reg & GMAC_MTL_CHAN_TX_OP_MODE_FTQ) == 0)
868                         break;
869                 delay(1);
870         }
871         if (i == 0) {
872                 printf("%s: timeout flushing TX queue\n",
873                     sc->sc_dev.dv_xname);
874         }
875
876         /* Disable transmitter */
877         reg = dwqe_read(sc, GMAC_MAC_CONF);
878         reg &= ~GMAC_MAC_CONF_TE;
879         dwqe_write(sc, GMAC_MAC_CONF, reg);
880
881         dwqe_write(sc, GMAC_CHAN_INTR_ENA(0), 0);
882
883         intr_barrier(sc->sc_ih);
884         ifq_barrier(&ifp->if_snd);
885
886         for (i = 0; i < DWQE_NTXDESC; i++) {
887                 txb = &sc->sc_txbuf[i];
888                 if (txb->tb_m) {
889                         bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0,
890                             txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
891                         bus_dmamap_unload(sc->sc_dmat, txb->tb_map);
892                         m_freem(txb->tb_m);
893                 }
894                 bus_dmamap_destroy(sc->sc_dmat, txb->tb_map);
895         }
896
897         dwqe_dmamem_free(sc, sc->sc_txring);
898         free(sc->sc_txbuf, M_DEVBUF, 0);
899
900         for (i = 0; i < DWQE_NRXDESC; i++) {
901                 rxb = &sc->sc_rxbuf[i];
902                 if (rxb->tb_m) {
903                         bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0,
904                             rxb->tb_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
905                         bus_dmamap_unload(sc->sc_dmat, rxb->tb_map);
906                         m_freem(rxb->tb_m);
907                 }
908                 bus_dmamap_destroy(sc->sc_dmat, rxb->tb_map);
909         }
910
911         dwqe_dmamem_free(sc, sc->sc_rxring);
912         free(sc->sc_rxbuf, M_DEVBUF, 0);
913 }
914
915 /* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
916 static uint32_t
917 bitrev32(uint32_t x)
918 {
919         x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
920         x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
921         x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
922         x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
923
924         return (x >> 16) | (x << 16);
925 }
926
927 void
928 dwqe_iff(struct dwqe_softc *sc)
929 {
930         struct arpcom *ac = &sc->sc_ac;
931         struct ifnet *ifp = &sc->sc_ac.ac_if;
932         struct ether_multi *enm;
933         struct ether_multistep step;
934         uint32_t crc, hash[2], hashbit, hashreg;
935         uint32_t reg;
936
937         reg = 0;
938
939         ifp->if_flags &= ~IFF_ALLMULTI;
940         bzero(hash, sizeof(hash));
941         if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
942                 ifp->if_flags |= IFF_ALLMULTI;
943                 reg |= GMAC_MAC_PACKET_FILTER_PM;
944                 if (ifp->if_flags & IFF_PROMISC)
945                         reg |= GMAC_MAC_PACKET_FILTER_PR |
946                             GMAC_MAC_PACKET_FILTER_PCF_ALL;
947         } else {
948                 reg |= GMAC_MAC_PACKET_FILTER_HMC;
949                 ETHER_FIRST_MULTI(step, ac, enm);
950                 while (enm != NULL) {
951                         crc = ether_crc32_le(enm->enm_addrlo,
952                             ETHER_ADDR_LEN) & 0x7f;
953
954                         crc = bitrev32(~crc) >> 26;
955                         hashreg = (crc >> 5);
956                         hashbit = (crc & 0x1f);
957                         hash[hashreg] |= (1 << hashbit);
958
959                         ETHER_NEXT_MULTI(step, enm);
960                 }
961         }
962
963         dwqe_lladdr_write(sc);
964
965         dwqe_write(sc, GMAC_MAC_HASH_TAB_REG0, hash[0]);
966         dwqe_write(sc, GMAC_MAC_HASH_TAB_REG1, hash[1]);
967
968         dwqe_write(sc, GMAC_MAC_PACKET_FILTER, reg);
969 }
970
971 int
972 dwqe_encap(struct dwqe_softc *sc, struct mbuf *m, int *idx, int *used)
973 {
974         struct dwqe_desc *txd, *txd_start;
975         bus_dmamap_t map;
976         int cur, frag, i;
977
978         cur = frag = *idx;
979         map = sc->sc_txbuf[cur].tb_map;
980
981         if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) {
982                 if (m_defrag(m, M_DONTWAIT))
983                         return (EFBIG);
984                 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT))
985                         return (EFBIG);
986         }
987
988         /* Sync the DMA map. */
989         bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
990             BUS_DMASYNC_PREWRITE);
991
992         txd = txd_start = &sc->sc_txdesc[frag];
993         for (i = 0; i < map->dm_nsegs; i++) {
994                 /* TODO: check for 32-bit vs 64-bit support */
995                 KASSERT((map->dm_segs[i].ds_addr >> 32) == 0);
996
997                 txd->sd_tdes0 = (uint32_t)map->dm_segs[i].ds_addr;
998                 txd->sd_tdes1 = (uint32_t)(map->dm_segs[i].ds_addr >> 32);
999                 txd->sd_tdes2 = map->dm_segs[i].ds_len;
1000                 txd->sd_tdes3 = m->m_pkthdr.len;
1001                 if (i == 0)
1002                         txd->sd_tdes3 |= TDES3_FS;
1003                 if (i == (map->dm_nsegs - 1)) {
1004                         txd->sd_tdes2 |= TDES2_IC;
1005                         txd->sd_tdes3 |= TDES3_LS;
1006                 }
1007                 if (i != 0)
1008                         txd->sd_tdes3 |= TDES3_OWN;
1009
1010                 bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_txring),
1011                     frag * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE);
1012
1013                 cur = frag;
1014                 if (frag == (DWQE_NTXDESC - 1)) {
1015                         txd = &sc->sc_txdesc[0];
1016                         frag = 0;
1017                 } else {
1018                         txd++;
1019                         frag++;
1020                 }
1021                 KASSERT(frag != sc->sc_tx_cons);
1022         }
1023
1024         txd_start->sd_tdes3 |= TDES3_OWN;
1025         bus_dmamap_sync(sc->sc_dmat, DWQE_DMA_MAP(sc->sc_txring),
1026             *idx * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE);
1027
1028         dwqe_write(sc, GMAC_CHAN_TX_END_ADDR(0), DWQE_DMA_DVA(sc->sc_txring) +
1029             frag * sizeof(*txd));
1030
1031         KASSERT(sc->sc_txbuf[cur].tb_m == NULL);
1032         sc->sc_txbuf[*idx].tb_map = sc->sc_txbuf[cur].tb_map;
1033         sc->sc_txbuf[cur].tb_map = map;
1034         sc->sc_txbuf[cur].tb_m = m;
1035
1036         *idx = frag;
1037         *used += map->dm_nsegs;
1038
1039         return (0);
1040 }
1041
1042 void
1043 dwqe_reset(struct dwqe_softc *sc)
1044 {
1045         int n;
1046
1047         dwqe_write(sc, GMAC_BUS_MODE, dwqe_read(sc, GMAC_BUS_MODE) |
1048             GMAC_BUS_MODE_SWR);
1049
1050         for (n = 0; n < 30000; n++) {
1051                 if ((dwqe_read(sc, GMAC_BUS_MODE) &
1052                     GMAC_BUS_MODE_SWR) == 0)
1053                         return;
1054                 delay(10);
1055         }
1056
1057         printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
1058 }
1059
1060 struct dwqe_dmamem *
1061 dwqe_dmamem_alloc(struct dwqe_softc *sc, bus_size_t size, bus_size_t align)
1062 {
1063         struct dwqe_dmamem *tdm;
1064         int nsegs;
1065
1066         tdm = malloc(sizeof(*tdm), M_DEVBUF, M_WAITOK | M_ZERO);
1067         tdm->tdm_size = size;
1068
1069         if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
1070             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0)
1071                 goto tdmfree;
1072
1073         if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &tdm->tdm_seg, 1,
1074             &nsegs, BUS_DMA_WAITOK) != 0)
1075                 goto destroy;
1076
1077         if (bus_dmamem_map(sc->sc_dmat, &tdm->tdm_seg, nsegs, size,
1078             &tdm->tdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0)
1079                 goto free;
1080
1081         if (bus_dmamap_load(sc->sc_dmat, tdm->tdm_map, tdm->tdm_kva, size,
1082             NULL, BUS_DMA_WAITOK) != 0)
1083                 goto unmap;
1084
1085         bzero(tdm->tdm_kva, size);
1086
1087         return (tdm);
1088
1089 unmap:
1090         bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, size);
1091 free:
1092         bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1);
1093 destroy:
1094         bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map);
1095 tdmfree:
1096         free(tdm, M_DEVBUF, 0);
1097
1098         return (NULL);
1099 }
1100
1101 void
1102 dwqe_dmamem_free(struct dwqe_softc *sc, struct dwqe_dmamem *tdm)
1103 {
1104         bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, tdm->tdm_size);
1105         bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1);
1106         bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map);
1107         free(tdm, M_DEVBUF, 0);
1108 }
1109
1110 struct mbuf *
1111 dwqe_alloc_mbuf(struct dwqe_softc *sc, bus_dmamap_t map)
1112 {
1113         struct mbuf *m = NULL;
1114
1115         m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES);
1116         if (!m)
1117                 return (NULL);
1118         m->m_len = m->m_pkthdr.len = MCLBYTES;
1119         m_adj(m, ETHER_ALIGN);
1120
1121         if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) {
1122                 printf("%s: could not load mbuf DMA map", DEVNAME(sc));
1123                 m_freem(m);
1124                 return (NULL);
1125         }
1126
1127         bus_dmamap_sync(sc->sc_dmat, map, 0,
1128             m->m_pkthdr.len, BUS_DMASYNC_PREREAD);
1129
1130         return (m);
1131 }
1132
1133 void
1134 dwqe_fill_rx_ring(struct dwqe_softc *sc)
1135 {
1136         struct dwqe_desc *rxd;
1137         struct dwqe_buf *rxb;
1138         u_int slots;
1139
1140         for (slots = if_rxr_get(&sc->sc_rx_ring, DWQE_NRXDESC);
1141             slots > 0; slots--) {
1142                 rxb = &sc->sc_rxbuf[sc->sc_rx_prod];
1143                 rxb->tb_m = dwqe_alloc_mbuf(sc, rxb->tb_map);
1144                 if (rxb->tb_m == NULL)
1145                         break;
1146
1147                 /* TODO: check for 32-bit vs 64-bit support */
1148                 KASSERT((rxb->tb_map->dm_segs[0].ds_addr >> 32) == 0);
1149
1150                 rxd = &sc->sc_rxdesc[sc->sc_rx_prod];
1151                 rxd->sd_tdes0 = (uint32_t)rxb->tb_map->dm_segs[0].ds_addr;
1152                 rxd->sd_tdes1 = (uint32_t)(rxb->tb_map->dm_segs[0].ds_addr >> 32);
1153                 rxd->sd_tdes2 = 0;
1154                 rxd->sd_tdes3 = RDES3_OWN | RDES3_IC | RDES3_BUF1V;
1155
1156                 if (sc->sc_rx_prod == (DWQE_NRXDESC - 1))
1157                         sc->sc_rx_prod = 0;
1158                 else
1159                         sc->sc_rx_prod++;
1160         }
1161         if_rxr_put(&sc->sc_rx_ring, slots);
1162
1163         dwqe_write(sc, GMAC_CHAN_RX_END_ADDR(0), DWQE_DMA_DVA(sc->sc_rxring) +
1164             sc->sc_rx_prod * sizeof(*rxd));
1165
1166         if (if_rxr_inuse(&sc->sc_rx_ring) == 0)
1167                 timeout_add(&sc->sc_rxto, 1);
1168 }