xref: /openbsd-src/sys/dev/fdt/if_dwge.c (revision fc405d53b73a2d73393cb97f684863d17b583e38)
1 /*	$OpenBSD: if_dwge.c,v 1.15 2023/02/26 13:28:12 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
4  * Copyright (c) 2017 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 /* Registers */
61 
62 #define GMAC_MAC_CONF		0x0000
63 #define  GMAC_MAC_CONF_JD		(1 << 22)
64 #define  GMAC_MAC_CONF_BE		(1 << 21)
65 #define  GMAC_MAC_CONF_DCRS		(1 << 16)
66 #define  GMAC_MAC_CONF_PS		(1 << 15)
67 #define  GMAC_MAC_CONF_FES		(1 << 14)
68 #define  GMAC_MAC_CONF_LM		(1 << 12)
69 #define  GMAC_MAC_CONF_DM		(1 << 11)
70 #define  GMAC_MAC_CONF_TE		(1 << 3)
71 #define  GMAC_MAC_CONF_RE		(1 << 2)
72 #define GMAC_MAC_FRM_FILT	0x0004
73 #define  GMAC_MAC_FRM_FILT_PM		(1 << 4)
74 #define  GMAC_MAC_FRM_FILT_HMC		(1 << 2)
75 #define  GMAC_MAC_FRM_FILT_PR		(1 << 0)
76 #define GMAC_HASH_TAB_HI	0x0008
77 #define GMAC_HASH_TAB_LO	0x000c
78 #define GMAC_GMII_ADDR		0x0010
79 #define  GMAC_GMII_ADDR_PA_SHIFT	11
80 #define  GMAC_GMII_ADDR_GR_SHIFT	6
81 #define  GMAC_GMII_ADDR_CR_SHIFT	2
82 #define  GMAC_GMII_ADDR_CR_MASK		0xf
83 #define  GMAC_GMII_ADDR_CR_DIV_42	0
84 #define  GMAC_GMII_ADDR_CR_DIV_62	1
85 #define  GMAC_GMII_ADDR_CR_DIV_16	2
86 #define  GMAC_GMII_ADDR_CR_DIV_26	3
87 #define  GMAC_GMII_ADDR_CR_DIV_102	4
88 #define  GMAC_GMII_ADDR_CR_DIV_124	5
89 #define  GMAC_GMII_ADDR_GW		(1 << 1)
90 #define  GMAC_GMII_ADDR_GB		(1 << 0)
91 #define GMAC_GMII_DATA		0x0014
92 #define GMAC_VERSION		0x0020
93 #define  GMAC_VERSION_SNPS_MASK		0xff
94 #define GMAC_INT_MASK		0x003c
95 #define  GMAC_INT_MASK_LPIIM		(1 << 10)
96 #define  GMAC_INT_MASK_PIM		(1 << 3)
97 #define  GMAC_INT_MASK_RIM		(1 << 0)
98 #define GMAC_MAC_ADDR0_HI	0x0040
99 #define GMAC_MAC_ADDR0_LO	0x0044
100 #define GMAC_MMC_RX_INT_MSK	0x010c
101 #define GMAC_MMC_TX_INT_MSK	0x0110
102 #define GMAC_MMC_IPC_INT_MSK	0x0200
103 #define GMAC_BUS_MODE		0x1000
104 #define  GMAC_BUS_MODE_8XPBL		(1 << 24)
105 #define  GMAC_BUS_MODE_USP		(1 << 23)
106 #define  GMAC_BUS_MODE_RPBL_MASK	(0x3f << 17)
107 #define  GMAC_BUS_MODE_RPBL_SHIFT	17
108 #define  GMAC_BUS_MODE_FB		(1 << 16)
109 #define  GMAC_BUS_MODE_PBL_MASK		(0x3f << 8)
110 #define  GMAC_BUS_MODE_PBL_SHIFT	8
111 #define  GMAC_BUS_MODE_SWR		(1 << 0)
112 #define GMAC_TX_POLL_DEMAND	0x1004
113 #define GMAC_RX_DESC_LIST_ADDR	0x100c
114 #define GMAC_TX_DESC_LIST_ADDR	0x1010
115 #define GMAC_STATUS		0x1014
116 #define  GMAC_STATUS_RI			(1 << 6)
117 #define  GMAC_STATUS_TU			(1 << 2)
118 #define  GMAC_STATUS_TI			(1 << 0)
119 #define GMAC_OP_MODE		0x1018
120 #define  GMAC_OP_MODE_RSF		(1 << 25)
121 #define  GMAC_OP_MODE_TSF		(1 << 21)
122 #define  GMAC_OP_MODE_FTF		(1 << 20)
123 #define  GMAC_OP_MODE_TTC_MASK		(0x7 << 14)
124 #define  GMAC_OP_MODE_TTC_64		(0x0 << 14)
125 #define  GMAC_OP_MODE_TTC_128		(0x1 << 14)
126 #define  GMAC_OP_MODE_ST		(1 << 13)
127 #define  GMAC_OP_MODE_RTC_MASK		(0x3 << 3)
128 #define  GMAC_OP_MODE_RTC_64		(0x0 << 3)
129 #define  GMAC_OP_MODE_RTC_128		(0x3 << 3)
130 #define  GMAC_OP_MODE_OSF		(1 << 2)
131 #define  GMAC_OP_MODE_SR		(1 << 1)
132 #define GMAC_INT_ENA		0x101c
133 #define  GMAC_INT_ENA_NIE		(1 << 16)
134 #define  GMAC_INT_ENA_RIE		(1 << 6)
135 #define  GMAC_INT_ENA_TUE		(1 << 2)
136 #define  GMAC_INT_ENA_TIE		(1 << 0)
137 #define GMAC_AXI_BUS_MODE	0x1028
138 #define  GMAC_AXI_BUS_MODE_WR_OSR_LMT_MASK	(0xf << 20)
139 #define  GMAC_AXI_BUS_MODE_WR_OSR_LMT_SHIFT	20
140 #define  GMAC_AXI_BUS_MODE_RD_OSR_LMT_MASK	(0xf << 16)
141 #define  GMAC_AXI_BUS_MODE_RD_OSR_LMT_SHIFT	16
142 #define  GMAC_AXI_BUS_MODE_BLEN_256		(1 << 7)
143 #define  GMAC_AXI_BUS_MODE_BLEN_128		(1 << 6)
144 #define  GMAC_AXI_BUS_MODE_BLEN_64		(1 << 5)
145 #define  GMAC_AXI_BUS_MODE_BLEN_32		(1 << 4)
146 #define  GMAC_AXI_BUS_MODE_BLEN_16		(1 << 3)
147 #define  GMAC_AXI_BUS_MODE_BLEN_8		(1 << 2)
148 #define  GMAC_AXI_BUS_MODE_BLEN_4		(1 << 1)
149 #define GMAC_HW_FEATURE		0x1058
150 #define  GMAC_HW_FEATURE_ENHDESSEL	(1 << 24)
151 
152 /*
153  * DWGE descriptors.
154  */
155 
156 struct dwge_desc {
157 	uint32_t sd_status;
158 	uint32_t sd_len;
159 	uint32_t sd_addr;
160 	uint32_t sd_next;
161 };
162 
163 /* Tx status bits. */
164 #define TDES0_DB		(1 << 0)
165 #define TDES0_UF		(1 << 1)
166 #define TDES0_ED		(1 << 2)
167 #define TDES0_CC_MASK		(0xf << 3)
168 #define TDES0_CC_SHIFT		3
169 #define TDES0_EC		(1 << 8)
170 #define TDES0_LC		(1 << 9)
171 #define TDES0_NC		(1 << 10)
172 #define TDES0_PCE		(1 << 12)
173 #define TDES0_JT		(1 << 14)
174 #define TDES0_IHE		(1 << 16)
175 #define TDES0_OWN		(1 << 31)
176 
177 #define ETDES0_TCH		(1 << 20)
178 #define ETDES0_FS		(1 << 28)
179 #define ETDES0_LS		(1 << 29)
180 #define ETDES0_IC		(1 << 30)
181 
182 /* Rx status bits */
183 #define RDES0_PE		(1 << 0)
184 #define RDES0_CE		(1 << 1)
185 #define RDES0_RE		(1 << 3)
186 #define RDES0_RWT		(1 << 4)
187 #define RDES0_FT		(1 << 5)
188 #define RDES0_LC		(1 << 6)
189 #define RDES0_IPC		(1 << 7)
190 #define RDES0_LS		(1 << 8)
191 #define RDES0_FS		(1 << 9)
192 #define RDES0_OE		(1 << 11)
193 #define RDES0_SAF		(1 << 13)
194 #define RDES0_DE		(1 << 14)
195 #define RDES0_FL_MASK		0x3fff
196 #define RDES0_FL_SHIFT		16
197 #define RDES0_AFM		(1 << 30)
198 #define RDES0_OWN		(1 << 31)
199 
200 /* Tx size bits */
201 #define TDES1_TBS1		(0xfff << 0)
202 #define TDES1_TCH		(1 << 24)
203 #define TDES1_DC		(1 << 26)
204 #define TDES1_CIC_MASK		(0x3 << 27)
205 #define TDES1_CIC_IP		(1 << 27)
206 #define TDES1_CIC_NO_PSE	(2 << 27)
207 #define TDES1_CIC_FULL		(3 << 27)
208 #define TDES1_FS		(1 << 29)
209 #define TDES1_LS		(1 << 30)
210 #define TDES1_IC		(1 << 31)
211 
212 /* Rx size bits */
213 #define RDES1_RBS1		(0xfff << 0)
214 #define RDES1_RCH		(1 << 24)
215 #define RDES1_DIC		(1 << 31)
216 
217 #define ERDES1_RCH		(1 << 14)
218 
219 struct dwge_buf {
220 	bus_dmamap_t	tb_map;
221 	struct mbuf	*tb_m;
222 };
223 
224 #define DWGE_NTXDESC	512
225 #define DWGE_NTXSEGS	16
226 
227 #define DWGE_NRXDESC	512
228 
229 struct dwge_dmamem {
230 	bus_dmamap_t		tdm_map;
231 	bus_dma_segment_t	tdm_seg;
232 	size_t			tdm_size;
233 	caddr_t			tdm_kva;
234 };
235 #define DWGE_DMA_MAP(_tdm)	((_tdm)->tdm_map)
236 #define DWGE_DMA_LEN(_tdm)	((_tdm)->tdm_size)
237 #define DWGE_DMA_DVA(_tdm)	((_tdm)->tdm_map->dm_segs[0].ds_addr)
238 #define DWGE_DMA_KVA(_tdm)	((void *)(_tdm)->tdm_kva)
239 
240 struct dwge_softc {
241 	struct device		sc_dev;
242 	int			sc_node;
243 	bus_space_tag_t		sc_iot;
244 	bus_space_handle_t	sc_ioh;
245 	bus_dma_tag_t		sc_dmat;
246 	void			*sc_ih;
247 
248 	struct arpcom		sc_ac;
249 #define sc_lladdr	sc_ac.ac_enaddr
250 	struct mii_data		sc_mii;
251 #define sc_media	sc_mii.mii_media
252 	int			sc_link;
253 	int			sc_phyloc;
254 	int			sc_force_thresh_dma_mode;
255 	int			sc_enh_desc;
256 	int			sc_defrag;
257 
258 	struct dwge_dmamem	*sc_txring;
259 	struct dwge_buf		*sc_txbuf;
260 	struct dwge_desc	*sc_txdesc;
261 	int			sc_tx_prod;
262 	int			sc_tx_cons;
263 
264 	struct dwge_dmamem	*sc_rxring;
265 	struct dwge_buf		*sc_rxbuf;
266 	struct dwge_desc	*sc_rxdesc;
267 	int			sc_rx_prod;
268 	struct if_rxring	sc_rx_ring;
269 	int			sc_rx_cons;
270 
271 	struct timeout		sc_tick;
272 	struct timeout		sc_rxto;
273 
274 	uint32_t		sc_clk;
275 
276 	bus_size_t		sc_clk_sel;
277 	uint32_t		sc_clk_sel_125;
278 	uint32_t		sc_clk_sel_25;
279 	uint32_t		sc_clk_sel_2_5;
280 };
281 
282 #define DEVNAME(_s)	((_s)->sc_dev.dv_xname)
283 
284 int	dwge_match(struct device *, void *, void *);
285 void	dwge_attach(struct device *, struct device *, void *);
286 void	dwge_setup_allwinner(struct dwge_softc *);
287 void	dwge_setup_rockchip(struct dwge_softc *);
288 
289 const struct cfattach dwge_ca = {
290 	sizeof(struct dwge_softc), dwge_match, dwge_attach
291 };
292 
293 struct cfdriver dwge_cd = {
294 	NULL, "dwge", DV_IFNET
295 };
296 
297 void	dwge_reset_phy(struct dwge_softc *);
298 
299 uint32_t dwge_read(struct dwge_softc *, bus_addr_t);
300 void	dwge_write(struct dwge_softc *, bus_addr_t, uint32_t);
301 
302 int	dwge_ioctl(struct ifnet *, u_long, caddr_t);
303 void	dwge_start(struct ifqueue *);
304 void	dwge_watchdog(struct ifnet *);
305 
306 int	dwge_media_change(struct ifnet *);
307 void	dwge_media_status(struct ifnet *, struct ifmediareq *);
308 
309 int	dwge_mii_readreg(struct device *, int, int);
310 void	dwge_mii_writereg(struct device *, int, int, int);
311 void	dwge_mii_statchg(struct device *);
312 
313 void	dwge_lladdr_read(struct dwge_softc *, uint8_t *);
314 void	dwge_lladdr_write(struct dwge_softc *);
315 
316 void	dwge_tick(void *);
317 void	dwge_rxtick(void *);
318 
319 int	dwge_intr(void *);
320 void	dwge_tx_proc(struct dwge_softc *);
321 void	dwge_rx_proc(struct dwge_softc *);
322 
323 void	dwge_up(struct dwge_softc *);
324 void	dwge_down(struct dwge_softc *);
325 void	dwge_iff(struct dwge_softc *);
326 int	dwge_encap(struct dwge_softc *, struct mbuf *, int *, int *);
327 
328 void	dwge_reset(struct dwge_softc *);
329 void	dwge_stop_dma(struct dwge_softc *);
330 
331 struct dwge_dmamem *
332 	dwge_dmamem_alloc(struct dwge_softc *, bus_size_t, bus_size_t);
333 void	dwge_dmamem_free(struct dwge_softc *, struct dwge_dmamem *);
334 struct mbuf *dwge_alloc_mbuf(struct dwge_softc *, bus_dmamap_t);
335 void	dwge_fill_rx_ring(struct dwge_softc *);
336 
337 int
338 dwge_match(struct device *parent, void *cfdata, void *aux)
339 {
340 	struct fdt_attach_args *faa = aux;
341 
342 	return (OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-gmac") ||
343 	    OF_is_compatible(faa->fa_node, "amlogic,meson-axg-dwmac") ||
344 	    OF_is_compatible(faa->fa_node, "amlogic,meson-g12a-dwmac") ||
345 	    OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") ||
346 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") ||
347 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") ||
348 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-gmac") ||
349 	    OF_is_compatible(faa->fa_node, "snps,dwmac"));
350 }
351 
352 void
353 dwge_attach(struct device *parent, struct device *self, void *aux)
354 {
355 	struct dwge_softc *sc = (void *)self;
356 	struct fdt_attach_args *faa = aux;
357 	struct ifnet *ifp;
358 	uint32_t phy, phy_supply;
359 	uint32_t axi_config;
360 	uint32_t mode, pbl;
361 	uint32_t version;
362 	uint32_t feature;
363 	int node;
364 
365 	sc->sc_node = faa->fa_node;
366 	sc->sc_iot = faa->fa_iot;
367 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
368 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
369 		printf("%s: cannot map registers\n", self->dv_xname);
370 		return;
371 	}
372 	sc->sc_dmat = faa->fa_dmat;
373 
374 	/* Lookup PHY. */
375 	phy = OF_getpropint(faa->fa_node, "phy", 0);
376 	if (phy == 0)
377 		phy = OF_getpropint(faa->fa_node, "phy-handle", 0);
378 	node = OF_getnodebyphandle(phy);
379 	if (node)
380 		sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY);
381 	else
382 		sc->sc_phyloc = MII_PHY_ANY;
383 
384 	pinctrl_byname(faa->fa_node, "default");
385 
386 	/* Enable clocks. */
387 	clock_set_assigned(faa->fa_node);
388 	clock_enable(faa->fa_node, "stmmaceth");
389 	reset_deassert(faa->fa_node, "stmmaceth");
390 	if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") ||
391 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") ||
392 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") ||
393 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-gmac")) {
394 		clock_enable(faa->fa_node, "mac_clk_rx");
395 		clock_enable(faa->fa_node, "mac_clk_tx");
396 		clock_enable(faa->fa_node, "aclk_mac");
397 		clock_enable(faa->fa_node, "pclk_mac");
398 	}
399 	delay(5000);
400 
401 	version = dwge_read(sc, GMAC_VERSION);
402 	printf(": rev 0x%02x", version & GMAC_VERSION_SNPS_MASK);
403 
404 	if ((version & GMAC_VERSION_SNPS_MASK) > 0x35) {
405 		feature = dwge_read(sc, GMAC_HW_FEATURE);
406 		if (feature & GMAC_HW_FEATURE_ENHDESSEL)
407 			sc->sc_enh_desc = 1;
408 	}
409 
410 	/*
411 	 * The GMAC on the StarFive JH7100 (core version 3.70)
412 	 * sometimes transmits corrupted packets.  The exact
413 	 * conditions under which this happens are unclear, but
414 	 * defragmenting mbufs before transmitting them fixes the
415 	 * issue.
416 	 */
417 	if (OF_is_compatible(faa->fa_node, "starfive,jh7100-gmac"))
418 		sc->sc_defrag = 1;
419 
420 	/* Power up PHY. */
421 	phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0);
422 	if (phy_supply)
423 		regulator_enable(phy_supply);
424 
425 	/* Reset PHY */
426 	dwge_reset_phy(sc);
427 
428 	sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth");
429 	if (sc->sc_clk > 250000000)
430 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_124;
431 	else if (sc->sc_clk > 150000000)
432 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_102;
433 	else if (sc->sc_clk > 100000000)
434 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_62;
435 	else if (sc->sc_clk > 60000000)
436 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_42;
437 	else if (sc->sc_clk > 35000000)
438 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_26;
439 	else
440 		sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_16;
441 
442 	if (OF_getprop(faa->fa_node, "local-mac-address",
443 	    &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN)
444 		dwge_lladdr_read(sc, sc->sc_lladdr);
445 	printf(", address %s\n", ether_sprintf(sc->sc_lladdr));
446 
447 	timeout_set(&sc->sc_tick, dwge_tick, sc);
448 	timeout_set(&sc->sc_rxto, dwge_rxtick, sc);
449 
450 	ifp = &sc->sc_ac.ac_if;
451 	ifp->if_softc = sc;
452 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
453 	ifp->if_xflags = IFXF_MPSAFE;
454 	ifp->if_ioctl = dwge_ioctl;
455 	ifp->if_qstart = dwge_start;
456 	ifp->if_watchdog = dwge_watchdog;
457 	ifq_set_maxlen(&ifp->if_snd, DWGE_NTXDESC - 1);
458 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
459 
460 	ifp->if_capabilities = IFCAP_VLAN_MTU;
461 
462 	sc->sc_mii.mii_ifp = ifp;
463 	sc->sc_mii.mii_readreg = dwge_mii_readreg;
464 	sc->sc_mii.mii_writereg = dwge_mii_writereg;
465 	sc->sc_mii.mii_statchg = dwge_mii_statchg;
466 
467 	ifmedia_init(&sc->sc_media, 0, dwge_media_change, dwge_media_status);
468 
469 	/* Do hardware specific initializations. */
470 	if (OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-gmac"))
471 		dwge_setup_allwinner(sc);
472 	if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") ||
473 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") ||
474 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") ||
475 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-gmac"))
476 		dwge_setup_rockchip(sc);
477 
478 	if (OF_getpropbool(faa->fa_node, "snps,force_thresh_dma_mode"))
479 		sc->sc_force_thresh_dma_mode = 1;
480 
481 	dwge_reset(sc);
482 
483 	/* Configure MAC. */
484 	dwge_write(sc, GMAC_MAC_CONF, dwge_read(sc, GMAC_MAC_CONF) |
485 	    GMAC_MAC_CONF_JD | GMAC_MAC_CONF_BE | GMAC_MAC_CONF_DCRS);
486 
487 	/* Configure DMA engine. */
488 	mode = dwge_read(sc, GMAC_BUS_MODE);
489 	mode |= GMAC_BUS_MODE_USP;
490 	if (!OF_getpropbool(faa->fa_node, "snps,no-pbl-x8"))
491 		mode |= GMAC_BUS_MODE_8XPBL;
492 	mode &= ~(GMAC_BUS_MODE_RPBL_MASK | GMAC_BUS_MODE_PBL_MASK);
493 	pbl = OF_getpropint(faa->fa_node, "snps,pbl", 8);
494 	mode |= pbl << GMAC_BUS_MODE_RPBL_SHIFT;
495 	mode |= pbl << GMAC_BUS_MODE_PBL_SHIFT;
496 	if (OF_getpropbool(faa->fa_node, "snps,fixed-burst"))
497 		mode |= GMAC_BUS_MODE_FB;
498 	dwge_write(sc, GMAC_BUS_MODE, mode);
499 
500 	/* Configure AXI master. */
501 	axi_config = OF_getpropint(faa->fa_node, "snps,axi-config", 0);
502 	node = OF_getnodebyphandle(axi_config);
503 	if (node) {
504 		uint32_t blen[7] = { 0 };
505 		uint32_t osr_lmt;
506 		int i;
507 
508 		mode = dwge_read(sc, GMAC_AXI_BUS_MODE);
509 
510 		osr_lmt = OF_getpropint(node, "snps,wr_osr_lmt", 1);
511 		mode &= ~GMAC_AXI_BUS_MODE_WR_OSR_LMT_MASK;
512 		mode |= (osr_lmt << GMAC_AXI_BUS_MODE_WR_OSR_LMT_SHIFT);
513 		osr_lmt = OF_getpropint(node, "snps,rd_osr_lmt", 1);
514 		mode &= ~GMAC_AXI_BUS_MODE_RD_OSR_LMT_MASK;
515 		mode |= (osr_lmt << GMAC_AXI_BUS_MODE_RD_OSR_LMT_SHIFT);
516 
517 		OF_getpropintarray(node, "snps,blen", blen, sizeof(blen));
518 		for (i = 0; i < nitems(blen); i++) {
519 			switch (blen[i]) {
520 			case 256:
521 				mode |= GMAC_AXI_BUS_MODE_BLEN_256;
522 				break;
523 			case 128:
524 				mode |= GMAC_AXI_BUS_MODE_BLEN_128;
525 				break;
526 			case 64:
527 				mode |= GMAC_AXI_BUS_MODE_BLEN_64;
528 				break;
529 			case 32:
530 				mode |= GMAC_AXI_BUS_MODE_BLEN_32;
531 				break;
532 			case 16:
533 				mode |= GMAC_AXI_BUS_MODE_BLEN_16;
534 				break;
535 			case 8:
536 				mode |= GMAC_AXI_BUS_MODE_BLEN_8;
537 				break;
538 			case 4:
539 				mode |= GMAC_AXI_BUS_MODE_BLEN_4;
540 				break;
541 			}
542 		}
543 
544 		dwge_write(sc, GMAC_AXI_BUS_MODE, mode);
545 	}
546 
547 	mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc,
548 	    (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, 0);
549 	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
550 		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
551 		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
552 		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
553 	} else
554 		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
555 
556 	if_attach(ifp);
557 	ether_ifattach(ifp);
558 
559 	/* Disable interrupts. */
560 	dwge_write(sc, GMAC_INT_ENA, 0);
561 	dwge_write(sc, GMAC_INT_MASK,
562 	    GMAC_INT_MASK_LPIIM | GMAC_INT_MASK_PIM | GMAC_INT_MASK_RIM);
563 	dwge_write(sc, GMAC_MMC_RX_INT_MSK, 0xffffffff);
564 	dwge_write(sc, GMAC_MMC_TX_INT_MSK, 0xffffffff);
565 	dwge_write(sc, GMAC_MMC_IPC_INT_MSK, 0xffffffff);
566 
567 	sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_NET | IPL_MPSAFE,
568 	    dwge_intr, sc, sc->sc_dev.dv_xname);
569 	if (sc->sc_ih == NULL)
570 		printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
571 }
572 
573 void
574 dwge_reset_phy(struct dwge_softc *sc)
575 {
576 	uint32_t *gpio;
577 	uint32_t delays[3];
578 	int active = 1;
579 	int len;
580 
581 	len = OF_getproplen(sc->sc_node, "snps,reset-gpio");
582 	if (len <= 0)
583 		return;
584 
585 	gpio = malloc(len, M_TEMP, M_WAITOK);
586 
587 	/* Gather information. */
588 	OF_getpropintarray(sc->sc_node, "snps,reset-gpio", gpio, len);
589 	if (OF_getpropbool(sc->sc_node, "snps-reset-active-low"))
590 		active = 0;
591 	delays[0] = delays[1] = delays[2] = 0;
592 	OF_getpropintarray(sc->sc_node, "snps,reset-delays-us", delays,
593 	    sizeof(delays));
594 
595 	/* Perform reset sequence. */
596 	gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
597 	gpio_controller_set_pin(gpio, !active);
598 	delay(delays[0]);
599 	gpio_controller_set_pin(gpio, active);
600 	delay(delays[1]);
601 	gpio_controller_set_pin(gpio, !active);
602 	delay(delays[2]);
603 
604 	free(gpio, M_TEMP, len);
605 }
606 
607 uint32_t
608 dwge_read(struct dwge_softc *sc, bus_addr_t addr)
609 {
610 	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, addr);
611 }
612 
613 void
614 dwge_write(struct dwge_softc *sc, bus_addr_t addr, uint32_t data)
615 {
616 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, addr, data);
617 }
618 
619 void
620 dwge_lladdr_read(struct dwge_softc *sc, uint8_t *lladdr)
621 {
622 	uint32_t machi, maclo;
623 
624 	machi = dwge_read(sc, GMAC_MAC_ADDR0_HI);
625 	maclo = dwge_read(sc, GMAC_MAC_ADDR0_LO);
626 
627 	lladdr[0] = (maclo >> 0) & 0xff;
628 	lladdr[1] = (maclo >> 8) & 0xff;
629 	lladdr[2] = (maclo >> 16) & 0xff;
630 	lladdr[3] = (maclo >> 24) & 0xff;
631 	lladdr[4] = (machi >> 0) & 0xff;
632 	lladdr[5] = (machi >> 8) & 0xff;
633 }
634 
635 void
636 dwge_lladdr_write(struct dwge_softc *sc)
637 {
638 	dwge_write(sc, GMAC_MAC_ADDR0_HI,
639 	    sc->sc_lladdr[5] << 8 | sc->sc_lladdr[4] << 0);
640 	dwge_write(sc, GMAC_MAC_ADDR0_LO,
641 	    sc->sc_lladdr[3] << 24 | sc->sc_lladdr[2] << 16 |
642 	    sc->sc_lladdr[1] << 8 | sc->sc_lladdr[0] << 0);
643 }
644 
645 void
646 dwge_start(struct ifqueue *ifq)
647 {
648 	struct ifnet *ifp = ifq->ifq_if;
649 	struct dwge_softc *sc = ifp->if_softc;
650 	struct mbuf *m;
651 	int error, idx, left, used;
652 
653 	if (!(ifp->if_flags & IFF_RUNNING))
654 		return;
655 	if (ifq_is_oactive(&ifp->if_snd))
656 		return;
657 	if (ifq_empty(&ifp->if_snd))
658 		return;
659 	if (!sc->sc_link)
660 		return;
661 
662 	idx = sc->sc_tx_prod;
663 	left = sc->sc_tx_cons;
664 	if (left <= idx)
665 		left += DWGE_NTXDESC;
666 	left -= idx;
667 	used = 0;
668 
669 	for (;;) {
670 		if (used + DWGE_NTXSEGS + 1 > left) {
671 			ifq_set_oactive(ifq);
672 			break;
673 		}
674 
675 		m = ifq_dequeue(ifq);
676 		if (m == NULL)
677 			break;
678 
679 		error = dwge_encap(sc, m, &idx, &used);
680 		if (error == EFBIG) {
681 			m_freem(m); /* give up: drop it */
682 			ifp->if_oerrors++;
683 			continue;
684 		}
685 
686 #if NBPFILTER > 0
687 		if (ifp->if_bpf)
688 			bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
689 #endif
690 	}
691 
692 	if (sc->sc_tx_prod != idx) {
693 		sc->sc_tx_prod = idx;
694 
695 		/* Set a timeout in case the chip goes out to lunch. */
696 		ifp->if_timer = 5;
697 
698 		dwge_write(sc, GMAC_TX_POLL_DEMAND, 0xffffffff);
699 	}
700 }
701 
702 int
703 dwge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
704 {
705 	struct dwge_softc *sc = ifp->if_softc;
706 	struct ifreq *ifr = (struct ifreq *)addr;
707 	int error = 0, s;
708 
709 	s = splnet();
710 
711 	switch (cmd) {
712 	case SIOCSIFADDR:
713 		ifp->if_flags |= IFF_UP;
714 		/* FALLTHROUGH */
715 	case SIOCSIFFLAGS:
716 		if (ifp->if_flags & IFF_UP) {
717 			if (ifp->if_flags & IFF_RUNNING)
718 				error = ENETRESET;
719 			else
720 				dwge_up(sc);
721 		} else {
722 			if (ifp->if_flags & IFF_RUNNING)
723 				dwge_down(sc);
724 		}
725 		break;
726 
727 	case SIOCGIFMEDIA:
728 	case SIOCSIFMEDIA:
729 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
730 		break;
731 
732 	case SIOCGIFRXR:
733 		error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
734 		    NULL, MCLBYTES, &sc->sc_rx_ring);
735 		break;
736 
737 	default:
738 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr);
739 		break;
740 	}
741 
742 	if (error == ENETRESET) {
743 		if (ifp->if_flags & IFF_RUNNING)
744 			dwge_iff(sc);
745 		error = 0;
746 	}
747 
748 	splx(s);
749 	return (error);
750 }
751 
752 void
753 dwge_watchdog(struct ifnet *ifp)
754 {
755 	printf("%s\n", __func__);
756 }
757 
758 int
759 dwge_media_change(struct ifnet *ifp)
760 {
761 	struct dwge_softc *sc = ifp->if_softc;
762 
763 	if (LIST_FIRST(&sc->sc_mii.mii_phys))
764 		mii_mediachg(&sc->sc_mii);
765 
766 	return (0);
767 }
768 
769 void
770 dwge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
771 {
772 	struct dwge_softc *sc = ifp->if_softc;
773 
774 	if (LIST_FIRST(&sc->sc_mii.mii_phys)) {
775 		mii_pollstat(&sc->sc_mii);
776 		ifmr->ifm_active = sc->sc_mii.mii_media_active;
777 		ifmr->ifm_status = sc->sc_mii.mii_media_status;
778 	}
779 }
780 
781 int
782 dwge_mii_readreg(struct device *self, int phy, int reg)
783 {
784 	struct dwge_softc *sc = (void *)self;
785 	int n;
786 
787 	dwge_write(sc, GMAC_GMII_ADDR,
788 	    sc->sc_clk << GMAC_GMII_ADDR_CR_SHIFT |
789 	    phy << GMAC_GMII_ADDR_PA_SHIFT |
790 	    reg << GMAC_GMII_ADDR_GR_SHIFT |
791 	    GMAC_GMII_ADDR_GB);
792 	for (n = 0; n < 1000; n++) {
793 		if ((dwge_read(sc, GMAC_GMII_ADDR) & GMAC_GMII_ADDR_GB) == 0)
794 			return dwge_read(sc, GMAC_GMII_DATA);
795 		delay(10);
796 	}
797 
798 	printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
799 	return (0);
800 }
801 
802 void
803 dwge_mii_writereg(struct device *self, int phy, int reg, int val)
804 {
805 	struct dwge_softc *sc = (void *)self;
806 	int n;
807 
808 	dwge_write(sc, GMAC_GMII_DATA, val);
809 	dwge_write(sc, GMAC_GMII_ADDR,
810 	    sc->sc_clk << GMAC_GMII_ADDR_CR_SHIFT |
811 	    phy << GMAC_GMII_ADDR_PA_SHIFT |
812 	    reg << GMAC_GMII_ADDR_GR_SHIFT |
813 	    GMAC_GMII_ADDR_GW | GMAC_GMII_ADDR_GB);
814 	for (n = 0; n < 1000; n++) {
815 		if ((dwge_read(sc, GMAC_GMII_ADDR) & GMAC_GMII_ADDR_GB) == 0)
816 			return;
817 		delay(10);
818 	}
819 
820 	printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
821 }
822 
823 void
824 dwge_mii_statchg(struct device *self)
825 {
826 	struct dwge_softc *sc = (void *)self;
827 	uint32_t conf;
828 
829 	conf = dwge_read(sc, GMAC_MAC_CONF);
830 	conf &= ~(GMAC_MAC_CONF_PS | GMAC_MAC_CONF_FES);
831 
832 	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
833 	case IFM_1000_SX:
834 	case IFM_1000_LX:
835 	case IFM_1000_CX:
836 	case IFM_1000_T:
837 		sc->sc_link = 1;
838 		break;
839 	case IFM_100_TX:
840 		conf |= GMAC_MAC_CONF_PS | GMAC_MAC_CONF_FES;
841 		sc->sc_link = 1;
842 		break;
843 	case IFM_10_T:
844 		conf |= GMAC_MAC_CONF_PS;
845 		sc->sc_link = 1;
846 		break;
847 	default:
848 		sc->sc_link = 0;
849 		return;
850 	}
851 
852 	if (sc->sc_link == 0)
853 		return;
854 
855 	conf &= ~GMAC_MAC_CONF_DM;
856 	if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
857 		conf |= GMAC_MAC_CONF_DM;
858 
859 	/* XXX: RX/TX flow control? */
860 
861 	dwge_write(sc, GMAC_MAC_CONF, conf);
862 }
863 
864 void
865 dwge_tick(void *arg)
866 {
867 	struct dwge_softc *sc = arg;
868 	int s;
869 
870 	s = splnet();
871 	mii_tick(&sc->sc_mii);
872 	splx(s);
873 
874 	timeout_add_sec(&sc->sc_tick, 1);
875 }
876 
877 void
878 dwge_rxtick(void *arg)
879 {
880 	struct dwge_softc *sc = arg;
881 	uint32_t mode;
882 	int s;
883 
884 	s = splnet();
885 
886 	mode = dwge_read(sc, GMAC_OP_MODE);
887 	dwge_write(sc, GMAC_OP_MODE, mode & ~GMAC_OP_MODE_SR);
888 
889 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_rxring),
890 	    0, DWGE_DMA_LEN(sc->sc_rxring),
891 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
892 
893 	dwge_write(sc, GMAC_RX_DESC_LIST_ADDR, 0);
894 
895 	sc->sc_rx_prod = sc->sc_rx_cons = 0;
896 	dwge_fill_rx_ring(sc);
897 
898 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_rxring),
899 	    0, DWGE_DMA_LEN(sc->sc_rxring),
900 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
901 
902 	dwge_write(sc, GMAC_RX_DESC_LIST_ADDR, DWGE_DMA_DVA(sc->sc_rxring));
903 	dwge_write(sc, GMAC_OP_MODE, mode);
904 
905 	splx(s);
906 }
907 
908 int
909 dwge_intr(void *arg)
910 {
911 	struct dwge_softc *sc = arg;
912 	uint32_t reg;
913 
914 	reg = dwge_read(sc, GMAC_STATUS);
915 	dwge_write(sc, GMAC_STATUS, reg);
916 
917 	if (reg & GMAC_STATUS_RI)
918 		dwge_rx_proc(sc);
919 
920 	if (reg & GMAC_STATUS_TI ||
921 	    reg & GMAC_STATUS_TU)
922 		dwge_tx_proc(sc);
923 
924 	return (1);
925 }
926 
927 void
928 dwge_tx_proc(struct dwge_softc *sc)
929 {
930 	struct ifnet *ifp = &sc->sc_ac.ac_if;
931 	struct dwge_desc *txd;
932 	struct dwge_buf *txb;
933 	int idx, txfree;
934 
935 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_txring), 0,
936 	    DWGE_DMA_LEN(sc->sc_txring),
937 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
938 
939 	txfree = 0;
940 	while (sc->sc_tx_cons != sc->sc_tx_prod) {
941 		idx = sc->sc_tx_cons;
942 		KASSERT(idx < DWGE_NTXDESC);
943 
944 		txd = &sc->sc_txdesc[idx];
945 		if (txd->sd_status & TDES0_OWN)
946 			break;
947 
948 		txb = &sc->sc_txbuf[idx];
949 		if (txb->tb_m) {
950 			bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0,
951 			    txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
952 			bus_dmamap_unload(sc->sc_dmat, txb->tb_map);
953 
954 			m_freem(txb->tb_m);
955 			txb->tb_m = NULL;
956 		}
957 
958 		txfree++;
959 
960 		if (sc->sc_tx_cons == (DWGE_NTXDESC - 1))
961 			sc->sc_tx_cons = 0;
962 		else
963 			sc->sc_tx_cons++;
964 
965 		txd->sd_status = sc->sc_enh_desc ? ETDES0_TCH : 0;
966 	}
967 
968 	if (sc->sc_tx_cons == sc->sc_tx_prod)
969 		ifp->if_timer = 0;
970 
971 	if (txfree) {
972 		if (ifq_is_oactive(&ifp->if_snd))
973 			ifq_restart(&ifp->if_snd);
974 	}
975 }
976 
977 void
978 dwge_rx_proc(struct dwge_softc *sc)
979 {
980 	struct ifnet *ifp = &sc->sc_ac.ac_if;
981 	struct dwge_desc *rxd;
982 	struct dwge_buf *rxb;
983 	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
984 	struct mbuf *m;
985 	int idx, len, cnt, put;
986 
987 	if ((ifp->if_flags & IFF_RUNNING) == 0)
988 		return;
989 
990 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_rxring), 0,
991 	    DWGE_DMA_LEN(sc->sc_rxring),
992 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
993 
994 	cnt = if_rxr_inuse(&sc->sc_rx_ring);
995 	put = 0;
996 	while (put < cnt) {
997 		idx = sc->sc_rx_cons;
998 		KASSERT(idx < DWGE_NRXDESC);
999 
1000 		rxd = &sc->sc_rxdesc[idx];
1001 		if (rxd->sd_status & RDES0_OWN)
1002 			break;
1003 
1004 		len = (rxd->sd_status >> RDES0_FL_SHIFT) & RDES0_FL_MASK;
1005 		rxb = &sc->sc_rxbuf[idx];
1006 		KASSERT(rxb->tb_m);
1007 
1008 		bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0,
1009 		    len, BUS_DMASYNC_POSTREAD);
1010 		bus_dmamap_unload(sc->sc_dmat, rxb->tb_map);
1011 
1012 		/* Strip off CRC. */
1013 		len -= ETHER_CRC_LEN;
1014 		KASSERT(len > 0);
1015 
1016 		m = rxb->tb_m;
1017 		rxb->tb_m = NULL;
1018 		m->m_pkthdr.len = m->m_len = len;
1019 
1020 		ml_enqueue(&ml, m);
1021 
1022 		put++;
1023 		if (sc->sc_rx_cons == (DWGE_NRXDESC - 1))
1024 			sc->sc_rx_cons = 0;
1025 		else
1026 			sc->sc_rx_cons++;
1027 	}
1028 
1029 	if_rxr_put(&sc->sc_rx_ring, put);
1030 	if (ifiq_input(&ifp->if_rcv, &ml))
1031 		if_rxr_livelocked(&sc->sc_rx_ring);
1032 
1033 	dwge_fill_rx_ring(sc);
1034 
1035 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_rxring), 0,
1036 	    DWGE_DMA_LEN(sc->sc_rxring),
1037 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1038 
1039 }
1040 
1041 void
1042 dwge_up(struct dwge_softc *sc)
1043 {
1044 	struct ifnet *ifp = &sc->sc_ac.ac_if;
1045 	struct dwge_buf *txb, *rxb;
1046 	uint32_t mode;
1047 	int i;
1048 
1049 	/* Allocate Tx descriptor ring. */
1050 	sc->sc_txring = dwge_dmamem_alloc(sc,
1051 	    DWGE_NTXDESC * sizeof(struct dwge_desc), 8);
1052 	sc->sc_txdesc = DWGE_DMA_KVA(sc->sc_txring);
1053 
1054 	sc->sc_txbuf = malloc(sizeof(struct dwge_buf) * DWGE_NTXDESC,
1055 	    M_DEVBUF, M_WAITOK);
1056 	for (i = 0; i < DWGE_NTXDESC; i++) {
1057 		txb = &sc->sc_txbuf[i];
1058 		bus_dmamap_create(sc->sc_dmat, MCLBYTES, DWGE_NTXSEGS,
1059 		    MCLBYTES, 0, BUS_DMA_WAITOK, &txb->tb_map);
1060 		txb->tb_m = NULL;
1061 
1062 		sc->sc_txdesc[i].sd_next =
1063 		    DWGE_DMA_DVA(sc->sc_txring) +
1064 		    ((i+1) % DWGE_NTXDESC) * sizeof(struct dwge_desc);
1065 		if (sc->sc_enh_desc)
1066 			sc->sc_txdesc[i].sd_status = ETDES0_TCH;
1067 		else
1068 			sc->sc_txdesc[i].sd_len = TDES1_TCH;
1069 	}
1070 
1071 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_txring),
1072 	    0, DWGE_DMA_LEN(sc->sc_txring), BUS_DMASYNC_PREWRITE);
1073 
1074 	sc->sc_tx_prod = sc->sc_tx_cons = 0;
1075 
1076 	dwge_write(sc, GMAC_TX_DESC_LIST_ADDR, DWGE_DMA_DVA(sc->sc_txring));
1077 
1078 	/* Allocate  descriptor ring. */
1079 	sc->sc_rxring = dwge_dmamem_alloc(sc,
1080 	    DWGE_NRXDESC * sizeof(struct dwge_desc), 8);
1081 	sc->sc_rxdesc = DWGE_DMA_KVA(sc->sc_rxring);
1082 
1083 	sc->sc_rxbuf = malloc(sizeof(struct dwge_buf) * DWGE_NRXDESC,
1084 	    M_DEVBUF, M_WAITOK);
1085 
1086 	for (i = 0; i < DWGE_NRXDESC; i++) {
1087 		rxb = &sc->sc_rxbuf[i];
1088 		bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
1089 		    MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->tb_map);
1090 		rxb->tb_m = NULL;
1091 
1092 		sc->sc_rxdesc[i].sd_next =
1093 		    DWGE_DMA_DVA(sc->sc_rxring) +
1094 		    ((i+1) % DWGE_NRXDESC) * sizeof(struct dwge_desc);
1095 		sc->sc_rxdesc[i].sd_len =
1096 		    sc->sc_enh_desc ? ERDES1_RCH : RDES1_RCH;
1097 	}
1098 
1099 	if_rxr_init(&sc->sc_rx_ring, 2, DWGE_NRXDESC);
1100 
1101 	sc->sc_rx_prod = sc->sc_rx_cons = 0;
1102 	dwge_fill_rx_ring(sc);
1103 
1104 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_rxring),
1105 	    0, DWGE_DMA_LEN(sc->sc_rxring),
1106 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1107 
1108 	dwge_write(sc, GMAC_RX_DESC_LIST_ADDR, DWGE_DMA_DVA(sc->sc_rxring));
1109 
1110 	dwge_lladdr_write(sc);
1111 
1112 	/* Configure media. */
1113 	if (LIST_FIRST(&sc->sc_mii.mii_phys))
1114 		mii_mediachg(&sc->sc_mii);
1115 
1116 	/* Program promiscuous mode and multicast filters. */
1117 	dwge_iff(sc);
1118 
1119 	ifp->if_flags |= IFF_RUNNING;
1120 	ifq_clr_oactive(&ifp->if_snd);
1121 
1122 	dwge_write(sc, GMAC_INT_ENA, GMAC_INT_ENA_NIE |
1123 	    GMAC_INT_ENA_RIE | GMAC_INT_ENA_TIE | GMAC_INT_ENA_TUE);
1124 
1125 	mode = dwge_read(sc, GMAC_OP_MODE);
1126 	if (sc->sc_force_thresh_dma_mode) {
1127 		mode &= ~(GMAC_OP_MODE_TSF | GMAC_OP_MODE_TTC_MASK);
1128 		mode |= GMAC_OP_MODE_TTC_128;
1129 		mode &= ~(GMAC_OP_MODE_RSF | GMAC_OP_MODE_RTC_MASK);
1130 		mode |= GMAC_OP_MODE_RTC_128;
1131 	} else {
1132 		mode |= GMAC_OP_MODE_TSF | GMAC_OP_MODE_OSF;
1133 		mode |= GMAC_OP_MODE_RSF;
1134 	}
1135 	dwge_write(sc, GMAC_OP_MODE, mode | GMAC_OP_MODE_ST | GMAC_OP_MODE_SR);
1136 
1137 	dwge_write(sc, GMAC_MAC_CONF, dwge_read(sc, GMAC_MAC_CONF) |
1138 	    GMAC_MAC_CONF_TE | GMAC_MAC_CONF_RE);
1139 
1140 	timeout_add_sec(&sc->sc_tick, 1);
1141 }
1142 
1143 void
1144 dwge_down(struct dwge_softc *sc)
1145 {
1146 	struct ifnet *ifp = &sc->sc_ac.ac_if;
1147 	struct dwge_buf *txb, *rxb;
1148 	uint32_t dmactrl;
1149 	int i;
1150 
1151 	timeout_del(&sc->sc_rxto);
1152 	timeout_del(&sc->sc_tick);
1153 
1154 	ifp->if_flags &= ~IFF_RUNNING;
1155 	ifq_clr_oactive(&ifp->if_snd);
1156 	ifp->if_timer = 0;
1157 
1158 	dwge_stop_dma(sc);
1159 
1160 	dwge_write(sc, GMAC_MAC_CONF, dwge_read(sc,
1161 	    GMAC_MAC_CONF) & ~(GMAC_MAC_CONF_TE | GMAC_MAC_CONF_RE));
1162 
1163 	dmactrl = dwge_read(sc, GMAC_OP_MODE);
1164 	dmactrl &= ~(GMAC_OP_MODE_ST | GMAC_OP_MODE_SR);
1165 	dwge_write(sc, GMAC_OP_MODE, dmactrl);
1166 
1167 	dwge_write(sc, GMAC_INT_ENA, 0);
1168 
1169 	intr_barrier(sc->sc_ih);
1170 	ifq_barrier(&ifp->if_snd);
1171 
1172 	for (i = 0; i < DWGE_NTXDESC; i++) {
1173 		txb = &sc->sc_txbuf[i];
1174 		if (txb->tb_m) {
1175 			bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0,
1176 			    txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1177 			bus_dmamap_unload(sc->sc_dmat, txb->tb_map);
1178 			m_freem(txb->tb_m);
1179 		}
1180 		bus_dmamap_destroy(sc->sc_dmat, txb->tb_map);
1181 	}
1182 
1183 	dwge_dmamem_free(sc, sc->sc_txring);
1184 	free(sc->sc_txbuf, M_DEVBUF, 0);
1185 
1186 	for (i = 0; i < DWGE_NRXDESC; i++) {
1187 		rxb = &sc->sc_rxbuf[i];
1188 		if (rxb->tb_m) {
1189 			bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0,
1190 			    rxb->tb_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1191 			bus_dmamap_unload(sc->sc_dmat, rxb->tb_map);
1192 			m_freem(rxb->tb_m);
1193 		}
1194 		bus_dmamap_destroy(sc->sc_dmat, rxb->tb_map);
1195 	}
1196 
1197 	dwge_dmamem_free(sc, sc->sc_rxring);
1198 	free(sc->sc_rxbuf, M_DEVBUF, 0);
1199 }
1200 
1201 /* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
1202 static uint32_t
1203 bitrev32(uint32_t x)
1204 {
1205 	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
1206 	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
1207 	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
1208 	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
1209 
1210 	return (x >> 16) | (x << 16);
1211 }
1212 
1213 void
1214 dwge_iff(struct dwge_softc *sc)
1215 {
1216 	struct arpcom *ac = &sc->sc_ac;
1217 	struct ifnet *ifp = &sc->sc_ac.ac_if;
1218 	struct ether_multi *enm;
1219 	struct ether_multistep step;
1220 	uint32_t crc, hash[2], hashbit, hashreg;
1221 	uint32_t reg;
1222 
1223 	reg = 0;
1224 
1225 	ifp->if_flags &= ~IFF_ALLMULTI;
1226 	bzero(hash, sizeof(hash));
1227 	if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
1228 		ifp->if_flags |= IFF_ALLMULTI;
1229 		reg |= GMAC_MAC_FRM_FILT_PM;
1230 		if (ifp->if_flags & IFF_PROMISC)
1231 			reg |= GMAC_MAC_FRM_FILT_PR;
1232 	} else {
1233 		reg |= GMAC_MAC_FRM_FILT_HMC;
1234 		ETHER_FIRST_MULTI(step, ac, enm);
1235 		while (enm != NULL) {
1236 			crc = ether_crc32_le(enm->enm_addrlo,
1237 			    ETHER_ADDR_LEN) & 0x7f;
1238 
1239 			crc = bitrev32(~crc) >> 26;
1240 			hashreg = (crc >> 5);
1241 			hashbit = (crc & 0x1f);
1242 			hash[hashreg] |= (1 << hashbit);
1243 
1244 			ETHER_NEXT_MULTI(step, enm);
1245 		}
1246 	}
1247 
1248 	dwge_lladdr_write(sc);
1249 
1250 	dwge_write(sc, GMAC_HASH_TAB_HI, hash[1]);
1251 	dwge_write(sc, GMAC_HASH_TAB_LO, hash[0]);
1252 
1253 	dwge_write(sc, GMAC_MAC_FRM_FILT, reg);
1254 }
1255 
1256 int
1257 dwge_encap(struct dwge_softc *sc, struct mbuf *m, int *idx, int *used)
1258 {
1259 	struct dwge_desc *txd, *txd_start;
1260 	bus_dmamap_t map;
1261 	int cur, frag, i;
1262 
1263 	cur = frag = *idx;
1264 	map = sc->sc_txbuf[cur].tb_map;
1265 
1266 	if (sc->sc_defrag) {
1267 		if (m_defrag(m, M_DONTWAIT))
1268 			return (ENOBUFS);
1269 	}
1270 
1271 	if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) {
1272 		if (m_defrag(m, M_DONTWAIT))
1273 			return (EFBIG);
1274 		if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT))
1275 			return (EFBIG);
1276 	}
1277 
1278 	/* Sync the DMA map. */
1279 	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
1280 	    BUS_DMASYNC_PREWRITE);
1281 
1282 	txd = txd_start = &sc->sc_txdesc[frag];
1283 	for (i = 0; i < map->dm_nsegs; i++) {
1284 		txd->sd_addr = map->dm_segs[i].ds_addr;
1285 		if (sc->sc_enh_desc) {
1286 			txd->sd_status = ETDES0_TCH;
1287 			txd->sd_len = map->dm_segs[i].ds_len;
1288 			if (i == 0)
1289 				txd->sd_status |= ETDES0_FS;
1290 			if (i == (map->dm_nsegs - 1))
1291 				txd->sd_status |= ETDES0_LS | ETDES0_IC;
1292 		} else {
1293 			txd->sd_status = 0;
1294 			txd->sd_len = map->dm_segs[i].ds_len | TDES1_TCH;
1295 			if (i == 0)
1296 				txd->sd_len |= TDES1_FS;
1297 			if (i == (map->dm_nsegs - 1))
1298 				txd->sd_len |= TDES1_LS | TDES1_IC;
1299 		}
1300 		if (i != 0)
1301 			txd->sd_status |= TDES0_OWN;
1302 
1303 		bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_txring),
1304 		    frag * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE);
1305 
1306 		cur = frag;
1307 		if (frag == (DWGE_NTXDESC - 1)) {
1308 			txd = &sc->sc_txdesc[0];
1309 			frag = 0;
1310 		} else {
1311 			txd++;
1312 			frag++;
1313 		}
1314 		KASSERT(frag != sc->sc_tx_cons);
1315 	}
1316 
1317 	txd_start->sd_status |= TDES0_OWN;
1318 	bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_txring),
1319 	    *idx * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE);
1320 
1321 	KASSERT(sc->sc_txbuf[cur].tb_m == NULL);
1322 	sc->sc_txbuf[*idx].tb_map = sc->sc_txbuf[cur].tb_map;
1323 	sc->sc_txbuf[cur].tb_map = map;
1324 	sc->sc_txbuf[cur].tb_m = m;
1325 
1326 	*idx = frag;
1327 	*used += map->dm_nsegs;
1328 
1329 	return (0);
1330 }
1331 
1332 void
1333 dwge_reset(struct dwge_softc *sc)
1334 {
1335 	int n;
1336 
1337 	dwge_stop_dma(sc);
1338 
1339 	dwge_write(sc, GMAC_BUS_MODE, dwge_read(sc, GMAC_BUS_MODE) |
1340 	    GMAC_BUS_MODE_SWR);
1341 
1342 	for (n = 0; n < 30000; n++) {
1343 		if ((dwge_read(sc, GMAC_BUS_MODE) &
1344 		    GMAC_BUS_MODE_SWR) == 0)
1345 			return;
1346 		delay(10);
1347 	}
1348 
1349 	printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
1350 }
1351 
1352 void
1353 dwge_stop_dma(struct dwge_softc *sc)
1354 {
1355 	uint32_t dmactrl;
1356 
1357 	/* Stop DMA. */
1358 	dmactrl = dwge_read(sc, GMAC_OP_MODE);
1359 	dmactrl &= ~GMAC_OP_MODE_ST;
1360 	dmactrl |= GMAC_OP_MODE_FTF;
1361 	dwge_write(sc, GMAC_OP_MODE, dmactrl);
1362 }
1363 
1364 struct dwge_dmamem *
1365 dwge_dmamem_alloc(struct dwge_softc *sc, bus_size_t size, bus_size_t align)
1366 {
1367 	struct dwge_dmamem *tdm;
1368 	int nsegs;
1369 
1370 	tdm = malloc(sizeof(*tdm), M_DEVBUF, M_WAITOK | M_ZERO);
1371 	tdm->tdm_size = size;
1372 
1373 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
1374 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0)
1375 		goto tdmfree;
1376 
1377 	if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &tdm->tdm_seg, 1,
1378 	    &nsegs, BUS_DMA_WAITOK) != 0)
1379 		goto destroy;
1380 
1381 	if (bus_dmamem_map(sc->sc_dmat, &tdm->tdm_seg, nsegs, size,
1382 	    &tdm->tdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0)
1383 		goto free;
1384 
1385 	if (bus_dmamap_load(sc->sc_dmat, tdm->tdm_map, tdm->tdm_kva, size,
1386 	    NULL, BUS_DMA_WAITOK) != 0)
1387 		goto unmap;
1388 
1389 	bzero(tdm->tdm_kva, size);
1390 
1391 	return (tdm);
1392 
1393 unmap:
1394 	bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, size);
1395 free:
1396 	bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1);
1397 destroy:
1398 	bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map);
1399 tdmfree:
1400 	free(tdm, M_DEVBUF, 0);
1401 
1402 	return (NULL);
1403 }
1404 
1405 void
1406 dwge_dmamem_free(struct dwge_softc *sc, struct dwge_dmamem *tdm)
1407 {
1408 	bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, tdm->tdm_size);
1409 	bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1);
1410 	bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map);
1411 	free(tdm, M_DEVBUF, 0);
1412 }
1413 
1414 struct mbuf *
1415 dwge_alloc_mbuf(struct dwge_softc *sc, bus_dmamap_t map)
1416 {
1417 	struct mbuf *m = NULL;
1418 
1419 	m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES);
1420 	if (!m)
1421 		return (NULL);
1422 	m->m_len = m->m_pkthdr.len = MCLBYTES;
1423 	m_adj(m, ETHER_ALIGN);
1424 
1425 	if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) {
1426 		printf("%s: could not load mbuf DMA map", DEVNAME(sc));
1427 		m_freem(m);
1428 		return (NULL);
1429 	}
1430 
1431 	bus_dmamap_sync(sc->sc_dmat, map, 0,
1432 	    m->m_pkthdr.len, BUS_DMASYNC_PREREAD);
1433 
1434 	return (m);
1435 }
1436 
1437 void
1438 dwge_fill_rx_ring(struct dwge_softc *sc)
1439 {
1440 	struct dwge_desc *rxd;
1441 	struct dwge_buf *rxb;
1442 	u_int slots;
1443 
1444 	for (slots = if_rxr_get(&sc->sc_rx_ring, DWGE_NRXDESC);
1445 	    slots > 0; slots--) {
1446 		rxb = &sc->sc_rxbuf[sc->sc_rx_prod];
1447 		rxb->tb_m = dwge_alloc_mbuf(sc, rxb->tb_map);
1448 		if (rxb->tb_m == NULL)
1449 			break;
1450 
1451 		rxd = &sc->sc_rxdesc[sc->sc_rx_prod];
1452 		rxd->sd_len = rxb->tb_map->dm_segs[0].ds_len;
1453 		rxd->sd_len |= sc->sc_enh_desc ? ERDES1_RCH : RDES1_RCH;
1454 		rxd->sd_addr = rxb->tb_map->dm_segs[0].ds_addr;
1455 		rxd->sd_status = RDES0_OWN;
1456 
1457 		if (sc->sc_rx_prod == (DWGE_NRXDESC - 1))
1458 			sc->sc_rx_prod = 0;
1459 		else
1460 			sc->sc_rx_prod++;
1461 	}
1462 	if_rxr_put(&sc->sc_rx_ring, slots);
1463 
1464 	if (if_rxr_inuse(&sc->sc_rx_ring) == 0)
1465 		timeout_add(&sc->sc_rxto, 1);
1466 }
1467 
1468 /*
1469  * Allwinner A20/A31.
1470  */
1471 
1472 void
1473 dwge_setup_allwinner(struct dwge_softc *sc)
1474 {
1475 	char phy_mode[8];
1476 	uint32_t freq;
1477 
1478 	/* default to RGMII */
1479 	OF_getprop(sc->sc_node, "phy-mode", phy_mode, sizeof(phy_mode));
1480 	if (strcmp(phy_mode, "mii") == 0)
1481 		freq = 25000000;
1482 	else
1483 		freq = 125000000;
1484 	clock_set_frequency(sc->sc_node, "allwinner_gmac_tx", freq);
1485 }
1486 
1487 /*
1488  * Rockchip RK3288/RK3399.
1489  */
1490 
1491 /* RK3308 registers */
1492 #define RK3308_GRF_MAC_CON0	0x04a0
1493 #define RK3308_MAC_SPEED_100M	((0x1 << 0) << 16 | (0x1 << 0))
1494 #define RK3308_MAC_SPEED_10M	((0x1 << 0) << 16 | (0x0 << 0))
1495 #define RK3308_INTF_SEL_RMII	((0x1 << 4) << 16 | (0x1 << 4))
1496 
1497 /* RK3288 registers */
1498 #define RK3288_GRF_SOC_CON1	0x0248
1499 #define  RK3288_GMAC_PHY_INTF_SEL_RGMII	((0x7 << 6) << 16 | (0x1 << 6))
1500 #define  RK3288_GMAC_PHY_INTF_SEL_RMII	((0x7 << 6) << 16 | (0x4 << 6))
1501 #define  RK3288_RMII_MODE_RMII		((1 << 14) << 16 | (1 << 14))
1502 #define  RK3288_RMII_MODE_MII		((1 << 14) << 16 | (0 << 14))
1503 #define  RK3288_GMAC_CLK_SEL_125	((0x3 << 12) << 16 | (0x0 << 12))
1504 #define  RK3288_GMAC_CLK_SEL_25		((0x3 << 12) << 16 | (0x3 << 12))
1505 #define  RK3288_GMAC_CLK_SEL_2_5	((0x3 << 12) << 16 | (0x2 << 12))
1506 
1507 #define RK3288_GRF_SOC_CON3	0x0250
1508 #define  RK3288_GMAC_RXCLK_DLY_ENA	((1 << 15) << 16 | (1 << 15))
1509 #define  RK3288_GMAC_CLK_RX_DL_CFG(val) ((0x7f << 7) << 16 | ((val) << 7))
1510 #define  RK3288_GMAC_TXCLK_DLY_ENA	((1 << 14) << 16 | (1 << 14))
1511 #define  RK3288_GMAC_CLK_TX_DL_CFG(val) ((0x7f << 0) << 16 | ((val) << 0))
1512 
1513 /* RK3328 registers */
1514 #define RK3328_GRF_MAC_CON0	0x0900
1515 #define  RK3328_GMAC_CLK_RX_DL_CFG(val) ((0x7f << 7) << 16 | ((val) << 7))
1516 #define  RK3328_GMAC_CLK_TX_DL_CFG(val) ((0x7f << 0) << 16 | ((val) << 0))
1517 
1518 #define RK3328_GRF_MAC_CON1	0x0904
1519 #define  RK3328_GMAC_PHY_INTF_SEL_RGMII	((0x7 << 4) << 16 | (0x1 << 4))
1520 #define  RK3328_GMAC_PHY_INTF_SEL_RMII	((0x7 << 4) << 16 | (0x4 << 4))
1521 #define  RK3328_RMII_MODE_RMII		((1 << 9) << 16 | (1 << 9))
1522 #define  RK3328_RMII_MODE_MII		((1 << 9) << 16 | (0 << 9))
1523 #define  RK3328_GMAC_CLK_SEL_125	((0x3 << 11) << 16 | (0x0 << 11))
1524 #define  RK3328_GMAC_CLK_SEL_25		((0x3 << 11) << 16 | (0x3 << 11))
1525 #define  RK3328_GMAC_CLK_SEL_2_5	((0x3 << 11) << 16 | (0x2 << 11))
1526 #define  RK3328_GMAC_RXCLK_DLY_ENA	((1 << 1) << 16 | (1 << 1))
1527 #define  RK3328_GMAC_TXCLK_DLY_ENA	((1 << 0) << 16 | (1 << 0))
1528 
1529 /* RK3399 registers */
1530 #define RK3399_GRF_SOC_CON5	0xc214
1531 #define  RK3399_GMAC_PHY_INTF_SEL_RGMII	((0x7 << 9) << 16 | (0x1 << 9))
1532 #define  RK3399_GMAC_PHY_INTF_SEL_RMII	((0x7 << 9) << 16 | (0x4 << 9))
1533 #define  RK3399_RMII_MODE_RMII		((1 << 6) << 16 | (1 << 6))
1534 #define  RK3399_RMII_MODE_MII		((1 << 6) << 16 | (0 << 6))
1535 #define  RK3399_GMAC_CLK_SEL_125	((0x3 << 4) << 16 | (0x0 << 4))
1536 #define  RK3399_GMAC_CLK_SEL_25		((0x3 << 4) << 16 | (0x3 << 4))
1537 #define  RK3399_GMAC_CLK_SEL_2_5	((0x3 << 4) << 16 | (0x2 << 4))
1538 #define RK3399_GRF_SOC_CON6	0xc218
1539 #define  RK3399_GMAC_RXCLK_DLY_ENA	((1 << 15) << 16 | (1 << 15))
1540 #define  RK3399_GMAC_CLK_RX_DL_CFG(val) ((0x7f << 8) << 16 | ((val) << 8))
1541 #define  RK3399_GMAC_TXCLK_DLY_ENA	((1 << 7) << 16 | (1 << 7))
1542 #define  RK3399_GMAC_CLK_TX_DL_CFG(val) ((0x7f << 0) << 16 | ((val) << 0))
1543 
1544 void	dwge_mii_statchg_rockchip(struct device *);
1545 
1546 void
1547 dwge_setup_rockchip(struct dwge_softc *sc)
1548 {
1549 	struct regmap *rm;
1550 	uint32_t grf;
1551 	int tx_delay, rx_delay;
1552 	char clock_mode[8];
1553 
1554 	grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0);
1555 	rm = regmap_byphandle(grf);
1556 	if (rm == NULL)
1557 		return;
1558 
1559 	tx_delay = OF_getpropint(sc->sc_node, "tx_delay", 0x30);
1560 	rx_delay = OF_getpropint(sc->sc_node, "rx_delay", 0x10);
1561 
1562 	if (OF_is_compatible(sc->sc_node, "rockchip,rk3288-gmac")) {
1563 		/* Use RGMII interface. */
1564 		regmap_write_4(rm, RK3288_GRF_SOC_CON1,
1565 		    RK3288_GMAC_PHY_INTF_SEL_RGMII | RK3288_RMII_MODE_MII);
1566 
1567 		/* Program clock delay lines. */
1568 		regmap_write_4(rm, RK3288_GRF_SOC_CON3,
1569 		    RK3288_GMAC_TXCLK_DLY_ENA | RK3288_GMAC_RXCLK_DLY_ENA |
1570 		    RK3288_GMAC_CLK_TX_DL_CFG(tx_delay) |
1571 		    RK3288_GMAC_CLK_RX_DL_CFG(rx_delay));
1572 
1573 		/* Clock speed bits. */
1574 		sc->sc_clk_sel = RK3288_GRF_SOC_CON1;
1575 		sc->sc_clk_sel_2_5 = RK3288_GMAC_CLK_SEL_2_5;
1576 		sc->sc_clk_sel_25 = RK3288_GMAC_CLK_SEL_25;
1577 		sc->sc_clk_sel_125 = RK3288_GMAC_CLK_SEL_125;
1578 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3308-mac")) {
1579 		/* Use RMII interface. */
1580 		regmap_write_4(rm, RK3308_GRF_MAC_CON0,
1581 		    RK3308_INTF_SEL_RMII | RK3308_MAC_SPEED_100M);
1582 
1583 		/* Adjust MAC clock if necessary. */
1584 		OF_getprop(sc->sc_node, "clock_in_out", clock_mode,
1585 		    sizeof(clock_mode));
1586 		if (strcmp(clock_mode, "output") == 0) {
1587 			clock_set_frequency(sc->sc_node, "stmmaceth",
1588 			    50000000);
1589 			sc->sc_clk = GMAC_GMII_ADDR_CR_DIV_26;
1590 		}
1591 
1592 		/* Clock speed bits. */
1593 		sc->sc_clk_sel = RK3308_GRF_MAC_CON0;
1594 		sc->sc_clk_sel_2_5 = RK3308_MAC_SPEED_10M;
1595 		sc->sc_clk_sel_25 = RK3308_MAC_SPEED_100M;
1596 	} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3328-gmac")) {
1597 		/* Use RGMII interface. */
1598 		regmap_write_4(rm, RK3328_GRF_MAC_CON1,
1599 		    RK3328_GMAC_PHY_INTF_SEL_RGMII | RK3328_RMII_MODE_MII);
1600 
1601 		/* Program clock delay lines. */
1602 		regmap_write_4(rm, RK3328_GRF_MAC_CON0,
1603 		    RK3328_GMAC_CLK_TX_DL_CFG(tx_delay) |
1604 		    RK3328_GMAC_CLK_RX_DL_CFG(rx_delay));
1605 		regmap_write_4(rm, RK3328_GRF_MAC_CON1,
1606 		    RK3328_GMAC_TXCLK_DLY_ENA | RK3328_GMAC_RXCLK_DLY_ENA);
1607 
1608 		/* Clock speed bits. */
1609 		sc->sc_clk_sel = RK3328_GRF_MAC_CON1;
1610 		sc->sc_clk_sel_2_5 = RK3328_GMAC_CLK_SEL_2_5;
1611 		sc->sc_clk_sel_25 = RK3328_GMAC_CLK_SEL_25;
1612 		sc->sc_clk_sel_125 = RK3328_GMAC_CLK_SEL_125;
1613 	} else {
1614 		/* Use RGMII interface. */
1615 		regmap_write_4(rm, RK3399_GRF_SOC_CON5,
1616 		    RK3399_GMAC_PHY_INTF_SEL_RGMII | RK3399_RMII_MODE_MII);
1617 
1618 		/* Program clock delay lines. */
1619 		regmap_write_4(rm, RK3399_GRF_SOC_CON6,
1620 		    RK3399_GMAC_TXCLK_DLY_ENA | RK3399_GMAC_RXCLK_DLY_ENA |
1621 		    RK3399_GMAC_CLK_TX_DL_CFG(tx_delay) |
1622 		    RK3399_GMAC_CLK_RX_DL_CFG(rx_delay));
1623 
1624 		/* Clock speed bits. */
1625 		sc->sc_clk_sel = RK3399_GRF_SOC_CON5;
1626 		sc->sc_clk_sel_2_5 = RK3399_GMAC_CLK_SEL_2_5;
1627 		sc->sc_clk_sel_25 = RK3399_GMAC_CLK_SEL_25;
1628 		sc->sc_clk_sel_125 = RK3399_GMAC_CLK_SEL_125;
1629 	}
1630 
1631 	sc->sc_mii.mii_statchg = dwge_mii_statchg_rockchip;
1632 }
1633 
1634 void
1635 dwge_mii_statchg_rockchip(struct device *self)
1636 {
1637 	struct dwge_softc *sc = (void *)self;
1638 	struct regmap *rm;
1639 	uint32_t grf;
1640 	uint32_t gmac_clk_sel = 0;
1641 
1642 	dwge_mii_statchg(self);
1643 
1644 	grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0);
1645 	rm = regmap_byphandle(grf);
1646 	if (rm == NULL)
1647 		return;
1648 
1649 	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
1650 	case IFM_10_T:
1651 		gmac_clk_sel = sc->sc_clk_sel_2_5;
1652 		break;
1653 	case IFM_100_TX:
1654 		gmac_clk_sel = sc->sc_clk_sel_25;
1655 		break;
1656 	case IFM_1000_T:
1657 		gmac_clk_sel = sc->sc_clk_sel_125;
1658 		break;
1659 	}
1660 
1661 	regmap_write_4(rm, sc->sc_clk_sel, gmac_clk_sel);
1662 }
1663