net: dsa: microchip: keep compatibility with device tree blobs with no phy-mode
authorVladimir Oltean <vladimir.oltean@nxp.com>
Thu, 18 Aug 2022 14:32:50 +0000 (17:32 +0300)
committerJakub Kicinski <kuba@kernel.org>
Tue, 23 Aug 2022 00:50:40 +0000 (17:50 -0700)
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>
drivers/net/dsa/microchip/ksz_common.c

index ed7d137..7461272 100644 (file)
@@ -803,9 +803,15 @@ static 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);