diff mbox series

[net-next,v3,2/7] ethtool: Get link mode in use instead of speed and duplex parameters

Message ID 20210120093713.4000363-3-danieller@nvidia.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series Support setting lanes via ethtool | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 15 maintainers not CCed: meirl@mellanox.com leon@kernel.org dmurphy@ti.com richardcochran@gmail.com irusskikh@marvell.com ecree@solarflare.com cforno12@linux.vnet.ibm.com amitc@mellanox.com ayal@mellanox.com alobakin@pm.me magnus.karlsson@intel.com gustavo@embeddedor.com gaurav1086@gmail.com linux@rempel-privat.de acardace@redhat.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 3290 this patch: 3290
netdev/kdoc success Errors and warnings before: 14 this patch: 14
netdev/verify_fixes success Link
netdev/checkpatch warning CHECK: Please use a blank line after function/struct/union/enum declarations
netdev/build_allmodconfig_warn success Errors and warnings before: 3595 this patch: 3595
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Danielle Ratson Jan. 20, 2021, 9:37 a.m. UTC
Currently, when user space queries the link's parameters, as speed and
duplex, each parameter is passed from the driver to ethtool.

Instead, get the link mode bit in use, and derive each of the parameters
from it in ethtool.

Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---

Notes:
    v3:
    	* Remove 'ETHTOOL_A_LINKMODES_LINK_MODE' from Documentation since
    	  it is not used.
    	* Remove LINK_MODE_UNKNOWN from uapi.
    	* Remove an unnecessary loop.
    	* Move link_mode_info and link_mode_params to common file.
    	* Move the speed, duplex and lanes derivation to the wrapper
    	  __ethtool_get_link_ksettings().

 include/linux/ethtool.h |   1 +
 net/ethtool/common.c    | 114 ++++++++++++++++++++++++++++++++++++
 net/ethtool/common.h    |   7 +++
 net/ethtool/ioctl.c     |  18 +++++-
 net/ethtool/linkmodes.c | 124 +---------------------------------------
 5 files changed, 141 insertions(+), 123 deletions(-)

Comments

Edwin Peer Jan. 20, 2021, 11:39 p.m. UTC | #1
On Wed, Jan 20, 2021 at 3:21 AM Danielle Ratson <danieller@nvidia.com> wrote:

> +       link_ksettings->link_mode = -1;
> +       err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
> +       if (err)
> +               return err;
> +
> +       if (link_ksettings->link_mode != -1) {
> +               link_info = &link_mode_params[link_ksettings->link_mode];
> +               link_ksettings->base.speed = link_info->speed;
> +               link_ksettings->lanes = link_info->lanes;
> +               link_ksettings->base.duplex = link_info->duplex;
> +       }

Why isn't this also handled using a capability bit as is done for
lanes? Is link_mode read-only? Should it / will it always be? If not,
can drivers also derive the other fields if asked to set link_mode?
That would be easy enough. Why don't we simply allow user space to set
link mode directly too (in addition to being able to constrain lanes
for autoneg or forced speeds)?

Regards,
Edwin Peer
Danielle Ratson Jan. 24, 2021, 8:36 a.m. UTC | #2
> -----Original Message-----
> From: Edwin Peer <edwin.peer@broadcom.com>
> Sent: Thursday, January 21, 2021 1:39 AM
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>; Jiri Pirko
> <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; Michal Kubecek <mkubecek@suse.cz>; mlxsw
> <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> 
> On Wed, Jan 20, 2021 at 3:21 AM Danielle Ratson <danieller@nvidia.com> wrote:
> 
> > +       link_ksettings->link_mode = -1;
> > +       err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
> > +       if (err)
> > +               return err;
> > +
> > +       if (link_ksettings->link_mode != -1) {
> > +               link_info = &link_mode_params[link_ksettings->link_mode];
> > +               link_ksettings->base.speed = link_info->speed;
> > +               link_ksettings->lanes = link_info->lanes;
> > +               link_ksettings->base.duplex = link_info->duplex;
> > +       }
> 
> Why isn't this also handled using a capability bit as is done for
> lanes? Is link_mode read-only? Should it / will it always be? If not,
> can drivers also derive the other fields if asked to set link_mode?

The link_mode param is only for deriving all the speed, lanes and duplex params in ethtool instead of deriving in driver and then passing each individual, as Michal asked.

> That would be easy enough. Why don't we simply allow user space to set
> link mode directly too (in addition to being able to constrain lanes
> for autoneg or forced speeds)?

It is already possible to do using 'advertise' parameter. 

> 
> Regards,
> Edwin Peer
Edwin Peer Jan. 25, 2021, 6:03 p.m. UTC | #3
On Sun, Jan 24, 2021 at 12:36 AM Danielle Ratson <danieller@nvidia.com> wrote:

> > Why isn't this also handled using a capability bit as is done for
> > lanes? Is link_mode read-only? Should it / will it always be? If not,
> > can drivers also derive the other fields if asked to set link_mode?
>
> The link_mode param is only for deriving all the speed, lanes and duplex params in ethtool instead of deriving in driver and then > passing each individual, as Michal asked.

