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