Hi!

Background
==========

This series adds a generic ethtool loopback framework with GET/SET
netlink commands, using a component/id/name/direction model that can
(Hopefully! Please refer to "Open questions" below.) represent
loopback points across the network path (MAC, MODULE, PHY, PCS).

This is the v1 proper of the loopback series, reworked based on
feedback from previous RFC v2 [1].

The main change since the RFC v2 is that LOOPBACK_GET no longer
returns an array of entries in a single doit reply. Instead, it uses
the dumpit infrastructure -- each loopback entry is a separate netlink
message in a DUMP response. This follows the same pattern as PHY_GET
and the perphy helpers in net/ethtool/netlink.c, as suggested by
Maxime.

A filtered DUMP (with a dev-index in the header) lists all loopback
entries for that netdev; an unfiltered DUMP iterates over all netdevs.
The doit handler is also available: when the request includes an
ETHTOOL_A_LOOPBACK_ENTRY nest with component + name, it returns that
specific entry.

The loopback model remains the same: LOOPBACK_GET/SET with a generic
component/name/direction model that can represent loopback points
across the data path -- MODULE, PHY, MAC, and PCS. This series wires
up MODULE/CMIS and MAC as the first users; PHY and PCS return
-EOPNOTSUPP for now.

Loopback lookup and enumeration
===============================

Each loopback entry is uniquely identified by the tuple (component,
id, name). The kernel provides two GET paths:

 - Exact lookup (doit): the user specifies component + name (and
   optionally id) in the request. The kernel dispatches to the right
   component handler: for MAC, it calls the driver's
   get_loopback(dev, name, id, entry) ethtool_op; for MODULE, it
   calls ethtool_cmis_get_loopback(dev, name, entry). Returns a
   single entry or -EOPNOTSUPP.

 - Index enumeration (dump): the kernel iterates a flat index space
   across all components on a device. Each component's
   get_loopback_by_index(dev, index, entry) is tried in order (MAC
   first via ethtool_ops, then MODULE/CMIS). The dump stops when all
   components return -EOPNOTSUPP. This integrates with the generic
   dump_one_dev sub-iterator infrastructure added in patch 1.

SET takes one or more entries, each with component + name + direction,
and dispatches to the driver's set_loopback() ethtool_op (MAC) or
ethtool_cmis_set_loopback() (MODULE).

The Common Management Interface Specification (CMIS) defines four
diagnostic loopback types, characterized by location (Host or Media
Side) and signal direction:

 - Host Side Input (Rx->Tx) -- near-end
 - Host Side Output (Tx->Rx) -- far-end
 - Media Side Input (Rx->Tx) -- near-end
 - Media Side Output (Tx->Rx) -- far-end

Support is detected via Page 13h Byte 128, and loopback is controlled
via Page 13h Bytes 180-183 (one byte per type, one bit per lane).

The CMIS helpers work entirely over get/set_module_eeprom_by_page, so
any driver that already has EEPROM page access gets module loopback
without new ethtool_ops or driver changes.

Currently, only mellanox/mlxsw, and broadcom/bnxt support CMIS
operations. I'll follow-up with mlx5 support.

Implementation
==============

Patch 1/11 ethtool: Add dump_one_dev callback for per-device sub-iteration
  Replaces the per-PHY specific dump functions with a generic
  sub-iterator infrastructure driven by a dump_one_dev callback in
  ethnl_request_ops. When ops->dump_one_dev is set,
  ethnl_default_start() saves the target device's ifindex for
  filtered dumps, and ethnl_default_dumpit() delegates per-device
  iteration to the callback. No separate start/dumpit/done functions
  are needed.

Patch 2/11 ethtool: Add loopback netlink UAPI definitions
  Adds the YAML spec and generated UAPI header for the new
  LOOPBACK_GET/SET commands. Each loopback entry carries a component
  type, optional id, name string, supported directions bitmask, and
  current direction.

Patch 3/11 ethtool: Add loopback GET/SET netlink implementation
  Implements GET/SET dispatch in a new loopback.c. GET uses the
  dump_one_dev infrastructure for dump enumeration (by flat index)
  and supports doit exact lookup by (component, id, name) via
  parse_request. SET switches on the component and calls the right
  handler per entry. No components are wired yet.

Patch 4/11 ethtool: Add CMIS loopback helpers for module loopback control
  Adds cmis_loopback.c with the MODULE component handlers and wires
  them into loopback.c's dispatch. GET enumerates entries by index
  (ethtool_cmis_get_loopback_by_index) or looks up by name
  (ethtool_cmis_get_loopback). SET (ethtool_cmis_set_loopback)
  resolves name to control byte indices and enforces mutual
  exclusivity.

Patch 5/11 selftests: drv-net: Add loopback driver test
  Adds loopback_drv.py with generic tests that work on any device
  with module loopback support: enable/disable, direction switching,
  idempotent enable, and rejection while interface is up.

Patch 6/11 ethtool: Add MAC loopback support via ethtool_ops
  Extends struct ethtool_ops with three loopback callbacks for
  driver-level MAC loopback: get_loopback (exact lookup by name/id),
  get_loopback_by_index (dump enumeration), and set_loopback. Wires
  the MAC component into loopback.c's dispatch. For dump enumeration,
  MAC entries are tried first, then MODULE/CMIS entries follow at the
  next index offset.

Patch 7/11 netdevsim: Add MAC loopback simulation
  Implements the three ethtool loopback ops in netdevsim. Exposes a
  single MAC loopback entry ("mac") with both near-end and far-end
  support. State is stored in memory and exposed via debugfs under
  ethtool/mac_lb/{supported,direction}.