I understand the benefit of deriving the dependent fields in core code
rather than in each driver, I just don't think this is necessarily
mutually exclusive with being able to force a particular link mode at
the driver API, making link_mode R/W (and even extend this interface
to user space). For a driver that works internally in terms of the
link_mode it's returning, this would be more natural.

> > That would be easy enough. Why don't we simply allow user space to set
> > link mode directly too (in addition to being able to constrain lanes
> > for autoneg or forced speeds)?
>
> It is already possible to do using 'advertise' parameter.

That's not the same thing. If it were, you wouldn't need the lanes
parameter in the first place.

Regards,
Edwin Peer
Danielle Ratson Jan. 26, 2021, 5:06 p.m. UTC | #4
> -----Original Message-----
> From: Edwin Peer <edwin.peer@broadcom.com>
> Sent: Monday, January 25, 2021 8:04 PM
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>; Jiri Pirko
> <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; Michal Kubecek <mkubecek@suse.cz>; mlxsw
> <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> 
> On Sun, Jan 24, 2021 at 12:36 AM Danielle Ratson <danieller@nvidia.com> wrote:
> 
> > > Why isn't this also handled using a capability bit as is done for
> > > lanes? Is link_mode read-only? Should it / will it always be? If not,
> > > can drivers also derive the other fields if asked to set link_mode?
> >
> > The link_mode param is only for deriving all the speed, lanes and duplex params in ethtool instead of deriving in driver and then >
> passing each individual, as Michal asked.
> 
> I understand the benefit of deriving the dependent fields in core code
> rather than in each driver, I just don't think this is necessarily
> mutually exclusive with being able to force a particular link mode at
> the driver API, making link_mode R/W (and even extend this interface
> to user space). For a driver that works internally in terms of the
> link_mode it's returning, this would be more natural.

I am not sure I fully understood you, but it seems like some expansion that can be done in the future if needed, and doesn't need to hold that patchset back. 

Thanks,
Danielle

> 
> > > That would be easy enough. Why don't we simply allow user space to set
> > > link mode directly too (in addition to being able to constrain lanes
> > > for autoneg or forced speeds)?
> >
> > It is already possible to do using 'advertise' parameter.
> 
> That's not the same thing. If it were, you wouldn't need the lanes
> parameter in the first place.
> 
> Regards,
> Edwin Peer
Edwin Peer Jan. 26, 2021, 5:14 p.m. UTC | #5
On Tue, Jan 26, 2021 at 9:09 AM Danielle Ratson <danieller@nvidia.com> wrote:

> > I understand the benefit of deriving the dependent fields in core code
> > rather than in each driver, I just don't think this is necessarily
> > mutually exclusive with being able to force a particular link mode at
> > the driver API, making link_mode R/W (and even extend this interface
> > to user space). For a driver that works internally in terms of the
> > link_mode it's returning, this would be more natural.
>
> I am not sure I fully understood you, but it seems like some expansion that can be
> done in the future if needed, and doesn't need to hold that patchset back.

For one thing, it's cleaner if the driver API is symmetric. The
proposed solution sets attributes in terms of speeds and lanes, etc.,
but it gets them in terms of a compound link_info. But, this asymmetry
aside, if link_mode may eventually become R/W at the driver API, as
you suggest, then it is more appropriate to guard it with a capability
bit, as has been done for lanes, rather than use the -1 special value
to indicate that the driver did not set it.

Regards,
Edwin Peer
Danielle Ratson Jan. 27, 2021, 1:22 p.m. UTC | #6
> -----Original Message-----
> From: Edwin Peer <edwin.peer@broadcom.com>
> Sent: Tuesday, January 26, 2021 7:14 PM
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>; Jiri Pirko
> <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; Michal Kubecek <mkubecek@suse.cz>; mlxsw
> <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> 
> On Tue, Jan 26, 2021 at 9:09 AM Danielle Ratson <danieller@nvidia.com> wrote:
> 
> > > I understand the benefit of deriving the dependent fields in core code
> > > rather than in each driver, I just don't think this is necessarily
> > > mutually exclusive with being able to force a particular link mode at
> > > the driver API, making link_mode R/W (and even extend this interface
> > > to user space). For a driver that works internally in terms of the
> > > link_mode it's returning, this would be more natural.
> >
> > I am not sure I fully understood you, but it seems like some expansion that can be
> > done in the future if needed, and doesn't need to hold that patchset back.
> 
> For one thing, it's cleaner if the driver API is symmetric. The
> proposed solution sets attributes in terms of speeds and lanes, etc.,
> but it gets them in terms of a compound link_info. But, this asymmetry
> aside, if link_mode may eventually become R/W at the driver API, as
> you suggest, then it is more appropriate to guard it with a capability
> bit, as has been done for lanes, rather than use the -1 special value
> to indicate that the driver did not set it.
> 
> Regards,
> Edwin Peer

This patchset adds lanes parameter, not link_mode. The link_mode addition was added as a read-only parameter for the reasons we mentioned, and I am not sure that implementing the symmetric side is relevant for this patchset.

Michal, do you think we will use the Write side of the link_mode parameter? And if so, do you think it is relevant for this specific patchset?

