Commit a17b9b3a authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'net-phy-support-master-slave-config-via-device-tree'

Oleksij Rempel says:

====================
net: phy: Support master-slave config via device tree

This patch series adds support for configuring the master/slave role of
PHYs via the device tree. A new `master-slave` property is introduced in
the device tree bindings, allowing PHYs to be forced into either master
or slave mode. This is particularly necessary for Single Pair Ethernet
(SPE) PHYs (1000/100/10Base-T1), where hardware strap pins may not be
available or correctly configured, but it is applicable to all PHY
types.

changes v5:
- sync DT options with ethtool nameing.

changes v4:
- add Reviewed-by
- rebase against latest net-next

changes v3:
- rename  master-slave to timing-role
- add prefer-master/slave support
====================

Link: https://patch.msgid.link/20241004090100.1654353-1-o.rempel@pengutronix.de


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 138d21b6 20a4da20
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -158,6 +158,27 @@ properties:
      Mark the corresponding energy efficient ethernet mode as
      broken and request the ethernet to stop advertising it.

  timing-role:
    $ref: /schemas/types.yaml#/definitions/string
    enum:
      - forced-master
      - forced-slave
      - preferred-master
      - preferred-slave
    description: |
      Specifies the timing role of the PHY in the network link. This property is
      required for setups where the role must be explicitly assigned via the
      device tree due to limitations in hardware strapping or incorrect strap
      configurations.
      It is applicable to Single Pair Ethernet (1000/100/10Base-T1) and other
      PHY types, including 1000Base-T, where it controls whether the PHY should
      be a master (clock source) or a slave (clock receiver).

      - 'forced-master': The PHY is forced to operate as a master.
      - 'forced-slave': The PHY is forced to operate as a slave.
      - 'preferred-master': Prefer the PHY to be master but allow negotiation.
      - 'preferred-slave': Prefer the PHY to be slave but allow negotiation.

  pses:
    $ref: /schemas/types.yaml#/definitions/phandle-array
    maxItems: 1
+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);

/**