From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 5fbb08eb7f945c7e8896ea39f03143ce66dfa4c7 ]
DSA has multiple ways of specifying a MAC connection to an internal PHY. One requires a DT description like this:
port@0 { reg = <0>; phy-handle = <&internal_phy>; phy-mode = "internal"; };
(which is IMO the recommended approach, as it is the clearest description)
but it is also possible to leave the specification as just:
port@0 { reg = <0>; }
and if the driver implements ds->ops->phy_read and ds->ops->phy_write, the DSA framework "knows" it should create a ds->slave_mii_bus, and it should connect to a non-OF-based internal PHY on this MDIO bus, at an MDIO address equal to the port address.
There is also an intermediary way of describing things:
port@0 { reg = <0>; phy-handle = <&internal_phy>; };
In case 2, DSA calls phylink_connect_phy() and in case 3, it calls phylink_of_phy_connect(). In both cases, phylink_create() has been called with a phy_interface_t of PHY_INTERFACE_MODE_NA, and in both cases, PHY_INTERFACE_MODE_NA is translated into phy->interface.
It is important to note that phy_device_create() initializes dev->interface = PHY_INTERFACE_MODE_GMII, and so, when we use phylink_create(PHY_INTERFACE_MODE_NA), no one will override this, and we will end up with a PHY_INTERFACE_MODE_GMII interface inherited from the PHY.
All this means that in order to maintain compatibility with device tree blobs where the phy-mode property is missing, we need to allow the "gmii" phy-mode and treat it as "internal".
Fixes: 2c709e0bdad4 ("net: dsa: microchip: ksz8795: add phylink support") Link: https://bugzilla.kernel.org/show_bug.cgi?id=216320 Reported-by: Craig McQueen craig@mcqueen.id.au Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Alvin Šipraga alsi@bang-olufsen.dk Tested-by: Rasmus Villemoes rasmus.villemoes@prevas.dk Link: https://lore.kernel.org/r/20220818143250.2797111-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/microchip/ksz_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 0f02c62b02685..c9389880ad1fa 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -453,9 +453,15 @@ void ksz_phylink_get_caps(struct dsa_switch *ds, int port, if (dev->info->supports_rgmii[port]) phy_interface_set_rgmii(config->supported_interfaces);
- if (dev->info->internal_phy[port]) + if (dev->info->internal_phy[port]) { __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); + /* Compatibility for phylib's default interface type when the + * phy-mode property is absent + */ + __set_bit(PHY_INTERFACE_MODE_GMII, + config->supported_interfaces); + }
if (dev->dev_ops->get_caps) dev->dev_ops->get_caps(dev, port, config);