Thanks,
Danielle
Michal Kubecek Jan. 28, 2021, 8:26 p.m. UTC | #7
On Wed, Jan 27, 2021 at 01:22:02PM +0000, Danielle Ratson wrote:
> > -----Original Message-----
> > From: Edwin Peer <edwin.peer@broadcom.com>
> > Sent: Tuesday, January 26, 2021 7:14 PM
> > To: Danielle Ratson <danieller@nvidia.com>
> > Cc: netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>; Jiri Pirko
> > <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; Michal Kubecek <mkubecek@suse.cz>; mlxsw
> > <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> > Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> > 
> > For one thing, it's cleaner if the driver API is symmetric. The
> > proposed solution sets attributes in terms of speeds and lanes,
> > etc., but it gets them in terms of a compound link_info. But, this
> > asymmetry aside, if link_mode may eventually become R/W at the
> > driver API, as you suggest, then it is more appropriate to guard it
> > with a capability bit, as has been done for lanes, rather than use
> > the -1 special value to indicate that the driver did not set it.
> > 
> > Regards,
> > Edwin Peer
> 
> This patchset adds lanes parameter, not link_mode. The link_mode
> addition was added as a read-only parameter for the reasons we
> mentioned, and I am not sure that implementing the symmetric side is
> relevant for this patchset.
> 
> Michal, do you think we will use the Write side of the link_mode
> parameter?

It makes sense, IMHO. Unless we also add "media" (or whatever name would
be most appropriate) parameter, we cannot in general fully determine the
link mode by speed, duplex and lanes. And using "advertise" to select
a specific mode with disabled autonegotiation would be rather confusing,
I believe. (At the moment, ethtool does not even support syntax like
"advertise <mode>" but it will be easy to support
"advertise <mode>... [--]" and I think we should extend the syntax to
support it, regardless of what we choose.) So if we want to allow user
to pick a specific link node by name or bit mask (or rather index?),
I would prefer using a separate parameter.

>            And if so, do you think it is relevant for this specific
> patchset?

I don't see an obvious problem with leaving that part for later so
I would say it's up to you.

Michal
Danielle Ratson Jan. 31, 2021, 3:33 p.m. UTC | #8
> -----Original Message-----
> From: Michal Kubecek <mkubecek@suse.cz>
> Sent: Thursday, January 28, 2021 10:27 PM
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: Edwin Peer <edwin.peer@broadcom.com>; netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub
> Kicinski <kuba@kernel.org>; Jiri Pirko <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; mlxsw
> <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> 
> On Wed, Jan 27, 2021 at 01:22:02PM +0000, Danielle Ratson wrote:
> > > -----Original Message-----
> > > From: Edwin Peer <edwin.peer@broadcom.com>
> > > Sent: Tuesday, January 26, 2021 7:14 PM
> > > To: Danielle Ratson <danieller@nvidia.com>
> > > Cc: netdev <netdev@vger.kernel.org>; David S . Miller
> > > <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>; Jiri Pirko
> > > <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>;
> > > f.fainelli@gmail.com; Michal Kubecek <mkubecek@suse.cz>; mlxsw
> > > <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> > > Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use
> > > instead of speed and duplex parameters
> > >
> > > For one thing, it's cleaner if the driver API is symmetric. The
> > > proposed solution sets attributes in terms of speeds and lanes,
> > > etc., but it gets them in terms of a compound link_info. But, this
> > > asymmetry aside, if link_mode may eventually become R/W at the
> > > driver API, as you suggest, then it is more appropriate to guard it
> > > with a capability bit, as has been done for lanes, rather than use
> > > the -1 special value to indicate that the driver did not set it.
> > >
> > > Regards,
> > > Edwin Peer
> >
> > This patchset adds lanes parameter, not link_mode. The link_mode
> > addition was added as a read-only parameter for the reasons we
> > mentioned, and I am not sure that implementing the symmetric side is
> > relevant for this patchset.
> >
> > Michal, do you think we will use the Write side of the link_mode
> > parameter?
> 
> It makes sense, IMHO. Unless we also add "media" (or whatever name would be most appropriate) parameter, we cannot in general
> fully determine the link mode by speed, duplex and lanes. And using "advertise" to select a specific mode with disabled
> autonegotiation would be rather confusing, I believe. (At the moment, ethtool does not even support syntax like "advertise <mode>"
> but it will be easy to support "advertise <mode>... [--]" and I think we should extend the syntax to support it, regardless of what we
> choose.) So if we want to allow user to pick a specific link node by name or bit mask (or rather index?), I would prefer using a separate
> parameter.
> 
> >            And if so, do you think it is relevant for this specific
> > patchset?
> 
> I don't see an obvious problem with leaving that part for later so I would say it's up to you.
> 
> Michal

Thanks Michal.

Edwin, adding the a new parameter requires a new patchset in my opinion. Implementing the symmetrical side of the link_mode get,
however can be a part of this set. But, the problem with that would be that, as Michal said, speed lanes and duplex can't provide us a single
link_mode because of the media. And since link_mode is one bit parameter, passing it to the driver while randomly choosing the media, may
cause either information loss, or even fail to sync on a link mode if the chosen media is specifically not supported in the lower levels.
So, in my opinion it is related to adding the new parameter we discussed, and should be done in a separate set.

