[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250226100929.1646454-1-maxime.chevallier@bootlin.com>
Date: Wed, 26 Feb 2025 11:09:15 +0100
From: Maxime Chevallier <maxime.chevallier@...tlin.com>
To: davem@...emloft.net,
Andrew Lunn <andrew@...n.ch>,
Jakub Kicinski <kuba@...nel.org>,
Eric Dumazet <edumazet@...gle.com>,
Paolo Abeni <pabeni@...hat.com>,
Russell King <linux@...linux.org.uk>,
Heiner Kallweit <hkallweit1@...il.com>
Cc: Maxime Chevallier <maxime.chevallier@...tlin.com>,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org,
thomas.petazzoni@...tlin.com,
linux-arm-kernel@...ts.infradead.org,
Christophe Leroy <christophe.leroy@...roup.eu>,
Herve Codina <herve.codina@...tlin.com>,
Florian Fainelli <f.fainelli@...il.com>,
Vladimir Oltean <vladimir.oltean@....com>,
Köry Maincent <kory.maincent@...tlin.com>,
Oleksij Rempel <o.rempel@...gutronix.de>,
Simon Horman <horms@...nel.org>,
Romain Gantois <romain.gantois@...tlin.com>
Subject: [PATCH net-next v2 00/13] net: phy: Rework linkmodes handling in a dedicated file
Hello everyone,
This is the V2 of the phy_caps series. This series aims at reworking the way
we do conversions between speed/duplex, linkmodes and interfaces. There's two
goals here :
- Make that conversion easier to maintain and somewhat more efficient, by
avoiding the re-definitions of capabilities to linkmodes to interfaces that
exist in phylib and phylink
- create an internal API for these conversions, in preparation for the phy_port
work.
This V2 reworks the way we deal with the phy_interface_t <-> caps <-> linkmodes,
leaving the MAC_*** capabilities a phylink-only set of values.
This V2 also addresses the comments from Köry as well as a kdoc warning.
V1 : https://lore.kernel.org/netdev/20250222142727.894124-1-maxime.chevallier@bootlin.com/
For context, The text below is an extract from the V1 cover :
Following the V4 of the phy_port series [1] we've discussed about attempting
to extract some of the linkmode <-> capabilities (speed/duplex) <-> interface
logic into a dedicated file, so that we can re-use that logic out of
phylink.
While trying to do that, I might have gotten a bit carried-away, and I'm
therefore submitting this series to rework the way we are currently
managing the linkmodes <-> capabilities handling.
We are currently defining all the possible Ethernet linkmodes in an
enum ethtool_link_mode_bit_indices value defined in uapi/linux/ethtool.h :
ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0,
ETHTOOL_LINK_MODE_10baseT_Full_BIT = 1,
...
Each of these modes represents a media-side link definition, and runs at
a given speed and duplex.
Specific attributes for each modes are stored in net/ethtool/common.c, as
an array of struct link_mode_info :
struct link_mode_info {
int speed;
u8 lanes;
u8 duplex;
}
The link_mode_params[] array is the canonical definition for these modes,
as (1) there are build-time checks to make sure any new linkmode
definition is also defined in this array and (2) this array is always
compiled-in, as it's part of the net stack (i.e. it is not phylib-specific).
This array is however not optimized for lookups, as it is not ordered in
any particular fashion (new modes go at the end, regardless of their speed
and duplex).
Phylib also includes a similar array, in the form of the phy_settings
array in drivers/net/phy/phy-core.c :
struct phy_setting {
u32 speed;
u8 duplex;
u8 bit; // The enum index for the linkmode
};
The phy_settings array however is ordered by descending speeds. A variety
of helpers in phylib rely on that ordering to perform lookups, usually
to get one or any linkmode corresponding to a requested speed and duplex.
Finally, we have some helpers in phylink (phylink_caps_to_linkmodes) that
allows getting the list of linkmodes that match a set of speed and duplex
value, all at once.
While the phylink and phylib helpers allows for efficient lookups, they
have some drawbacks as well :
(1) : It's easy to forget updating of all of these helpers and structures
when adding a new linkmode. New linkmodes are actually added fairly
often, lately either for slow BaseT1 flavours, or for crazy-fast
modes (800Gbps modes, but I guess people won't stop there)
(2) : Even though the phylink and phylib modes use carefull sorting
to speed-up the lookup process, the phylib lookups are usually
done in descending speed order and will therefore get slower
as people add even faster link speeds.
This series introduces a new "link_capabilities" structure that is used
to build an array of link_caps :
struct link_capabilities {
int speed;
unsigned int duplex;
__ETHTOOL_DECLARE_LINK_MODE_MASK(linkmodes);
};
We group these in an array, indexed with LINK_CAPA enums that are basically
identical to the phylink MAC_CAPS :
...
LINK_CAPA_1000HD,
LINK_CAPA_1000FD,
LINK_CAPA_2500FD,
LINK_CAPA_5000FD,
...
We now have an associative array of <speed,duplex> <-> All compatible linkmodes
This array is initialized at phylib-init time based on the content of
the link_mode_params[] array from net/ethtool/common.c, that way it is
always up-to-date with new modes, and always properly ordered.
Patches 3 to 8 then convert all lookups from the phy_settings array into
lookups from this link_caps array, hopefully speeding-up lookups in the
meantime (we iterate over possible speeds instead of individual linkmodes)
This series is not meant to introduce changes in behaviour, however patches
9 and 10 do introduce functionnal changes. When configuring the advert
for speeds >= 1G in PHY devices, as well as when constructing the link
parameters for fixed links in phylink, we used to rely on phy_settings
lookups returning one, and only one, compatible linkmode. This series will
make so that the lookups will result on all matching linkmodes being
returned, and MAY cause advert/fixed-link configuring more linkmodes.
Patches 12 and 13 extract the conversion logic for interface <-> caps from
phylink.
There are cons as well for this, as this is a bit more init time for phylib,
but maybe more importantly, we lose in the precision for the lookups in
phy_settings. However, given all the uses for phy_settings (most are just
to get speed/duplex), I think this is actually ok, but any comment would
be very welcome.
This series was tested with :
- 10/100/1000M links
- 2,5, 5, 10G BaseT links
- 1G Fixed link
I also made sure that this compiles with the following options :
CONFIG_PHYLIB=n
CNFIG_PHYLINK=m
CONFIG_PHYLIB=m
CNFIG_PHYLINK=m
CONFIG_PHYLIB=y
CNFIG_PHYLINK=y
CONFIG_PHYLIB=y
All the new helpers that were introduced (in drivers/net/phy/phy-caps.h)
are for internal use only (only users should be core stuff, such as phylib and
phylink, and in the future, phy_port).
Thanks,
Maxime
[1]: https://lore.kernel.org/netdev/20250213101606.1154014-1-maxime.chevallier@bootlin.com/
Maxime Chevallier (13):
net: ethtool: Export the link_mode_params definitions
net: phy: Use an internal, searchable storage for the linkmodes
net: phy: phy_caps: Move phy_speeds to phy_caps
net: phy: phy_caps: Move __set_linkmode_max_speed to phy_caps
net: phy: phy_caps: Introduce phy_caps_valid
net: phy: phy_caps: Implement link_capabilities lookup by linkmode
net: phy: phy_caps: Allow looking-up link caps based on speed and
duplex
net: phy: phy_device: Use link_capabilities lookup for PHY aneg config
net: phy: phylink: Use phy_caps_lookup for fixed-link configuration
net: phy: drop phy_settings and the associated lookup helpers
net: phy: phylink: Add a mapping between MAC_CAPS and LINK_CAPS
net: phy: phylink: Convert capabilities to linkmodes using phy_caps
net: phy: phy_caps: Allow getting an phy_interface's capabilities
drivers/net/phy/Makefile | 2 +-
drivers/net/phy/phy-caps.h | 62 +++++++
drivers/net/phy/phy-core.c | 253 ++------------------------
drivers/net/phy/phy.c | 37 ++--
drivers/net/phy/phy_caps.c | 340 +++++++++++++++++++++++++++++++++++
drivers/net/phy/phy_device.c | 13 +-
drivers/net/phy/phylink.c | 337 +++++++++-------------------------
include/linux/ethtool.h | 8 +
include/linux/phy.h | 15 --
net/ethtool/common.c | 1 +
net/ethtool/common.h | 7 -
11 files changed, 532 insertions(+), 543 deletions(-)
create mode 100644 drivers/net/phy/phy-caps.h
create mode 100644 drivers/net/phy/phy_caps.c
--
2.48.1
Powered by blists - more mailing lists