Skip to content

Commit

Permalink
Merge branch 'ethtool-fec-netlink'
Browse files Browse the repository at this point in the history
Jakub Kicinski says:

====================
ethtool: support FEC configuration over netlink

This series adds support for the equivalents of ETHTOOL_GFECPARAM
and ETHTOOL_SFECPARAM over netlink.

As a reminder - this is an API which allows user to query current
FEC mode, as well as set FEC manually if autoneg is disabled.
It does not configure anything if autoneg is enabled (that said
few/no drivers currently reject .set_fecparam calls while autoneg
is disabled, hopefully FW will just ignore the settings).

The existing functionality is mostly preserved in the new API.
The ioctl interface uses a set of flags, and link modes to tell
user which modes are supported. Here is how the flags translate
to the new interface (skipping descriptions for actual FEC modes):

  ioctl flag      |   description         |  new API
================================================================
ETHTOOL_FEC_OFF   | disabled (supported)  | \
ETHTOOL_FEC_RS    |                       |  ` link mode bitset
ETHTOOL_FEC_BASER |                       |  / .._A_FEC_MODES
ETHTOOL_FEC_LLRS  |                       | /
ETHTOOL_FEC_AUTO  | pick based on cable   | bool .._A_FEC_AUTO
ETHTOOL_FEC_NONE  | not supported         | no bit, no AUTO reported

Since link modes are already depended on (although somewhat implicitly)
for expressing supported modes - the new interface uses them for
the manual configuration, as well as uses link mode bit number
to communicate the active mode.

Use of link modes allows us to define any number of FEC modes we want,
and reuse the strset we already have defined.

Separating AUTO as its own attribute is the biggest changed compared
to the ioctl. It means drivers can no longer report AUTO as the
active FEC mode because there is no link mode for AUTO.
active_fec == AUTO makes little sense in the first place IMHO,
active_fec should be the actual mode, so hopefully this is fine.

The other minor departure is that None is no longer explicitly
expressed in the API. But drivers are reasonable in handling of
this somewhat pointless bit, so I'm not expecting any issues there.

One extension which could be considered would be moving active FEC
to ETHTOOL_MSG_LINKMODE_*, but then why not move all of FEC into
link modes? I don't know where to draw the line.

netdevsim support and a simple self test are included.

Next step is adding stats similar to the ones added for pause.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

,
  • Loading branch information
David S. Miller committed Mar 31, 2021
2 parents 2811005 + 1da07e5 commit e3f685a
Show file tree
Hide file tree
Showing 10 changed files with 492 additions and 4 deletions.
62 changes: 60 additions & 2 deletions Documentation/networking/ethtool-netlink.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ Userspace to kernel:
``ETHTOOL_MSG_CABLE_TEST_ACT`` action start cable test
``ETHTOOL_MSG_CABLE_TEST_TDR_ACT`` action start raw TDR cable test
``ETHTOOL_MSG_TUNNEL_INFO_GET`` get tunnel offload info
``ETHTOOL_MSG_FEC_GET`` get FEC settings
``ETHTOOL_MSG_FEC_SET`` set FEC settings
===================================== ================================

Kernel to userspace:
Expand Down Expand Up @@ -242,6 +244,8 @@ Kernel to userspace:
``ETHTOOL_MSG_CABLE_TEST_NTF`` Cable test results
``ETHTOOL_MSG_CABLE_TEST_TDR_NTF`` Cable test TDR results
``ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY`` tunnel offload info
``ETHTOOL_MSG_FEC_GET_REPLY`` FEC settings
``ETHTOOL_MSG_FEC_NTF`` FEC settings
===================================== =================================

``GET`` requests are sent by userspace applications to retrieve device
Expand Down Expand Up @@ -1280,6 +1284,60 @@ Kernel response contents:
For UDP tunnel table empty ``ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES`` indicates that
the table contains static entries, hard-coded by the NIC.

FEC_GET
=======

Gets FEC configuration and state like ``ETHTOOL_GFECPARAM`` ioctl request.

Request contents:

===================================== ====== ==========================
``ETHTOOL_A_FEC_HEADER`` nested request header
===================================== ====== ==========================

Kernel response contents:

===================================== ====== ==========================
``ETHTOOL_A_FEC_HEADER`` nested request header
``ETHTOOL_A_FEC_MODES`` bitset configured modes
``ETHTOOL_A_FEC_AUTO`` bool FEC mode auto selection
``ETHTOOL_A_FEC_ACTIVE`` u32 index of active FEC mode
===================================== ====== ==========================

``ETHTOOL_A_FEC_ACTIVE`` is the bit index of the FEC link mode currently
active on the interface. This attribute may not be present if device does
not support FEC.

``ETHTOOL_A_FEC_MODES`` and ``ETHTOOL_A_FEC_AUTO`` are only meaningful when
autonegotiation is disabled. If ``ETHTOOL_A_FEC_AUTO`` is non-zero driver will
select the FEC mode automatically based on the parameters of the SFP module.
This is equivalent to the ``ETHTOOL_FEC_AUTO`` bit of the ioctl interface.
``ETHTOOL_A_FEC_MODES`` carry the current FEC configuration using link mode
bits (rather than old ``ETHTOOL_FEC_*`` bits).

FEC_SET
=======

Sets FEC parameters like ``ETHTOOL_SFECPARAM`` ioctl request.

Request contents:

===================================== ====== ==========================
``ETHTOOL_A_FEC_HEADER`` nested request header
``ETHTOOL_A_FEC_MODES`` bitset configured modes
``ETHTOOL_A_FEC_AUTO`` bool FEC mode auto selection
===================================== ====== ==========================

``FEC_SET`` is only meaningful when autonegotiation is disabled. Otherwise
FEC mode is selected as part of autonegotiation.

``ETHTOOL_A_FEC_MODES`` selects which FEC mode should be used. It's recommended
to set only one bit, if multiple bits are set driver may choose between them
in an implementation specific way.

``ETHTOOL_A_FEC_AUTO`` requests the driver to choose FEC mode based on SFP
module parameters. This does not mean autonegotiation.

Request translation
===================

Expand Down Expand Up @@ -1373,8 +1431,8 @@ are netlink only.
``ETHTOOL_MSG_LINKMODES_SET``
``ETHTOOL_PHY_GTUNABLE`` n/a
``ETHTOOL_PHY_STUNABLE`` n/a
``ETHTOOL_GFECPARAM`` n/a
``ETHTOOL_SFECPARAM`` n/a
``ETHTOOL_GFECPARAM`` ``ETHTOOL_MSG_FEC_GET``
``ETHTOOL_SFECPARAM`` ``ETHTOOL_MSG_FEC_SET``
n/a ''ETHTOOL_MSG_CABLE_TEST_ACT''
n/a ''ETHTOOL_MSG_CABLE_TEST_TDR_ACT''
n/a ``ETHTOOL_MSG_TUNNEL_INFO_GET``
Expand Down
36 changes: 36 additions & 0 deletions drivers/net/netdevsim/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ static int nsim_set_ringparam(struct net_device *dev,
return 0;
}

static int
nsim_get_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
{
struct netdevsim *ns = netdev_priv(dev);

if (ns->ethtool.get_err)
return -ns->ethtool.get_err;
memcpy(fecparam, &ns->ethtool.fec, sizeof(ns->ethtool.fec));
return 0;
}

static int
nsim_set_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
{
struct netdevsim *ns = netdev_priv(dev);
u32 fec;

if (ns->ethtool.set_err)
return -ns->ethtool.set_err;
memcpy(&ns->ethtool.fec, fecparam, sizeof(ns->ethtool.fec));
fec = fecparam->fec;
if (fec == ETHTOOL_FEC_AUTO)
fec |= ETHTOOL_FEC_OFF;
fec |= ETHTOOL_FEC_NONE;
ns->ethtool.fec.active_fec = 1 << (fls(fec) - 1);
return 0;
}

static const struct ethtool_ops nsim_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_ALL_PARAMS,
.get_pause_stats = nsim_get_pause_stats,
Expand All @@ -86,6 +114,8 @@ static const struct ethtool_ops nsim_ethtool_ops = {
.get_coalesce = nsim_get_coalesce,
.get_ringparam = nsim_get_ringparam,
.set_ringparam = nsim_set_ringparam,
.get_fecparam = nsim_get_fecparam,
.set_fecparam = nsim_set_fecparam,
};

static void nsim_ethtool_ring_init(struct netdevsim *ns)
Expand All @@ -104,8 +134,14 @@ void nsim_ethtool_init(struct netdevsim *ns)

nsim_ethtool_ring_init(ns);

ns->ethtool.fec.fec = ETHTOOL_FEC_NONE;
ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;

ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);

debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
debugfs_create_u32("set_err", 0600, ethtool, &ns->ethtool.set_err);

dir = debugfs_create_dir("pause", ethtool);
debugfs_create_bool("report_stats_rx", 0600, dir,
&ns->ethtool.pauseparam.report_stats_rx);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/netdevsim/netdevsim.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ struct nsim_ethtool_pauseparam {
};

struct nsim_ethtool {
u32 get_err;
u32 set_err;
struct nsim_ethtool_pauseparam pauseparam;
struct ethtool_coalesce coalesce;
struct ethtool_ringparam ring;
struct ethtool_fecparam fec;
};

struct netdevsim {
Expand Down
17 changes: 17 additions & 0 deletions include/uapi/linux/ethtool_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ enum {
ETHTOOL_MSG_CABLE_TEST_ACT,
ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
ETHTOOL_MSG_TUNNEL_INFO_GET,
ETHTOOL_MSG_FEC_GET,
ETHTOOL_MSG_FEC_SET,

/* add new constants above here */
__ETHTOOL_MSG_USER_CNT,
Expand Down Expand Up @@ -80,6 +82,8 @@ enum {
ETHTOOL_MSG_CABLE_TEST_NTF,
ETHTOOL_MSG_CABLE_TEST_TDR_NTF,
ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY,
ETHTOOL_MSG_FEC_GET_REPLY,
ETHTOOL_MSG_FEC_NTF,

/* add new constants above here */
__ETHTOOL_MSG_KERNEL_CNT,
Expand Down Expand Up @@ -629,6 +633,19 @@ enum {
ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1)
};

/* FEC */

enum {
ETHTOOL_A_FEC_UNSPEC,
ETHTOOL_A_FEC_HEADER, /* nest - _A_HEADER_* */
ETHTOOL_A_FEC_MODES, /* bitset */
ETHTOOL_A_FEC_AUTO, /* u8 */
ETHTOOL_A_FEC_ACTIVE, /* u32 */

__ETHTOOL_A_FEC_CNT,
ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1)
};

/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
Expand Down
2 changes: 1 addition & 1 deletion net/ethtool/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o
ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
linkstate.o debug.o wol.o features.o privflags.o rings.o \
channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
tunnels.o
tunnels.o fec.o
Loading

0 comments on commit e3f685a

Please sign in to comment.