Thanks,
Danielle
Edwin Peer Jan. 31, 2021, 5:39 p.m. UTC | #9
On Sun, Jan 31, 2021 at 7:33 AM Danielle Ratson <danieller@nvidia.com> wrote:

> Edwin, adding the a new parameter requires a new patchset in my opinion.
> Implementing the symmetrical side of the link_mode get, however can be a
> part of this set. But, the problem with that would be that, as Michal said,
> speed lanes and duplex can't provide us a single link_mode because of the
> media. And since link_mode is one bit parameter, passing it to the driver
> while randomly choosing the media, may cause either information loss, or
> even fail to sync on a link mode if the chosen media is specifically not
> supported in the lower levels. So, in my opinion it is related to adding the
> new parameter we discussed, and should be done in a separate set.

Media is a little special in the sense that it physically depends on
what's plugged in. In that sense, media is truly read only. Setting it
won't change what's plugged in, so not having a separate knob for it
is probably okay, as it can be inferred from the active link mode on
the query side.

I don't see why the driver can't error if asked to set a link mode
having an incompatible media? The link modes corresponding to media
that's not plugged in wouldn't be listed in the supported set, so
there's no reason the user should expect to be able to set those.
There's no ambiguity or information loss if you refuse to set modes
that don't have the matching media attached.

Regards,
Edwin Peer
Danielle Ratson Feb. 1, 2021, 1:49 p.m. UTC | #10
> -----Original Message-----
> From: Edwin Peer <edwin.peer@broadcom.com>
> Sent: Sunday, January 31, 2021 7:39 PM
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: Michal Kubecek <mkubecek@suse.cz>; netdev <netdev@vger.kernel.org>; David S . Miller <davem@davemloft.net>; Jakub
> Kicinski <kuba@kernel.org>; Jiri Pirko <jiri@nvidia.com>; Andrew Lunn <andrew@lunn.ch>; f.fainelli@gmail.com; mlxsw
> <mlxsw@nvidia.com>; Ido Schimmel <idosch@nvidia.com>
> Subject: Re: [PATCH net-next v3 2/7] ethtool: Get link mode in use instead of speed and duplex parameters
> 
> On Sun, Jan 31, 2021 at 7:33 AM Danielle Ratson <danieller@nvidia.com> wrote:
> 
> > Edwin, adding the a new parameter requires a new patchset in my opinion.
> > Implementing the symmetrical side of the link_mode get, however can be a
> > part of this set. But, the problem with that would be that, as Michal said,
> > speed lanes and duplex can't provide us a single link_mode because of the
> > media. And since link_mode is one bit parameter, passing it to the driver
> > while randomly choosing the media, may cause either information loss, or
> > even fail to sync on a link mode if the chosen media is specifically not
> > supported in the lower levels. So, in my opinion it is related to adding the
> > new parameter we discussed, and should be done in a separate set.
> 
> Media is a little special in the sense that it physically depends on
> what's plugged in. In that sense, media is truly read only. Setting it
> won't change what's plugged in, so not having a separate knob for it
> is probably okay, as it can be inferred from the active link mode on
> the query side.
> 
> I don't see why the driver can't error if asked to set a link mode
> having an incompatible media? The link modes corresponding to media
> that's not plugged in wouldn't be listed in the supported set, so
> there's no reason the user should expect to be able to set those.
> There's no ambiguity or information loss if you refuse to set modes
> that don't have the matching media attached.
> 
> Regards,
> Edwin Peer

Ok, ill send another version with the symmetrical side. Ethtool will try to compose
a supported link_mode from the parameters from user space and will choose
randomly between the supported ones. Sounds ok?

Thanks,
Danielle
Edwin Peer Feb. 1, 2021, 6:14 p.m. UTC | #11
On Mon, Feb 1, 2021 at 5:49 AM Danielle Ratson <danieller@nvidia.com> wrote:
> Ok, ill send another version with the symmetrical side. Ethtool will try to compose
> a supported link_mode from the parameters from user space and will choose
> randomly between the supported ones. Sounds ok?

I think it should be deterministic. It should be possible to select
the appropriate mode either based on the current media type or the
current link mode (which implies a media type). Alternatively, if the
user space request only specifies a subset, such as speed, fall back
to the existing behaviour and don't supply the request to the driver
in the form of a compound link mode in those cases (perhaps indicating
this by not setting the capability bit). The former approach has the
potential to tidy up drivers if we decide that drivers providing the
capability can ignore the other fields and rely solely on link mode,
the latter is no worse than what we have today.

Regards,
Edwin Peer
Jakub Kicinski Feb. 1, 2021, 8:29 p.m. UTC | #12
On Mon, 1 Feb 2021 10:14:35 -0800 Edwin Peer wrote:
> On Mon, Feb 1, 2021 at 5:49 AM Danielle Ratson <danieller@nvidia.com> wrote:
> > Ok, ill send another version with the symmetrical side. Ethtool
> > will try to compose a supported link_mode from the parameters from
> > user space and will choose randomly between the supported ones.
> > Sounds ok?  
> 
> I think it should be deterministic. It should be possible to select
> the appropriate mode either based on the current media type or the
> current link mode (which implies a media type). Alternatively, if the
> user space request only specifies a subset, such as speed, fall back
> to the existing behaviour and don't supply the request to the driver
> in the form of a compound link mode in those cases (perhaps indicating
> this by not setting the capability bit). The former approach has the
> potential to tidy up drivers if we decide that drivers providing the
> capability can ignore the other fields and rely solely on link mode,
> the latter is no worse than what we have today.

