1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2021 Alstom Group. 5 * Copyright (c) 2021 Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/kernel.h> 35 #include <sys/module.h> 36 #include <sys/socket.h> 37 #include <sys/sockio.h> 38 #include <sys/sysctl.h> 39 #include <sys/rman.h> 40 41 #include <machine/bus.h> 42 #include <machine/resource.h> 43 44 #include <net/if.h> 45 #include <net/if_media.h> 46 #include <net/if_types.h> 47 48 #include <dev/enetc/enetc_mdio.h> 49 50 #include <dev/etherswitch/etherswitch.h> 51 #include <dev/mii/mii.h> 52 #include <dev/mii/miivar.h> 53 #include <dev/pci/pcireg.h> 54 #include <dev/pci/pcivar.h> 55 56 #include <dev/ofw/ofw_bus.h> 57 #include <dev/ofw/ofw_bus_subr.h> 58 59 #include <dev/etherswitch/felix/felix_var.h> 60 #include <dev/etherswitch/felix/felix_reg.h> 61 62 #include "etherswitch_if.h" 63 #include "miibus_if.h" 64 65 MALLOC_DECLARE(M_FELIX); 66 MALLOC_DEFINE(M_FELIX, "felix", "felix switch"); 67 68 static device_probe_t felix_probe; 69 static device_attach_t felix_attach; 70 static device_detach_t felix_detach; 71 72 static etherswitch_info_t* felix_getinfo(device_t); 73 static int felix_getconf(device_t, etherswitch_conf_t *); 74 static int felix_setconf(device_t, etherswitch_conf_t *); 75 static void felix_lock(device_t); 76 static void felix_unlock(device_t); 77 static int felix_getport(device_t, etherswitch_port_t *); 78 static int felix_setport(device_t, etherswitch_port_t *); 79 static int felix_readreg_wrapper(device_t, int); 80 static int felix_writereg_wrapper(device_t, int, int); 81 static int felix_readphy(device_t, int, int); 82 static int felix_writephy(device_t, int, int, int); 83 static int felix_setvgroup(device_t, etherswitch_vlangroup_t *); 84 static int felix_getvgroup(device_t, etherswitch_vlangroup_t *); 85 86 static int felix_parse_port_fdt(felix_softc_t, phandle_t, int *); 87 static int felix_setup(felix_softc_t); 88 static void felix_setup_port(felix_softc_t, int); 89 90 static void felix_tick(void *); 91 static int felix_ifmedia_upd(struct ifnet *); 92 static void felix_ifmedia_sts(struct ifnet *, struct ifmediareq *); 93 94 static void felix_get_port_cfg(felix_softc_t, etherswitch_port_t *); 95 static void felix_set_port_cfg(felix_softc_t, etherswitch_port_t *); 96 97 static bool felix_is_phyport(felix_softc_t, int); 98 static struct mii_data *felix_miiforport(felix_softc_t, unsigned int); 99 100 static struct felix_pci_id felix_pci_ids[] = { 101 {PCI_VENDOR_FREESCALE, FELIX_DEV_ID, FELIX_DEV_NAME}, 102 {0, 0, NULL} 103 }; 104 105 static device_method_t felix_methods[] = { 106 /* device interface */ 107 DEVMETHOD(device_probe, felix_probe), 108 DEVMETHOD(device_attach, felix_attach), 109 DEVMETHOD(device_detach, felix_detach), 110 111 /* bus interface */ 112 DEVMETHOD(bus_add_child, device_add_child_ordered), 113 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 114 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 115 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 116 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 117 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 118 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 119 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 120 121 /* etherswitch interface */ 122 DEVMETHOD(etherswitch_getinfo, felix_getinfo), 123 DEVMETHOD(etherswitch_getconf, felix_getconf), 124 DEVMETHOD(etherswitch_setconf, felix_setconf), 125 DEVMETHOD(etherswitch_lock, felix_lock), 126 DEVMETHOD(etherswitch_unlock, felix_unlock), 127 DEVMETHOD(etherswitch_getport, felix_getport), 128 DEVMETHOD(etherswitch_setport, felix_setport), 129 DEVMETHOD(etherswitch_readreg, felix_readreg_wrapper), 130 DEVMETHOD(etherswitch_writereg, felix_writereg_wrapper), 131 DEVMETHOD(etherswitch_readphyreg, felix_readphy), 132 DEVMETHOD(etherswitch_writephyreg, felix_writephy), 133 DEVMETHOD(etherswitch_setvgroup, felix_setvgroup), 134 DEVMETHOD(etherswitch_getvgroup, felix_getvgroup), 135 136 /* miibus interface */ 137 DEVMETHOD(miibus_readreg, felix_readphy), 138 DEVMETHOD(miibus_writereg, felix_writephy), 139 140 DEVMETHOD_END 141 }; 142 143 static devclass_t felix_devclass; 144 DEFINE_CLASS_0(felix, felix_driver, felix_methods, 145 sizeof(struct felix_softc)); 146 147 DRIVER_MODULE_ORDERED(felix, pci, felix_driver, felix_devclass, 148 NULL, NULL, SI_ORDER_ANY); 149 DRIVER_MODULE(miibus, felix, miibus_fdt_driver, miibus_fdt_devclass, 150 NULL, NULL); 151 DRIVER_MODULE(etherswitch, felix, etherswitch_driver, etherswitch_devclass, 152 NULL, NULL); 153 MODULE_VERSION(felix, 1); 154 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, felix, 155 felix_pci_ids, nitems(felix_pci_ids) - 1); 156 157 static int 158 felix_probe(device_t dev) 159 { 160 struct felix_pci_id *id; 161 felix_softc_t sc; 162 163 sc = device_get_softc(dev); 164 sc->dev = dev; 165 166 for (id = felix_pci_ids; id->vendor != 0; ++id) { 167 if (pci_get_device(dev) != id->device || 168 pci_get_vendor(dev) != id->vendor) 169 continue; 170 171 device_set_desc(dev, id->desc); 172 173 return (BUS_PROBE_DEFAULT); 174 } 175 176 return (ENXIO); 177 } 178 179 static int 180 felix_parse_port_fdt(felix_softc_t sc, phandle_t child, int *pport) 181 { 182 uint32_t port, status; 183 phandle_t node; 184 185 if (OF_getencprop(child, "reg", (void *)&port, sizeof(port)) < 0) { 186 device_printf(sc->dev, "Port node doesn't have reg property\n"); 187 return (ENXIO); 188 } 189 190 *pport = port; 191 192 node = OF_getproplen(child, "ethernet"); 193 if (node <= 0) 194 sc->ports[port].cpu_port = false; 195 else 196 sc->ports[port].cpu_port = true; 197 198 node = ofw_bus_find_child(child, "fixed-link"); 199 if (node <= 0) { 200 sc->ports[port].fixed_port = false; 201 return (0); 202 } 203 204 sc->ports[port].fixed_port = true;; 205 206 if (OF_getencprop(node, "speed", &status, sizeof(status)) <= 0) { 207 device_printf(sc->dev, 208 "Port has fixed-link node without link speed specified\n"); 209 return (ENXIO); 210 } 211 212 switch (status) { 213 case 2500: 214 status = IFM_2500_T; 215 break; 216 case 1000: 217 status = IFM_1000_T; 218 break; 219 case 100: 220 status = IFM_100_T; 221 break; 222 case 10: 223 status = IFM_10_T; 224 break; 225 default: 226 device_printf(sc->dev, 227 "Unsupported link speed value of %d\n", 228 status); 229 return (ENXIO); 230 } 231 232 if (OF_hasprop(node, "full-duplex")) 233 status |= IFM_FDX; 234 else 235 status |= IFM_HDX; 236 237 status |= IFM_ETHER; 238 sc->ports[port].fixed_link_status = status; 239 return (0); 240 } 241 242 static int 243 felix_init_interface(felix_softc_t sc, int port) 244 { 245 char name[IFNAMSIZ]; 246 247 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->dev)); 248 249 sc->ports[port].ifp = if_alloc(IFT_ETHER); 250 if (sc->ports[port].ifp == NULL) 251 return (ENOMEM); 252 253 sc->ports[port].ifp->if_softc = sc; 254 sc->ports[port].ifp->if_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST | 255 IFF_DRV_RUNNING | IFF_SIMPLEX; 256 sc->ports[port].ifname = malloc(strlen(name) + 1, M_FELIX, M_NOWAIT); 257 if (sc->ports[port].ifname == NULL) { 258 if_free(sc->ports[port].ifp); 259 return (ENOMEM); 260 } 261 262 memcpy(sc->ports[port].ifname, name, strlen(name) + 1); 263 if_initname(sc->ports[port].ifp, sc->ports[port].ifname, port); 264 return (0); 265 } 266 267 static void 268 felix_setup_port(felix_softc_t sc, int port) 269 { 270 271 /* Link speed has to be always set to 1000 in the clock register. */ 272 FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_CLK_CFG, 273 FELIX_DEVGMII_CLK_CFG_SPEED_1000); 274 FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_MAC_CFG, 275 FELIX_DEVGMII_MAC_CFG_TX_ENA | FELIX_DEVGMII_MAC_CFG_RX_ENA); 276 FELIX_WR4(sc, FELIX_QSYS_PORT_MODE(port), 277 FELIX_QSYS_PORT_MODE_PORT_ENA); 278 279 /* 280 * Enable "VLANMTU". Each port has a configurable MTU. 281 * Accept frames that are 8 and 4 bytes longer than it 282 * for double and single tagged frames respectively. 283 * Since etherswitch API doesn't provide an option to change 284 * MTU don't touch it for now. 285 */ 286 FELIX_DEVGMII_PORT_WR4(sc, port, FELIX_DEVGMII_VLAN_CFG, 287 FELIX_DEVGMII_VLAN_CFG_ENA | 288 FELIX_DEVGMII_VLAN_CFG_LEN_ENA | 289 FELIX_DEVGMII_VLAN_CFG_DOUBLE_ENA); 290 } 291 292 static int 293 felix_setup(felix_softc_t sc) 294 { 295 int timeout, i; 296 uint32_t reg; 297 298 /* Trigger soft reset, bit is self-clearing, with 5s timeout. */ 299 FELIX_WR4(sc, FELIX_DEVCPU_GCB_RST, FELIX_DEVCPU_GCB_RST_EN); 300 timeout = FELIX_INIT_TIMEOUT; 301 do { 302 DELAY(1000); 303 reg = FELIX_RD4(sc, FELIX_DEVCPU_GCB_RST); 304 if ((reg & FELIX_DEVCPU_GCB_RST_EN) == 0) 305 break; 306 } while (timeout-- > 0); 307 if (timeout == 0) { 308 device_printf(sc->dev, 309 "Timeout while waiting for switch to reset\n"); 310 return (ETIMEDOUT); 311 } 312 313 FELIX_WR4(sc, FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT); 314 timeout = FELIX_INIT_TIMEOUT; 315 do { 316 DELAY(1000); 317 reg = FELIX_RD4(sc, FELIX_SYS_RAM_CTRL); 318 if ((reg & FELIX_SYS_RAM_CTRL_INIT) == 0) 319 break; 320 } while (timeout-- > 0); 321 if (timeout == 0) { 322 device_printf(sc->dev, 323 "Timeout while waiting for switch RAM init.\n"); 324 return (ETIMEDOUT); 325 } 326 327 FELIX_WR4(sc, FELIX_SYS_CFG, FELIX_SYS_CFG_CORE_EN); 328 329 for (i = 0; i < sc->info.es_nports; i++) 330 felix_setup_port(sc, i); 331 332 return (0); 333 } 334 335 static int 336 felix_timer_rate(SYSCTL_HANDLER_ARGS) 337 { 338 felix_softc_t sc; 339 int error, value, old; 340 341 sc = arg1; 342 343 old = value = sc->timer_ticks; 344 error = sysctl_handle_int(oidp, &value, 0, req); 345 if (error != 0 || req->newptr == NULL) 346 return (error); 347 348 if (value < 0) 349 return (EINVAL); 350 351 if (value == old) 352 return (0); 353 354 FELIX_LOCK(sc); 355 sc->timer_ticks = value; 356 callout_reset(&sc->tick_callout, sc->timer_ticks, felix_tick, sc); 357 FELIX_UNLOCK(sc); 358 359 return (0); 360 } 361 362 static int 363 felix_attach(device_t dev) 364 { 365 phandle_t child, ports, node; 366 int error, port, rid; 367 felix_softc_t sc; 368 uint32_t phy_addr; 369 ssize_t size; 370 371 sc = device_get_softc(dev); 372 sc->info.es_nports = 0; 373 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q; 374 strlcpy(sc->info.es_name, "Felix TSN Switch", sizeof(sc->info.es_name)); 375 376 rid = PCIR_BAR(FELIX_BAR_MDIO); 377 sc->mdio = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 378 RF_ACTIVE); 379 if (sc->mdio == NULL) { 380 device_printf(dev, "Failed to allocate MDIO registers.\n"); 381 return (ENXIO); 382 } 383 384 rid = PCIR_BAR(FELIX_BAR_REGS); 385 sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 386 RF_ACTIVE); 387 if (sc->regs == NULL) { 388 device_printf(dev, "Failed to allocate registers BAR.\n"); 389 error = ENXIO; 390 goto out_fail; 391 } 392 393 mtx_init(&sc->mtx, "felix lock", NULL, MTX_DEF); 394 callout_init_mtx(&sc->tick_callout, &sc->mtx, 0); 395 396 node = ofw_bus_get_node(dev); 397 if (node <= 0) { 398 error = ENXIO; 399 goto out_fail; 400 } 401 402 ports = ofw_bus_find_child(node, "ports"); 403 if (ports == 0) { 404 device_printf(dev, 405 "Failed to find \"ports\" property in DTS.\n"); 406 error = ENXIO; 407 goto out_fail; 408 } 409 410 for (child = OF_child(ports); child != 0; child = OF_peer(child)) { 411 /* Do not parse disabled ports. */ 412 if (ofw_bus_node_status_okay(child) == 0) 413 continue; 414 415 error = felix_parse_port_fdt(sc, child, &port); 416 if (error != 0) 417 goto out_fail; 418 419 error = felix_init_interface(sc, port); 420 if (error != 0) { 421 device_printf(sc->dev, 422 "Failed to initialize interface.\n"); 423 goto out_fail; 424 } 425 426 if (sc->ports[port].fixed_port) { 427 sc->info.es_nports++; 428 continue; 429 } 430 431 size = OF_getencprop(child, "phy-handle", &node, sizeof(node)); 432 if (size <= 0) { 433 device_printf(sc->dev, 434 "Failed to acquire PHY handle from FDT.\n"); 435 error = ENXIO; 436 goto out_fail; 437 } 438 439 node = OF_node_from_xref(node); 440 size = OF_getencprop(node, "reg", &phy_addr, sizeof(phy_addr)); 441 if (size <= 0) { 442 device_printf(sc->dev, 443 "Failed to obtain PHY address.\n"); 444 error = ENXIO; 445 goto out_fail; 446 } 447 448 sc->ports[port].phyaddr = phy_addr; 449 sc->ports[port].miibus = NULL; 450 error = mii_attach(dev, &sc->ports[port].miibus, sc->ports[port].ifp, 451 felix_ifmedia_upd, felix_ifmedia_sts, BMSR_DEFCAPMASK, 452 phy_addr, MII_OFFSET_ANY, 0); 453 if (error != 0) 454 goto out_fail; 455 456 sc->info.es_nports++; 457 } 458 459 error = felix_setup(sc); 460 if (error != 0) 461 goto out_fail; 462 463 sc->timer_ticks = hz; /* Default to 1s. */ 464 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 465 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 466 OID_AUTO, "timer_ticks", CTLTYPE_INT | CTLFLAG_RW, 467 sc, 0, felix_timer_rate, "I", 468 "Number of ticks between timer invocations"); 469 470 /* The tick routine has to be called with the lock held. */ 471 FELIX_LOCK(sc); 472 felix_tick(sc); 473 FELIX_UNLOCK(sc); 474 475 /* Allow etherswitch to attach as our child. */ 476 bus_generic_probe(dev); 477 bus_generic_attach(dev); 478 479 return (0); 480 481 out_fail: 482 felix_detach(dev); 483 return (error); 484 } 485 486 static int 487 felix_detach(device_t dev) 488 { 489 felix_softc_t sc; 490 int error; 491 int i; 492 493 error = 0; 494 sc = device_get_softc(dev); 495 bus_generic_detach(dev); 496 497 mtx_lock(&sc->mtx); 498 callout_stop(&sc->tick_callout); 499 mtx_unlock(&sc->mtx); 500 mtx_destroy(&sc->mtx); 501 502 /* 503 * If we have been fully attached do a soft reset. 504 * This way after when driver is unloaded switch is left in unmanaged mode. 505 */ 506 if (device_is_attached(dev)) 507 felix_setup(sc); 508 509 for (i = 0; i < sc->info.es_nports; i++) { 510 if (sc->ports[i].miibus != NULL) 511 device_delete_child(dev, sc->ports[i].miibus); 512 if (sc->ports[i].ifp != NULL) 513 if_free(sc->ports[i].ifp); 514 if (sc->ports[i].ifname != NULL) 515 free(sc->ports[i].ifname, M_FELIX); 516 } 517 518 if (sc->regs != NULL) 519 error = bus_release_resource(sc->dev, SYS_RES_MEMORY, 520 rman_get_rid(sc->regs), sc->regs); 521 522 if (sc->mdio != NULL) 523 error = bus_release_resource(sc->dev, SYS_RES_MEMORY, 524 rman_get_rid(sc->mdio), sc->mdio); 525 526 return (error); 527 } 528 529 static etherswitch_info_t* 530 felix_getinfo(device_t dev) 531 { 532 felix_softc_t sc; 533 534 sc = device_get_softc(dev); 535 return (&sc->info); 536 } 537 538 static int 539 felix_getconf(device_t dev, etherswitch_conf_t *conf) 540 { 541 felix_softc_t sc; 542 543 sc = device_get_softc(dev); 544 545 /* Return the VLAN mode. */ 546 conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; 547 conf->vlan_mode = sc->vlan_mode; 548 return (0); 549 } 550 551 static int 552 felix_init_vlan(felix_softc_t sc) 553 { 554 int timeout = FELIX_INIT_TIMEOUT; 555 uint32_t reg; 556 int i; 557 558 /* Flush VLAN table in hardware. */ 559 FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_RESET); 560 do { 561 DELAY(1000); 562 reg = FELIX_RD4(sc, FELIX_ANA_VT); 563 if ((reg & FELIX_ANA_VT_STS) == FELIX_ANA_VT_IDLE) 564 break; 565 } while (timeout-- > 0); 566 if (timeout == 0) { 567 device_printf(sc->dev, 568 "Timeout during VLAN table reset.\n"); 569 return (ETIMEDOUT); 570 } 571 572 /* Flush VLAN table in sc. */ 573 for (i = 0; i < sc->info.es_nvlangroups; i++) 574 sc->vlans[i] = 0; 575 576 /* 577 * Make all ports VLAN aware. 578 * Read VID from incoming frames and use it for port grouping 579 * purposes. 580 * Don't set this if pvid is set. 581 */ 582 for (i = 0; i < sc->info.es_nports; i++) { 583 reg = FELIX_ANA_PORT_RD4(sc, i, FELIX_ANA_PORT_VLAN_CFG); 584 if ((reg & FELIX_ANA_PORT_VLAN_CFG_VID_MASK) != 0) 585 continue; 586 587 reg |= FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; 588 FELIX_ANA_PORT_WR4(sc, i, FELIX_ANA_PORT_VLAN_CFG, reg); 589 } 590 return (0); 591 } 592 593 static int 594 felix_setconf(device_t dev, etherswitch_conf_t *conf) 595 { 596 felix_softc_t sc; 597 int error; 598 599 error = 0; 600 /* Set the VLAN mode. */ 601 sc = device_get_softc(dev); 602 FELIX_LOCK(sc); 603 if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) { 604 switch (conf->vlan_mode) { 605 case ETHERSWITCH_VLAN_DOT1Q: 606 sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; 607 sc->info.es_nvlangroups = FELIX_NUM_VLANS; 608 error = felix_init_vlan(sc); 609 break; 610 default: 611 error = EINVAL; 612 } 613 } 614 FELIX_UNLOCK(sc); 615 return (error); 616 } 617 618 static void 619 felix_lock(device_t dev) 620 { 621 felix_softc_t sc; 622 623 sc = device_get_softc(dev); 624 FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); 625 FELIX_LOCK(sc); 626 } 627 628 static void 629 felix_unlock(device_t dev) 630 { 631 felix_softc_t sc; 632 633 sc = device_get_softc(dev); 634 FELIX_LOCK_ASSERT(sc, MA_OWNED); 635 FELIX_UNLOCK(sc); 636 } 637 638 static void 639 felix_get_port_cfg(felix_softc_t sc, etherswitch_port_t *p) 640 { 641 uint32_t reg; 642 643 p->es_flags = 0; 644 645 reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG); 646 if (reg & FELIX_ANA_PORT_DROP_CFG_TAGGED) 647 p->es_flags |= ETHERSWITCH_PORT_DROPTAGGED; 648 649 if (reg & FELIX_ANA_PORT_DROP_CFG_UNTAGGED) 650 p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED; 651 652 reg = FELIX_DEVGMII_PORT_RD4(sc, p->es_port, FELIX_DEVGMII_VLAN_CFG); 653 if (reg & FELIX_DEVGMII_VLAN_CFG_DOUBLE_ENA) 654 p->es_flags |= ETHERSWITCH_PORT_DOUBLE_TAG; 655 656 reg = FELIX_REW_PORT_RD4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG); 657 if (reg & FELIX_REW_PORT_TAG_CFG_ALL) 658 p->es_flags |= ETHERSWITCH_PORT_ADDTAG; 659 660 reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG); 661 if (reg & FELIX_ANA_PORT_VLAN_CFG_POP) 662 p->es_flags |= ETHERSWITCH_PORT_STRIPTAGINGRESS; 663 664 p->es_pvid = reg & FELIX_ANA_PORT_VLAN_CFG_VID_MASK; 665 } 666 667 static int 668 felix_getport(device_t dev, etherswitch_port_t *p) 669 { 670 struct ifmediareq *ifmr; 671 struct mii_data *mii; 672 felix_softc_t sc; 673 int error; 674 675 error = 0; 676 sc = device_get_softc(dev); 677 FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); 678 679 if (p->es_port >= sc->info.es_nports || p->es_port < 0) 680 return (EINVAL); 681 682 FELIX_LOCK(sc); 683 felix_get_port_cfg(sc, p); 684 if (sc->ports[p->es_port].fixed_port) { 685 ifmr = &p->es_ifmr; 686 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; 687 ifmr->ifm_count = 0; 688 ifmr->ifm_active = sc->ports[p->es_port].fixed_link_status; 689 ifmr->ifm_current = ifmr->ifm_active; 690 ifmr->ifm_mask = 0; 691 } else { 692 mii = felix_miiforport(sc, p->es_port); 693 error = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, 694 &mii->mii_media, SIOCGIFMEDIA); 695 } 696 FELIX_UNLOCK(sc); 697 return (error); 698 } 699 700 static void 701 felix_set_port_cfg(felix_softc_t sc, etherswitch_port_t *p) 702 { 703 uint32_t reg; 704 705 reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG); 706 if (p->es_flags & ETHERSWITCH_PORT_DROPTAGGED) 707 reg |= FELIX_ANA_PORT_DROP_CFG_TAGGED; 708 else 709 reg &= ~FELIX_ANA_PORT_DROP_CFG_TAGGED; 710 711 if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED) 712 reg |= FELIX_ANA_PORT_DROP_CFG_UNTAGGED; 713 else 714 reg &= ~FELIX_ANA_PORT_DROP_CFG_UNTAGGED; 715 716 FELIX_ANA_PORT_WR4(sc, p->es_port, FELIX_ANA_PORT_DROP_CFG, reg); 717 718 reg = FELIX_REW_PORT_RD4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG); 719 if (p->es_flags & ETHERSWITCH_PORT_ADDTAG) 720 reg |= FELIX_REW_PORT_TAG_CFG_ALL; 721 else 722 reg &= ~FELIX_REW_PORT_TAG_CFG_ALL; 723 724 FELIX_REW_PORT_WR4(sc, p->es_port, FELIX_REW_PORT_TAG_CFG, reg); 725 726 reg = FELIX_ANA_PORT_RD4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG); 727 if (p->es_flags & ETHERSWITCH_PORT_STRIPTAGINGRESS) 728 reg |= FELIX_ANA_PORT_VLAN_CFG_POP; 729 else 730 reg &= ~FELIX_ANA_PORT_VLAN_CFG_POP; 731 732 reg &= ~FELIX_ANA_PORT_VLAN_CFG_VID_MASK; 733 reg |= p->es_pvid & FELIX_ANA_PORT_VLAN_CFG_VID_MASK; 734 /* 735 * If port VID is set use it for VLAN classification, 736 * instead of frame VID. 737 * By default the frame tag takes precedence. 738 * Force the switch to ignore it. 739 */ 740 if (p->es_pvid != 0) 741 reg &= ~FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; 742 else 743 reg |= FELIX_ANA_PORT_VLAN_CFG_VID_AWARE; 744 745 FELIX_ANA_PORT_WR4(sc, p->es_port, FELIX_ANA_PORT_VLAN_CFG, reg); 746 } 747 748 static int 749 felix_setport(device_t dev, etherswitch_port_t *p) 750 { 751 felix_softc_t sc; 752 struct mii_data *mii; 753 int error; 754 755 error = 0; 756 sc = device_get_softc(dev); 757 FELIX_LOCK_ASSERT(sc, MA_NOTOWNED); 758 759 if (p->es_port >= sc->info.es_nports || p->es_port < 0) 760 return (EINVAL); 761 762 FELIX_LOCK(sc); 763 felix_set_port_cfg(sc, p); 764 if (felix_is_phyport(sc, p->es_port)) { 765 mii = felix_miiforport(sc, p->es_port); 766 error = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, &mii->mii_media, 767 SIOCSIFMEDIA); 768 } 769 FELIX_UNLOCK(sc); 770 771 return (error); 772 } 773 774 static int 775 felix_readreg_wrapper(device_t dev, int addr_reg) 776 { 777 felix_softc_t sc; 778 779 sc = device_get_softc(dev); 780 if (addr_reg > rman_get_size(sc->regs)) 781 return (UINT32_MAX); /* Can't return errors here. */ 782 783 return (FELIX_RD4(sc, addr_reg)); 784 } 785 786 static int 787 felix_writereg_wrapper(device_t dev, int addr_reg, int val) 788 { 789 felix_softc_t sc; 790 791 sc = device_get_softc(dev); 792 if (addr_reg > rman_get_size(sc->regs)) 793 return (EINVAL); 794 795 FELIX_WR4(sc, addr_reg, val); 796 return (0); 797 } 798 799 static int 800 felix_readphy(device_t dev, int phy, int reg) 801 { 802 felix_softc_t sc; 803 804 sc = device_get_softc(dev); 805 806 return (enetc_mdio_read(sc->mdio, FELIX_MDIO_BASE, phy, reg)); 807 } 808 809 static int 810 felix_writephy(device_t dev, int phy, int reg, int data) 811 { 812 felix_softc_t sc; 813 814 sc = device_get_softc(dev); 815 816 return (enetc_mdio_write(sc->mdio, FELIX_MDIO_BASE, phy, reg, data)); 817 } 818 819 static int 820 felix_set_dot1q_vlan(felix_softc_t sc, etherswitch_vlangroup_t *vg) 821 { 822 uint32_t reg; 823 int i, vid; 824 825 vid = vg->es_vid & ETHERSWITCH_VID_MASK; 826 827 /* Tagged mode is not supported. */ 828 if (vg->es_member_ports != vg->es_untagged_ports) 829 return (EINVAL); 830 831 /* 832 * Hardware support 4096 groups, but we can't do group_id == vid. 833 * Note that hw_group_id == vid. 834 */ 835 if (vid == 0) { 836 /* Clear VLAN table entry using old VID. */ 837 FELIX_WR4(sc, FELIX_ANA_VTIDX, sc->vlans[vg->es_vlangroup]); 838 FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_WRITE); 839 sc->vlans[vg->es_vlangroup] = 0; 840 return (0); 841 } 842 843 /* The VID is already used in a different group. */ 844 for (i = 0; i < sc->info.es_nvlangroups; i++) 845 if (i != vg->es_vlangroup && vid == sc->vlans[i]) 846 return (EINVAL); 847 848 /* This group already uses a different VID. */ 849 if (sc->vlans[vg->es_vlangroup] != 0 && 850 sc->vlans[vg->es_vlangroup] != vid) 851 return (EINVAL); 852 853 sc->vlans[vg->es_vlangroup] = vid; 854 855 /* Assign members to the given group. */ 856 reg = vg->es_member_ports & FELIX_ANA_VT_PORTMASK_MASK; 857 reg <<= FELIX_ANA_VT_PORTMASK_SHIFT; 858 reg |= FELIX_ANA_VT_WRITE; 859 860 FELIX_WR4(sc, FELIX_ANA_VTIDX, vid); 861 FELIX_WR4(sc, FELIX_ANA_VT, reg); 862 863 /* 864 * According to documentation read and write commands 865 * are instant. 866 * Add a small delay just to be safe. 867 */ 868 mb(); 869 DELAY(100); 870 reg = FELIX_RD4(sc, FELIX_ANA_VT); 871 if ((reg & FELIX_ANA_VT_STS) != FELIX_ANA_VT_IDLE) 872 return (ENXIO); 873 874 return (0); 875 } 876 877 static int 878 felix_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) 879 { 880 felix_softc_t sc; 881 int error; 882 883 sc = device_get_softc(dev); 884 885 FELIX_LOCK(sc); 886 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 887 error = felix_set_dot1q_vlan(sc, vg); 888 else 889 error = EINVAL; 890 891 FELIX_UNLOCK(sc); 892 return (error); 893 } 894 895 static int 896 felix_get_dot1q_vlan(felix_softc_t sc, etherswitch_vlangroup_t *vg) 897 { 898 uint32_t reg; 899 int vid; 900 901 vid = sc->vlans[vg->es_vlangroup]; 902 903 if (vid == 0) 904 return (0); 905 906 FELIX_WR4(sc, FELIX_ANA_VTIDX, vid); 907 FELIX_WR4(sc, FELIX_ANA_VT, FELIX_ANA_VT_READ); 908 909 /* 910 * According to documentation read and write commands 911 * are instant. 912 * Add a small delay just to be safe. 913 */ 914 mb(); 915 DELAY(100); 916 reg = FELIX_RD4(sc, FELIX_ANA_VT); 917 if ((reg & FELIX_ANA_VT_STS) != FELIX_ANA_VT_IDLE) 918 return (ENXIO); 919 920 reg >>= FELIX_ANA_VT_PORTMASK_SHIFT; 921 reg &= FELIX_ANA_VT_PORTMASK_MASK; 922 923 vg->es_untagged_ports = vg->es_member_ports = reg; 924 vg->es_fid = 0; 925 vg->es_vid = vid | ETHERSWITCH_VID_VALID; 926 return (0); 927 } 928 929 static int 930 felix_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) 931 { 932 felix_softc_t sc; 933 int error; 934 935 sc = device_get_softc(dev); 936 937 FELIX_LOCK(sc); 938 if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) 939 error = felix_get_dot1q_vlan(sc, vg); 940 else 941 error = EINVAL; 942 943 FELIX_UNLOCK(sc); 944 return (error); 945 } 946 947 static void 948 felix_tick(void *arg) 949 { 950 struct mii_data *mii; 951 felix_softc_t sc; 952 int port; 953 954 sc = arg; 955 956 FELIX_LOCK_ASSERT(sc, MA_OWNED); 957 958 for (port = 0; port < sc->info.es_nports; port++) { 959 if (!felix_is_phyport(sc, port)) 960 continue; 961 962 mii = felix_miiforport(sc, port); 963 MPASS(mii != NULL); 964 mii_tick(mii); 965 } 966 if (sc->timer_ticks != 0) 967 callout_reset(&sc->tick_callout, sc->timer_ticks, felix_tick, sc); 968 } 969 970 static int 971 felix_ifmedia_upd(struct ifnet *ifp) 972 { 973 struct mii_data *mii; 974 felix_softc_t sc; 975 976 sc = ifp->if_softc; 977 mii = felix_miiforport(sc, ifp->if_dunit); 978 if (mii == NULL) 979 return (ENXIO); 980 981 mii_mediachg(mii); 982 return (0); 983 } 984 985 static void 986 felix_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 987 { 988 felix_softc_t sc; 989 struct mii_data *mii; 990 991 sc = ifp->if_softc; 992 mii = felix_miiforport(sc, ifp->if_dunit); 993 if (mii == NULL) 994 return; 995 996 mii_pollstat(mii); 997 ifmr->ifm_active = mii->mii_media_active; 998 ifmr->ifm_status = mii->mii_media_status; 999 } 1000 1001 static bool 1002 felix_is_phyport(felix_softc_t sc, int port) 1003 { 1004 1005 return (!sc->ports[port].fixed_port); 1006 } 1007 1008 static struct mii_data* 1009 felix_miiforport(felix_softc_t sc, unsigned int port) 1010 { 1011 1012 if (!felix_is_phyport(sc, port)) 1013 return (NULL); 1014 1015 return (device_get_softc(sc->ports[port].miibus)); 1016 } 1017