xref: /freebsd/sys/dev/dwc/if_dwc.c (revision edf8578117e8844e02c0121147f45e4609b30680)
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/cdefs.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42 #include <sys/gpio.h>
43 #include <sys/kernel.h>
44 #include <sys/lock.h>
45 #include <sys/malloc.h>
46 #include <sys/mbuf.h>
47 #include <sys/module.h>
48 #include <sys/mutex.h>
49 #include <sys/rman.h>
50 #include <sys/socket.h>
51 #include <sys/sockio.h>
52 
53 #include <net/bpf.h>
54 #include <net/if.h>
55 #include <net/ethernet.h>
56 #include <net/if_dl.h>
57 #include <net/if_media.h>
58 #include <net/if_types.h>
59 #include <net/if_var.h>
60 
61 #include <machine/bus.h>
62 
63 #include <dev/extres/clk/clk.h>
64 #include <dev/extres/hwreset/hwreset.h>
65 
66 #include <dev/mii/mii.h>
67 #include <dev/mii/miivar.h>
68 #include <dev/ofw/ofw_bus.h>
69 #include <dev/ofw/ofw_bus_subr.h>
70 #include <dev/mii/mii_fdt.h>
71 
72 #include <dev/dwc/if_dwcvar.h>
73 #include <dev/dwc/dwc1000_core.h>
74 #include <dev/dwc/dwc1000_dma.h>
75 
76 #include "if_dwc_if.h"
77 #include "gpio_if.h"
78 #include "miibus_if.h"
79 
80 static struct resource_spec dwc_spec[] = {
81 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
82 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
83 	{ -1, 0 }
84 };
85 
86 static void dwc_stop_locked(struct dwc_softc *sc);
87 
88 static void dwc_tick(void *arg);
89 
90 /*
91  * Media functions
92  */
93 
94 static void
95 dwc_media_status(if_t ifp, struct ifmediareq *ifmr)
96 {
97 	struct dwc_softc *sc;
98 	struct mii_data *mii;
99 
100 	sc = if_getsoftc(ifp);
101 	mii = sc->mii_softc;
102 	DWC_LOCK(sc);
103 	mii_pollstat(mii);
104 	ifmr->ifm_active = mii->mii_media_active;
105 	ifmr->ifm_status = mii->mii_media_status;
106 	DWC_UNLOCK(sc);
107 }
108 
109 static int
110 dwc_media_change_locked(struct dwc_softc *sc)
111 {
112 
113 	return (mii_mediachg(sc->mii_softc));
114 }
115 
116 static int
117 dwc_media_change(if_t ifp)
118 {
119 	struct dwc_softc *sc;
120 	int error;
121 
122 	sc = if_getsoftc(ifp);
123 
124 	DWC_LOCK(sc);
125 	error = dwc_media_change_locked(sc);
126 	DWC_UNLOCK(sc);
127 	return (error);
128 }
129 
130 /*
131  * if_ functions
132  */
133 
134 static void
135 dwc_txstart_locked(struct dwc_softc *sc)
136 {
137 	if_t ifp;
138 
139 	DWC_ASSERT_LOCKED(sc);
140 
141 	if (!sc->link_is_up)
142 		return;
143 
144 	ifp = sc->ifp;
145 
146 	if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
147 	    IFF_DRV_RUNNING)
148 		return;
149 	dma1000_txstart(sc);
150 }
151 
152 static void
153 dwc_txstart(if_t ifp)
154 {
155 	struct dwc_softc *sc = if_getsoftc(ifp);
156 
157 	DWC_LOCK(sc);
158 	dwc_txstart_locked(sc);
159 	DWC_UNLOCK(sc);
160 }
161 
162 static void
163 dwc_init_locked(struct dwc_softc *sc)
164 {
165 	if_t ifp = sc->ifp;
166 
167 	DWC_ASSERT_LOCKED(sc);
168 
169 	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
170 		return;
171 
172 	/*
173 	 * Call mii_mediachg() which will call back into dwc1000_miibus_statchg()
174 	 * to set up the remaining config registers based on current media.
175 	 */
176 	mii_mediachg(sc->mii_softc);
177 
178 	dwc1000_setup_rxfilter(sc);
179 	dwc1000_core_setup(sc);
180 	dwc1000_enable_mac(sc, true);
181 	dwc1000_enable_csum_offload(sc);
182 	dma1000_start(sc);
183 
184 	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
185 
186 	callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
187 }
188 
189 static void
190 dwc_init(void *if_softc)
191 {
192 	struct dwc_softc *sc = if_softc;
193 
194 	DWC_LOCK(sc);
195 	dwc_init_locked(sc);
196 	DWC_UNLOCK(sc);
197 }
198 
199 static void
200 dwc_stop_locked(struct dwc_softc *sc)
201 {
202 	if_t ifp;
203 
204 	DWC_ASSERT_LOCKED(sc);
205 
206 	ifp = sc->ifp;
207 	if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
208 	sc->tx_watchdog_count = 0;
209 	sc->stats_harvest_count = 0;
210 
211 	callout_stop(&sc->dwc_callout);
212 
213 	dma1000_stop(sc);
214 	dwc1000_enable_mac(sc, false);
215 }
216 
217 static int
218 dwc_ioctl(if_t ifp, u_long cmd, caddr_t data)
219 {
220 	struct dwc_softc *sc;
221 	struct mii_data *mii;
222 	struct ifreq *ifr;
223 	int flags, mask, error;
224 
225 	sc = if_getsoftc(ifp);
226 	ifr = (struct ifreq *)data;
227 
228 	error = 0;
229 	switch (cmd) {
230 	case SIOCSIFFLAGS:
231 		DWC_LOCK(sc);
232 		if (if_getflags(ifp) & IFF_UP) {
233 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
234 				flags = if_getflags(ifp) ^ sc->if_flags;
235 				if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
236 					dwc1000_setup_rxfilter(sc);
237 			} else {
238 				if (!sc->is_detaching)
239 					dwc_init_locked(sc);
240 			}
241 		} else {
242 			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
243 				dwc_stop_locked(sc);
244 		}
245 		sc->if_flags = if_getflags(ifp);
246 		DWC_UNLOCK(sc);
247 		break;
248 	case SIOCADDMULTI:
249 	case SIOCDELMULTI:
250 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
251 			DWC_LOCK(sc);
252 			dwc1000_setup_rxfilter(sc);
253 			DWC_UNLOCK(sc);
254 		}
255 		break;
256 	case SIOCSIFMEDIA:
257 	case SIOCGIFMEDIA:
258 		mii = sc->mii_softc;
259 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
260 		break;
261 	case SIOCSIFCAP:
262 		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
263 		if (mask & IFCAP_VLAN_MTU) {
264 			/* No work to do except acknowledge the change took */
265 			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
266 		}
267 		if (mask & IFCAP_RXCSUM)
268 			if_togglecapenable(ifp, IFCAP_RXCSUM);
269 		if (mask & IFCAP_TXCSUM)
270 			if_togglecapenable(ifp, IFCAP_TXCSUM);
271 		if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0)
272 			if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0);
273 		else
274 			if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP);
275 
276 		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
277 			DWC_LOCK(sc);
278 			dwc1000_enable_csum_offload(sc);
279 			DWC_UNLOCK(sc);
280 		}
281 		break;
282 
283 	default:
284 		error = ether_ioctl(ifp, cmd, data);
285 		break;
286 	}
287 
288 	return (error);
289 }
290 
291 /*
292  * Interrupts functions
293  */
294 
295 
296 static void
297 dwc_intr(void *arg)
298 {
299 	struct dwc_softc *sc;
300 	int rv;
301 
302 	sc = arg;
303 	DWC_LOCK(sc);
304 	dwc1000_intr(sc);
305 	rv = dma1000_intr(sc);
306 	if (rv == EIO) {
307 		device_printf(sc->dev,
308 		  "Ethernet DMA error, restarting controller.\n");
309 		dwc_stop_locked(sc);
310 		dwc_init_locked(sc);
311 	}
312 	DWC_UNLOCK(sc);
313 }
314 
315 static void
316 dwc_tick(void *arg)
317 {
318 	struct dwc_softc *sc;
319 	if_t ifp;
320 	int link_was_up;
321 
322 	sc = arg;
323 
324 	DWC_ASSERT_LOCKED(sc);
325 
326 	ifp = sc->ifp;
327 
328 	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
329 	    return;
330 
331 	/*
332 	 * Typical tx watchdog.  If this fires it indicates that we enqueued
333 	 * packets for output and never got a txdone interrupt for them.  Maybe
334 	 * it's a missed interrupt somehow, just pretend we got one.
335 	 */
336 	if (sc->tx_watchdog_count > 0) {
337 		if (--sc->tx_watchdog_count == 0) {
338 			dma1000_txfinish_locked(sc);
339 		}
340 	}
341 
342 	/* Gather stats from hardware counters. */
343 	dwc1000_harvest_stats(sc);
344 
345 	/* Check the media status. */
346 	link_was_up = sc->link_is_up;
347 	mii_tick(sc->mii_softc);
348 	if (sc->link_is_up && !link_was_up)
349 		dwc_txstart_locked(sc);
350 
351 	/* Schedule another check one second from now. */
352 	callout_reset(&sc->dwc_callout, hz, dwc_tick, sc);
353 }
354 
355 static int
356 dwc_reset_phy(struct dwc_softc *sc)
357 {
358 	pcell_t gpio_prop[4];
359 	pcell_t delay_prop[3];
360 	phandle_t gpio_node;
361 	device_t gpio;
362 	uint32_t pin, flags;
363 	uint32_t pin_value;
364 
365 	/*
366 	 * All those properties are deprecated but still used in some DTS.
367 	 * The new way to deal with this is to use the generic bindings
368 	 * present in the ethernet-phy node.
369 	 */
370 	if (OF_getencprop(sc->node, "snps,reset-gpio",
371 	    gpio_prop, sizeof(gpio_prop)) <= 0)
372 		return (0);
373 
374 	if (OF_getencprop(sc->node, "snps,reset-delays-us",
375 	    delay_prop, sizeof(delay_prop)) <= 0) {
376 		device_printf(sc->dev,
377 		    "Wrong property for snps,reset-delays-us");
378 		return (ENXIO);
379 	}
380 
381 	gpio_node = OF_node_from_xref(gpio_prop[0]);
382 	if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) {
383 		device_printf(sc->dev,
384 		    "Can't find gpio controller for phy reset\n");
385 		return (ENXIO);
386 	}
387 
388 	if (GPIO_MAP_GPIOS(gpio, sc->node, gpio_node,
389 	    nitems(gpio_prop) - 1,
390 	    gpio_prop + 1, &pin, &flags) != 0) {
391 		device_printf(sc->dev, "Can't map gpio for phy reset\n");
392 		return (ENXIO);
393 	}
394 
395 	pin_value = GPIO_PIN_LOW;
396 	if (OF_hasprop(sc->node, "snps,reset-active-low"))
397 		pin_value = GPIO_PIN_HIGH;
398 
399 	GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
400 	GPIO_PIN_SET(gpio, pin, pin_value);
401 	DELAY(delay_prop[0] * 5);
402 	GPIO_PIN_SET(gpio, pin, !pin_value);
403 	DELAY(delay_prop[1] * 5);
404 	GPIO_PIN_SET(gpio, pin, pin_value);
405 	DELAY(delay_prop[2] * 5);
406 
407 	return (0);
408 }
409 
410 static int
411 dwc_clock_init(struct dwc_softc *sc)
412 {
413 	int rv;
414 	int64_t freq;
415 
416 	/* Required clock */
417 	rv = clk_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->clk_stmmaceth);
418 	if (rv != 0) {
419 		device_printf(sc->dev, "Cannot get GMAC main clock\n");
420 		return (ENXIO);
421 	}
422 	if ((rv = clk_enable(sc->clk_stmmaceth)) != 0) {
423 		device_printf(sc->dev, "could not enable main clock\n");
424 		return (rv);
425 	}
426 
427 	/* Optional clock */
428 	rv = clk_get_by_ofw_name(sc->dev, 0, "pclk", &sc->clk_pclk);
429 	if (rv != 0)
430 		return (0);
431 	if ((rv = clk_enable(sc->clk_pclk)) != 0) {
432 		device_printf(sc->dev, "could not enable peripheral clock\n");
433 		return (rv);
434 	}
435 
436 	if (bootverbose) {
437 		clk_get_freq(sc->clk_stmmaceth, &freq);
438 		device_printf(sc->dev, "MAC clock(%s) freq: %jd\n",
439 		    clk_get_name(sc->clk_stmmaceth), (intmax_t)freq);
440 	}
441 
442 	return (0);
443 }
444 
445 static int
446 dwc_reset_deassert(struct dwc_softc *sc)
447 {
448 	int rv;
449 
450 	/* Required reset */
451 	rv = hwreset_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->rst_stmmaceth);
452 	if (rv != 0) {
453 		device_printf(sc->dev, "Cannot get GMAC reset\n");
454 		return (ENXIO);
455 	}
456 	rv = hwreset_deassert(sc->rst_stmmaceth);
457 	if (rv != 0) {
458 		device_printf(sc->dev, "could not de-assert GMAC reset\n");
459 		return (rv);
460 	}
461 
462 	/* Optional reset */
463 	rv = hwreset_get_by_ofw_name(sc->dev, 0, "ahb", &sc->rst_ahb);
464 	if (rv != 0)
465 		return (0);
466 	rv = hwreset_deassert(sc->rst_ahb);
467 	if (rv != 0) {
468 		device_printf(sc->dev, "could not de-assert AHB reset\n");
469 		return (rv);
470 	}
471 
472 	return (0);
473 }
474 
475 /*
476  * Probe/Attach functions
477  */
478 
479 static int
480 dwc_probe(device_t dev)
481 {
482 
483 	if (!ofw_bus_status_okay(dev))
484 		return (ENXIO);
485 
486 	if (!ofw_bus_is_compatible(dev, "snps,dwmac"))
487 		return (ENXIO);
488 
489 	device_set_desc(dev, "Gigabit Ethernet Controller");
490 	return (BUS_PROBE_DEFAULT);
491 }
492 
493 static int
494 dwc_attach(device_t dev)
495 {
496 	uint8_t macaddr[ETHER_ADDR_LEN];
497 	struct dwc_softc *sc;
498 	if_t ifp;
499 	int error;
500 	uint32_t pbl;
501 
502 	sc = device_get_softc(dev);
503 	sc->dev = dev;
504 	sc->rx_idx = 0;
505 	sc->tx_desccount = TX_DESC_COUNT;
506 	sc->tx_mapcount = 0;
507 
508 	sc->node = ofw_bus_get_node(dev);
509 	sc->phy_mode = mii_fdt_get_contype(sc->node);
510 	switch (sc->phy_mode) {
511 	case MII_CONTYPE_RGMII:
512 	case MII_CONTYPE_RGMII_ID:
513 	case MII_CONTYPE_RGMII_RXID:
514 	case MII_CONTYPE_RGMII_TXID:
515 	case MII_CONTYPE_RMII:
516 	case MII_CONTYPE_MII:
517 		break;
518 	default:
519 		device_printf(dev, "Unsupported MII type\n");
520 		return (ENXIO);
521 	}
522 
523 	if (OF_getencprop(sc->node, "snps,pbl", &pbl, sizeof(uint32_t)) <= 0)
524 		pbl = DMA_DEFAULT_PBL;
525 	if (OF_getencprop(sc->node, "snps,txpbl", &sc->txpbl, sizeof(uint32_t)) <= 0)
526 		sc->txpbl = pbl;
527 	if (OF_getencprop(sc->node, "snps,rxpbl", &sc->rxpbl, sizeof(uint32_t)) <= 0)
528 		sc->rxpbl = pbl;
529 	if (OF_hasprop(sc->node, "snps,no-pbl-x8") == 1)
530 		sc->nopblx8 = true;
531 	if (OF_hasprop(sc->node, "snps,fixed-burst") == 1)
532 		sc->fixed_burst = true;
533 	if (OF_hasprop(sc->node, "snps,mixed-burst") == 1)
534 		sc->mixed_burst = true;
535 	if (OF_hasprop(sc->node, "snps,aal") == 1)
536 		sc->aal = true;
537 
538 	error = clk_set_assigned(dev, ofw_bus_get_node(dev));
539 	if (error != 0) {
540 		device_printf(dev, "clk_set_assigned failed\n");
541 		return (error);
542 	}
543 
544 	/* Enable main clock */
545 	if ((error = dwc_clock_init(sc)) != 0)
546 		return (error);
547 	/* De-assert main reset */
548 	if ((error = dwc_reset_deassert(sc)) != 0)
549 		return (error);
550 
551 	if (IF_DWC_INIT(dev) != 0)
552 		return (ENXIO);
553 
554 	if ((sc->mii_clk = IF_DWC_MII_CLK(dev)) < 0) {
555 		device_printf(dev, "Cannot get mii clock value %d\n", -sc->mii_clk);
556 		return (ENXIO);
557 	}
558 
559 	if (bus_alloc_resources(dev, dwc_spec, sc->res)) {
560 		device_printf(dev, "could not allocate resources\n");
561 		return (ENXIO);
562 	}
563 
564 	/* Read MAC before reset */
565 	dwc1000_get_hwaddr(sc, macaddr);
566 
567 	/* Reset the PHY if needed */
568 	if (dwc_reset_phy(sc) != 0) {
569 		device_printf(dev, "Can't reset the PHY\n");
570 		bus_release_resources(dev, dwc_spec, sc->res);
571 		return (ENXIO);
572 	}
573 
574 	/* Reset */
575 	if ((error = dma1000_reset(sc)) != 0) {
576 		device_printf(sc->dev, "Can't reset DMA controller.\n");
577 		bus_release_resources(sc->dev, dwc_spec, sc->res);
578 		return (error);
579 	}
580 
581 	if (dma1000_init(sc)) {
582 		bus_release_resources(dev, dwc_spec, sc->res);
583 		return (ENXIO);
584 	}
585 
586 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
587 	    MTX_NETWORK_LOCK, MTX_DEF);
588 
589 	callout_init_mtx(&sc->dwc_callout, &sc->mtx, 0);
590 
591 	/* Setup interrupt handler. */
592 	error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
593 	    NULL, dwc_intr, sc, &sc->intr_cookie);
594 	if (error != 0) {
595 		device_printf(dev, "could not setup interrupt handler.\n");
596 		bus_release_resources(dev, dwc_spec, sc->res);
597 		return (ENXIO);
598 	}
599 
600 	/* Set up the ethernet interface. */
601 	sc->ifp = ifp = if_alloc(IFT_ETHER);
602 
603 	if_setsoftc(ifp, sc);
604 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
605 	if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
606 	if_setstartfn(ifp, dwc_txstart);
607 	if_setioctlfn(ifp, dwc_ioctl);
608 	if_setinitfn(ifp, dwc_init);
609 	if_setsendqlen(ifp, TX_MAP_COUNT - 1);
610 	if_setsendqready(sc->ifp);
611 	if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP);
612 	if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM);
613 	if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
614 
615 	/* Attach the mii driver. */
616 	error = mii_attach(dev, &sc->miibus, ifp, dwc_media_change,
617 	    dwc_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY,
618 	    MII_OFFSET_ANY, 0);
619 
620 	if (error != 0) {
621 		device_printf(dev, "PHY attach failed\n");
622 		bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
623 		bus_release_resources(dev, dwc_spec, sc->res);
624 		return (ENXIO);
625 	}
626 	sc->mii_softc = device_get_softc(sc->miibus);
627 
628 	/* All ready to run, attach the ethernet interface. */
629 	ether_ifattach(ifp, macaddr);
630 	sc->is_attached = true;
631 
632 	return (0);
633 }
634 
635 static int
636 dwc_detach(device_t dev)
637 {
638 	struct dwc_softc *sc;
639 
640 	sc = device_get_softc(dev);
641 
642 	/*
643 	 * Disable and tear down interrupts before anything else, so we don't
644 	 * race with the handler.
645 	 */
646 	dwc1000_intr_disable(sc);
647 	if (sc->intr_cookie != NULL) {
648 		bus_teardown_intr(dev, sc->res[1], sc->intr_cookie);
649 	}
650 
651 	if (sc->is_attached) {
652 		DWC_LOCK(sc);
653 		sc->is_detaching = true;
654 		dwc_stop_locked(sc);
655 		DWC_UNLOCK(sc);
656 		callout_drain(&sc->dwc_callout);
657 		ether_ifdetach(sc->ifp);
658 	}
659 
660 	if (sc->miibus != NULL) {
661 		device_delete_child(dev, sc->miibus);
662 		sc->miibus = NULL;
663 	}
664 	bus_generic_detach(dev);
665 
666 	/* Free DMA descriptors */
667 	dma1000_free(sc);
668 
669 	if (sc->ifp != NULL) {
670 		if_free(sc->ifp);
671 		sc->ifp = NULL;
672 	}
673 
674 	bus_release_resources(dev, dwc_spec, sc->res);
675 
676 	mtx_destroy(&sc->mtx);
677 	return (0);
678 }
679 
680 static device_method_t dwc_methods[] = {
681 	DEVMETHOD(device_probe,		dwc_probe),
682 	DEVMETHOD(device_attach,	dwc_attach),
683 	DEVMETHOD(device_detach,	dwc_detach),
684 
685 	/* MII Interface */
686 	DEVMETHOD(miibus_readreg,	dwc1000_miibus_read_reg),
687 	DEVMETHOD(miibus_writereg,	dwc1000_miibus_write_reg),
688 	DEVMETHOD(miibus_statchg,	dwc1000_miibus_statchg),
689 
690 	{ 0, 0 }
691 };
692 
693 driver_t dwc_driver = {
694 	"dwc",
695 	dwc_methods,
696 	sizeof(struct dwc_softc),
697 };
698 
699 DRIVER_MODULE(dwc, simplebus, dwc_driver, 0, 0);
700 DRIVER_MODULE(miibus, dwc, miibus_driver, 0, 0);
701 
702 MODULE_DEPEND(dwc, ether, 1, 1, 1);
703 MODULE_DEPEND(dwc, miibus, 1, 1, 1);
704