The media part is beginning to sound concerning. Every time we
under-specify an interface we end up with #vendors different
interpretations. And since HW is programmed by FW in most high 
speed devices we can't even review the right thing is done.

At least it's clear what setting a number of lanes means.
Edwin Peer Feb. 1, 2021, 9:05 p.m. UTC | #13
On Mon, Feb 1, 2021 at 12:29 PM Jakub Kicinski <kuba@kernel.org> wrote:

> > I think it should be deterministic. It should be possible to select
> > the appropriate mode either based on the current media type or the
> > current link mode (which implies a media type). Alternatively, if the
> > user space request only specifies a subset, such as speed, fall back
> > to the existing behaviour and don't supply the request to the driver
> > in the form of a compound link mode in those cases (perhaps indicating
> > this by not setting the capability bit). The former approach has the
> > potential to tidy up drivers if we decide that drivers providing the
> > capability can ignore the other fields and rely solely on link mode,
> > the latter is no worse than what we have today.
>
> The media part is beginning to sound concerning. Every time we
> under-specify an interface we end up with #vendors different
> interpretations. And since HW is programmed by FW in most high
> speed devices we can't even review the right thing is done.

Each link mode implies a very specific media type, the kernel can
reject illegal combinations based on the supported bitmask before
calling upon the driver to select it.

Regards,
Edwin Peer
Jakub Kicinski Feb. 1, 2021, 9:41 p.m. UTC | #14
On Mon, 1 Feb 2021 13:05:10 -0800 Edwin Peer wrote:
> On Mon, Feb 1, 2021 at 12:29 PM Jakub Kicinski <kuba@kernel.org> wrote:
> 
> > > I think it should be deterministic. It should be possible to select
> > > the appropriate mode either based on the current media type or the
> > > current link mode (which implies a media type). Alternatively, if the
> > > user space request only specifies a subset, such as speed, fall back
> > > to the existing behaviour and don't supply the request to the driver
> > > in the form of a compound link mode in those cases (perhaps indicating
> > > this by not setting the capability bit). The former approach has the
> > > potential to tidy up drivers if we decide that drivers providing the
> > > capability can ignore the other fields and rely solely on link mode,
> > > the latter is no worse than what we have today.  
> >
> > The media part is beginning to sound concerning. Every time we
> > under-specify an interface we end up with #vendors different
> > interpretations. And since HW is programmed by FW in most high
> > speed devices we can't even review the right thing is done.  
> 
> Each link mode implies a very specific media type, the kernel can
> reject illegal combinations based on the supported bitmask before
> calling upon the driver to select it.

Are you talking about validation against a driver-supplied list of
HW-supported modes, or SFP-supported modes for a currently plugged 
in module?

If I'm reading prior responses right it is the former.

The concern is around "what happens if user selected nnG-SR4 but user
plugged in nnG-CR4". The MAC/PHY/serdes settings will be identical.
Edwin Peer Feb. 1, 2021, 9:59 p.m. UTC | #15
On Mon, Feb 1, 2021 at 1:41 PM Jakub Kicinski <kuba@kernel.org> wrote:

> > > The media part is beginning to sound concerning. Every time we
> > > under-specify an interface we end up with #vendors different
> > > interpretations. And since HW is programmed by FW in most high
> > > speed devices we can't even review the right thing is done.
> >
> > Each link mode implies a very specific media type, the kernel can
> > reject illegal combinations based on the supported bitmask before
> > calling upon the driver to select it.
>
> Are you talking about validation against a driver-supplied list of
> HW-supported modes, or SFP-supported modes for a currently plugged
> in module?

Should they not be the same thing?

> The concern is around "what happens if user selected nnG-SR4 but user
> plugged in nnG-CR4". The MAC/PHY/serdes settings will be identical.

Yes, there would be multiple link modes that map to the same speed and
lane combination, but that doesn't mean you need to accept them if the
media doesn't match what's plugged in also. In the above scenario, the
supported mask should not list SR because CR is physically plugged in.
That way, the user knows what options are legal and the kernel knows
what it can reject.

Regards,
Edwin Peer
Jakub Kicinski Feb. 1, 2021, 10:20 p.m. UTC | #16
On Mon, 1 Feb 2021 13:59:45 -0800 Edwin Peer wrote:
> On Mon, Feb 1, 2021 at 1:41 PM Jakub Kicinski <kuba@kernel.org> wrote:
> > > Each link mode implies a very specific media type, the kernel can
> > > reject illegal combinations based on the supported bitmask before
> > > calling upon the driver to select it.  
> >
> > Are you talking about validation against a driver-supplied list of
> > HW-supported modes, or SFP-supported modes for a currently plugged
> > in module?  
> 
> Should they not be the same thing?

Okay. Does "supported modes" in ethtool for bnxt get ANDed with the
supported modes of the plugged in module?

What happens when no module is plugged in? List all?