Patch 8/11 selftests: drv-net: Add MAC loopback netdevsim test
  Adds loopback_nsim.py with netdevsim-specific tests for MAC
  loopback: entry presence, SET/GET round-trip with debugfs
  verification, and error paths.

Patch 9/11 MAINTAINERS: Add entry for ethtool loopback
  Adds a MAINTAINERS entry for the ethtool loopback subsystem covering
  the core loopback and CMIS loopback netlink implementation, and the
  associated selftests.

Patch 10/11 netdevsim: Add module EEPROM simulation via debugfs
  Adds get/set_module_eeprom_by_page to netdevsim, backed by a
  256-page x 128-byte array exposed via debugfs.

Patch 11/11 selftests: drv-net: Add CMIS loopback netdevsim test
  Extends loopback_nsim.py with netdevsim-specific tests that seed the
  EEPROM via debugfs: capability reporting, EEPROM byte verification,
  combined MAC + MODULE dump, and error paths.

Changes since RFC v2
====================

 - Switched LOOPBACK_GET from doit-with-array to dumpit, where each
   loopback entry is a separate netlink message. Uses the new generic
   dump_one_dev sub-iterator infrastructure instead of duplicating the
   perphy dump pattern. (Maxime)

 - u32 to u8 to represent the enums in the YAML. (Maxime)
   
 - Tried to document the YAML better. (Andrew)

 - Added doit exact lookup by (component, id, name) via
   parse_request, so single-entry GET doesn't need a flat index.

 - Added MAC loopback support via three new ethtool_ops callbacks
   (get_loopback(), get_loopback_by_index(), set_loopback()) with
   netdevsim implementation and tests.

 - Added MAINTAINERS entry.

Limitations
===========

PHY and PCS loopback are defined in the UAPI but not yet implemented.

No per-lane support -- loopback is all-or-nothing (0xff/0x00) across
lanes.

Open questions
==============

 - Is this the right extensibility model? I'd appreciate input from
   other NIC vendors on whether component/name/direction is flexible
   enough for their loopback implementations. Also, from the PHY/port
   folks (Maxime, Russell)! Naveen, please LMK if the MAC side of
   thing, is good enough for Marvell.

 - Are patches 10-11 (netdevsim EEPROM simulation + netdevsim-specific
   tests) worth carrying? They drive the CMIS Page 13h registers from
   debugfs, which gives good coverage without hardware, but it's
   another netdevsim surface to maintain. If the consensus is that the
   generic driver tests (patch 5) are sufficient, I'm happy to drop
   them.

 - Extend mellanox/mlx5 with .set_module_eeprom_by_page() callback. I
   got it to work in [6], but would like feedback from the Mellanox
   folks.

Related work
============

[1] Generic loopback support, RFC v2
  https://lore.kernel.org/netdev/[email protected]/
[2] CMIS loopback, RFC v1
  https://lore.kernel.org/netdev/[email protected]/
[3] New loopback modes
  https://lore.kernel.org/netdev/[email protected]/
[4] PHY loopback
  
https://lore.kernel.org/netdev/[email protected]/
[5] bnxt_en: add .set_module_eeprom_by_page() support
  
https://lore.kernel.org/netdev/[email protected]/
[6] net/mlx5e: Implement set_module_eeprom_by_page ethtool callback
  https://lore.kernel.org/netdev/[email protected]/


Björn Töpel (11):
  ethtool: Add dump_one_dev callback for per-device sub-iteration
  ethtool: Add loopback netlink UAPI definitions
  ethtool: Add loopback GET/SET netlink implementation
  ethtool: Add CMIS loopback helpers for module loopback control
  selftests: drv-net: Add loopback driver test
  ethtool: Add MAC loopback support via ethtool_ops
  netdevsim: Add MAC loopback simulation
  selftests: drv-net: Add MAC loopback netdevsim test
  MAINTAINERS: Add entry for ethtool loopback
  netdevsim: Add module EEPROM simulation via debugfs
  selftests: drv-net: Add CMIS loopback netdevsim test

 Documentation/netlink/specs/ethtool.yaml      | 123 ++++++
 MAINTAINERS                                   |   6 +
 drivers/net/netdevsim/ethtool.c               | 147 +++++++
 drivers/net/netdevsim/netdevsim.h             |  15 +
 include/linux/ethtool.h                       |  23 +
 .../uapi/linux/ethtool_netlink_generated.h    |  59 +++
 net/ethtool/Makefile                          |   2 +-
 net/ethtool/cmis_loopback.c                   | 407 ++++++++++++++++++
 net/ethtool/loopback.c                        | 341 +++++++++++++++
 net/ethtool/mse.c                             |   1 +
 net/ethtool/netlink.c                         | 285 ++++--------
 net/ethtool/netlink.h                         |  45 ++
 net/ethtool/phy.c                             |   1 +
 net/ethtool/plca.c                            |   2 +
 net/ethtool/pse-pd.c                          |   1 +
 .../testing/selftests/drivers/net/hw/Makefile |   2 +
 .../selftests/drivers/net/hw/loopback_drv.py  | 226 ++++++++++
 .../selftests/drivers/net/hw/loopback_nsim.py | 340 +++++++++++++++
 18 files changed, 1820 insertions(+), 206 deletions(-)
 create mode 100644 net/ethtool/cmis_loopback.c
 create mode 100644 net/ethtool/loopback.c
 create mode 100755 tools/testing/selftests/drivers/net/hw/loopback_drv.py
 create mode 100755 tools/testing/selftests/drivers/net/hw/loopback_nsim.py


base-commit: 52ede1bce557c66309f41ac29dd190be23ca9129
-- 
2.53.0


Reply via email to