aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorMarek BehĂșn <kabel@kernel.org>2022-09-30 16:21:03 +0200
committerDavid S. Miller <davem@davemloft.net>2022-10-03 11:08:32 +0100
commiteca68a3c7d05b38b4e728cead0c49718f2bc1d5a (patch)
tree027668050f298d475d7e30041575ed38ba53407f /drivers/net/phy
parentnet: phylink: rename phylink_sfp_config() (diff)
downloadlinux-dev-eca68a3c7d05b38b4e728cead0c49718f2bc1d5a.tar.xz
linux-dev-eca68a3c7d05b38b4e728cead0c49718f2bc1d5a.zip
net: phylink: pass supported host PHY interface modes to phylib for SFP's PHYs
Pass the supported PHY interface types to phylib if the PHY we are connecting is inside a SFP, so that the PHY driver can select an appropriate host configuration mode for their interface according to the host capabilities. For example the Marvell 88X3310 PHY inside RollBall SFP modules defaults to 10gbase-r mode on host's side, and the marvell10g driver currently does not change this setting. But a host may not support 10gbase-r. For example Turris Omnia only supports sgmii, 1000base-x and 2500base-x modes. The PHY can be configured to use those modes, but in order for the PHY driver to do that, it needs to know which modes are supported. Signed-off-by: Marek BehĂșn <kabel@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/phylink.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index f6e9231f0cbe..9ff8eb516666 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2814,6 +2814,8 @@ static const phy_interface_t phylink_sfp_interface_preference[] = {
PHY_INTERFACE_MODE_100BASEX,
};
+static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces);
+
static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl,
const unsigned long *intf)
{
@@ -3091,6 +3093,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_phy(pl, mode, phy);
if (ret < 0)
@@ -3444,4 +3450,15 @@ 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)
+{
+ for (int i = 0; i < ARRAY_SIZE(phylink_sfp_interface_preference); ++i)
+ __set_bit(phylink_sfp_interface_preference[i],
+ phylink_sfp_interfaces);
+
+ return 0;
+}
+
+module_init(phylink_init);
+
MODULE_LICENSE("GPL v2");