Pass the supported PHY interface types to phylib so that PHY drivers can select an appropriate host configuration mode for their interface according to the host capabilities. Signed-off-by: Marek Behún <kabel@xxxxxxxxxx> --- drivers/net/phy/phylink.c | 28 ++++++++++++++++++++++++++++ include/linux/phy.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 6d7c216a5dea..20403b9676e1 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1430,6 +1430,10 @@ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) { int ret; + /* Set the PHY's host supported interfaces */ + phy_interface_copy(phy->host_interfaces, + pl->config->supported_interfaces); + /* Use PHY device/driver interface */ if (pl->link_interface == PHY_INTERFACE_MODE_NA) { pl->link_interface = phy->interface; @@ -1505,6 +1509,10 @@ int phylink_fwnode_phy_connect(struct phylink *pl, if (!phy_dev) return -ENODEV; + /* Set the PHY's host supported interfaces */ + phy_interface_copy(phy_dev->host_interfaces, + pl->config->supported_interfaces); + ret = phy_attach_direct(pl->netdev, phy_dev, flags, pl->link_interface); if (ret) { @@ -2689,6 +2697,8 @@ static bool phylink_phy_no_inband(struct phy_device *phy) (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150; } +static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); + static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) { struct phylink *pl = upstream; @@ -2710,6 +2720,10 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) else mode = MLO_AN_INBAND; + /* Set the PHY's host supported interfaces */ + phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, + pl->config->supported_interfaces); + /* Do the initial configuration */ ret = phylink_sfp_config(pl, mode, phy->supported, phy->advertising); if (ret < 0) @@ -3071,4 +3085,18 @@ void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, } EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state); +static int __init phylink_init(void) +{ + __set_bit(PHY_INTERFACE_MODE_USXGMII, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GKR, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_5GBASER, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, phylink_sfp_interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, phylink_sfp_interfaces); + + return 0; +} +module_init(phylink_init); + MODULE_LICENSE("GPL v2"); diff --git a/include/linux/phy.h b/include/linux/phy.h index 83ae15ab1676..11f3b5b7d7b1 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -569,6 +569,7 @@ struct macsec_ops; * @advertising: Currently advertised linkmodes * @adv_old: Saved advertised while power saving for WoL * @lp_advertising: Current link partner advertised linkmodes + * @host_interfaces: PHY interface modes supported by host * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited * @autoneg: Flag autoneg being used * @link: Current link state @@ -658,6 +659,9 @@ struct phy_device { /* used with phy_speed_down */ __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old); + /* host supported PHY interface types */ + DECLARE_PHY_INTERFACE_MASK(host_interfaces); + /* Energy efficient ethernet modes which should be prohibited */ u32 eee_broken_modes; -- 2.32.0