net: stmmac: implement support for passive mode converters via dt
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>
This commit is contained in:
parent
c1609946b8
commit
0060c87833
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user