I've surveyed this behavior a few years back and three vendors I tested
all had different interpretation on what to list in supported modes :/

> > The concern is around "what happens if user selected nnG-SR4 but user
> > plugged in nnG-CR4". The MAC/PHY/serdes settings will be identical.  
> 
> Yes, there would be multiple link modes that map to the same speed and
> lane combination, but that doesn't mean you need to accept them if the
> media doesn't match what's plugged in also. In the above scenario, the
> supported mask should not list SR because CR is physically plugged in.
> That way, the user knows what options are legal and the kernel knows
> what it can reject.

If the modes depend on what's plugged in - what happens if cable gets
removed? We (you, Danielle, I) can agree what we think is best, but
history teaches us that doesn't matter in long run. We had a similar
conversation when it comes to FEC. There simply is no way for upstream
developers to review the behavior is correct.
Edwin Peer Feb. 2, 2021, 12:14 a.m. UTC | #17
On Mon, Feb 1, 2021 at 2:20 PM Jakub Kicinski <kuba@kernel.org> wrote:

> > Should they not be the same thing?
>
> Okay. Does "supported modes" in ethtool for bnxt get ANDed with the
> supported modes of the plugged in module?
>
> What happens when no module is plugged in? List all?
>
> I've surveyed this behavior a few years back and three vendors I tested
> all had different interpretation on what to list in supported modes :/

Fair enough, I can't argue there. ;)

> > Yes, there would be multiple link modes that map to the same speed and
> > lane combination, but that doesn't mean you need to accept them if the
> > media doesn't match what's plugged in also. In the above scenario, the
> > supported mask should not list SR because CR is physically plugged in.
> > That way, the user knows what options are legal and the kernel knows
> > what it can reject.
>
> If the modes depend on what's plugged in - what happens if cable gets
> removed? We (you, Danielle, I) can agree what we think is best, but
> history teaches us that doesn't matter in long run. We had a similar
> conversation when it comes to FEC. There simply is no way for upstream
> developers to review the behavior is correct.

Given that supported is only defined in the context of autoneg today,
once could still specify. But again, you raise a fair concern.

The asymmetry in interface is still ugly though, you get to decide
which ugly is worse. :P

Regards,
Edwin Peer
Jakub Kicinski Feb. 2, 2021, 1:08 a.m. UTC | #18
On Mon, 1 Feb 2021 16:14:05 -0800 Edwin Peer wrote:
> > > Yes, there would be multiple link modes that map to the same speed and
> > > lane combination, but that doesn't mean you need to accept them if the
> > > media doesn't match what's plugged in also. In the above scenario, the
> > > supported mask should not list SR because CR is physically plugged in.
> > > That way, the user knows what options are legal and the kernel knows
> > > what it can reject.  
> >
> > If the modes depend on what's plugged in - what happens if cable gets
> > removed? We (you, Danielle, I) can agree what we think is best, but
> > history teaches us that doesn't matter in long run. We had a similar
> > conversation when it comes to FEC. There simply is no way for upstream
> > developers to review the behavior is correct.  
> 
> Given that supported is only defined in the context of autoneg today,
> once could still specify. But again, you raise a fair concern.
> 
> The asymmetry in interface is still ugly though, you get to decide
> which ugly is worse. :P

Let's move with this series as is. We can see how prevalent the use of
link_mode is on get side first.
diff mbox series

Patch

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 1ab13c5dfb2f..ec4cd3921c67 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -129,6 +129,7 @@  struct ethtool_link_ksettings {
 		__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
 	} link_modes;
 	u32	lanes;
