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