Add the netlink YAML spec and auto-generated UAPI header for a unified
loopback interface covering MAC, PCS, PHY, and pluggable module
components.
Each loopback point is described by a nested entry attribute
containing:
- component where in the path (MAC, PCS, PHY, MODULE)
- name subsystem label, e.g. "cmis-host" or "cmis-media"
- id optional instance selector (e.g. PHY id, port id)
- supported bitmask of supported directions
- direction NEAR_END, FAR_END, or 0 (disabled)
Signed-off-by: Björn Töpel <bjorn@kernel.org>
---
Documentation/netlink/specs/ethtool.yaml | 115 ++++++++++++++++++
.../uapi/linux/ethtool_netlink_generated.h | 52 ++++++++
2 files changed, 167 insertions(+)
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 4707063af3b4..05ebad6ae4e0 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -211,6 +211,39 @@ definitions:
name: discard
value: 31
+ -
+ name: loopback-component
+ type: enum
+ doc: |
+ Loopback component. Identifies where in the network path the
+ loopback is applied.
+ entries:
+ -
+ name: mac
+ doc: MAC loopback
+ -
+ name: pcs
+ doc: PCS loopback
+ -
+ name: phy
+ doc: PHY loopback
+ -
+ name: module
+ doc: Pluggable module (e.g. CMIS (Q)SFP) loopback
+ -
+ name: loopback-direction
+ type: flags
+ doc: |
+ Loopback direction flags. Used as a bitmask in supported, and as
+ a single value in direction.
+ entries:
+ -
+ name: near-end
+ doc: Near-end loopback; host-loop-host
+ -
+ name: far-end
+ doc: Far-end loopback; line-loop-line
+
attribute-sets:
-
name: header
@@ -1903,6 +1936,60 @@ attribute-sets:
name: link
type: nest
nested-attributes: mse-snapshot
+ -
+ name: loopback-entry
+ doc: Per-component loopback configuration entry.
+ attr-cnt-name: __ethtool-a-loopback-entry-cnt
+ attributes:
+ -
+ name: unspec
+ type: unused
+ value: 0
+ -
+ name: component
+ type: u32
+ enum: loopback-component
+ doc: Loopback component
+ -
+ name: id
+ type: u32
+ doc: |
+ Optional component instance identifier. Required for PHY,
+ optional for MODULE, omitted for MAC and PCS.
+ -
+ name: name
+ type: string
+ doc: |
+ Subsystem-specific name for the loopback point within the
+ component.
+ -
+ name: supported
+ type: u32
+ enum: loopback-direction
+ enum-as-flags: true
+ doc: Bitmask of supported loopback directions
+ -
+ name: direction
+ type: u32
+ enum: loopback-direction
+ doc: Current loopback direction, 0 means disabled
+ -
+ name: loopback
+ attr-cnt-name: __ethtool-a-loopback-cnt
+ attributes:
+ -
+ name: unspec
+ type: unused
+ value: 0
+ -
+ name: header
+ type: nest
+ nested-attributes: header
+ -
+ name: entry
+ type: nest
+ multi-attr: true
+ nested-attributes: loopback-entry
operations:
enum-model: directional
@@ -2855,6 +2942,34 @@ operations:
- worst-channel
- link
dump: *mse-get-op
+ -
+ name: loopback-get
+ doc: Get loopback configuration and capabilities.
+
+ attribute-set: loopback
+
+ do: &loopback-get-op
+ request:
+ attributes:
+ - header
+ reply:
+ attributes: &loopback
+ - header
+ - entry
+ dump: *loopback-get-op
+ -
+ name: loopback-set
+ doc: Set loopback configuration.
+
+ attribute-set: loopback
+
+ do:
+ request:
+ attributes: *loopback
+ -
+ name: loopback-ntf
+ doc: Notification for change in loopback configuration.
+ notify: loopback-get
mcast-groups:
list:
diff --git a/include/uapi/linux/ethtool_netlink_generated.h b/include/uapi/linux/ethtool_netlink_generated.h
index 114b83017297..83fb17dd5daf 100644
--- a/include/uapi/linux/ethtool_netlink_generated.h
+++ b/include/uapi/linux/ethtool_netlink_generated.h
@@ -78,6 +78,33 @@ enum ethtool_pse_event {
ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR = 64,
};
+/**
+ * enum ethtool_loopback_component - Loopback component. Identifies where in
+ * the network path the loopback is applied.
+ * @ETHTOOL_LOOPBACK_COMPONENT_MAC: MAC loopback
+ * @ETHTOOL_LOOPBACK_COMPONENT_PCS: PCS loopback
+ * @ETHTOOL_LOOPBACK_COMPONENT_PHY: PHY loopback
+ * @ETHTOOL_LOOPBACK_COMPONENT_MODULE: Pluggable module (e.g. CMIS (Q)SFP)
+ * loopback
+ */
+enum ethtool_loopback_component {
+ ETHTOOL_LOOPBACK_COMPONENT_MAC,
+ ETHTOOL_LOOPBACK_COMPONENT_PCS,
+ ETHTOOL_LOOPBACK_COMPONENT_PHY,
+ ETHTOOL_LOOPBACK_COMPONENT_MODULE,
+};
+
+/**
+ * enum ethtool_loopback_direction - Loopback direction flags. Used as a
+ * bitmask in supported, and as a single value in direction.
+ * @ETHTOOL_LOOPBACK_DIRECTION_NEAR_END: Near-end loopback; host-loop-host
+ * @ETHTOOL_LOOPBACK_DIRECTION_FAR_END: Far-end loopback; line-loop-line
+ */
+enum ethtool_loopback_direction {
+ ETHTOOL_LOOPBACK_DIRECTION_NEAR_END = 1,
+ ETHTOOL_LOOPBACK_DIRECTION_FAR_END = 2,
+};
+
enum {
ETHTOOL_A_HEADER_UNSPEC,
ETHTOOL_A_HEADER_DEV_INDEX,
@@ -838,6 +865,27 @@ enum {
ETHTOOL_A_MSE_MAX = (__ETHTOOL_A_MSE_CNT - 1)
};
+enum {
+ ETHTOOL_A_LOOPBACK_ENTRY_UNSPEC,
+ ETHTOOL_A_LOOPBACK_ENTRY_COMPONENT,
+ ETHTOOL_A_LOOPBACK_ENTRY_ID,
+ ETHTOOL_A_LOOPBACK_ENTRY_NAME,
+ ETHTOOL_A_LOOPBACK_ENTRY_SUPPORTED,
+ ETHTOOL_A_LOOPBACK_ENTRY_DIRECTION,
+
+ __ETHTOOL_A_LOOPBACK_ENTRY_CNT,
+ ETHTOOL_A_LOOPBACK_ENTRY_MAX = (__ETHTOOL_A_LOOPBACK_ENTRY_CNT - 1)
+};
+
+enum {
+ ETHTOOL_A_LOOPBACK_UNSPEC,
+ ETHTOOL_A_LOOPBACK_HEADER,
+ ETHTOOL_A_LOOPBACK_ENTRY,
+
+ __ETHTOOL_A_LOOPBACK_CNT,
+ ETHTOOL_A_LOOPBACK_MAX = (__ETHTOOL_A_LOOPBACK_CNT - 1)
+};
+
enum {
ETHTOOL_MSG_USER_NONE = 0,
ETHTOOL_MSG_STRSET_GET = 1,
@@ -891,6 +939,8 @@ enum {
ETHTOOL_MSG_RSS_CREATE_ACT,
ETHTOOL_MSG_RSS_DELETE_ACT,
ETHTOOL_MSG_MSE_GET,
+ ETHTOOL_MSG_LOOPBACK_GET,
+ ETHTOOL_MSG_LOOPBACK_SET,
__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1)
@@ -952,6 +1002,8 @@ enum {
ETHTOOL_MSG_RSS_CREATE_NTF,
ETHTOOL_MSG_RSS_DELETE_NTF,
ETHTOOL_MSG_MSE_GET_REPLY,
+ ETHTOOL_MSG_LOOPBACK_GET_REPLY,
+ ETHTOOL_MSG_LOOPBACK_NTF,
__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)
--
2.53.0
Hi, On 08/03/2026 13:40, Björn Töpel wrote: > Add the netlink YAML spec and auto-generated UAPI header for a unified > loopback interface covering MAC, PCS, PHY, and pluggable module > components. > > Each loopback point is described by a nested entry attribute > containing: > > - component where in the path (MAC, PCS, PHY, MODULE) > - name subsystem label, e.g. "cmis-host" or "cmis-media" > - id optional instance selector (e.g. PHY id, port id) > - supported bitmask of supported directions > - direction NEAR_END, FAR_END, or 0 (disabled) > > Signed-off-by: Björn Töpel <bjorn@kernel.org> > --- > Documentation/netlink/specs/ethtool.yaml | 115 ++++++++++++++++++ > .../uapi/linux/ethtool_netlink_generated.h | 52 ++++++++ > 2 files changed, 167 insertions(+) > > diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml > index 4707063af3b4..05ebad6ae4e0 100644 > --- a/Documentation/netlink/specs/ethtool.yaml > +++ b/Documentation/netlink/specs/ethtool.yaml > @@ -211,6 +211,39 @@ definitions: > name: discard > value: 31 > > + - > + name: loopback-component > + type: enum > + doc: | > + Loopback component. Identifies where in the network path the > + loopback is applied. > + entries: > + - > + name: mac > + doc: MAC loopback > + - > + name: pcs > + doc: PCS loopback > + - > + name: phy > + doc: PHY loopback > + - > + name: module > + doc: Pluggable module (e.g. CMIS (Q)SFP) loopback Should we also add "serdes" ? > + - > + name: loopback-direction > + type: flags > + doc: | > + Loopback direction flags. Used as a bitmask in supported, and as > + a single value in direction. > + entries: > + - > + name: near-end > + doc: Near-end loopback; host-loop-host > + - > + name: far-end > + doc: Far-end loopback; line-loop-line > + > attribute-sets: > - > name: header > @@ -1903,6 +1936,60 @@ attribute-sets: > name: link > type: nest > nested-attributes: mse-snapshot > + - > + name: loopback-entry > + doc: Per-component loopback configuration entry. > + attr-cnt-name: __ethtool-a-loopback-entry-cnt > + attributes: > + - > + name: unspec > + type: unused > + value: 0 > + - > + name: component > + type: u32 > + enum: loopback-component > + doc: Loopback component > + - > + name: id > + type: u32 > + doc: | > + Optional component instance identifier. Required for PHY, > + optional for MODULE, omitted for MAC and PCS. it doesn't have to be required for PHY. The current idea is that if you don't pass any PHY index when issueing a PHY-targetting command, then it means you're targetting net_device->phydev, that is the PHY device attached to the netdev (if any). I think we can keep that behaviour, as systems with multiple PHYs are not very common. > + - > + name: name > + type: string > + doc: | > + Subsystem-specific name for the loopback point within the > + component. We'll need to be careful about keeping this subsystem-specific and not driver-specific :) > + - > + name: supported > + type: u32 > + enum: loopback-direction > + enum-as-flags: true > + doc: Bitmask of supported loopback directions > + - > + name: direction > + type: u32 > + enum: loopback-direction > + doc: Current loopback direction, 0 means disabled no need for an u32 for 3 different values I think :) Maxime
> > + doc: | > > + Loopback component. Identifies where in the network path the > > + loopback is applied. > > + entries: > > + - > > + name: mac > > + doc: MAC loopback > > + - > > + name: pcs > > + doc: PCS loopback > > + - > > + name: phy > > + doc: PHY loopback > > + - > > + name: module > > + doc: Pluggable module (e.g. CMIS (Q)SFP) loopback > > Should we also add "serdes" ? What is the difference between SERDES and PCS? Maybe we should also make it clear PHY means Ethernet PHY. The Marvell Generic PHYs have phy-mvebu-a3700-comphy.c:#define COMPHY_DIG_LOOPBACK_EN 0x23 phy-mvebu-cp110-comphy.c:#define MVEBU_COMPHY_LOOPBACK(n) (0x88c + (n) * 0x1000) which suggests it can also do loopback. We don't want PHY meaning two different things. And maybe we should comment that a Base-T SFP module which contains an Ethernet PHY should appear under PHY, not module? When Linux is driving the PHY, that should just happen. But if it is firmware driving the PHY in the module, we should make our expectations of the firmware clear. Andrew
On 09/03/2026 17:45, Andrew Lunn wrote: >>> + doc: | >>> + Loopback component. Identifies where in the network path the >>> + loopback is applied. >>> + entries: >>> + - >>> + name: mac >>> + doc: MAC loopback >>> + - >>> + name: pcs >>> + doc: PCS loopback >>> + - >>> + name: phy >>> + doc: PHY loopback >>> + - >>> + name: module >>> + doc: Pluggable module (e.g. CMIS (Q)SFP) loopback >> >> Should we also add "serdes" ? > > What is the difference between SERDES and PCS? By Serdes I mean "generic PHY", but as you state below I don't really want to use the word "PHY" as it's very prone to confusion with Ethernet PHYs. > > Maybe we should also make it clear PHY means Ethernet PHY. The Marvell > Generic PHYs have > > phy-mvebu-a3700-comphy.c:#define COMPHY_DIG_LOOPBACK_EN 0x23 > phy-mvebu-cp110-comphy.c:#define MVEBU_COMPHY_LOOPBACK(n) (0x88c + (n) * 0x1000) > > which suggests it can also do loopback. We don't want PHY meaning two > different things. Agreed, Maxime
On Tue, Mar 10, 2026 at 11:23:48AM +0100, Maxime Chevallier wrote: > > > On 09/03/2026 17:45, Andrew Lunn wrote: > >>> + doc: | > >>> + Loopback component. Identifies where in the network path the > >>> + loopback is applied. > >>> + entries: > >>> + - > >>> + name: mac > >>> + doc: MAC loopback > >>> + - > >>> + name: pcs > >>> + doc: PCS loopback > >>> + - > >>> + name: phy > >>> + doc: PHY loopback > >>> + - > >>> + name: module > >>> + doc: Pluggable module (e.g. CMIS (Q)SFP) loopback > >> > >> Should we also add "serdes" ? > > > > What is the difference between SERDES and PCS? > > By Serdes I mean "generic PHY", but as you state below I don't really > want to use the word "PHY" as it's very prone to confusion with Ethernet > PHYs. We probably want more than a minimum for doc: We actually want a full sentence, maybe a paragraph, clearly defining what we mean by each entry. We also need to the careful with generic PHY and serdes. Marvell's comment was that they have multiple loopback points, and named some of those with -serdes. Is that actually a PCS? Or is it the same functionality as a generic PHY, just not implemented as a Linux generic PHY? We have to assume vendors will get names wrong, because vendors often get names wrong. Ideally we want to point to clauses in 802.3, since it is very hard to argue against that. Andrew
Maxime Chevallier <maxime.chevallier@bootlin.com> writes: >> diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml >> index 4707063af3b4..05ebad6ae4e0 100644 >> --- a/Documentation/netlink/specs/ethtool.yaml >> +++ b/Documentation/netlink/specs/ethtool.yaml >> @@ -211,6 +211,39 @@ definitions: >> name: discard >> value: 31 >> >> + - >> + name: loopback-component >> + type: enum >> + doc: | >> + Loopback component. Identifies where in the network path the >> + loopback is applied. >> + entries: >> + - >> + name: mac >> + doc: MAC loopback >> + - >> + name: pcs >> + doc: PCS loopback >> + - >> + name: phy >> + doc: PHY loopback >> + - >> + name: module >> + doc: Pluggable module (e.g. CMIS (Q)SFP) loopback > > Should we also add "serdes" ? Good question! I've asked Naveen in another reply... >> @@ -1903,6 +1936,60 @@ attribute-sets: >> name: link >> type: nest >> nested-attributes: mse-snapshot >> + - >> + name: loopback-entry >> + doc: Per-component loopback configuration entry. >> + attr-cnt-name: __ethtool-a-loopback-entry-cnt >> + attributes: >> + - >> + name: unspec >> + type: unused >> + value: 0 >> + - >> + name: component >> + type: u32 >> + enum: loopback-component >> + doc: Loopback component >> + - >> + name: id >> + type: u32 >> + doc: | >> + Optional component instance identifier. Required for PHY, >> + optional for MODULE, omitted for MAC and PCS. > > it doesn't have to be required for PHY. The current idea is that if you > don't pass any PHY index when issueing a PHY-targetting command, then it > means you're targetting net_device->phydev, that is the PHY device > attached to the netdev (if any). > > I think we can keep that behaviour, as systems with multiple PHYs are > not very common. Got it! I'll update the wording! Thanks for the clarification! >> + - >> + name: name >> + type: string >> + doc: | >> + Subsystem-specific name for the loopback point within the >> + component. > > We'll need to be careful about keeping this subsystem-specific and not > driver-specific :) > >> + - >> + name: supported >> + type: u32 >> + enum: loopback-direction >> + enum-as-flags: true >> + doc: Bitmask of supported loopback directions >> + - >> + name: direction >> + type: u32 >> + enum: loopback-direction >> + doc: Current loopback direction, 0 means disabled > > no need for an u32 for 3 different values I think :) ACK! ...or maybe uint (which will use as least 32, but shows that we don't care)? Björn
© 2016 - 2026 Red Hat, Inc.