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