+	enum ethtool_link_mode_bit_indices link_mode;
 };
 
 /**
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 24036e3055a1..399eee4a2051 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -197,6 +197,120 @@  const char link_mode_names[][ETH_GSTRING_LEN] = {
 };
 static_assert(ARRAY_SIZE(link_mode_names) == __ETHTOOL_LINK_MODE_MASK_NBITS);
 
+#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _lanes, _duplex) \
+	[ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = { \
+		.speed	= SPEED_ ## _speed, \
+		.lanes	= _lanes, \
+		.duplex	= __DUPLEX_ ## _duplex \
+	}
+#define __DUPLEX_Half DUPLEX_HALF
+#define __DUPLEX_Full DUPLEX_FULL
+#define __DEFINE_SPECIAL_MODE_PARAMS(_mode) \
+	[ETHTOOL_LINK_MODE_ ## _mode ## _BIT] = { \
+		.speed	= SPEED_UNKNOWN, \
+		.lanes	= ETHTOOL_LANES_UNKNOWN, \
+		.duplex	= DUPLEX_UNKNOWN, \
+	}
+
+const struct link_mode_info link_mode_params[] = {
+	__DEFINE_LINK_MODE_PARAMS(10, T, 1, Half),
+	__DEFINE_LINK_MODE_PARAMS(10, T, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100, T, 1, Half),
+	__DEFINE_LINK_MODE_PARAMS(100, T, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(1000, T, 1, Half),
+	__DEFINE_LINK_MODE_PARAMS(1000, T, 1, Full),
+	__DEFINE_SPECIAL_MODE_PARAMS(Autoneg),
+	__DEFINE_SPECIAL_MODE_PARAMS(TP),
+	__DEFINE_SPECIAL_MODE_PARAMS(AUI),
+	__DEFINE_SPECIAL_MODE_PARAMS(MII),
+	__DEFINE_SPECIAL_MODE_PARAMS(FIBRE),
+	__DEFINE_SPECIAL_MODE_PARAMS(BNC),
+	__DEFINE_LINK_MODE_PARAMS(10000, T, 1, Full),
+	__DEFINE_SPECIAL_MODE_PARAMS(Pause),
+	__DEFINE_SPECIAL_MODE_PARAMS(Asym_Pause),
+	__DEFINE_LINK_MODE_PARAMS(2500, X, 1, Full),
+	__DEFINE_SPECIAL_MODE_PARAMS(Backplane),
+	__DEFINE_LINK_MODE_PARAMS(1000, KX, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, KX4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, KR, 1, Full),
+	[ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = {
+		.speed	= SPEED_10000,
+		.duplex = DUPLEX_FULL,
+	},
+	__DEFINE_LINK_MODE_PARAMS(20000, MLD2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(20000, KR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(40000, KR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(40000, CR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(40000, SR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(40000, LR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(56000, KR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(56000, CR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(56000, SR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(56000, LR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(25000, CR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(25000, KR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(25000, SR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, CR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, KR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR4_ER4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, SR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(1000, X, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, CR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, SR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, LR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, LRM, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(10000, ER, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(2500, T, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(5000, T, 1, Full),
+	__DEFINE_SPECIAL_MODE_PARAMS(FEC_NONE),
+	__DEFINE_SPECIAL_MODE_PARAMS(FEC_RS),
+	__DEFINE_SPECIAL_MODE_PARAMS(FEC_BASER),
+	__DEFINE_LINK_MODE_PARAMS(50000, KR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, SR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, CR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, LR_ER_FR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(50000, DR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR2_ER2_FR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, DR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, KR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, SR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, LR4_ER4_FR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, DR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, CR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(100, T1, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(1000, T1, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, KR8, 8, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, SR8, 8, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, LR8_ER8_FR8, 8, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, DR8, 8, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, CR8, 8, Full),
+	__DEFINE_SPECIAL_MODE_PARAMS(FEC_LLRS),
+	__DEFINE_LINK_MODE_PARAMS(100000, KR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, SR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, LR_ER_FR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, DR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(100000, CR, 1, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, KR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, SR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, LR2_ER2_FR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, DR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(200000, CR2, 2, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, KR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, SR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, LR4_ER4_FR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, DR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(400000, CR4, 4, Full),
+	__DEFINE_LINK_MODE_PARAMS(100, FX, 1, Half),
+	__DEFINE_LINK_MODE_PARAMS(100, FX, 1, Full),
+};
+static_assert(ARRAY_SIZE(link_mode_params) == __ETHTOOL_LINK_MODE_MASK_NBITS);
+
 const char netif_msg_class_names[][ETH_GSTRING_LEN] = {
 	[NETIF_MSG_DRV_BIT]		= "drv",
 	[NETIF_MSG_PROBE_BIT]		= "probe",
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
index 3d9251c95a8b..625c8472700c 100644
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -14,6 +14,12 @@ 
 
 #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1)
 
+struct link_mode_info {
+	int				speed;
+	u32				lanes;
+	u8				duplex;
+};
+
 extern const char
 netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN];
 extern const char
@@ -23,6 +29,7 @@  tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN];
 extern const char
 phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
 extern const char link_mode_names[][ETH_GSTRING_LEN];
+extern const struct link_mode_info link_mode_params[];
 extern const char netif_msg_class_names[][ETH_GSTRING_LEN];
 extern const char wol_mode_names[][ETH_GSTRING_LEN];
 extern const char sof_timestamping_names[][ETH_GSTRING_LEN];
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 771688e1b0da..24783b71c584 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -426,13 +426,29 @@  struct ethtool_link_usettings {
 int __ethtool_get_link_ksettings(struct net_device *dev,
 				 struct ethtool_link_ksettings *link_ksettings)
 {
+	const struct link_mode_info *link_info;
+	int err;
+
 	ASSERT_RTNL();
 
 	if (!dev->ethtool_ops->get_link_ksettings)
 		return -EOPNOTSUPP;
 
 	memset(link_ksettings, 0, sizeof(*link_ksettings));
-	return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
+
+	link_ksettings->link_mode = -1;
+	err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
+	if (err)
+		return err;
+
+	if (link_ksettings->link_mode != -1) {
+		link_info = &link_mode_params[link_ksettings->link_mode];
+		link_ksettings->base.speed = link_info->speed;
+		link_ksettings->lanes = link_info->lanes;
+		link_ksettings->base.duplex = link_info->duplex;
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(__ethtool_get_link_ksettings);
 
diff --git a/net/ethtool/linkmodes.c b/net/ethtool/linkmodes.c
index fb7d73250864..caf9111c5270 100644
--- a/net/ethtool/linkmodes.c
+++ b/net/ethtool/linkmodes.c
@@ -4,6 +4,8 @@ 
 #include "common.h"
 #include "bitset.h"
 
+/* LINKMODES_GET */
+
 struct linkmodes_req_info {
 	struct ethnl_req_info		base;
 };
