Skip to content

Commit de7d3f8

Browse files
minimaxwellPaolo Abeni
authored andcommitted
net: phylink: Use phy_caps_lookup for fixed-link configuration
When phylink creates a fixed-link configuration, it finds a matching linkmode to set as the advertised, lp_advertising and supported modes based on the speed and duplex of the fixed link. Use the newly introduced phy_caps_lookup to get these modes instead of phy_lookup_settings(). This has the side effect that the matched settings and configured linkmodes may now contain several linkmodes (the intersection of supported linkmodes from the phylink settings and the linkmodes that match speed/duplex) instead of the one from phy_lookup_settings(). Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20250307173611.129125-10-maxime.chevallier@bootlin.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent c7ae89c commit de7d3f8

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

drivers/net/phy/phylink.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -802,12 +802,26 @@ static int phylink_validate(struct phylink *pl, unsigned long *supported,
802802
return phylink_validate_mac_and_pcs(pl, supported, state);
803803
}
804804

805+
static void phylink_fill_fixedlink_supported(unsigned long *supported)
806+
{
807+
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, supported);
808+
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, supported);
809+
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, supported);
810+
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, supported);
811+
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, supported);
812+
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, supported);
813+
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);
814+
linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, supported);
815+
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, supported);
816+
}
817+
805818
static int phylink_parse_fixedlink(struct phylink *pl,
806819
const struct fwnode_handle *fwnode)
807820
{
821+
__ETHTOOL_DECLARE_LINK_MODE_MASK(match) = { 0, };
808822
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
823+
const struct link_capabilities *c;
809824
struct fwnode_handle *fixed_node;
810-
const struct phy_setting *s;
811825
struct gpio_desc *desc;
812826
u32 speed;
813827
int ret;
@@ -875,12 +889,16 @@ static int phylink_parse_fixedlink(struct phylink *pl,
875889
phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n",
876890
pl->link_config.speed);
877891

878-
linkmode_fill(pl->supported);
892+
linkmode_zero(pl->supported);
893+
phylink_fill_fixedlink_supported(pl->supported);
894+
879895
linkmode_copy(pl->link_config.advertising, pl->supported);
880896
phylink_validate(pl, pl->supported, &pl->link_config);
881897

882-
s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
883-
pl->supported, true);
898+
c = phy_caps_lookup(pl->link_config.speed, pl->link_config.duplex,
899+
pl->supported, true);
900+
if (c)
901+
linkmode_and(match, pl->supported, c->linkmodes);
884902

885903
linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, mask);
886904
linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, mask);
@@ -889,9 +907,10 @@ static int phylink_parse_fixedlink(struct phylink *pl,
889907

890908
phylink_set(pl->supported, MII);
891909

892-
if (s) {
893-
__set_bit(s->bit, pl->supported);
894-
__set_bit(s->bit, pl->link_config.lp_advertising);
910+
if (c) {
911+
linkmode_or(pl->supported, pl->supported, match);
912+
linkmode_or(pl->link_config.lp_advertising,
913+
pl->link_config.lp_advertising, match);
895914
} else {
896915
phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n",
897916
pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
@@ -1879,21 +1898,20 @@ static int phylink_register_sfp(struct phylink *pl,
18791898
int phylink_set_fixed_link(struct phylink *pl,
18801899
const struct phylink_link_state *state)
18811900
{
1882-
const struct phy_setting *s;
1901+
const struct link_capabilities *c;
18831902
unsigned long *adv;
18841903

18851904
if (pl->cfg_link_an_mode != MLO_AN_PHY || !state ||
18861905
!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
18871906
return -EINVAL;
18881907

1889-
s = phy_lookup_setting(state->speed, state->duplex,
1890-
pl->supported, true);
1891-
if (!s)
1908+
c = phy_caps_lookup(state->speed, state->duplex,
1909+
pl->supported, true);
1910+
if (!c)
18921911
return -EINVAL;
18931912

18941913
adv = pl->link_config.advertising;
1895-
linkmode_zero(adv);
1896-
linkmode_set_bit(s->bit, adv);
1914+
linkmode_and(adv, pl->supported, c->linkmodes);
18971915
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv);
18981916

18991917
pl->link_config.speed = state->speed;

0 commit comments

Comments
 (0)