]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
net: stmmac: implement support for passive mode converters via dt
authorAlexandru Ardelean <alexandru.ardelean@analog.com>
Fri, 6 Sep 2019 13:02:55 +0000 (16:02 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Sep 2019 14:27:09 +0000 (15:27 +0100)
In-between the MAC & PHY there can be a mode converter, which converts one
mode to another (e.g. GMII-to-RGMII).

The converter, can be passive (i.e. no driver or OS/SW information
required), so the MAC & PHY need to be configured differently.

For the `stmmac` driver, this is implemented via a `mac-mode` property in
the device-tree, which configures the MAC into a certain mode, and for the
PHY a `phy_interface` field will hold the mode of the PHY. The mode of the
PHY will be passed to the PHY and from there-on it work in a different
mode. If unspecified, the default `phy-mode` will be used for both.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
include/linux/stmmac.h

index 6e44013b20ccb5f3fdf3602e64ad0e95c1f5e768..c61d702fe83a176e2f84eb43f6a842ee1c2cb96e 100644 (file)
@@ -1036,7 +1036,7 @@ static int stmmac_init_phy(struct net_device *dev)
 static int stmmac_phy_setup(struct stmmac_priv *priv)
 {
        struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
-       int mode = priv->plat->interface;
+       int mode = priv->plat->phy_interface;
        struct phylink *phylink;
 
        priv->phylink_config.dev = &priv->dev->dev;
index 5de754a9fae9d1eb4130d1de49414767f46ca5ce..170c3a052b14bf18e159eff4c42e5cb7a0cb8f69 100644 (file)
@@ -358,6 +358,32 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
        return 0;
 }
 
+/**
+ * stmmac_of_get_mac_mode - retrieves the interface of the MAC
+ * @np - device-tree node
+ * Description:
+ * Similar to `of_get_phy_mode()`, this function will retrieve (from
+ * the device-tree) the interface mode on the MAC side. This assumes
+ * that there is mode converter in-between the MAC & PHY
+ * (e.g. GMII-to-RGMII).
+ */
+static int stmmac_of_get_mac_mode(struct device_node *np)
+{
+       const char *pm;
+       int err, i;
+
+       err = of_property_read_string(np, "mac-mode", &pm);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
+               if (!strcasecmp(pm, phy_modes(i)))
+                       return i;
+       }
+
+       return -ENODEV;
+}
+
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
@@ -386,7 +412,13 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
                *mac = NULL;
        }
 
-       plat->interface = of_get_phy_mode(np);
+       plat->phy_interface = of_get_phy_mode(np);
+       if (plat->phy_interface < 0)
+               return ERR_PTR(plat->phy_interface);
+
+       plat->interface = stmmac_of_get_mac_mode(np);
+       if (plat->interface < 0)
+               plat->interface = plat->phy_interface;
 
        /* Some wrapper drivers still rely on phy_node. Let's save it while
         * they are not converted to phylink. */
index 7ad7ae35cf88a884815aeea662c241dff8106f8c..dc60d03c4b606399c3ee016bf765bc94a061efff 100644 (file)
@@ -131,6 +131,7 @@ struct plat_stmmacenet_data {
        int bus_id;
        int phy_addr;
        int interface;
+       int phy_interface;
        struct stmmac_mdio_bus_data *mdio_bus_data;
        struct device_node *phy_node;
        struct device_node *phylink_node;