diff --git a/sys/dev/tsec/if_tsec.h b/sys/dev/tsec/if_tsec.h index af703f2d7581..d13f46398b06 100644 --- a/sys/dev/tsec/if_tsec.h +++ b/sys/dev/tsec/if_tsec.h @@ -135,6 +135,7 @@ struct tsec_softc { int phyaddr; bus_space_tag_t phy_bst; bus_space_handle_t phy_bsh; + int phy_regoff; }; /* interface to get/put generic objects */ @@ -258,9 +259,11 @@ extern struct mtx tsec_phy_mtx; #define TSEC_PHY_LOCK(sc) mtx_lock(&tsec_phy_mtx) #define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx) #define TSEC_PHY_READ(sc, reg) \ - bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg)) + bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \ + (reg) + (sc)->phy_regoff) #define TSEC_PHY_WRITE(sc, reg, val) \ - bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val)) + bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \ + (reg) + (sc)->phy_regoff, (val)) /* Lock for transmitter */ #define TSEC_TRANSMIT_LOCK(sc) do { \ diff --git a/sys/dev/tsec/if_tsec_fdt.c b/sys/dev/tsec/if_tsec_fdt.c index ce18ccac6f32..7f25a42e1624 100644 --- a/sys/dev/tsec/if_tsec_fdt.c +++ b/sys/dev/tsec/if_tsec_fdt.c @@ -121,25 +121,33 @@ tsec_fdt_probe(device_t dev) sc = device_get_softc(dev); - sc->sc_rrid = 0; - sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid, - RF_ACTIVE); - if (sc->sc_rres == NULL) - return (ENXIO); + /* + * Device trees with "fsl,etsec2" compatible nodes don't have a reg + * property, as it's been relegated to the queue-group children. + */ + if (ofw_bus_is_compatible(dev, "fsl,etsec2")) + sc->is_etsec = 1; + else { + sc->sc_rrid = 0; + sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid, + RF_ACTIVE); + if (sc->sc_rres == NULL) + return (ENXIO); - sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); - sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); + sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); + sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); - /* Check if we are eTSEC (enhanced TSEC) */ - id = TSEC_READ(sc, TSEC_REG_ID); - sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0; - id |= TSEC_READ(sc, TSEC_REG_ID2); + /* Check if we are eTSEC (enhanced TSEC) */ + id = TSEC_READ(sc, TSEC_REG_ID); + sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0; + id |= TSEC_READ(sc, TSEC_REG_ID2); - bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres); + bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres); - if (id == 0) { - device_printf(dev, "could not identify TSEC type\n"); - return (ENXIO); + if (id == 0) { + device_printf(dev, "could not identify TSEC type\n"); + return (ENXIO); + } } if (sc->is_etsec) @@ -154,13 +162,31 @@ static int tsec_fdt_attach(device_t dev) { struct tsec_softc *sc; - phandle_t phy; + struct resource_list *rl; + phandle_t child, mdio, phy; + int acells, scells; int error = 0; sc = device_get_softc(dev); sc->dev = dev; sc->node = ofw_bus_get_node(dev); + if (fdt_addrsize_cells(sc->node, &acells, &scells) != 0) { + acells = 1; + scells = 1; + } + if (ofw_bus_is_compatible(dev, "fsl,etsec2")) { + rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); + + /* + * TODO: Add all children resources to the list. Will be + * required to support multigroup mode. + */ + child = OF_child(sc->node); + ofw_bus_reg_to_rl(dev, child, acells, scells, rl); + ofw_bus_intr_to_rl(dev, child, rl, NULL); + } + /* Get phy address from fdt */ if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) { device_printf(dev, "PHY not found in device tree"); @@ -168,9 +194,17 @@ tsec_fdt_attach(device_t dev) } phy = OF_node_from_xref(phy); - OF_decode_addr(OF_parent(phy), 0, &sc->phy_bst, &sc->phy_bsh, NULL); + mdio = OF_parent(phy); + OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL); OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr)); + /* + * etsec2 MDIO nodes are given the MDIO module base address, so we need + * to add the MII offset to get the PHY registers. + */ + if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio")) + sc->phy_regoff = TSEC_REG_MIIBASE; + /* Init timer */ callout_init(&sc->tsec_callout, 1);