Commit f3a6bd39 authored by Simon Horman's avatar Simon Horman Committed by David S. Miller

phylib: Add phy_set_max_speed helper

Add a helper to allow ethernet drivers to limit the speed of a phy
(that they are attached to).

This mainly involves factoring out the business-end of
of_set_phy_supported() and exporting a new symbol.

This code seems to be open coded in several places, in several different
variants.

It is is envisaged that this will be used in situations where setting the
"max-speed" property in DT is not appropriate, e.g. because the maximum
speed is not a property of the phy hardware.
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f8e1100a
...@@ -1239,36 +1239,57 @@ static int gen10g_resume(struct phy_device *phydev) ...@@ -1239,36 +1239,57 @@ static int gen10g_resume(struct phy_device *phydev)
return 0; return 0;
} }
static void of_set_phy_supported(struct phy_device *phydev) static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
{ {
struct device_node *node = phydev->dev.of_node;
u32 max_speed;
if (!IS_ENABLED(CONFIG_OF_MDIO))
return;
if (!node)
return;
if (!of_property_read_u32(node, "max-speed", &max_speed)) {
/* The default values for phydev->supported are provided by the PHY /* The default values for phydev->supported are provided by the PHY
* driver "features" member, we want to reset to sane defaults fist * driver "features" member, we want to reset to sane defaults first
* before supporting higher speeds. * before supporting higher speeds.
*/ */
phydev->supported &= PHY_DEFAULT_FEATURES; phydev->supported &= PHY_DEFAULT_FEATURES;
switch (max_speed) { switch (max_speed) {
default: default:
return; return -ENOTSUPP;
case SPEED_1000: case SPEED_1000:
phydev->supported |= PHY_1000BT_FEATURES; phydev->supported |= PHY_1000BT_FEATURES;
/* fall through */
case SPEED_100: case SPEED_100:
phydev->supported |= PHY_100BT_FEATURES; phydev->supported |= PHY_100BT_FEATURES;
/* fall through */
case SPEED_10: case SPEED_10:
phydev->supported |= PHY_10BT_FEATURES; phydev->supported |= PHY_10BT_FEATURES;
} }
}
return 0;
}
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
{
int err;
err = __set_phy_supported(phydev, max_speed);
if (err)
return err;
phydev->advertising = phydev->supported;
return 0;
}
EXPORT_SYMBOL(phy_set_max_speed);
static void of_set_phy_supported(struct phy_device *phydev)
{
struct device_node *node = phydev->dev.of_node;
u32 max_speed;
if (!IS_ENABLED(CONFIG_OF_MDIO))
return;
if (!node)
return;
if (!of_property_read_u32(node, "max-speed", &max_speed))
__set_phy_supported(phydev, max_speed);
} }
/** /**
......
...@@ -798,6 +798,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd); ...@@ -798,6 +798,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
int phy_start_interrupts(struct phy_device *phydev); int phy_start_interrupts(struct phy_device *phydev);
void phy_print_status(struct phy_device *phydev); void phy_print_status(struct phy_device *phydev);
void phy_device_free(struct phy_device *phydev); void phy_device_free(struct phy_device *phydev);
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *)); int (*run)(struct phy_device *));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment