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