On 2/4/19 1:35 PM, Christian Lamparter wrote: > The QCA8337 enumerates 5 PHYs on the MDC/MDIO access: PHY0-PHY4. > Based on the System Block Diagram in Section 1.2 of the > QCA8337's datasheet. These PHYs are internally connected > to MACs of PORT 1 - PORT 5. However, neither qca8k's slave > mdio access functions qca8k_phy_read()/qca8k_phy_write() > nor the dsa framework is set up for that. > > This version of the patch uses the existing phy-handle > properties of each specified DSA Port in the DT to map > each PORT/MAC to its exposed PHY on the MDIO bus. This > is supported by the current binding document qca8k.txt > as well.
I don't think you should have to do any of this translation, because you can do a couple of things with DSA/Device Tree: - you can not provide a phy-handle property at all, in which case, the core DSA layer assumes that the PHY is part of the switch's internal MDIO bus which is implictly created by dsa_slave_mii_bus_create() - you can specify a phy-handle property and then the PHY device tree node can be placed pretty much anywhere in Device Tree, including on a separate MDIO bus Device Tre node which is "external" to the switch In either case, the PHY device's MDIO bus parent and its address are taken care of by drivers/of/of_mdio.c. You can look at mx88e6xxx for how it deals with its internal vs. external MDIO bus controller and that driver is used on a wide variety of cconfiguration. > > Signed-off-by: Christian Lamparter <chunk...@gmail.com> > --- > drivers/net/dsa/qca8k.c | 35 +++++++++++++++++++++++++++++++++-- > 1 file changed, 33 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c > index a4b6cda38016..6558b7ed855d 100644 > --- a/drivers/net/dsa/qca8k.c > +++ b/drivers/net/dsa/qca8k.c > @@ -11,6 +11,7 @@ > #include <linux/netdevice.h> > #include <net/dsa.h> > #include <linux/of_net.h> > +#include <linux/of_mdio.h> > #include <linux/of_platform.h> > #include <linux/if_bridge.h> > #include <linux/mdio.h> > @@ -612,20 +613,50 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, > struct phy_device *phy) > qca8k_port_set_status(priv, port, 1); > } > > +static int > +qca8k_to_real_phy(struct dsa_switch *ds, int phy) > +{ > + struct device_node *phy_dn, *port_dn; > + int id; > + > + if (phy >= ds->num_ports) > + return -EINVAL; > + > + port_dn = ds->ports[phy].dn; > + if (!port_dn) > + return -EINVAL; > + > + phy_dn = of_parse_phandle(port_dn, "phy-handle", 0); > + if (!phy_dn) > + return phy; > + > + id = of_mdio_parse_addr(ds->dev, phy_dn); > + of_node_put(phy_dn); > + return id; > +} > + > static int > qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum) > { > struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; > + int realphy = qca8k_to_real_phy(ds, phy); > + > + if (realphy < 0) > + return realphy; > > - return mdiobus_read(priv->bus, phy, regnum); > + return mdiobus_read(priv->bus, realphy, regnum); > } > > static int > qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val) > { > struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; > + int realphy = qca8k_to_real_phy(ds, phy); > + > + if (realphy < 0) > + return realphy; > > - return mdiobus_write(priv->bus, phy, regnum, val); > + return mdiobus_write(priv->bus, realphy, regnum, val); > } > > static void > -- Florian