When configuring a switch port to use an external phy, the phy is connected to external switch MII bus:
+---------+ +-----+ MII cpu | Switch | MII ext +-----+ | CPU | ---------> |---------| ---------> | PHY | +-----+ | MII int | +-----+ +---------+ In the device tree, the configuration looks something like this: / { /* ... */ mdio { /* phy on MII cpu */ phy0@0 { reg = <0>; }; /* switch on MII cpu */ switch0@1 { reg = <1>; ports { /* port internal phy */ port1@1 { reg = <1>; label = "lan1"; phy-handle <&switch0phy1>; }; /* port with external phy */ port0@0 { reg = <0>; label = "lan0"; phy-handle <&switch0phy0>; }; }; /* internal MII */ mdio { switch0phy1@1 { reg = <1>; }; }; /* external MII */ mdio1 { switch0phy0: switch0phy0@0 { reg = <0>; }; }; }; }; /* ... */ }; When connecting port0 to switch0phy0, the current dsa code assumes the phy to be connected to the internal MII bus, and thus fails with mv88e6085 f1072004.mdio-mii:02 lan0: no phy at 0 mv88e6085 f1072004.mdio-mii:02 lan0: failed to connect to phy0: -19 mvneta f1034000.ethernet eth2: error -19 setting up slave phy mv88e6085 f1072004.mdio-mii:02: Failed to create slave 0: -19 Fix this by using the phy of-handle to obtain a reference to the parent mdio_bus, which is then used to connect the phy. Signed-off-by: Martin Hundebøll <m...@prevas.dk> --- net/dsa/slave.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 45f4ea845c07..62ad69a728be 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -976,12 +976,16 @@ static int dsa_slave_fixed_link_update(struct net_device *dev, } /* slave device setup *******************************************************/ -static int dsa_slave_phy_connect(struct net_device *slave_dev, int addr) +static int dsa_slave_phy_connect(struct net_device *slave_dev, + struct mii_bus *bus, int addr) { struct dsa_slave_priv *p = netdev_priv(slave_dev); struct dsa_switch *ds = p->dp->ds; - slave_dev->phydev = mdiobus_get_phy(ds->slave_mii_bus, addr); + if (!bus) + bus = ds->slave_mii_bus; + + slave_dev->phydev = mdiobus_get_phy(bus, addr); if (!slave_dev->phydev) { netdev_err(slave_dev, "no phy at %d\n", addr); return -ENODEV; @@ -1029,6 +1033,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) if (phy_dn) { int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn); + struct mii_bus *bus = of_mdio_find_bus(phy_dn->parent); /* If this PHY address is part of phys_mii_mask, which means * that we need to divert reads and writes to/from it, then we @@ -1037,7 +1042,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) */ if (!phy_is_fixed && phy_id >= 0 && (ds->phys_mii_mask & (1 << phy_id))) { - ret = dsa_slave_phy_connect(slave_dev, phy_id); + ret = dsa_slave_phy_connect(slave_dev, bus, phy_id); if (ret) { netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret); of_node_put(phy_dn); @@ -1061,7 +1066,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) * MDIO bus instead */ if (!slave_dev->phydev) { - ret = dsa_slave_phy_connect(slave_dev, p->dp->index); + ret = dsa_slave_phy_connect(slave_dev, NULL, p->dp->index); if (ret) { netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->dp->index, ret); -- 2.14.2