1 /* 2 * Copyright (c) 2026 Justin Hibbits 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <sys/param.h> 8 #include <sys/systm.h> 9 #include <sys/bus.h> 10 #include <sys/kernel.h> 11 #include <sys/malloc.h> 12 #include <sys/mbuf.h> 13 #include <sys/module.h> 14 #include <sys/rman.h> 15 #include <sys/socket.h> 16 #include <sys/sysctl.h> 17 #include <sys/sockio.h> 18 19 #include <machine/bus.h> 20 #include <machine/resource.h> 21 22 #include <net/ethernet.h> 23 #include <net/if.h> 24 #include <net/if_dl.h> 25 #include <net/if_media.h> 26 #include <net/if_types.h> 27 #include <net/if_arp.h> 28 29 #include <dev/mii/mii.h> 30 #include <dev/mii/miivar.h> 31 #include <dev/ofw/ofw_bus.h> 32 #include <dev/ofw/ofw_bus_subr.h> 33 #include <dev/ofw/openfirm.h> 34 35 #include "miibus_if.h" 36 37 #include "dpaa_eth.h" 38 #include "fman.h" 39 #include "fman_port.h" 40 #include "if_memac.h" 41 42 #include "fman_if.h" 43 #include "fman_port_if.h" 44 45 #define MEMAC_MIN_FRAME_SIZE 64 46 #define MEMAC_MAX_FRAME_SIZE 32736 47 48 #define MEMAC_COMMAND_CONFIG 0x008 49 #define COMMAND_CONFIG_RXSTP 0x20000000 50 #define COMMAND_CONFIG_NO_LEN_CHK 0x00020000 51 #define COMMAND_CONFIG_SWR 0x00001000 52 #define COMMAND_CONFIG_TXP 0x00000800 53 #define COMMAND_CONFIG_CRC 0x00000040 54 #define COMMAND_CONFIG_PROMISC 0x00000010 55 #define COMMAND_CONFIG_RX_EN 0x00000002 56 #define COMMAND_CONFIG_TX_EN 0x00000001 57 #define MEMAC_MAC_ADDR_0 0x00c 58 #define MEMAC_MAC_ADDR_1 0x010 59 #define MEMAC_REG_MAXFRM 0x14 60 #define MEMAC_REG_TX_FIFO_SECTIONS 0x020 61 #define TX_FIFO_SECTIONS_TX_EMPTY_M 0xffff0000 62 #define TX_FIFO_SECTIONS_TX_EMPTY_S 16 63 #define TX_FIFO_SECTIONS_TX_AVAIL_M 0x0000ffff 64 65 #define HASHTABLE_CTRL 0x02c 66 #define CTRL_MCAST 0x00000100 67 #define CTRL_HASH_ADDR_M 0x0000003f 68 #define HASHTABLE_SIZE 64 69 #define MEMAC_IEVENT 0x040 70 #define IEVENT_RX_EMPTY 0x00000040 71 #define IEVENT_TX_EMPTY 0x00000020 72 #define MEMAC_CL01_PAUSE_QUANTA 0x054 73 #define MEMAC_IF_MODE 0x300 74 #define IF_MODE_ENA 0x00008000 75 #define IF_MODE_SSP_M 0x00006000 76 #define IF_MODE_SSP_100MB 0x00000000 77 #define IF_MODE_SSP_10MB 0x00002000 78 #define IF_MODE_SSP_1GB 0x00004000 79 #define IF_MODE_SFD 0x00001000 80 #define IF_MODE_MSG 0x00000200 81 #define IF_MODE_HG 0x00000100 82 #define IF_MODE_HD 0x00000040 83 #define IF_MODE_RLP 0x00000020 84 #define IF_MODE_RG 0x00000004 85 #define IF_MODE_IFMODE_M 0x00000003 86 #define IF_MODE_IFMODE_XGMII 0x00000000 87 #define IF_MODE_IFMODE_MII 0x00000001 88 #define IF_MODE_IFMODE_GMII 0x00000002 89 90 #define DEFAULT_PAUSE_QUANTA 0xf000 91 92 93 /** 94 * @group FMan MAC routines. 95 * @{ 96 */ 97 #define MEMAC_MAC_EXCEPTIONS_END (-1) 98 99 static void memac_if_init_locked(struct memac_softc *sc); 100 101 static int 102 memac_fm_mac_init(struct memac_softc *sc, uint8_t *mac) 103 { 104 uint32_t reg; 105 106 FMAN_GET_REVISION(device_get_parent(sc->sc_base.sc_dev), &sc->sc_base.sc_rev_major, 107 &sc->sc_base.sc_rev_minor); 108 109 if (FMAN_RESET_MAC(device_get_parent(sc->sc_base.sc_dev), sc->sc_base.sc_eth_id) != 0) 110 return (ENXIO); 111 112 reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG); 113 reg |= COMMAND_CONFIG_SWR; 114 bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg); 115 116 while (bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG) & COMMAND_CONFIG_SWR) 117 ; 118 119 /* TODO: TX_FIFO_SECTIONS */ 120 /* TODO: CL01 pause quantum */ 121 bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, 122 COMMAND_CONFIG_NO_LEN_CHK | COMMAND_CONFIG_TXP | COMMAND_CONFIG_CRC); 123 124 reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE); 125 reg &= ~(IF_MODE_IFMODE_M | IF_MODE_RG); 126 switch (sc->sc_base.sc_mac_enet_mode) { 127 case MII_CONTYPE_RGMII: 128 reg |= IF_MODE_RG; 129 /* FALLTHROUGH */ 130 case MII_CONTYPE_GMII: 131 case MII_CONTYPE_SGMII: 132 case MII_CONTYPE_QSGMII: 133 reg |= IF_MODE_IFMODE_GMII; 134 break; 135 case MII_CONTYPE_RMII: 136 reg |= IF_MODE_RG; 137 /* FALLTHROUGH */ 138 case MII_CONTYPE_MII: 139 reg |= IF_MODE_IFMODE_MII; 140 break; 141 } 142 143 bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg); 144 145 return (0); 146 } 147 /** @} */ 148 149 150 /** 151 * @group IFnet routines. 152 * @{ 153 */ 154 static int 155 memac_set_mtu(struct memac_softc *sc, unsigned int mtu) 156 { 157 158 mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN; 159 160 MEMAC_LOCK_ASSERT(sc); 161 162 if (mtu >= MEMAC_MIN_FRAME_SIZE && mtu <= MEMAC_MAX_FRAME_SIZE) { 163 bus_write_4(sc->sc_base.sc_mem, MEMAC_REG_MAXFRM, mtu); 164 return (mtu); 165 } 166 167 return (0); 168 } 169 170 static u_int 171 memac_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) 172 { 173 struct memac_softc *sc = arg; 174 uint8_t *addr = LLADDR(sdl); 175 uint32_t hash = 0; 176 uint8_t a, h; 177 178 /* Hash is 6 bits, composed if [XOR{47:40},XOR{39:32},....] */ 179 for (int i = 0; i < 6; i++) { 180 a = addr[i]; 181 h = 0; 182 for (int j = 0; j < 8; j++, a >>= 1) { 183 h ^= (a & 0x1); 184 } 185 hash |= (h << i); 186 } 187 bus_write_4(sc->sc_base.sc_mem, HASHTABLE_CTRL, hash | CTRL_MCAST); 188 189 return (1); 190 } 191 192 static void 193 memac_setup_multicast(struct memac_softc *sc) 194 { 195 196 if (if_getflags(sc->sc_base.sc_ifnet) & IFF_ALLMULTI) { 197 for (int i = 0; i < HASHTABLE_SIZE; i++) 198 bus_write_4(sc->sc_base.sc_mem, 199 HASHTABLE_CTRL, CTRL_MCAST | i); 200 } else { 201 /* Clear the hash table */ 202 for (int i = 0; i < HASHTABLE_SIZE; i++) 203 bus_write_4(sc->sc_base.sc_mem, 204 HASHTABLE_CTRL, i); 205 } 206 207 if_foreach_llmaddr(sc->sc_base.sc_ifnet, memac_hash_maddr, sc); 208 } 209 210 static void 211 memac_setup_promisc(struct memac_softc *sc) 212 { 213 uint32_t reg; 214 215 reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG); 216 reg &= ~COMMAND_CONFIG_PROMISC; 217 218 if ((if_getflags(sc->sc_base.sc_ifnet) & IFF_PROMISC) != 0) 219 bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, 220 reg | COMMAND_CONFIG_PROMISC); 221 } 222 223 static void 224 memac_if_graceful_stop(struct memac_softc *sc) 225 { 226 struct resource *regs = sc->sc_base.sc_mem; 227 uint32_t reg; 228 229 reg = bus_read_4(regs, MEMAC_COMMAND_CONFIG); 230 reg |= COMMAND_CONFIG_RXSTP; 231 232 bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg); 233 while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_RX_EMPTY) == 0) 234 ; 235 reg &= COMMAND_CONFIG_RX_EN; 236 bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg); 237 238 while ((bus_read_4(regs, MEMAC_IEVENT) & IEVENT_TX_EMPTY) == 0) 239 ; 240 bus_write_4(regs, MEMAC_COMMAND_CONFIG, reg & ~COMMAND_CONFIG_TX_EN); 241 } 242 243 static void 244 memac_mac_enable(struct memac_softc *sc) 245 { 246 uint32_t reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG); 247 248 reg |= (COMMAND_CONFIG_RX_EN | COMMAND_CONFIG_TX_EN); 249 250 bus_write_4(sc->sc_base.sc_mem, MEMAC_COMMAND_CONFIG, reg); 251 } 252 253 static int 254 memac_if_enable_locked(struct memac_softc *sc) 255 { 256 int error; 257 258 MEMAC_LOCK_ASSERT(sc); 259 260 memac_set_mtu(sc, if_getmtu(sc->sc_base.sc_ifnet)); 261 memac_mac_enable(sc); 262 263 error = FMAN_PORT_ENABLE(sc->sc_base.sc_rx_port); 264 if (error != 0) 265 return (EIO); 266 267 error = FMAN_PORT_ENABLE(sc->sc_base.sc_tx_port); 268 if (error != 0) 269 return (EIO); 270 271 bus_write_4(sc->sc_base.sc_mem, MEMAC_IEVENT, 0); 272 memac_setup_multicast(sc); 273 memac_setup_promisc(sc); 274 275 if_setdrvflagbits(sc->sc_base.sc_ifnet, IFF_DRV_RUNNING, 0); 276 277 /* Refresh link state */ 278 memac_miibus_statchg(sc->sc_base.sc_dev); 279 280 return (0); 281 } 282 283 static int 284 memac_if_disable_locked(struct memac_softc *sc) 285 { 286 int error; 287 288 MEMAC_LOCK_ASSERT(sc); 289 290 error = FMAN_PORT_DISABLE(sc->sc_base.sc_tx_port); 291 if (error != 0) 292 return (EIO); 293 294 memac_if_graceful_stop(sc); 295 296 error = FMAN_PORT_DISABLE(sc->sc_base.sc_rx_port); 297 if (error != 0) 298 return (EIO); 299 300 if_setdrvflagbits(sc->sc_base.sc_ifnet, 0, IFF_DRV_RUNNING); 301 302 return (0); 303 } 304 305 static int 306 memac_if_ioctl(if_t ifp, u_long command, caddr_t data) 307 { 308 struct memac_softc *sc; 309 struct ifreq *ifr; 310 uint32_t changed; 311 int error; 312 313 sc = if_getsoftc(ifp); 314 ifr = (struct ifreq *)data; 315 error = 0; 316 317 /* Basic functionality to achieve media status reports */ 318 switch (command) { 319 case SIOCSIFMTU: 320 MEMAC_LOCK(sc); 321 if (memac_set_mtu(sc, ifr->ifr_mtu)) 322 if_setmtu(ifp, ifr->ifr_mtu); 323 else 324 error = EINVAL; 325 MEMAC_UNLOCK(sc); 326 break; 327 case SIOCSIFFLAGS: 328 MEMAC_LOCK(sc); 329 if (if_getflags(ifp) & IFF_UP) { 330 if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) 331 memac_if_init_locked(sc); 332 } else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) 333 error = memac_if_disable_locked(sc); 334 335 MEMAC_UNLOCK(sc); 336 break; 337 338 case SIOCADDMULTI: 339 case SIOCDELMULTI: 340 if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) { 341 MEMAC_LOCK(sc); 342 memac_setup_multicast(sc); 343 MEMAC_UNLOCK(sc); 344 } 345 break; 346 347 case SIOCSIFCAP: 348 changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap; 349 if ((changed & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != 0) 350 if_togglecapenable(ifp, 351 IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); 352 if ((changed & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != 0) { 353 if_togglecapenable(ifp, 354 IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6); 355 if_togglehwassist(ifp, DPAA_CSUM_TX_OFFLOAD); 356 } 357 break; 358 359 case SIOCGIFMEDIA: 360 case SIOCSIFMEDIA: 361 error = ifmedia_ioctl(ifp, ifr, &sc->sc_base.sc_mii->mii_media, 362 command); 363 break; 364 365 default: 366 error = ether_ioctl(ifp, command, data); 367 } 368 369 return (error); 370 } 371 372 static void 373 memac_if_tick(void *arg) 374 { 375 struct memac_softc *sc; 376 377 sc = arg; 378 379 /* TODO */ 380 MEMAC_LOCK(sc); 381 382 mii_tick(sc->sc_base.sc_mii); 383 callout_reset(&sc->sc_base.sc_tick_callout, hz, memac_if_tick, sc); 384 385 MEMAC_UNLOCK(sc); 386 } 387 388 static void 389 memac_if_deinit_locked(struct memac_softc *sc) 390 { 391 392 MEMAC_LOCK_ASSERT(sc); 393 394 MEMAC_UNLOCK(sc); 395 callout_drain(&sc->sc_base.sc_tick_callout); 396 MEMAC_LOCK(sc); 397 } 398 399 static void 400 memac_if_set_macaddr(struct memac_softc *sc, const char *addr) 401 { 402 uint32_t reg; 403 404 reg = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 405 bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_0, reg); 406 reg = (addr[5] << 8) | (addr[4]); 407 bus_write_4(sc->sc_base.sc_mem, MEMAC_MAC_ADDR_1, reg); 408 } 409 410 static void 411 memac_if_init_locked(struct memac_softc *sc) 412 { 413 int error; 414 const char *macaddr; 415 416 MEMAC_LOCK_ASSERT(sc); 417 418 macaddr = if_getlladdr(sc->sc_base.sc_ifnet); 419 memac_if_set_macaddr(sc, macaddr); 420 421 /* Start MII polling */ 422 if (sc->sc_base.sc_mii) 423 callout_reset(&sc->sc_base.sc_tick_callout, hz, 424 memac_if_tick, sc); 425 426 if (if_getflags(sc->sc_base.sc_ifnet) & IFF_UP) { 427 error = memac_if_enable_locked(sc); 428 if (error != 0) 429 goto err; 430 } else { 431 error = memac_if_disable_locked(sc); 432 if (error != 0) 433 goto err; 434 } 435 436 if_link_state_change(sc->sc_base.sc_ifnet, LINK_STATE_UP); 437 438 bus_write_4(sc->sc_base.sc_mem, MEMAC_CL01_PAUSE_QUANTA, 439 DEFAULT_PAUSE_QUANTA); 440 441 return; 442 443 err: 444 memac_if_deinit_locked(sc); 445 device_printf(sc->sc_base.sc_dev, "initialization error.\n"); 446 return; 447 } 448 449 static void 450 memac_if_init(void *data) 451 { 452 struct memac_softc *sc; 453 454 sc = data; 455 456 MEMAC_LOCK(sc); 457 memac_if_init_locked(sc); 458 MEMAC_UNLOCK(sc); 459 } 460 461 static void 462 memac_if_start(if_t ifp) 463 { 464 struct memac_softc *sc; 465 466 sc = if_getsoftc(ifp); 467 MEMAC_LOCK(sc); 468 dpaa_eth_if_start_locked(&sc->sc_base); 469 MEMAC_UNLOCK(sc); 470 } 471 472 static void 473 memac_if_watchdog(if_t ifp) 474 { 475 /* TODO */ 476 } 477 /** @} */ 478 479 480 /** 481 * @group IFmedia routines. 482 * @{ 483 */ 484 static int 485 memac_ifmedia_upd(if_t ifp) 486 { 487 struct memac_softc *sc = if_getsoftc(ifp); 488 489 return (0); 490 MEMAC_LOCK(sc); 491 mii_mediachg(sc->sc_base.sc_mii); 492 MEMAC_UNLOCK(sc); 493 494 return (0); 495 } 496 497 static void 498 memac_ifmedia_fixed_sts(if_t ifp, struct ifmediareq *ifmr) 499 { 500 struct memac_softc *sc = if_getsoftc(ifp); 501 502 MEMAC_LOCK(sc); 503 ifmr->ifm_count = 1; 504 ifmr->ifm_mask = 0; 505 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; 506 ifmr->ifm_current = ifmr->ifm_active = 507 sc->sc_base.sc_mii->mii_media.ifm_cur->ifm_media; 508 ifmr->ifm_active = ifmr->ifm_current; 509 510 /* 511 * In non-PHY usecases, we need to signal link state up, otherwise 512 * certain things requiring a link event (e.g async DHCP client) from 513 * devd do not happen. 514 */ 515 if (if_getlinkstate(ifp) == LINK_STATE_UNKNOWN) { 516 if_link_state_change(ifp, LINK_STATE_UP); 517 } 518 519 /* We assume the link is static, as in a peer switch. */ 520 521 MEMAC_UNLOCK(sc); 522 523 return; 524 } 525 526 static void 527 memac_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) 528 { 529 struct memac_softc *sc = if_getsoftc(ifp); 530 531 MEMAC_LOCK(sc); 532 533 mii_pollstat(sc->sc_base.sc_mii); 534 535 ifmr->ifm_active = sc->sc_base.sc_mii->mii_media_active; 536 ifmr->ifm_status = sc->sc_base.sc_mii->mii_media_status; 537 538 MEMAC_UNLOCK(sc); 539 } 540 /** @} */ 541 542 543 /** 544 * @group dTSEC bus interface. 545 * @{ 546 */ 547 548 int 549 memac_attach(device_t dev) 550 { 551 struct memac_softc *sc; 552 int error; 553 if_t ifp; 554 555 sc = device_get_softc(dev); 556 557 sc->sc_base.sc_dev = dev; 558 559 /* Init locks */ 560 mtx_init(&sc->sc_base.sc_lock, device_get_nameunit(dev), 561 "mEMAC Global Lock", MTX_DEF); 562 563 mtx_init(&sc->sc_base.sc_mii_lock, device_get_nameunit(dev), 564 "mEMAC MII Lock", MTX_DEF); 565 566 /* Init callouts */ 567 callout_init(&sc->sc_base.sc_tick_callout, CALLOUT_MPSAFE); 568 569 /* Create RX buffer pool */ 570 error = dpaa_eth_pool_rx_init(&sc->sc_base); 571 if (error != 0) 572 return (EIO); 573 574 /* Create RX frame queue range */ 575 error = dpaa_eth_fq_rx_init(&sc->sc_base); 576 if (error != 0) 577 return (EIO); 578 579 /* Create frame info pool */ 580 error = dpaa_eth_fi_pool_init(&sc->sc_base); 581 if (error != 0) 582 return (EIO); 583 584 /* Create TX frame queue range */ 585 error = dpaa_eth_fq_tx_init(&sc->sc_base); 586 if (error != 0) 587 return (EIO); 588 589 /* Init FMan MAC module. */ 590 error = memac_fm_mac_init(sc, sc->sc_base.sc_mac_addr); 591 if (error != 0) { 592 memac_detach(dev); 593 return (ENXIO); 594 } 595 596 dpaa_eth_fm_port_rx_init(&sc->sc_base); 597 dpaa_eth_fm_port_tx_init(&sc->sc_base); 598 599 /* Create network interface for upper layers */ 600 ifp = sc->sc_base.sc_ifnet = if_alloc(IFT_ETHER); 601 if_setsoftc(ifp, sc); 602 603 if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST); 604 if_setinitfn(ifp, memac_if_init); 605 if_setstartfn(ifp, memac_if_start); 606 if_setioctlfn(ifp, memac_if_ioctl); 607 if_setsendqlen(ifp, IFQ_MAXLEN); 608 if_setsendqready(ifp); 609 610 if (sc->sc_base.sc_phy_addr >= 0) 611 if_initname(ifp, device_get_name(sc->sc_base.sc_dev), 612 device_get_unit(sc->sc_base.sc_dev)); 613 else 614 if_initname(ifp, "memac_phy", 615 device_get_unit(sc->sc_base.sc_dev)); 616 617 618 if_setcapabilities(ifp, IFCAP_JUMBO_MTU | 619 IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM | 620 IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | 621 IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6); 622 if_setcapenable(ifp, if_getcapabilities(ifp)); 623 if_sethwassist(ifp, DPAA_CSUM_TX_OFFLOAD); 624 625 /* Attach PHY(s) */ 626 if (!sc->sc_fixed_link) { 627 error = mii_attach(sc->sc_base.sc_dev, &sc->sc_base.sc_mii_dev, 628 ifp, memac_ifmedia_upd, memac_ifmedia_sts, BMSR_DEFCAPMASK, 629 sc->sc_base.sc_phy_addr, MII_OFFSET_ANY, 0); 630 if (error) { 631 device_printf(sc->sc_base.sc_dev, 632 "attaching PHYs failed: %d\n", error); 633 memac_detach(sc->sc_base.sc_dev); 634 return (error); 635 } 636 sc->sc_base.sc_mii = device_get_softc(sc->sc_base.sc_mii_dev); 637 } else { 638 phandle_t node; 639 uint32_t type = IFM_ETHER; 640 uint32_t speed; 641 642 node = ofw_bus_find_child(ofw_bus_get_node(dev), "fixed-link"); 643 if (OF_getencprop(node, "speed", &speed, sizeof(speed)) <= 0) { 644 device_printf(dev, 645 "fixed link has no speed property\n"); 646 memac_detach(sc->sc_base.sc_dev); 647 return (ENXIO); 648 } 649 switch (speed) { 650 case 10: 651 type |= IFM_10_T; 652 break; 653 case 100: 654 type |= IFM_100_TX; 655 break; 656 case 1000: 657 type |= IFM_1000_T; 658 break; 659 case 2500: 660 type |= IFM_2500_T; 661 break; 662 case 5000: 663 type |= IFM_5000_T; 664 break; 665 case 10000: 666 type |= IFM_10G_T; 667 break; 668 } 669 if (OF_hasprop(node, "full-duplex")) 670 type |= IFM_FDX; 671 sc->sc_base.sc_mii = malloc(sizeof(*sc->sc_base.sc_mii), 672 M_DEVBUF, M_WAITOK | M_ZERO); 673 ifmedia_init(&sc->sc_base.sc_mii->mii_media, 0, 674 memac_ifmedia_upd, memac_ifmedia_fixed_sts); 675 ifmedia_add(&sc->sc_base.sc_mii->mii_media, type, 0, NULL); 676 ifmedia_set(&sc->sc_base.sc_mii->mii_media, type); 677 } 678 679 /* Attach to stack */ 680 ether_ifattach(ifp, sc->sc_base.sc_mac_addr); 681 682 return (0); 683 } 684 685 int 686 memac_detach(device_t dev) 687 { 688 struct memac_softc *sc; 689 if_t ifp; 690 691 sc = device_get_softc(dev); 692 ifp = sc->sc_base.sc_ifnet; 693 694 if (device_is_attached(dev)) { 695 ether_ifdetach(ifp); 696 /* Shutdown interface */ 697 MEMAC_LOCK(sc); 698 memac_if_deinit_locked(sc); 699 MEMAC_UNLOCK(sc); 700 } 701 702 if (sc->sc_base.sc_ifnet) { 703 if_free(sc->sc_base.sc_ifnet); 704 sc->sc_base.sc_ifnet = NULL; 705 } 706 707 /* Free RX/TX FQRs */ 708 dpaa_eth_fq_rx_free(&sc->sc_base); 709 dpaa_eth_fq_tx_free(&sc->sc_base); 710 711 /* Free frame info pool */ 712 dpaa_eth_fi_pool_free(&sc->sc_base); 713 714 /* Free RX buffer pool */ 715 dpaa_eth_pool_rx_free(&sc->sc_base); 716 717 /* Destroy lock */ 718 mtx_destroy(&sc->sc_base.sc_lock); 719 720 return (0); 721 } 722 723 int 724 memac_suspend(device_t dev) 725 { 726 727 return (0); 728 } 729 730 int 731 memac_resume(device_t dev) 732 { 733 734 return (0); 735 } 736 737 int 738 memac_shutdown(device_t dev) 739 { 740 741 return (0); 742 } 743 /** @} */ 744 745 746 /** 747 * @group MII bus interface. 748 * @{ 749 */ 750 int 751 memac_miibus_readreg(device_t dev, int phy, int reg) 752 { 753 struct memac_softc *sc; 754 755 sc = device_get_softc(dev); 756 757 return (MIIBUS_READREG(sc->sc_base.sc_mdio, phy, reg)); 758 } 759 760 int 761 memac_miibus_writereg(device_t dev, int phy, int reg, int value) 762 { 763 764 struct memac_softc *sc; 765 766 sc = device_get_softc(dev); 767 768 return (MIIBUS_WRITEREG(sc->sc_base.sc_mdio, phy, reg, value)); 769 } 770 771 void 772 memac_miibus_statchg(device_t dev) 773 { 774 struct memac_softc *sc; 775 uint32_t reg; 776 bool duplex; 777 int speed; 778 779 sc = device_get_softc(dev); 780 781 MEMAC_LOCK_ASSERT(sc); 782 783 duplex = ((sc->sc_base.sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX); 784 785 switch (IFM_SUBTYPE(sc->sc_base.sc_mii->mii_media_active)) { 786 case IFM_AUTO: 787 speed = IF_MODE_ENA; 788 break; 789 case IFM_1000_T: 790 case IFM_1000_SX: 791 if (!duplex) { 792 device_printf(sc->sc_base.sc_dev, 793 "Only full-duplex supported for 1Gbps speeds"); 794 return; 795 } 796 speed = IF_MODE_SSP_1GB; 797 break; 798 799 case IFM_100_TX: 800 speed = IF_MODE_SSP_100MB; 801 break; 802 default: 803 speed = IF_MODE_SSP_10MB; 804 break; 805 } 806 807 reg = bus_read_4(sc->sc_base.sc_mem, MEMAC_IF_MODE); 808 reg &= ~(IF_MODE_ENA | IF_MODE_SSP_M | IF_MODE_SFD); 809 reg |= 0x2; 810 811 if (duplex) 812 reg |= IF_MODE_SFD; 813 else 814 reg |= IF_MODE_HD; 815 reg |= speed; 816 bus_write_4(sc->sc_base.sc_mem, MEMAC_IF_MODE, reg); 817 } 818 /** @} */ 819