On Tuesday, February 5, 2019 3:45:33 AM CET Andrew Lunn wrote: > On Mon, Feb 04, 2019 at 10:35:55PM +0100, 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. > > Hi Christian > > Looking at Documentation/devicetree/bindings/net/dsa/qca8k.txt > > I think everything you need is already implemented. What problem do > you actually have?
Thankfully, Florian's reply answered the question to me. The problem has to do with the qca8k's slave qca8k_phy_read and qca8k_phy_write. Here are the functions: |qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum) |{ | struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; | | return mdiobus_read(priv->bus, phy, 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; | | return mdiobus_write(priv->bus, phy, regnum, val); |} The trick here is that priv->bus is not the internal bus instead it's set to the SoC's (external) mii bus in qca8k_sw_probe()). So this isn't a slave bus! And as stated in the qca8k, the the external and internal PHY bus are not mapped 1:1. >From what I can tell from the datasheet, the QCA8337N does have dedicated MDIO master control register which is what is needed here. It's at 0x003C. So these mdiobus_read/writes on the SoCs MDIO bus would either need to be converted to read and write to 0x003c... Or the qca8k_phy_read() and qca8k_phy_write could be dropped all together. I've tested it on the WPQ864 and driver works without since it was never a real slave bus there to begin with. Thanks, Christian --- diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 7e97e620bd44..a26850c888cf 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -620,22 +620,6 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy) qca8k_port_set_status(priv, port, 1); } -static int -qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum) -{ - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - - return mdiobus_read(priv->bus, phy, 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; - - return mdiobus_write(priv->bus, phy, regnum, val); -} - static void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) { @@ -876,8 +860,6 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .setup = qca8k_setup, .adjust_link = qca8k_adjust_link, .get_strings = qca8k_get_strings, - .phy_read = qca8k_phy_read, - .phy_write = qca8k_phy_write, .get_ethtool_stats = qca8k_get_ethtool_stats, .get_sset_count = qca8k_get_sset_count, .get_mac_eee = qca8k_get_mac_eee,