Commit b2db6f4a authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller
Browse files

net: phy: add helpers to handle sfp phy connect/disconnect



There are a few PHY drivers that can handle SFP modules through their
sfp_upstream_ops. Introduce Phylib helpers to keep track of connected
SFP PHYs in a netdevice's namespace, by adding the SFP PHY to the
upstream PHY's netdev's namespace.

By doing so, these SFP PHYs can be enumerated and exposed to users,
which will be able to use their capabilities.

Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Tested-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4d76f115
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -553,6 +553,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = {
	.link_down = mv2222_sfp_link_down,
	.attach = phy_sfp_attach,
	.detach = phy_sfp_detach,
	.connect_phy = phy_sfp_connect_phy,
	.disconnect_phy = phy_sfp_disconnect_phy,
};

static int mv2222_probe(struct phy_device *phydev)
+2 −0
Original line number Diff line number Diff line
@@ -3613,6 +3613,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = {
	.module_remove = m88e1510_sfp_remove,
	.attach = phy_sfp_attach,
	.detach = phy_sfp_detach,
	.connect_phy = phy_sfp_connect_phy,
	.disconnect_phy = phy_sfp_disconnect_phy,
};

static int m88e1510_probe(struct phy_device *phydev)
+2 −0
Original line number Diff line number Diff line
@@ -503,6 +503,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
static const struct sfp_upstream_ops mv3310_sfp_ops = {
	.attach = phy_sfp_attach,
	.detach = phy_sfp_detach,
	.connect_phy = phy_sfp_connect_phy,
	.disconnect_phy = phy_sfp_disconnect_phy,
	.module_insert = mv3310_sfp_insert,
};

+42 −0
Original line number Diff line number Diff line
@@ -1385,6 +1385,48 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_standalone);

/**
 * phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY
 * @upstream: pointer to the upstream phy device
 * @phy: pointer to the SFP module's phy device
 *
 * This helper allows keeping track of PHY devices on the link. It adds the
 * SFP module's phy to the phy namespace of the upstream phy
 *
 * Return: 0 on success, otherwise a negative error code.
 */
int phy_sfp_connect_phy(void *upstream, struct phy_device *phy)
{
	struct phy_device *phydev = upstream;
	struct net_device *dev = phydev->attached_dev;

	if (dev)
		return phy_link_topo_add_phy(dev, phy, PHY_UPSTREAM_PHY, phydev);

	return 0;
}
EXPORT_SYMBOL(phy_sfp_connect_phy);

/**
 * phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY
 * @upstream: pointer to the upstream phy device
 * @phy: pointer to the SFP module's phy device
 *
 * This helper allows keeping track of PHY devices on the link. It removes the
 * SFP module's phy to the phy namespace of the upstream phy. As the module phy
 * will be destroyed, re-inserting the same module will add a new phy with a
 * new index.
 */
void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy)
{
	struct phy_device *phydev = upstream;
	struct net_device *dev = phydev->attached_dev;

	if (dev)
		phy_link_topo_del_phy(dev, phy);
}
EXPORT_SYMBOL(phy_sfp_disconnect_phy);

/**
 * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
 * @upstream: pointer to the phy device
+2 −0
Original line number Diff line number Diff line
@@ -770,6 +770,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = {
	.attach = phy_sfp_attach,
	.detach = phy_sfp_detach,
	.module_insert = at8031_sfp_insert,
	.connect_phy = phy_sfp_connect_phy,
	.disconnect_phy = phy_sfp_disconnect_phy,
};

static int at8031_parse_dt(struct phy_device *phydev)
Loading