@@ -150,125 +152,6 @@  const struct ethnl_request_ops ethnl_linkmodes_request_ops = {
 
 /* LINKMODES_SET */
 
-struct link_mode_info {
-	int				speed;
-	u32				lanes;
-	u8				duplex;
-};
-
-#define __DEFINE_LINK_MODE_PARAMS(_speed, _type, _lanes, _duplex) \
-	[ETHTOOL_LINK_MODE(_speed, _type, _duplex)] = { \
-		.speed	= SPEED_ ## _speed, \
-		.lanes	= _lanes, \
-		.duplex	= __DUPLEX_ ## _duplex \
-	}
-#define __DUPLEX_Half DUPLEX_HALF
-#define __DUPLEX_Full DUPLEX_FULL
-#define __DEFINE_SPECIAL_MODE_PARAMS(_mode) \
-	[ETHTOOL_LINK_MODE_ ## _mode ## _BIT] = { \
-		.speed	= SPEED_UNKNOWN, \
-		.lanes	= ETHTOOL_LANES_UNKNOWN, \
-		.duplex	= DUPLEX_UNKNOWN, \
-	}
-
-static const struct link_mode_info link_mode_params[] = {
-	__DEFINE_LINK_MODE_PARAMS(10, T, 1, Half),
-	__DEFINE_LINK_MODE_PARAMS(10, T, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, T, 1, Half),
-	__DEFINE_LINK_MODE_PARAMS(100, T, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, T, 1, Half),
-	__DEFINE_LINK_MODE_PARAMS(1000, T, 1, Full),
-	__DEFINE_SPECIAL_MODE_PARAMS(Autoneg),
-	__DEFINE_SPECIAL_MODE_PARAMS(TP),
-	__DEFINE_SPECIAL_MODE_PARAMS(AUI),
-	__DEFINE_SPECIAL_MODE_PARAMS(MII),
-	__DEFINE_SPECIAL_MODE_PARAMS(FIBRE),
-	__DEFINE_SPECIAL_MODE_PARAMS(BNC),
-	__DEFINE_LINK_MODE_PARAMS(10000, T, 1, Full),
-	__DEFINE_SPECIAL_MODE_PARAMS(Pause),
-	__DEFINE_SPECIAL_MODE_PARAMS(Asym_Pause),
-	__DEFINE_LINK_MODE_PARAMS(2500, X, 1, Full),
-	__DEFINE_SPECIAL_MODE_PARAMS(Backplane),
-	__DEFINE_LINK_MODE_PARAMS(1000, KX, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, KX4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, KR, 1, Full),
-	[ETHTOOL_LINK_MODE_10000baseR_FEC_BIT] = {
-		.speed	= SPEED_10000,
-		.duplex = DUPLEX_FULL,
-	},
-	__DEFINE_LINK_MODE_PARAMS(20000, MLD2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(20000, KR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, KR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, CR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, SR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(40000, LR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, KR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, CR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, SR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(56000, LR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, CR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, KR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(25000, SR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, CR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, KR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR4_ER4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, SR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, X, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, CR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, SR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, LR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, LRM, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(10000, ER, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(2500, T, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(5000, T, 1, Full),
-	__DEFINE_SPECIAL_MODE_PARAMS(FEC_NONE),
-	__DEFINE_SPECIAL_MODE_PARAMS(FEC_RS),
-	__DEFINE_SPECIAL_MODE_PARAMS(FEC_BASER),
-	__DEFINE_LINK_MODE_PARAMS(50000, KR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, SR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, CR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, LR_ER_FR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(50000, DR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR2_ER2_FR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, DR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, KR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, SR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, LR4_ER4_FR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, DR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, CR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, T1, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(1000, T1, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, KR8, 8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, SR8, 8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, LR8_ER8_FR8, 8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, DR8, 8, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, CR8, 8, Full),
-	__DEFINE_SPECIAL_MODE_PARAMS(FEC_LLRS),
-	__DEFINE_LINK_MODE_PARAMS(100000, KR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, SR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, LR_ER_FR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, DR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(100000, CR, 1, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, KR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, SR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, LR2_ER2_FR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, DR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(200000, CR2, 2, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, KR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, SR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, LR4_ER4_FR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, DR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(400000, CR4, 4, Full),
-	__DEFINE_LINK_MODE_PARAMS(100, FX, 1, Half),
-	__DEFINE_LINK_MODE_PARAMS(100, FX, 1, Full),
-};
-
 const struct nla_policy ethnl_linkmodes_set_policy[] = {
 	[ETHTOOL_A_LINKMODES_HEADER]		=
 		NLA_POLICY_NESTED(ethnl_header_policy),
@@ -294,9 +177,6 @@  static bool ethnl_auto_linkmodes(struct ethtool_link_ksettings *ksettings,
 	DECLARE_BITMAP(old_adv, __ETHTOOL_LINK_MODE_MASK_NBITS);
 	unsigned int i;
 
-	BUILD_BUG_ON(ARRAY_SIZE(link_mode_params) !=
-		     __ETHTOOL_LINK_MODE_MASK_NBITS);
-
 	bitmap_copy(old_adv, advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
 
 	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {