xref: /freebsd/sys/dev/dwc/if_dwc.c (revision c4fde87a3236b500246d4fce76dbca2a3d64f73a)
1 /*-
2  * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3  *
4  * This software was developed by SRI International and the University of
5  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
6  * ("CTSRD"), as part of the DARPA CRASH research programme.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * Ethernet media access controller (EMAC)
32  * Chapter 17, Altera Cyclone V Device Handbook (CV-5V2 2014.07.22)
33  *
34  * EMAC is an instance of the Synopsys DesignWare 3504-0
35  * Universal 10/100/1000 Ethernet MAC (DWC_gmac).
36  */
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/bus.h>
41 #include <sys/gpio.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/module.h>
47 #include <sys/mutex.h>
48 #include <sys/rman.h>
49 #include <sys/socket.h>
50 #include <sys/sockio.h>
51 
52 #include <net/bpf.h>
53 #include <net/if.h>
54 #include <net/ethernet.h>
55 #include <net/if_dl.h>
56 #include <net/if_media.h>
57 #include <net/if_types.h>
58 #include <net/if_var.h>
59 
60 #include <machine/bus.h>
61 
62 #include <dev/clk/clk.h>
63 #include <dev/hwreset/hwreset.h>
64 
65 #include <dev/mii/mii.h>
66 #include <dev/mii/miivar.h>
67 #include <dev/ofw/ofw_bus.h>
68 #include <dev/ofw/ofw_bus_subr.h>
69 #include <dev/mii/mii_fdt.h>
70 
71 #include <dev/dwc/if_dwcvar.h>
72 #include <dev/dwc/dwc1000_core.h>
73 #include <dev/dwc/dwc1000_reg.h>
74 #include <dev/dwc/dwc1000_dma.h>
75 #include <dev/dwc/dwc4_dma.h>
76 #include <dev/dwc/dwc4_reg.h>
77 
78 #include "if_dwc_if.h"
79 #include "gpio_if.h"
80 #include "miibus_if.h"
81 
82 static struct resource_spec dwc_spec[] = {
83 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
84 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
85 	{ -1, 0 }
86 };
87 
88 static void dwc_stop_locked(struct dwc_softc *sc);
89 
90 static void dwc_tick(void *arg);
91 
92 /*
93  * Media functions
94  */
95 
96 static void
97 dwc_media_status(if_t ifp, struct ifmediareq *ifmr)
98 {
99 	struct dwc_softc *sc;
100 	struct mii_data *mii;
101 
102 	sc = if_getsoftc(ifp);
103 	mii = sc->mii_softc;
104 	DWC_LOCK(sc);
105 	mii_pollstat(mii);
106 	ifmr->ifm_active = mii->mii_media_active;
107 	ifmr->ifm_status = mii->mii_media_status;
108 	DWC_UNLOCK(sc);
109 }
110 
111 static int
112 dwc_media_change_locked(struct dwc_softc *sc)
113 {
114 
115 	return (mii_mediachg(sc->mii_softc));
116 }
117 
118 static int
119 dwc_media_change(if_t ifp)
120 {
121 	struct dwc_softc *sc;
122 	int error;
123 
124 	sc = if_getsoftc(ifp);
125 
126 	DWC_LOCK(sc);
127 	error = dwc_media_change_locked(sc);
128 	DWC_UNLOCK(sc);
129 	return (error);
130 }
131 
132 /*
133  * if_ functions
134  */
135 
136 static void
137 dwc_txstart_locked(struct dwc_softc *sc)
138 {
139 	if_t ifp;
140 
141 	DWC_ASSERT_LOCKED(sc);
142 
143 	if (!sc->link_is_up)
144 		return;
145 
146 	ifp = sc->ifp;
147 
148 	if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
149 	    IFF_DRV_RUNNING)
150 		return;
151 	sc->ops->dma_txstart(sc);
152 }
153 
154 static void
155 dwc_txstart(if_t ifp)
156 {
157 	struct dwc_softc *sc = if_getsoftc(ifp);
158 
159 	DWC_LOCK(sc);
160 	dwc_txstart_locked(sc);
161 	DWC_UNLOCK(sc);
162 }
163 
164 static void
165 dwc_init_locked(struct dwc_softc *sc)
166 {
167 	if_t ifp = sc->ifp;
168 
169 	DWC_ASSERT_LOCKED(sc);
170 
171 	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
172 		return;
173 
174 	/*
175 	 * Call mii_mediachg() which will call back into dwc*_miibus_statchg()
176 	 * to set up the remaining config registers based on current media.
177 	 */
178 	mii_mediachg(sc->mii_softc);
179 
180 	sc->ops->core_setup_rxfilter(sc);
181 	sc->ops->core_setup(sc);
182 	sc->ops->core_enable_mac(sc, true);
183 	sc->ops->core_enable_csum_offload(sc);
184 	sc->ops->dma_start(sc);
185 
186 	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
187 
188 	callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
189 }
190 
191 static void
192 dwc_init(void *if_softc)
193 {
194 	struct dwc_softc *sc = if_softc;
195 
196 	DWC_LOCK(sc);
197 	dwc_init_locked(sc);
198 	DWC_UNLOCK(sc);
199 }
200 
201 static void
202 dwc_stop_locked(struct dwc_softc *sc)
203 {
204 	if_t ifp;
205 
206 	DWC_ASSERT_LOCKED(sc);
207 
208 	ifp = sc->ifp;
209 	if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
210 	sc->tx_watchdog_count = 0;
211 	sc->stats_harvest_count = 0;
212 
213 	callout_stop(&sc->dwc_callout);
214 
215 	sc->ops->dma_stop(sc);
216 	sc->ops->core_enable_mac(sc, false);
217 }
218 
219 static int
220 dwc_ioctl(if_t ifp, u_long cmd, caddr_t data)
221 {
222 	struct dwc_softc *sc;
223 	struct mii_data *mii;
224 	struct ifreq *ifr;
225 	int flags, mask, error;
226 
227 	sc = if_getsoftc(ifp);
228 	ifr = (struct ifreq *)data;
229 
230 	error = 0;
231 	switch (cmd) {
232 	case SIOCSIFFLAGS:
233 		DWC_LOCK(sc);
234 		if (if_getflags(ifp) & IFF_UP) {
235 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
236 				flags = if_getflags(ifp) ^ sc->if_flags;
237 				if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
238 					sc->ops->core_setup_rxfilter(sc);
239 			} else {
240 				if (!sc->is_detaching)
241 					dwc_init_locked(sc);
242 			}
243 		} else {
244 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
245 				dwc_stop_locked(sc);
246 		}
247 		sc->if_flags = if_getflags(ifp);
248 		DWC_UNLOCK(sc);
249 		break;
250 	case SIOCADDMULTI:
251 	case SIOCDELMULTI:
252 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
253 			DWC_LOCK(sc);
254 			sc->ops->core_setup_rxfilter(sc);
255 			DWC_UNLOCK(sc);
256 		}
257 		break;
258 	case SIOCSIFMEDIA:
259 	case SIOCGIFMEDIA:
260 		mii = sc->mii_softc;
261 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
262 		break;
263 	case SIOCSIFCAP:
264 		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
265 		if (mask & IFCAP_VLAN_MTU) {
266 			/* No work to do except acknowledge the change took */
267 			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
268 		}
269 		if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))
270 			if_togglecapenable(ifp, IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
271 		if (mask & IFCAP_TXCSUM) {
272 			if_togglecapenable(ifp, IFCAP_TXCSUM);
273 			if_togglehwassist(ifp, CSUM_IP | CSUM_DELAY_DATA);
274 		}
275 		if (mask & IFCAP_TXCSUM_IPV6) {
276 			if_togglecapenable(ifp, IFCAP_TXCSUM_IPV6);
277 			if_togglehwassist(ifp, CSUM_DELAY_DATA_IPV6);
278 		}
279 
280 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
281 			DWC_LOCK(sc);
282 			sc->ops->core_enable_csum_offload(sc);
283 			DWC_UNLOCK(sc);
284 		}
285 		break;
286 
287 	default:
288 		error = ether_ioctl(ifp, cmd, data);
289 		break;
290 	}
291 
292 	return (error);
293 }
294 
295 /*
296  * Interrupts functions
297  */
298 
299 
300 static void
301 dwc_intr(void *arg)
302 {
303 	struct dwc_softc *sc;
304 	int rv;
305 
306 	sc = arg;
307 	DWC_LOCK(sc);
308 	sc->ops->core_intr(sc);
309 	rv = sc->ops->dma_intr(sc);
310 	if (rv == EIO) {
311 		device_printf(sc->dev,
312 		  "Ethernet DMA error, restarting controller.\n");
313 		dwc_stop_locked(sc);
314 		dwc_init_locked(sc);
315 	}
316 	DWC_UNLOCK(sc);
317 }
318 
319 static void
320 dwc_tick(void *arg)
321 {
322 	struct dwc_softc *sc;
323 	if_t ifp;
324 	int link_was_up;
325 
326 	sc = arg;
327 
328 	DWC_ASSERT_LOCKED(sc);
329 
330 	ifp = sc->ifp;
331 
332 	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
333 	    return;
334 
335 	/*
336 	 * Typical tx watchdog.  If this fires it indicates that we enqueued
337 	 * packets for output and never got a txdone interrupt for them.  Maybe
338 	 * it's a missed interrupt somehow, just pretend we got one.
339 	 */
340 	if (sc->tx_watchdog_count > 0) {
341 		if (--sc->tx_watchdog_count == 0) {
342 			sc->ops->dma_txfinish_locked(sc);
343 		}
344 	}
345 
346 	/* Gather stats from hardware counters. */
347 	sc->ops->core_harvest_stats(sc);
348 
349 	/* Check the media status. */
350 	link_was_up = sc->link_is_up;
351 	mii_tick(sc->mii_softc);
352 	if (sc->link_is_up && !link_was_up)
353 		dwc_txstart_locked(sc);
354 
355 	/* Schedule another check one second from now. */
356 	callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
357 }
358 
359 static int
360 dwc_reset_phy(struct dwc_softc *sc)
361 {
362 	pcell_t gpio_prop[4];
363 	pcell_t delay_prop[3];
364 	phandle_t gpio_node;
365 	device_t gpio;
366 	uint32_t pin, flags;
367 	uint32_t pin_value;
368 
369 	/*
370 	 * All those properties are deprecated but still used in some DTS.
371 	 * The new way to deal with this is to use the generic bindings
372 	 * present in the ethernet-phy node.
373 	 */
374 	if (OF_getencprop(sc->node, "snps,reset-gpio",
375 	    gpio_prop, sizeof(gpio_prop)) <= 0)
376 		return (0);
377 
378 	if (OF_getencprop(sc->node, "snps,reset-delays-us",
379 	    delay_prop, sizeof(delay_prop)) <= 0) {
380 		device_printf(sc->dev,
381 		    "Wrong property for snps,reset-delays-us");
382 		return (ENXIO);
383 	}
384 
385 	gpio_node = OF_node_from_xref(gpio_prop[0]);
386 	if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) {
387 		device_printf(sc->dev,
388 		    "Can't find gpio controller for phy reset\n");
389 		return (ENXIO);
390 	}
391 
392 	if (GPIO_MAP_GPIOS(gpio, sc->node, gpio_node,
393 	    nitems(gpio_prop) - 1,
394 	    gpio_prop + 1, &pin, &flags) != 0) {
395 		device_printf(sc->dev, "Can't map gpio for phy reset\n");
396 		return (ENXIO);
397 	}
398 
399 	pin_value = GPIO_PIN_LOW;
400 	if (OF_hasprop(sc->node, "snps,reset-active-low"))
401 		pin_value = GPIO_PIN_HIGH;
402 
403 	GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
404 	GPIO_PIN_SET(gpio, pin, pin_value);
405 	DELAY(delay_prop[0] * 5);
406 	GPIO_PIN_SET(gpio, pin, !pin_value);
407 	DELAY(delay_prop[1] * 5);
408 	GPIO_PIN_SET(gpio, pin, pin_value);
409 	DELAY(delay_prop[2] * 5);
410 
411 	return (0);
412 }
413 
414 static int
415 dwc_clock_init(struct dwc_softc *sc)
416 {
417 	int rv;
418 	int64_t freq;
419 
420 	/* Required clock */
421 	rv = clk_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->clk_stmmaceth);
422 	if (rv != 0) {
423 		device_printf(sc->dev, "Cannot get GMAC main clock\n");
424 		return (ENXIO);
425 	}
426 	if ((rv = clk_enable(sc->clk_stmmaceth)) != 0) {
427 		device_printf(sc->dev, "could not enable main clock\n");
428 		return (rv);
429 	}
430 
431 	/* Optional clock */
432 	rv = clk_get_by_ofw_name(sc->dev, 0, "pclk", &sc->clk_pclk);
433 	if (rv != 0)
434 		return (0);
435 	if ((rv = clk_enable(sc->clk_pclk)) != 0) {
436 		device_printf(sc->dev, "could not enable peripheral clock\n");
437 		return (rv);
438 	}
439 
440 	if (bootverbose) {
441 		clk_get_freq(sc->clk_stmmaceth, &freq);
442 		device_printf(sc->dev, "MAC clock(%s) freq: %jd\n",
443 		    clk_get_name(sc->clk_stmmaceth), (intmax_t)freq);
444 	}
445 
446 	return (0);
447 }
448 
449 static int
450 dwc_reset_deassert(struct dwc_softc *sc)
451 {
452 	int rv;
453 
454 	/* Required reset */
455 	rv = hwreset_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->rst_stmmaceth);
456 	if (rv != 0) {
457 		device_printf(sc->dev, "Cannot get GMAC reset\n");
458 		return (ENXIO);
459 	}
460 	rv = hwreset_deassert(sc->rst_stmmaceth);
461 	if (rv != 0) {
462 		device_printf(sc->dev, "could not de-assert GMAC reset\n");
463 		return (rv);
464 	}
465 
466 	/* Optional reset */
467 	rv = hwreset_get_by_ofw_name(sc->dev, 0, "ahb", &sc->rst_ahb);
468 	if (rv != 0)
469 		return (0);
470 	rv = hwreset_deassert(sc->rst_ahb);
471 	if (rv != 0) {
472 		device_printf(sc->dev, "could not de-assert AHB reset\n");
473 		return (rv);
474 	}
475 
476 	return (0);
477 }
478 
479 static struct dwc_ops dwc_ops_3 = {
480 	.dma_init = dma1000_init,
481 	.dma_free = dma1000_free,
482 	.dma_start = dma1000_start,
483 	.dma_stop = dma1000_stop,
484 	.dma_reset = dma1000_reset,
485 	.dma_txfinish_locked = dma1000_txfinish_locked,
486 	.dma_txstart = dma1000_txstart,
487 	.dma_intr = dma1000_intr,
488 
489 	.core_miibus_read_reg = dwc1000_miibus_read_reg,
490 	.core_miibus_write_reg = dwc1000_miibus_write_reg,
491 	.core_miibus_statchg = dwc1000_miibus_statchg,
492 	.core_setup = dwc1000_core_setup,
493 	.core_enable_mac = dwc1000_enable_mac,
494 	.core_enable_csum_offload = dwc1000_enable_csum_offload,
495 	.core_setup_rxfilter = dwc1000_setup_rxfilter,
496 	.core_get_hwaddr = dwc1000_get_hwaddr,
497 	.core_harvest_stats = dwc1000_harvest_stats,
498 	.core_intr = dwc1000_intr,
499 	.core_intr_disable = dwc1000_intr_disable,
500 };
501 
502 static struct dwc_ops dwc_ops_4 = {
503 	.dma_init = dma4_init,
504 	.dma_free = dma4_free,
505 	.dma_start = dma4_start,
506 	.dma_stop = dma4_stop,
507 	.dma_reset = dma4_reset,
508 	.dma_txfinish_locked = dma4_txfinish_locked,
509 	.dma_txstart = dma4_txstart,
510 	.dma_intr = dma4_intr,
511 
512 	.core_miibus_read_reg = dwc4_miibus_read_reg,
513 	.core_miibus_write_reg = dwc4_miibus_write_reg,
514 	.core_miibus_statchg = dwc4_miibus_statchg,
515 	.core_setup = dwc4_core_setup,
516 	.core_enable_mac = dwc4_enable_mac,
517 	.core_enable_csum_offload = dwc4_enable_csum_offload,
518 	.core_setup_rxfilter = dwc4_setup_rxfilter,
519 	.core_get_hwaddr = dwc4_get_hwaddr,
520 	.core_harvest_stats = dwc4_harvest_stats,
521 	.core_intr = dwc4_intr,
522 	.core_intr_disable = dwc4_intr_disable,
523 };
524 
525 /*
526  * Probe/Attach functions
527  */
528 
529 static int
530 dwc_probe(device_t dev)
531 {
532 
533 	if (!ofw_bus_status_okay(dev))
534 		return (ENXIO);
535 
536 	if (!ofw_bus_is_compatible(dev, "snps,dwmac"))
537 		return (ENXIO);
538 
539 	device_set_desc(dev, "Gigabit Ethernet Controller");
540 	return (BUS_PROBE_DEFAULT);
541 }
542 
543 static int
544 dwc_attach(device_t dev)
545 {
546 	uint8_t macaddr[ETHER_ADDR_LEN];
547 	struct dwc_softc *sc;
548 	if_t ifp;
549 	int error;
550 	uint32_t pbl;
551 
552 	sc = device_get_softc(dev);
553 	sc->dev = dev;
554 	sc->rx_idx = 0;
555 	sc->tx_desccount = TX_DESC_COUNT;
556 	sc->tx_mapcount = 0;
557 
558 	sc->node = ofw_bus_get_node(dev);
559 	sc->phy_mode = mii_fdt_get_contype(sc->node);
560 	switch (sc->phy_mode) {
561 	case MII_CONTYPE_RGMII:
562 	case MII_CONTYPE_RGMII_ID:
563 	case MII_CONTYPE_RGMII_RXID:
564 	case MII_CONTYPE_RGMII_TXID:
565 	case MII_CONTYPE_RMII:
566 	case MII_CONTYPE_MII:
567 		break;
568 	default:
569 		device_printf(dev, "Unsupported MII type\n");
570 		return (ENXIO);
571 	}
572 
573 	if (OF_getencprop(sc->node, "snps,pbl", &pbl, sizeof(uint32_t)) <= 0)
574 		pbl = DMA_DEFAULT_PBL;
575 	if (OF_getencprop(sc->node, "snps,txpbl", &sc->txpbl, sizeof(uint32_t)) <= 0)
576 		sc->txpbl = pbl;
577 	if (OF_getencprop(sc->node, "snps,rxpbl", &sc->rxpbl, sizeof(uint32_t)) <= 0)
578 		sc->rxpbl = pbl;
579 	if (OF_hasprop(sc->node, "snps,no-pbl-x8"))
580 		sc->nopblx8 = true;
581 	if (OF_hasprop(sc->node, "snps,fixed-burst"))
582 		sc->fixed_burst = true;
583 	if (OF_hasprop(sc->node, "snps,mixed-burst"))
584 		sc->mixed_burst = true;
585 	if (OF_hasprop(sc->node, "snps,aal"))
586 		sc->aal = true;
587 
588 	error = clk_set_assigned(dev, ofw_bus_get_node(dev));
589 	if (error != 0 && error != ENOENT) {
590 		device_printf(dev, "clk_set_assigned failed\n");
591 		return (error);
592 	}
593 
594 	/* Enable main clock */
595 	if ((error = dwc_clock_init(sc)) != 0)
596 		return (error);
597 	/* De-assert main reset */
598 	if ((error = dwc_reset_deassert(sc)) != 0)
599 		return (error);
600 
601 	if (IF_DWC_INIT(dev) != 0)
602 		return (ENXIO);
603 
604 	if ((sc->mii_clk = IF_DWC_MII_CLK(dev)) < 0) {
605 		device_printf(dev, "Cannot get mii clock value %d\n", -sc->mii_clk);
606 		return (ENXIO);
607 	}
608 
609 	if (bus_alloc_resources(dev, dwc_spec, sc->res)) {
610 		device_printf(dev, "could not allocate resources\n");
611 		return (ENXIO);
612 	}
613 
614 	if (sc->flags & DWC_HAS_GMAC5 || sc->flags & DWC_HAS_GMAC4) {
615 		device_printf(dev, "gmac version %x\n", READ4(sc, ETH_MACVR));
616 		sc->ops = &dwc_ops_4;
617 	} else {
618 		device_printf(dev, "gmac version %x\n", READ4(sc, VERSION));
619 		sc->ops = &dwc_ops_3;
620 	}
621 
622 	/* Read MAC before reset */
623 	sc->ops->core_get_hwaddr(sc, macaddr);
624 
625 	/* Reset the PHY if needed */
626 	if (dwc_reset_phy(sc) != 0) {
627 		device_printf(dev, "Can't reset the PHY\n");
628 		bus_release_resources(dev, dwc_spec, sc->res);
629 		return (ENXIO);
630 	}
631 
632 	/* Reset */
633 	if ((error = sc->ops->dma_reset(sc)) != 0) {
634 		device_printf(sc->dev, "Can't reset DMA controller.\n");
635 		bus_release_resources(sc->dev, dwc_spec, sc->res);
636 		return (error);
637 	}
638 
639 	if (sc->ops->dma_init(sc)) {
640 		bus_release_resources(dev, dwc_spec, sc->res);
641 		return (ENXIO);
642 	}
643 
644 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
645 	    MTX_NETWORK_LOCK, MTX_DEF);
646 
647 	callout_init_mtx(&sc->dwc_callout, &sc->mtx, 0);
648 
649 	/* Setup interrupt handler. */
650 	error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
651 	    NULL, dwc_intr, sc, &sc->intr_cookie);
652 	if (error != 0) {
653 		device_printf(dev, "could not setup interrupt handler.\n");
654 		bus_release_resources(dev, dwc_spec, sc->res);
655 		return (ENXIO);
656 	}
657 
658 	/* Set up the ethernet interface. */
659 	sc->ifp = ifp = if_alloc(IFT_ETHER);
660 
661 	if_setsoftc(ifp, sc);
662 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
663 	if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
664 	if_setstartfn(ifp, dwc_txstart);
665 	if_setioctlfn(ifp, dwc_ioctl);
666 	if_setinitfn(ifp, dwc_init);
667 	if_setsendqlen(ifp, TX_MAP_COUNT - 1);
668 	if_setsendqready(sc->ifp);
669 	if_sethwassist(sc->ifp, CSUM_IP | CSUM_DELAY_DATA | CSUM_DELAY_DATA_IPV6);
670 	if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
671 	if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
672 
673 	/* Attach the mii driver. */
674 	error = mii_attach(dev, &sc->miibus, ifp, dwc_media_change,
675 	    dwc_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY,
676 	    MII_OFFSET_ANY, 0);
677 
678 	if (error != 0) {
679 		device_printf(dev, "PHY attach failed\n");
680 		bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
681 		bus_release_resources(dev, dwc_spec, sc->res);
682 		return (ENXIO);
683 	}
684 	sc->mii_softc = device_get_softc(sc->miibus);
685 
686 	/* All ready to run, attach the ethernet interface. */
687 	ether_ifattach(ifp, macaddr);
688 	sc->is_attached = true;
689 
690 	return (0);
691 }
692 
693 static int
694 dwc_detach(device_t dev)
695 {
696 	struct dwc_softc *sc;
697 
698 	sc = device_get_softc(dev);
699 
700 	/*
701 	 * Disable and tear down interrupts before anything else, so we don't
702 	 * race with the handler.
703 	 */
704 	sc->ops->core_intr_disable(sc);
705 	if (sc->intr_cookie != NULL) {
706 		bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
707 	}
708 
709 	if (sc->is_attached) {
710 		DWC_LOCK(sc);
711 		sc->is_detaching = true;
712 		dwc_stop_locked(sc);
713 		DWC_UNLOCK(sc);
714 		callout_drain(&sc->dwc_callout);
715 		ether_ifdetach(sc->ifp);
716 	}
717 
718 	bus_generic_detach(dev);
719 
720 	/* Free DMA descriptors */
721 	sc->ops->dma_free(sc);
722 
723 	if (sc->ifp != NULL) {
724 		if_free(sc->ifp);
725 		sc->ifp = NULL;
726 	}
727 
728 	bus_release_resources(dev, dwc_spec, sc->res);
729 
730 	mtx_destroy(&sc->mtx);
731 	return (0);
732 }
733 
734 static int
735 dwc_miibus_read_reg(device_t dev, int phy, int reg)
736 {
737 	struct dwc_softc *sc;
738 
739 	sc = device_get_softc(dev);
740 	return (sc->ops->core_miibus_read_reg(dev, phy, reg));
741 }
742 
743 static int
744 dwc_miibus_write_reg(device_t dev, int phy, int reg, int val)
745 {
746 	struct dwc_softc *sc;
747 
748 	sc = device_get_softc(dev);
749 	return (sc->ops->core_miibus_write_reg(dev, phy, reg, val));
750 }
751 
752 static void
753 dwc_miibus_statchg(device_t dev)
754 {
755 	struct dwc_softc *sc;
756 
757 	sc = device_get_softc(dev);
758 	sc->ops->core_miibus_statchg(dev);
759 }
760 
761 static device_method_t dwc_methods[] = {
762 	DEVMETHOD(device_probe,		dwc_probe),
763 	DEVMETHOD(device_attach,	dwc_attach),
764 	DEVMETHOD(device_detach,	dwc_detach),
765 
766 	/* MII Interface */
767 	DEVMETHOD(miibus_readreg,	dwc_miibus_read_reg),
768 	DEVMETHOD(miibus_writereg,	dwc_miibus_write_reg),
769 	DEVMETHOD(miibus_statchg,	dwc_miibus_statchg),
770 
771 	DEVMETHOD_END
772 };
773 
774 driver_t dwc_driver = {
775 	"dwc",
776 	dwc_methods,
777 	sizeof(struct dwc_softc),
778 };
779 
780 DRIVER_MODULE(dwc, simplebus, dwc_driver, 0, 0);
781 DRIVER_MODULE(miibus, dwc, miibus_driver, 0, 0);
782 
783 MODULE_DEPEND(dwc, ether, 1, 1, 1);
784 MODULE_DEPEND(dwc, miibus, 1, 1, 1);
785