@@ -1178,6 +1178,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;
@@ -1253,6 +1257,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) {
@@ -2437,6 +2445,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;
@@ -2458,6 +2468,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)
@@ -2819,4 +2833,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");
@@ -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;
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@kernel.org> --- drivers/net/phy/phylink.c | 28 ++++++++++++++++++++++++++++ include/linux/phy.h | 4 ++++ 2 files changed, 32 insertions(+)