Commit 20a4da20 authored by Oleksij Rempel's avatar Oleksij Rempel Committed by Paolo Abeni
Browse files

net: phy: Add support for PHY timing-role configuration via device tree



Introduce support for configuring the master/slave role of PHYs based on
the `timing-role` property in the device tree. While this functionality
is necessary for Single Pair Ethernet (SPE) PHYs (1000/100/10Base-T1)
where hardware strap pins may be unavailable or incorrectly set, it
works for any PHY type.

Signed-off-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarFlorian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: default avatarDivya Koppera <divya.koppera@microchip.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 31a9ce20
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -412,6 +412,39 @@ void of_set_phy_eee_broken(struct phy_device *phydev)
	phydev->eee_broken_modes = broken;
}

/**
 * of_set_phy_timing_role - Set the master/slave mode of the PHY
 *
 * @phydev: The phy_device struct
 *
 * Set master/slave configuration of the PHY based on the device tree.
 */
void of_set_phy_timing_role(struct phy_device *phydev)
{
	struct device_node *node = phydev->mdio.dev.of_node;
	const char *master;

	if (!IS_ENABLED(CONFIG_OF_MDIO))
		return;

	if (!node)
		return;

	if (of_property_read_string(node, "timing-role", &master))
		return;

	if (strcmp(master, "forced-master") == 0)
		phydev->master_slave_set = MASTER_SLAVE_CFG_MASTER_FORCE;
	else if (strcmp(master, "forced-slave") == 0)
		phydev->master_slave_set = MASTER_SLAVE_CFG_SLAVE_FORCE;
	else if (strcmp(master, "preferred-master") == 0)
		phydev->master_slave_set = MASTER_SLAVE_CFG_MASTER_PREFERRED;
	else if (strcmp(master, "preferred-slave") == 0)
		phydev->master_slave_set = MASTER_SLAVE_CFG_SLAVE_PREFERRED;
	else
		phydev_warn(phydev, "Unknown master-slave mode %s\n", master);
}

/**
 * phy_resolve_aneg_pause - Determine pause autoneg results
 *
+3 −0
Original line number Diff line number Diff line
@@ -3608,6 +3608,9 @@ static int phy_probe(struct device *dev)
	 */
	of_set_phy_eee_broken(phydev);

	/* Get master/slave strap overrides */
	of_set_phy_timing_role(phydev);

	/* The Pause Frame bits indicate that the PHY can support passing
	 * pause frames. During autonegotiation, the PHYs will determine if
	 * they should allow pause frames to pass.  The MAC driver should then
+1 −0
Original line number Diff line number Diff line
@@ -1260,6 +1260,7 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
		  unsigned long *mask);
void of_set_phy_supported(struct phy_device *phydev);
void of_set_phy_eee_broken(struct phy_device *phydev);
void of_set_phy_timing_role(struct phy_device *phydev);
int phy_speed_down_core(struct phy_device *phydev);

/**