From 127e2ee52faec1d70a22b95affa2b1da179e3b98 Mon Sep 17 00:00:00 2001 From: Dimitri Daskalakis Date: Thu, 1 Oct 2026 17:43:46 -0700 Subject: [PATCH 1/3] include: import linux/ethtool_netlink_generated.h from kernel v7.3-rc2 Only the generated header is imported, as everything needed (the genl family name, commands, attributes and header flags) is defined there, and linux/ethtool_netlink.h itself would be unused. Preparation for supporting the ethtool genl family in sd-netlink. --- .../uapi/linux/ethtool_netlink_generated.h | 964 ++++++++++++++++++ 1 file changed, 964 insertions(+) create mode 100644 src/include/uapi/linux/ethtool_netlink_generated.h diff --git a/src/include/uapi/linux/ethtool_netlink_generated.h b/src/include/uapi/linux/ethtool_netlink_generated.h new file mode 100644 index 00000000000..572c5f93e43 --- /dev/null +++ b/src/include/uapi/linux/ethtool_netlink_generated.h @@ -0,0 +1,964 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ethtool.yaml */ +/* YNL-GEN uapi header */ +/* To regenerate run: tools/net/ynl/ynl-regen.sh */ + +#ifndef _LINUX_ETHTOOL_NETLINK_GENERATED_H +#define _LINUX_ETHTOOL_NETLINK_GENERATED_H + +#define ETHTOOL_GENL_NAME "ethtool" +#define ETHTOOL_GENL_VERSION 1 + +enum { + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN, + ETHTOOL_UDP_TUNNEL_TYPE_GENEVE, + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE, + + /* private: */ + __ETHTOOL_UDP_TUNNEL_TYPE_CNT, + ETHTOOL_UDP_TUNNEL_TYPE_MAX = (__ETHTOOL_UDP_TUNNEL_TYPE_CNT - 1) +}; + +/** + * enum ethtool_header_flags - common ethtool header flags + * @ETHTOOL_FLAG_COMPACT_BITSETS: use compact bitsets in reply + * @ETHTOOL_FLAG_OMIT_REPLY: provide optional reply for SET or ACT requests + * @ETHTOOL_FLAG_STATS: request statistics, if supported by the driver + */ +enum ethtool_header_flags { + ETHTOOL_FLAG_COMPACT_BITSETS = 1, + ETHTOOL_FLAG_OMIT_REPLY = 2, + ETHTOOL_FLAG_STATS = 4, +}; + +enum ethtool_tcp_data_split { + ETHTOOL_TCP_DATA_SPLIT_UNKNOWN, + ETHTOOL_TCP_DATA_SPLIT_DISABLED, + ETHTOOL_TCP_DATA_SPLIT_ENABLED, +}; + +/** + * enum hwtstamp_source - Source of the hardware timestamp + * @HWTSTAMP_SOURCE_NETDEV: Hardware timestamp comes from a MAC or a device + * which has MAC and PHY integrated + * @HWTSTAMP_SOURCE_PHYLIB: Hardware timestamp comes from one PHY device of the + * network topology + */ +enum hwtstamp_source { + HWTSTAMP_SOURCE_NETDEV = 1, + HWTSTAMP_SOURCE_PHYLIB, +}; + +/** + * enum ethtool_pse_event - PSE event list for the PSE controller + * @ETHTOOL_PSE_EVENT_OVER_CURRENT: PSE output current is too high + * @ETHTOOL_PSE_EVENT_OVER_TEMP: PSE in over temperature state + * @ETHTOOL_C33_PSE_EVENT_DETECTION: detection process occur on the PSE. IEEE + * 802.3-2022 33.2.5 and 145.2.6 PSE detection of PDs. IEEE 802.3-202 + * 30.9.1.1.5 aPSEPowerDetectionStatus + * @ETHTOOL_C33_PSE_EVENT_CLASSIFICATION: classification process occur on the + * PSE. IEEE 802.3-2022 33.2.6 and 145.2.8 classification of PDs mutual + * identification. IEEE 802.3-2022 30.9.1.1.8 aPSEPowerClassification. + * @ETHTOOL_C33_PSE_EVENT_DISCONNECTION: PD has been disconnected on the PSE. + * IEEE 802.3-2022 33.3.8 and 145.3.9 PD Maintain Power Signature. IEEE + * 802.3-2022 33.5.1.2.9 MPS Absent. IEEE 802.3-2022 30.9.1.1.20 + * aPSEMPSAbsentCounter. + * @ETHTOOL_PSE_EVENT_OVER_BUDGET: PSE turned off due to over budget situation + * @ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR: PSE faced an error managing the + * power control from software + */ +enum ethtool_pse_event { + ETHTOOL_PSE_EVENT_OVER_CURRENT = 1, + ETHTOOL_PSE_EVENT_OVER_TEMP = 2, + ETHTOOL_C33_PSE_EVENT_DETECTION = 4, + ETHTOOL_C33_PSE_EVENT_CLASSIFICATION = 8, + ETHTOOL_C33_PSE_EVENT_DISCONNECTION = 16, + ETHTOOL_PSE_EVENT_OVER_BUDGET = 32, + ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR = 64, +}; + +enum { + ETHTOOL_A_HEADER_UNSPEC, + ETHTOOL_A_HEADER_DEV_INDEX, + ETHTOOL_A_HEADER_DEV_NAME, + ETHTOOL_A_HEADER_FLAGS, + ETHTOOL_A_HEADER_PHY_INDEX, + + __ETHTOOL_A_HEADER_CNT, + ETHTOOL_A_HEADER_MAX = (__ETHTOOL_A_HEADER_CNT - 1) +}; + +enum { + ETHTOOL_A_BITSET_BIT_UNSPEC, + ETHTOOL_A_BITSET_BIT_INDEX, + ETHTOOL_A_BITSET_BIT_NAME, + ETHTOOL_A_BITSET_BIT_VALUE, + + __ETHTOOL_A_BITSET_BIT_CNT, + ETHTOOL_A_BITSET_BIT_MAX = (__ETHTOOL_A_BITSET_BIT_CNT - 1) +}; + +enum { + ETHTOOL_A_BITSET_BITS_UNSPEC, + ETHTOOL_A_BITSET_BITS_BIT, + + __ETHTOOL_A_BITSET_BITS_CNT, + ETHTOOL_A_BITSET_BITS_MAX = (__ETHTOOL_A_BITSET_BITS_CNT - 1) +}; + +enum { + ETHTOOL_A_BITSET_UNSPEC, + ETHTOOL_A_BITSET_NOMASK, + ETHTOOL_A_BITSET_SIZE, + ETHTOOL_A_BITSET_BITS, + ETHTOOL_A_BITSET_VALUE, + ETHTOOL_A_BITSET_MASK, + + __ETHTOOL_A_BITSET_CNT, + ETHTOOL_A_BITSET_MAX = (__ETHTOOL_A_BITSET_CNT - 1) +}; + +enum { + ETHTOOL_A_STRING_UNSPEC, + ETHTOOL_A_STRING_INDEX, + ETHTOOL_A_STRING_VALUE, + + __ETHTOOL_A_STRING_CNT, + ETHTOOL_A_STRING_MAX = (__ETHTOOL_A_STRING_CNT - 1) +}; + +enum { + ETHTOOL_A_STRINGS_UNSPEC, + ETHTOOL_A_STRINGS_STRING, + + __ETHTOOL_A_STRINGS_CNT, + ETHTOOL_A_STRINGS_MAX = (__ETHTOOL_A_STRINGS_CNT - 1) +}; + +enum { + ETHTOOL_A_STRINGSET_UNSPEC, + ETHTOOL_A_STRINGSET_ID, + ETHTOOL_A_STRINGSET_COUNT, + ETHTOOL_A_STRINGSET_STRINGS, + + __ETHTOOL_A_STRINGSET_CNT, + ETHTOOL_A_STRINGSET_MAX = (__ETHTOOL_A_STRINGSET_CNT - 1) +}; + +enum { + ETHTOOL_A_STRINGSETS_UNSPEC, + ETHTOOL_A_STRINGSETS_STRINGSET, + + __ETHTOOL_A_STRINGSETS_CNT, + ETHTOOL_A_STRINGSETS_MAX = (__ETHTOOL_A_STRINGSETS_CNT - 1) +}; + +enum { + ETHTOOL_A_STRSET_UNSPEC, + ETHTOOL_A_STRSET_HEADER, + ETHTOOL_A_STRSET_STRINGSETS, + ETHTOOL_A_STRSET_COUNTS_ONLY, + + __ETHTOOL_A_STRSET_CNT, + ETHTOOL_A_STRSET_MAX = (__ETHTOOL_A_STRSET_CNT - 1) +}; + +enum { + ETHTOOL_A_PRIVFLAGS_UNSPEC, + ETHTOOL_A_PRIVFLAGS_HEADER, + ETHTOOL_A_PRIVFLAGS_FLAGS, + + __ETHTOOL_A_PRIVFLAGS_CNT, + ETHTOOL_A_PRIVFLAGS_MAX = (__ETHTOOL_A_PRIVFLAGS_CNT - 1) +}; + +enum { + ETHTOOL_A_RINGS_UNSPEC, + ETHTOOL_A_RINGS_HEADER, + ETHTOOL_A_RINGS_RX_MAX, + ETHTOOL_A_RINGS_RX_MINI_MAX, + ETHTOOL_A_RINGS_RX_JUMBO_MAX, + ETHTOOL_A_RINGS_TX_MAX, + ETHTOOL_A_RINGS_RX, + ETHTOOL_A_RINGS_RX_MINI, + ETHTOOL_A_RINGS_RX_JUMBO, + ETHTOOL_A_RINGS_TX, + ETHTOOL_A_RINGS_RX_BUF_LEN, + ETHTOOL_A_RINGS_TCP_DATA_SPLIT, + ETHTOOL_A_RINGS_CQE_SIZE, + ETHTOOL_A_RINGS_TX_PUSH, + ETHTOOL_A_RINGS_RX_PUSH, + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, + ETHTOOL_A_RINGS_HDS_THRESH, + ETHTOOL_A_RINGS_HDS_THRESH_MAX, + + __ETHTOOL_A_RINGS_CNT, + ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1) +}; + +enum { + ETHTOOL_A_MM_STAT_UNSPEC, + ETHTOOL_A_MM_STAT_PAD, + ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS, + ETHTOOL_A_MM_STAT_SMD_ERRORS, + ETHTOOL_A_MM_STAT_REASSEMBLY_OK, + ETHTOOL_A_MM_STAT_RX_FRAG_COUNT, + ETHTOOL_A_MM_STAT_TX_FRAG_COUNT, + ETHTOOL_A_MM_STAT_HOLD_COUNT, + + __ETHTOOL_A_MM_STAT_CNT, + ETHTOOL_A_MM_STAT_MAX = (__ETHTOOL_A_MM_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_MM_UNSPEC, + ETHTOOL_A_MM_HEADER, + ETHTOOL_A_MM_PMAC_ENABLED, + ETHTOOL_A_MM_TX_ENABLED, + ETHTOOL_A_MM_TX_ACTIVE, + ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, + ETHTOOL_A_MM_RX_MIN_FRAG_SIZE, + ETHTOOL_A_MM_VERIFY_ENABLED, + ETHTOOL_A_MM_VERIFY_STATUS, + ETHTOOL_A_MM_VERIFY_TIME, + ETHTOOL_A_MM_MAX_VERIFY_TIME, + ETHTOOL_A_MM_STATS, + + __ETHTOOL_A_MM_CNT, + ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1) +}; + +enum { + ETHTOOL_A_LINKINFO_UNSPEC, + ETHTOOL_A_LINKINFO_HEADER, + ETHTOOL_A_LINKINFO_PORT, + ETHTOOL_A_LINKINFO_PHYADDR, + ETHTOOL_A_LINKINFO_TP_MDIX, + ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, + ETHTOOL_A_LINKINFO_TRANSCEIVER, + + __ETHTOOL_A_LINKINFO_CNT, + ETHTOOL_A_LINKINFO_MAX = (__ETHTOOL_A_LINKINFO_CNT - 1) +}; + +enum { + ETHTOOL_A_LINKMODES_UNSPEC, + ETHTOOL_A_LINKMODES_HEADER, + ETHTOOL_A_LINKMODES_AUTONEG, + ETHTOOL_A_LINKMODES_OURS, + ETHTOOL_A_LINKMODES_PEER, + ETHTOOL_A_LINKMODES_SPEED, + ETHTOOL_A_LINKMODES_DUPLEX, + ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, + ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, + ETHTOOL_A_LINKMODES_LANES, + ETHTOOL_A_LINKMODES_RATE_MATCHING, + + __ETHTOOL_A_LINKMODES_CNT, + ETHTOOL_A_LINKMODES_MAX = (__ETHTOOL_A_LINKMODES_CNT - 1) +}; + +enum { + ETHTOOL_A_LINKSTATE_UNSPEC, + ETHTOOL_A_LINKSTATE_HEADER, + ETHTOOL_A_LINKSTATE_LINK, + ETHTOOL_A_LINKSTATE_SQI, + ETHTOOL_A_LINKSTATE_SQI_MAX, + ETHTOOL_A_LINKSTATE_EXT_STATE, + ETHTOOL_A_LINKSTATE_EXT_SUBSTATE, + ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT, + + __ETHTOOL_A_LINKSTATE_CNT, + ETHTOOL_A_LINKSTATE_MAX = (__ETHTOOL_A_LINKSTATE_CNT - 1) +}; + +enum { + ETHTOOL_A_DEBUG_UNSPEC, + ETHTOOL_A_DEBUG_HEADER, + ETHTOOL_A_DEBUG_MSGMASK, + + __ETHTOOL_A_DEBUG_CNT, + ETHTOOL_A_DEBUG_MAX = (__ETHTOOL_A_DEBUG_CNT - 1) +}; + +enum { + ETHTOOL_A_WOL_UNSPEC, + ETHTOOL_A_WOL_HEADER, + ETHTOOL_A_WOL_MODES, + ETHTOOL_A_WOL_SOPASS, + + __ETHTOOL_A_WOL_CNT, + ETHTOOL_A_WOL_MAX = (__ETHTOOL_A_WOL_CNT - 1) +}; + +enum { + ETHTOOL_A_FEATURES_UNSPEC, + ETHTOOL_A_FEATURES_HEADER, + ETHTOOL_A_FEATURES_HW, + ETHTOOL_A_FEATURES_WANTED, + ETHTOOL_A_FEATURES_ACTIVE, + ETHTOOL_A_FEATURES_NOCHANGE, + + __ETHTOOL_A_FEATURES_CNT, + ETHTOOL_A_FEATURES_MAX = (__ETHTOOL_A_FEATURES_CNT - 1) +}; + +enum { + ETHTOOL_A_CHANNELS_UNSPEC, + ETHTOOL_A_CHANNELS_HEADER, + ETHTOOL_A_CHANNELS_RX_MAX, + ETHTOOL_A_CHANNELS_TX_MAX, + ETHTOOL_A_CHANNELS_OTHER_MAX, + ETHTOOL_A_CHANNELS_COMBINED_MAX, + ETHTOOL_A_CHANNELS_RX_COUNT, + ETHTOOL_A_CHANNELS_TX_COUNT, + ETHTOOL_A_CHANNELS_OTHER_COUNT, + ETHTOOL_A_CHANNELS_COMBINED_COUNT, + + __ETHTOOL_A_CHANNELS_CNT, + ETHTOOL_A_CHANNELS_MAX = (__ETHTOOL_A_CHANNELS_CNT - 1) +}; + +enum { + ETHTOOL_A_IRQ_MODERATION_UNSPEC, + ETHTOOL_A_IRQ_MODERATION_USEC, + ETHTOOL_A_IRQ_MODERATION_PKTS, + ETHTOOL_A_IRQ_MODERATION_COMPS, + + __ETHTOOL_A_IRQ_MODERATION_CNT, + ETHTOOL_A_IRQ_MODERATION_MAX = (__ETHTOOL_A_IRQ_MODERATION_CNT - 1) +}; + +enum { + ETHTOOL_A_PROFILE_UNSPEC, + ETHTOOL_A_PROFILE_IRQ_MODERATION, + + __ETHTOOL_A_PROFILE_CNT, + ETHTOOL_A_PROFILE_MAX = (__ETHTOOL_A_PROFILE_CNT - 1) +}; + +enum { + ETHTOOL_A_COALESCE_UNSPEC, + ETHTOOL_A_COALESCE_HEADER, + ETHTOOL_A_COALESCE_RX_USECS, + ETHTOOL_A_COALESCE_RX_MAX_FRAMES, + ETHTOOL_A_COALESCE_RX_USECS_IRQ, + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, + ETHTOOL_A_COALESCE_TX_USECS, + ETHTOOL_A_COALESCE_TX_MAX_FRAMES, + ETHTOOL_A_COALESCE_TX_USECS_IRQ, + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, + ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, + ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, + ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, + ETHTOOL_A_COALESCE_PKT_RATE_LOW, + ETHTOOL_A_COALESCE_RX_USECS_LOW, + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, + ETHTOOL_A_COALESCE_TX_USECS_LOW, + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, + ETHTOOL_A_COALESCE_PKT_RATE_HIGH, + ETHTOOL_A_COALESCE_RX_USECS_HIGH, + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, + ETHTOOL_A_COALESCE_TX_USECS_HIGH, + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, + ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, + ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, + ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, + ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES, + ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES, + ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS, + ETHTOOL_A_COALESCE_RX_PROFILE, + ETHTOOL_A_COALESCE_TX_PROFILE, + ETHTOOL_A_COALESCE_RX_CQE_FRAMES, + ETHTOOL_A_COALESCE_RX_CQE_NSECS, + + __ETHTOOL_A_COALESCE_CNT, + ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1) +}; + +enum { + ETHTOOL_A_PAUSE_STAT_UNSPEC, + ETHTOOL_A_PAUSE_STAT_PAD, + ETHTOOL_A_PAUSE_STAT_TX_FRAMES, + ETHTOOL_A_PAUSE_STAT_RX_FRAMES, + ETHTOOL_A_PAUSE_STAT_TX_PAUSE_STORM_EVENTS, + + __ETHTOOL_A_PAUSE_STAT_CNT, + ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_PAUSE_UNSPEC, + ETHTOOL_A_PAUSE_HEADER, + ETHTOOL_A_PAUSE_AUTONEG, + ETHTOOL_A_PAUSE_RX, + ETHTOOL_A_PAUSE_TX, + ETHTOOL_A_PAUSE_STATS, + ETHTOOL_A_PAUSE_STATS_SRC, + + __ETHTOOL_A_PAUSE_CNT, + ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1) +}; + +enum { + ETHTOOL_A_EEE_UNSPEC, + ETHTOOL_A_EEE_HEADER, + ETHTOOL_A_EEE_MODES_OURS, + ETHTOOL_A_EEE_MODES_PEER, + ETHTOOL_A_EEE_ACTIVE, + ETHTOOL_A_EEE_ENABLED, + ETHTOOL_A_EEE_TX_LPI_ENABLED, + ETHTOOL_A_EEE_TX_LPI_TIMER, + + __ETHTOOL_A_EEE_CNT, + ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1) +}; + +enum { + ETHTOOL_A_TS_STAT_UNSPEC, + ETHTOOL_A_TS_STAT_TX_PKTS, + ETHTOOL_A_TS_STAT_TX_LOST, + ETHTOOL_A_TS_STAT_TX_ERR, + ETHTOOL_A_TS_STAT_TX_ONESTEP_PKTS_UNCONFIRMED, + + __ETHTOOL_A_TS_STAT_CNT, + ETHTOOL_A_TS_STAT_MAX = (__ETHTOOL_A_TS_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_TS_HWTSTAMP_PROVIDER_UNSPEC, + ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX, + ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER, + + __ETHTOOL_A_TS_HWTSTAMP_PROVIDER_CNT, + ETHTOOL_A_TS_HWTSTAMP_PROVIDER_MAX = (__ETHTOOL_A_TS_HWTSTAMP_PROVIDER_CNT - 1) +}; + +enum { + ETHTOOL_A_TSINFO_UNSPEC, + ETHTOOL_A_TSINFO_HEADER, + ETHTOOL_A_TSINFO_TIMESTAMPING, + ETHTOOL_A_TSINFO_TX_TYPES, + ETHTOOL_A_TSINFO_RX_FILTERS, + ETHTOOL_A_TSINFO_PHC_INDEX, + ETHTOOL_A_TSINFO_STATS, + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER, + ETHTOOL_A_TSINFO_HWTSTAMP_SOURCE, + ETHTOOL_A_TSINFO_HWTSTAMP_PHYINDEX, + + __ETHTOOL_A_TSINFO_CNT, + ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_RESULT_UNSPEC, + ETHTOOL_A_CABLE_RESULT_PAIR, + ETHTOOL_A_CABLE_RESULT_CODE, + ETHTOOL_A_CABLE_RESULT_SRC, + + __ETHTOOL_A_CABLE_RESULT_CNT, + ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC, + ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR, + ETHTOOL_A_CABLE_FAULT_LENGTH_CM, + ETHTOOL_A_CABLE_FAULT_LENGTH_SRC, + + __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT, + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_NEST_UNSPEC, + ETHTOOL_A_CABLE_NEST_RESULT, + ETHTOOL_A_CABLE_NEST_FAULT_LENGTH, + + __ETHTOOL_A_CABLE_NEST_CNT, + ETHTOOL_A_CABLE_NEST_MAX = (__ETHTOOL_A_CABLE_NEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_UNSPEC, + ETHTOOL_A_CABLE_TEST_HEADER, + + __ETHTOOL_A_CABLE_TEST_CNT, + ETHTOOL_A_CABLE_TEST_MAX = (__ETHTOOL_A_CABLE_TEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_NTF_HEADER, + ETHTOOL_A_CABLE_TEST_NTF_STATUS, + ETHTOOL_A_CABLE_TEST_NTF_NEST, + + __ETHTOOL_A_CABLE_TEST_NTF_CNT, + ETHTOOL_A_CABLE_TEST_NTF_MAX = (__ETHTOOL_A_CABLE_TEST_NTF_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST, + ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST, + ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP, + ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR, + + __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT, + ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX = (__ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER, + ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS, + ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST, + + __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT, + ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = (__ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_HEADER, + ETHTOOL_A_CABLE_TEST_TDR_CFG, + + __ETHTOOL_A_CABLE_TEST_TDR_CNT, + ETHTOOL_A_CABLE_TEST_TDR_MAX = (__ETHTOOL_A_CABLE_TEST_TDR_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC, + ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT, + ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE, + + __ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT, + ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC, + ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE, + ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, + ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, + + __ETHTOOL_A_TUNNEL_UDP_TABLE_CNT, + ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_UNSPEC, + ETHTOOL_A_TUNNEL_UDP_TABLE, + + __ETHTOOL_A_TUNNEL_UDP_CNT, + ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_INFO_UNSPEC, + ETHTOOL_A_TUNNEL_INFO_HEADER, + ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, + + __ETHTOOL_A_TUNNEL_INFO_CNT, + ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1) +}; + +enum { + ETHTOOL_A_FEC_HIST_PAD = 1, + ETHTOOL_A_FEC_HIST_BIN_LOW, + ETHTOOL_A_FEC_HIST_BIN_HIGH, + ETHTOOL_A_FEC_HIST_BIN_VAL, + ETHTOOL_A_FEC_HIST_BIN_VAL_PER_LANE, + + __ETHTOOL_A_FEC_HIST_CNT, + ETHTOOL_A_FEC_HIST_MAX = (__ETHTOOL_A_FEC_HIST_CNT - 1) +}; + +enum { + ETHTOOL_A_FEC_STAT_UNSPEC, + ETHTOOL_A_FEC_STAT_PAD, + ETHTOOL_A_FEC_STAT_CORRECTED, + ETHTOOL_A_FEC_STAT_UNCORR, + ETHTOOL_A_FEC_STAT_CORR_BITS, + ETHTOOL_A_FEC_STAT_HIST, + + __ETHTOOL_A_FEC_STAT_CNT, + ETHTOOL_A_FEC_STAT_MAX = (__ETHTOOL_A_FEC_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_FEC_UNSPEC, + ETHTOOL_A_FEC_HEADER, + ETHTOOL_A_FEC_MODES, + ETHTOOL_A_FEC_AUTO, + ETHTOOL_A_FEC_ACTIVE, + ETHTOOL_A_FEC_STATS, + + __ETHTOOL_A_FEC_CNT, + ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1) +}; + +enum { + ETHTOOL_A_MODULE_EEPROM_UNSPEC, + ETHTOOL_A_MODULE_EEPROM_HEADER, + ETHTOOL_A_MODULE_EEPROM_OFFSET, + ETHTOOL_A_MODULE_EEPROM_LENGTH, + ETHTOOL_A_MODULE_EEPROM_PAGE, + ETHTOOL_A_MODULE_EEPROM_BANK, + ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, + ETHTOOL_A_MODULE_EEPROM_DATA, + + __ETHTOOL_A_MODULE_EEPROM_CNT, + ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1) +}; + +enum { + ETHTOOL_A_STATS_GRP_UNSPEC, + ETHTOOL_A_STATS_GRP_PAD, + ETHTOOL_A_STATS_GRP_ID, + ETHTOOL_A_STATS_GRP_SS_ID, + ETHTOOL_A_STATS_GRP_STAT, + ETHTOOL_A_STATS_GRP_HIST_RX, + ETHTOOL_A_STATS_GRP_HIST_TX, + ETHTOOL_A_STATS_GRP_HIST_BKT_LOW, + ETHTOOL_A_STATS_GRP_HIST_BKT_HI, + ETHTOOL_A_STATS_GRP_HIST_VAL, + + __ETHTOOL_A_STATS_GRP_CNT, + ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1) +}; + +enum { + ETHTOOL_A_STATS_UNSPEC, + ETHTOOL_A_STATS_PAD, + ETHTOOL_A_STATS_HEADER, + ETHTOOL_A_STATS_GROUPS, + ETHTOOL_A_STATS_GRP, + ETHTOOL_A_STATS_SRC, + + __ETHTOOL_A_STATS_CNT, + ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1) +}; + +enum { + ETHTOOL_A_PHC_VCLOCKS_UNSPEC, + ETHTOOL_A_PHC_VCLOCKS_HEADER, + ETHTOOL_A_PHC_VCLOCKS_NUM, + ETHTOOL_A_PHC_VCLOCKS_INDEX, + + __ETHTOOL_A_PHC_VCLOCKS_CNT, + ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1) +}; + +enum { + ETHTOOL_A_MODULE_UNSPEC, + ETHTOOL_A_MODULE_HEADER, + ETHTOOL_A_MODULE_POWER_MODE_POLICY, + ETHTOOL_A_MODULE_POWER_MODE, + + __ETHTOOL_A_MODULE_CNT, + ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1) +}; + +enum { + ETHTOOL_A_C33_PSE_PW_LIMIT_UNSPEC, + ETHTOOL_A_C33_PSE_PW_LIMIT_MIN, + ETHTOOL_A_C33_PSE_PW_LIMIT_MAX, + + __ETHTOOL_A_C33_PSE_PW_LIMIT_CNT, + __ETHTOOL_A_C33_PSE_PW_LIMIT_MAX = (__ETHTOOL_A_C33_PSE_PW_LIMIT_CNT - 1) +}; + +enum { + ETHTOOL_A_PSE_UNSPEC, + ETHTOOL_A_PSE_HEADER, + ETHTOOL_A_PODL_PSE_ADMIN_STATE, + ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, + ETHTOOL_A_PODL_PSE_PW_D_STATUS, + ETHTOOL_A_C33_PSE_ADMIN_STATE, + ETHTOOL_A_C33_PSE_ADMIN_CONTROL, + ETHTOOL_A_C33_PSE_PW_D_STATUS, + ETHTOOL_A_C33_PSE_PW_CLASS, + ETHTOOL_A_C33_PSE_ACTUAL_PW, + ETHTOOL_A_C33_PSE_EXT_STATE, + ETHTOOL_A_C33_PSE_EXT_SUBSTATE, + ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT, + ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES, + ETHTOOL_A_PSE_PW_D_ID, + ETHTOOL_A_PSE_PRIO_MAX, + ETHTOOL_A_PSE_PRIO, + + __ETHTOOL_A_PSE_CNT, + ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1) +}; + +enum { + ETHTOOL_A_FLOW_ETHER = 1, + ETHTOOL_A_FLOW_IP4, + ETHTOOL_A_FLOW_IP6, + ETHTOOL_A_FLOW_TCP4, + ETHTOOL_A_FLOW_TCP6, + ETHTOOL_A_FLOW_UDP4, + ETHTOOL_A_FLOW_UDP6, + ETHTOOL_A_FLOW_SCTP4, + ETHTOOL_A_FLOW_SCTP6, + ETHTOOL_A_FLOW_AH4, + ETHTOOL_A_FLOW_AH6, + ETHTOOL_A_FLOW_ESP4, + ETHTOOL_A_FLOW_ESP6, + ETHTOOL_A_FLOW_AH_ESP4, + ETHTOOL_A_FLOW_AH_ESP6, + ETHTOOL_A_FLOW_GTPU4, + ETHTOOL_A_FLOW_GTPU6, + ETHTOOL_A_FLOW_GTPC4, + ETHTOOL_A_FLOW_GTPC6, + ETHTOOL_A_FLOW_GTPC_TEID4, + ETHTOOL_A_FLOW_GTPC_TEID6, + ETHTOOL_A_FLOW_GTPU_EH4, + ETHTOOL_A_FLOW_GTPU_EH6, + ETHTOOL_A_FLOW_GTPU_UL4, + ETHTOOL_A_FLOW_GTPU_UL6, + ETHTOOL_A_FLOW_GTPU_DL4, + ETHTOOL_A_FLOW_GTPU_DL6, + + __ETHTOOL_A_FLOW_CNT, + ETHTOOL_A_FLOW_MAX = (__ETHTOOL_A_FLOW_CNT - 1) +}; + +enum { + ETHTOOL_A_RSS_UNSPEC, + ETHTOOL_A_RSS_HEADER, + ETHTOOL_A_RSS_CONTEXT, + ETHTOOL_A_RSS_HFUNC, + ETHTOOL_A_RSS_INDIR, + ETHTOOL_A_RSS_HKEY, + ETHTOOL_A_RSS_INPUT_XFRM, + ETHTOOL_A_RSS_START_CONTEXT, + ETHTOOL_A_RSS_FLOW_HASH, + + __ETHTOOL_A_RSS_CNT, + ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1) +}; + +enum { + ETHTOOL_A_PLCA_UNSPEC, + ETHTOOL_A_PLCA_HEADER, + ETHTOOL_A_PLCA_VERSION, + ETHTOOL_A_PLCA_ENABLED, + ETHTOOL_A_PLCA_STATUS, + ETHTOOL_A_PLCA_NODE_CNT, + ETHTOOL_A_PLCA_NODE_ID, + ETHTOOL_A_PLCA_TO_TMR, + ETHTOOL_A_PLCA_BURST_CNT, + ETHTOOL_A_PLCA_BURST_TMR, + + __ETHTOOL_A_PLCA_CNT, + ETHTOOL_A_PLCA_MAX = (__ETHTOOL_A_PLCA_CNT - 1) +}; + +enum { + ETHTOOL_A_MODULE_FW_FLASH_UNSPEC, + ETHTOOL_A_MODULE_FW_FLASH_HEADER, + ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME, + ETHTOOL_A_MODULE_FW_FLASH_PASSWORD, + ETHTOOL_A_MODULE_FW_FLASH_STATUS, + ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG, + ETHTOOL_A_MODULE_FW_FLASH_DONE, + ETHTOOL_A_MODULE_FW_FLASH_TOTAL, + + __ETHTOOL_A_MODULE_FW_FLASH_CNT, + ETHTOOL_A_MODULE_FW_FLASH_MAX = (__ETHTOOL_A_MODULE_FW_FLASH_CNT - 1) +}; + +enum { + ETHTOOL_A_PHY_UNSPEC, + ETHTOOL_A_PHY_HEADER, + ETHTOOL_A_PHY_INDEX, + ETHTOOL_A_PHY_DRVNAME, + ETHTOOL_A_PHY_NAME, + ETHTOOL_A_PHY_UPSTREAM_TYPE, + ETHTOOL_A_PHY_UPSTREAM_INDEX, + ETHTOOL_A_PHY_UPSTREAM_SFP_NAME, + ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME, + + __ETHTOOL_A_PHY_CNT, + ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1) +}; + +enum { + ETHTOOL_A_TSCONFIG_UNSPEC, + ETHTOOL_A_TSCONFIG_HEADER, + ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER, + ETHTOOL_A_TSCONFIG_TX_TYPES, + ETHTOOL_A_TSCONFIG_RX_FILTERS, + ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS, + + __ETHTOOL_A_TSCONFIG_CNT, + ETHTOOL_A_TSCONFIG_MAX = (__ETHTOOL_A_TSCONFIG_CNT - 1) +}; + +enum { + ETHTOOL_A_PSE_NTF_HEADER = 1, + ETHTOOL_A_PSE_NTF_EVENTS, + + __ETHTOOL_A_PSE_NTF_CNT, + ETHTOOL_A_PSE_NTF_MAX = (__ETHTOOL_A_PSE_NTF_CNT - 1) +}; + +enum { + ETHTOOL_A_MSE_CAPABILITIES_MAX_AVERAGE_MSE = 1, + ETHTOOL_A_MSE_CAPABILITIES_MAX_PEAK_MSE, + ETHTOOL_A_MSE_CAPABILITIES_REFRESH_RATE_PS, + ETHTOOL_A_MSE_CAPABILITIES_NUM_SYMBOLS, + + __ETHTOOL_A_MSE_CAPABILITIES_CNT, + ETHTOOL_A_MSE_CAPABILITIES_MAX = (__ETHTOOL_A_MSE_CAPABILITIES_CNT - 1) +}; + +enum { + ETHTOOL_A_MSE_SNAPSHOT_AVERAGE_MSE = 1, + ETHTOOL_A_MSE_SNAPSHOT_PEAK_MSE, + ETHTOOL_A_MSE_SNAPSHOT_WORST_PEAK_MSE, + + __ETHTOOL_A_MSE_SNAPSHOT_CNT, + ETHTOOL_A_MSE_SNAPSHOT_MAX = (__ETHTOOL_A_MSE_SNAPSHOT_CNT - 1) +}; + +enum { + ETHTOOL_A_MSE_HEADER = 1, + ETHTOOL_A_MSE_CAPABILITIES, + ETHTOOL_A_MSE_CHANNEL_A, + ETHTOOL_A_MSE_CHANNEL_B, + ETHTOOL_A_MSE_CHANNEL_C, + ETHTOOL_A_MSE_CHANNEL_D, + ETHTOOL_A_MSE_WORST_CHANNEL, + ETHTOOL_A_MSE_LINK, + + __ETHTOOL_A_MSE_CNT, + ETHTOOL_A_MSE_MAX = (__ETHTOOL_A_MSE_CNT - 1) +}; + +enum { + ETHTOOL_MSG_USER_NONE = 0, + ETHTOOL_MSG_STRSET_GET = 1, + ETHTOOL_MSG_LINKINFO_GET, + ETHTOOL_MSG_LINKINFO_SET, + ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_MSG_LINKMODES_SET, + ETHTOOL_MSG_LINKSTATE_GET, + ETHTOOL_MSG_DEBUG_GET, + ETHTOOL_MSG_DEBUG_SET, + ETHTOOL_MSG_WOL_GET, + ETHTOOL_MSG_WOL_SET, + ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_MSG_FEATURES_SET, + ETHTOOL_MSG_PRIVFLAGS_GET, + ETHTOOL_MSG_PRIVFLAGS_SET, + ETHTOOL_MSG_RINGS_GET, + ETHTOOL_MSG_RINGS_SET, + ETHTOOL_MSG_CHANNELS_GET, + ETHTOOL_MSG_CHANNELS_SET, + ETHTOOL_MSG_COALESCE_GET, + ETHTOOL_MSG_COALESCE_SET, + ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_MSG_PAUSE_SET, + ETHTOOL_MSG_EEE_GET, + ETHTOOL_MSG_EEE_SET, + ETHTOOL_MSG_TSINFO_GET, + ETHTOOL_MSG_CABLE_TEST_ACT, + ETHTOOL_MSG_CABLE_TEST_TDR_ACT, + ETHTOOL_MSG_TUNNEL_INFO_GET, + ETHTOOL_MSG_FEC_GET, + ETHTOOL_MSG_FEC_SET, + ETHTOOL_MSG_MODULE_EEPROM_GET, + ETHTOOL_MSG_STATS_GET, + ETHTOOL_MSG_PHC_VCLOCKS_GET, + ETHTOOL_MSG_MODULE_GET, + ETHTOOL_MSG_MODULE_SET, + ETHTOOL_MSG_PSE_GET, + ETHTOOL_MSG_PSE_SET, + ETHTOOL_MSG_RSS_GET, + ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_MSG_PLCA_SET_CFG, + ETHTOOL_MSG_PLCA_GET_STATUS, + ETHTOOL_MSG_MM_GET, + ETHTOOL_MSG_MM_SET, + ETHTOOL_MSG_MODULE_FW_FLASH_ACT, + ETHTOOL_MSG_PHY_GET, + ETHTOOL_MSG_TSCONFIG_GET, + ETHTOOL_MSG_TSCONFIG_SET, + ETHTOOL_MSG_RSS_SET, + ETHTOOL_MSG_RSS_CREATE_ACT, + ETHTOOL_MSG_RSS_DELETE_ACT, + ETHTOOL_MSG_MSE_GET, + + __ETHTOOL_MSG_USER_CNT, + ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1) +}; + +enum { + ETHTOOL_MSG_KERNEL_NONE = 0, + ETHTOOL_MSG_STRSET_GET_REPLY = 1, + ETHTOOL_MSG_LINKINFO_GET_REPLY, + ETHTOOL_MSG_LINKINFO_NTF, + ETHTOOL_MSG_LINKMODES_GET_REPLY, + ETHTOOL_MSG_LINKMODES_NTF, + ETHTOOL_MSG_LINKSTATE_GET_REPLY, + ETHTOOL_MSG_DEBUG_GET_REPLY, + ETHTOOL_MSG_DEBUG_NTF, + ETHTOOL_MSG_WOL_GET_REPLY, + ETHTOOL_MSG_WOL_NTF, + ETHTOOL_MSG_FEATURES_GET_REPLY, + ETHTOOL_MSG_FEATURES_SET_REPLY, + ETHTOOL_MSG_FEATURES_NTF, + ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, + ETHTOOL_MSG_PRIVFLAGS_NTF, + ETHTOOL_MSG_RINGS_GET_REPLY, + ETHTOOL_MSG_RINGS_NTF, + ETHTOOL_MSG_CHANNELS_GET_REPLY, + ETHTOOL_MSG_CHANNELS_NTF, + ETHTOOL_MSG_COALESCE_GET_REPLY, + ETHTOOL_MSG_COALESCE_NTF, + ETHTOOL_MSG_PAUSE_GET_REPLY, + ETHTOOL_MSG_PAUSE_NTF, + ETHTOOL_MSG_EEE_GET_REPLY, + ETHTOOL_MSG_EEE_NTF, + ETHTOOL_MSG_TSINFO_GET_REPLY, + 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, + ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, + ETHTOOL_MSG_STATS_GET_REPLY, + ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, + ETHTOOL_MSG_MODULE_GET_REPLY, + ETHTOOL_MSG_MODULE_NTF, + ETHTOOL_MSG_PSE_GET_REPLY, + ETHTOOL_MSG_RSS_GET_REPLY, + ETHTOOL_MSG_PLCA_GET_CFG_REPLY, + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, + ETHTOOL_MSG_PLCA_NTF, + ETHTOOL_MSG_MM_GET_REPLY, + ETHTOOL_MSG_MM_NTF, + ETHTOOL_MSG_MODULE_FW_FLASH_NTF, + ETHTOOL_MSG_PHY_GET_REPLY, + ETHTOOL_MSG_PHY_NTF, + ETHTOOL_MSG_TSCONFIG_GET_REPLY, + ETHTOOL_MSG_TSCONFIG_SET_REPLY, + ETHTOOL_MSG_PSE_NTF, + ETHTOOL_MSG_RSS_NTF, + ETHTOOL_MSG_RSS_CREATE_ACT_REPLY, + ETHTOOL_MSG_RSS_CREATE_NTF, + ETHTOOL_MSG_RSS_DELETE_NTF, + ETHTOOL_MSG_MSE_GET_REPLY, + + __ETHTOOL_MSG_KERNEL_CNT, + ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1) +}; + +#define ETHTOOL_MCGRP_MONITOR_NAME "monitor" + +#endif /* _LINUX_ETHTOOL_NETLINK_GENERATED_H */ From e893d5982bb69cbf137202a43bbb8c65adc45bf6 Mon Sep 17 00:00:00 2001 From: Dimitri Daskalakis Date: Thu, 1 Oct 2026 17:43:46 -0700 Subject: [PATCH 2/3] sd-netlink: support ethtool genl family Unlike the other genl families, the attributes of ethtool depend on the command. As mentioned in commit 9270ec60bc ("sd-netlink: drop genl type system indexed by command"), reintroduce a mechanism to index the policy set by command for the ethtool family. Currently, only ETHTOOL_MSG_COALESCE_SET is supported. Parsing replies and notifications of the family is not supported yet. The kernel to userspace commands are numbered separately from the userspace to kernel commands and the two overlap, so the command of a received message cannot be used to look up the request policy set. These messages will be dropped when received rather than making the whole read fail. --- src/libsystemd/sd-netlink/netlink-genl.c | 31 ++++++-- .../sd-netlink/netlink-types-genl.c | 75 +++++++++++++++++++ src/libsystemd/sd-netlink/netlink-types.h | 1 + src/libsystemd/sd-netlink/test-netlink.c | 51 +++++++++++++ 4 files changed, 153 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index d4d33ae52da..2becbdf801e 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -16,6 +16,7 @@ typedef struct GenericNetlinkFamily { sd_netlink *genl; const NLAPolicySet *policy_set; + bool policy_set_indexed_by_command; uint16_t id; /* a.k.a nlmsg_type */ char *name; @@ -87,6 +88,7 @@ static int genl_family_new_unsupported( *f = (GenericNetlinkFamily) { .policy_set = policy_set, + .policy_set_indexed_by_command = genl_family_is_indexed_by_command(family_name), }; f->name = strdup(family_name); @@ -126,6 +128,7 @@ static int genl_family_new( *f = (GenericNetlinkFamily) { .policy_set = policy_set, + .policy_set_indexed_by_command = genl_family_is_indexed_by_command(expected_family_name), }; r = sd_genl_message_get_family_name(nl, message, &family_name); @@ -227,6 +230,12 @@ static const NLAPolicySet *genl_family_get_policy_set(const GenericNetlinkFamily return genl_get_policy_set_by_name(family->name); } +static size_t genl_family_get_header_size(const GenericNetlinkFamily *family) { + assert(family); + + return sizeof(struct genlmsghdr) + family->additional_header_size; +} + static int genl_message_new( sd_netlink *nl, const GenericNetlinkFamily *family, @@ -246,8 +255,14 @@ static int genl_message_new( if (!policy_set) return -EOPNOTSUPP; + if (family->policy_set_indexed_by_command) { + policy_set = policy_set_get_policy_set(policy_set, cmd); + if (!policy_set) + return -EOPNOTSUPP; + } + r = message_new_full(nl, family->id, NLM_F_REQUEST | NLM_F_ACK, policy_set, - sizeof(struct genlmsghdr) + family->additional_header_size, &m); + genl_family_get_header_size(family), &m); if (r < 0) return r; @@ -364,6 +379,12 @@ int genl_get_policy_set_and_header_size( if (r < 0) return r; + /* For families whose policy sets are indexed by command, the kernel to userspace commands are + * numbered separately from the userspace to kernel commands and the two overlap. Parsing replies + * and notifications of such families is not supported yet. */ + if (f->policy_set_indexed_by_command) + return -EOPNOTSUPP; + if (ret_policy_set) { const NLAPolicySet *p; @@ -374,7 +395,7 @@ int genl_get_policy_set_and_header_size( *ret_policy_set = p; } if (ret_header_size) - *ret_header_size = sizeof(struct genlmsghdr) + f->additional_header_size; + *ret_header_size = genl_family_get_header_size(f); return 0; } @@ -417,9 +438,9 @@ int sd_genl_message_get_family_name(sd_netlink *nl, sd_netlink_message *m, const } int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t *ret) { + const GenericNetlinkFamily *family; struct genlmsghdr *h; uint16_t nlmsg_type; - size_t size; int r; assert_return(nl, -EINVAL); @@ -433,11 +454,11 @@ int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t * if (r < 0) return r; - r = genl_get_policy_set_and_header_size(nl, nlmsg_type, NULL, &size); + r = genl_family_get_by_id(nl, nlmsg_type, &family); if (r < 0) return r; - if (m->hdr->nlmsg_len < NLMSG_LENGTH(size)) + if (m->hdr->nlmsg_len < NLMSG_LENGTH(genl_family_get_header_size(family))) return -EBADMSG; h = NLMSG_DATA(m->hdr); diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index e97d9012235..84eed0b1455 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include #include #include @@ -14,6 +15,7 @@ #include "missing-network.h" #include "netlink-genl.h" #include "netlink-types-internal.h" +#include "string-util.h" /***************** genl ctrl type systems *****************/ static const NLAPolicy genl_ctrl_mcast_group_policies[] = { @@ -109,6 +111,74 @@ static const NLAPolicy genl_batadv_policies[] = { [BATADV_ATTR_THROUGHPUT_OVERRIDE] = BUILD_POLICY(U32), }; +/***************** genl ethtool type systems *****************/ +static const NLAPolicy genl_ethtool_header_policies[] = { + [ETHTOOL_A_HEADER_DEV_INDEX] = BUILD_POLICY(U32), + [ETHTOOL_A_HEADER_DEV_NAME] = BUILD_POLICY_WITH_SIZE(STRING, ALTIFNAMSIZ - 1), + [ETHTOOL_A_HEADER_FLAGS] = BUILD_POLICY(U32), + [ETHTOOL_A_HEADER_PHY_INDEX] = BUILD_POLICY(U32), +}; + +DEFINE_POLICY_SET(genl_ethtool_header); + +static const NLAPolicy genl_ethtool_irq_moderation_policies[] = { + [ETHTOOL_A_IRQ_MODERATION_USEC] = BUILD_POLICY(U32), + [ETHTOOL_A_IRQ_MODERATION_PKTS] = BUILD_POLICY(U32), + [ETHTOOL_A_IRQ_MODERATION_COMPS] = BUILD_POLICY(U32), +}; + +DEFINE_POLICY_SET(genl_ethtool_irq_moderation); + +static const NLAPolicy genl_ethtool_profile_policies[] = { + [ETHTOOL_A_PROFILE_IRQ_MODERATION] = BUILD_POLICY_NESTED(genl_ethtool_irq_moderation), +}; + +DEFINE_POLICY_SET(genl_ethtool_profile); + +static const NLAPolicy genl_ethtool_coalesce_policies[] = { + [ETHTOOL_A_COALESCE_HEADER] = BUILD_POLICY_NESTED(genl_ethtool_header), + [ETHTOOL_A_COALESCE_RX_USECS] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_USECS_IRQ] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_USECS] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_USECS_IRQ] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_STATS_BLOCK_USECS] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX] = BUILD_POLICY(U8), + [ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX] = BUILD_POLICY(U8), + [ETHTOOL_A_COALESCE_PKT_RATE_LOW] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_USECS_LOW] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_USECS_LOW] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_PKT_RATE_HIGH] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_USECS_HIGH] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_USECS_HIGH] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_USE_CQE_MODE_TX] = BUILD_POLICY(U8), + [ETHTOOL_A_COALESCE_USE_CQE_MODE_RX] = BUILD_POLICY(U8), + [ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_PROFILE] = BUILD_POLICY_NESTED(genl_ethtool_profile), + [ETHTOOL_A_COALESCE_TX_PROFILE] = BUILD_POLICY_NESTED(genl_ethtool_profile), + [ETHTOOL_A_COALESCE_RX_CQE_FRAMES] = BUILD_POLICY(U32), + [ETHTOOL_A_COALESCE_RX_CQE_NSECS] = BUILD_POLICY(U32), +}; + +DEFINE_POLICY_SET(genl_ethtool_coalesce); + +/* Unlike the other families, the attributes of ethtool depend on the command. Hence, the policy set of + * ethtool is indexed by the (userspace to kernel) command, and each entry refers to the policy set of the + * attributes for that command. See genl_family_is_indexed_by_command(). */ +static const NLAPolicy genl_ethtool_policies[] = { + [ETHTOOL_MSG_COALESCE_SET] = BUILD_POLICY_NESTED(genl_ethtool_coalesce), +}; + /***************** genl fou type systems *****************/ static const NLAPolicy genl_fou_policies[] = { [FOU_ATTR_PORT] = BUILD_POLICY(U16), @@ -236,6 +306,7 @@ static const NLAPolicy genl_wireguard_policies[] = { static const NLAPolicySetUnionElement genl_policy_set_union_elements[] = { BUILD_UNION_ELEMENT_BY_STRING(CTRL_GENL_NAME, genl_ctrl), BUILD_UNION_ELEMENT_BY_STRING(BATADV_NL_NAME, genl_batadv), + BUILD_UNION_ELEMENT_BY_STRING(ETHTOOL_GENL_NAME, genl_ethtool), BUILD_UNION_ELEMENT_BY_STRING(FOU_GENL_NAME, genl_fou), BUILD_UNION_ELEMENT_BY_STRING(L2TP_GENL_NAME, genl_l2tp), BUILD_UNION_ELEMENT_BY_STRING(MACSEC_GENL_NAME, genl_macsec), @@ -250,3 +321,7 @@ DEFINE_POLICY_SET_UNION(genl, 0); const NLAPolicySet *genl_get_policy_set_by_name(const char *name) { return policy_set_union_get_policy_set_by_string(&genl_policy_set_union, name); } + +bool genl_family_is_indexed_by_command(const char *name) { + return streq(name, ETHTOOL_GENL_NAME); +} diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 8682a9b8b98..21b70a187dd 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -37,6 +37,7 @@ const NLAPolicy *rtnl_get_policy(uint16_t nlmsg_type); const NLAPolicy *nfnl_get_policy(uint16_t nlmsg_type); const NLAPolicy *sdnl_get_policy(uint16_t nlmsg_type, uint16_t nlmsg_flags); const NLAPolicySet *genl_get_policy_set_by_name(const char *name); +bool genl_family_is_indexed_by_command(const char *name); int genl_get_policy_set_and_header_size( sd_netlink *nl, uint16_t id, diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index e0154b7ef77..0bc183a7a29 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include #include #include #include @@ -604,6 +605,56 @@ TEST(genl) { } } +TEST(genl_ethtool) { + _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; + const struct nlmsgerr *ack; + const char *name; + uint8_t cmd; + int r; + + ASSERT_OK(sd_genl_socket_open(&genl)); + + r = sd_genl_message_new(genl, ETHTOOL_GENL_NAME, ETHTOOL_MSG_COALESCE_SET, &m); + if (r == -EOPNOTSUPP) + return (void) log_tests_skipped("ethtool netlink is not supported"); + ASSERT_OK(r); + + ASSERT_OK(sd_netlink_message_open_container(m, ETHTOOL_A_COALESCE_HEADER)); + ASSERT_OK(sd_netlink_message_append_u32(m, ETHTOOL_A_HEADER_DEV_INDEX, LOOPBACK_IFINDEX)); + ASSERT_OK(sd_netlink_message_close_container(m)); + ASSERT_OK(sd_netlink_message_append_u32(m, ETHTOOL_A_COALESCE_RX_CQE_FRAMES, 8)); + ASSERT_OK(sd_netlink_message_append_u32(m, ETHTOOL_A_COALESCE_RX_CQE_NSECS, 1000)); + /* Check that the policy set for the command is used. */ + ASSERT_ERROR(sd_netlink_message_append_u8(m, ETHTOOL_A_COALESCE_RX_CQE_FRAMES, 1), EINVAL); + ASSERT_ERROR(sd_netlink_message_append_u32(m, ETHTOOL_A_COALESCE_MAX + 1, 1), EOPNOTSUPP); + ASSERT_OK(sd_genl_message_get_family_name(genl, m, &name)); + ASSERT_STREQ(name, ETHTOOL_GENL_NAME); + ASSERT_OK(sd_genl_message_get_command(genl, m, &cmd)); + ASSERT_EQ(cmd, (uint8_t) ETHTOOL_MSG_COALESCE_SET); + ASSERT_NULL(m = sd_netlink_message_unref(m)); + + /* Commands without policy set are refused. */ + ASSERT_ERROR(sd_genl_message_new(genl, ETHTOOL_GENL_NAME, ETHTOOL_MSG_RINGS_SET, &m), EOPNOTSUPP); + + /* Replies are not supported yet, and must be dropped without breaking the socket. As the header + * attribute of ETHTOOL_MSG_LINKSTATE_GET is the same as the one of ETHTOOL_MSG_COALESCE_SET, let's + * build the request by rewriting the command, which does not require any privileges. The kernel + * sends ETHTOOL_MSG_LINKSTATE_GET_REPLY, which must be dropped, followed by the ACK. */ + ASSERT_OK(sd_genl_message_new(genl, ETHTOOL_GENL_NAME, ETHTOOL_MSG_COALESCE_SET, &m)); + ASSERT_OK(sd_netlink_message_open_container(m, ETHTOOL_A_LINKSTATE_HEADER)); + ASSERT_OK(sd_netlink_message_append_u32(m, ETHTOOL_A_HEADER_DEV_INDEX, LOOPBACK_IFINDEX)); + ASSERT_OK(sd_netlink_message_close_container(m)); + ((struct genlmsghdr*) NLMSG_DATA(m->hdr))->cmd = ETHTOOL_MSG_LINKSTATE_GET; + ASSERT_OK(sd_netlink_call(genl, m, /* timeout= */ 0, &reply)); + ASSERT_TRUE(sd_netlink_message_is_error(reply)); + ASSERT_OK_ZERO(sd_netlink_message_get_errno(reply)); + /* The ACK echoes the header of the request it acknowledges. */ + ack = NLMSG_DATA(reply->hdr); + ASSERT_EQ(ack->msg.nlmsg_type, m->hdr->nlmsg_type); + ASSERT_EQ(ack->msg.nlmsg_seq, m->hdr->nlmsg_seq); +} + static void remove_dummy_interfacep(int *ifindex) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; From bee24ebb57181f75add0047f5cf4c3c660807f6a Mon Sep 17 00:00:00 2001 From: Dimitri Daskalakis Date: Thu, 1 Oct 2026 17:43:46 -0700 Subject: [PATCH 3/3] udev/net: add settings for Rx CQE coalescing This adds RxMaxCoalescedCQEFrames= and RxCoalesceCQENSec= settings, which configure ETHTOOL_A_COALESCE_RX_CQE_FRAMES and ETHTOOL_A_COALESCE_RX_CQE_NSECS respectively. These are not supported by the ethtool ioctl interface, hence they are configured through the ethtool genl family. The other coalesce settings are still configured through the ioctl interface, to keep the change minimal and to not affect systems running older kernels. Both paths are applied independently, so a failure in one does not prevent the other. --- man/systemd.link.xml | 21 ++++++++ src/shared/ethtool-util.c | 77 ++++++++++++++++++++++++++-- src/shared/ethtool-util.h | 6 +++ src/udev/net/link-config-gperf.gperf | 2 + src/udev/net/link-config.c | 11 +++- 5 files changed, 110 insertions(+), 7 deletions(-) diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 5f5930adf50..df352b0a427 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -1376,6 +1376,27 @@ + + RxMaxCoalescedCQEFrames= + + Configures the maximum number of received frames that can be + coalesced into a single Completion Queue Entry (CQE) or descriptor writeback. An unsigned integer + in the range 0…4294967295. When unset, the kernel's default will be used. + + + + + + RxCoalesceCQENSec= + + Takes a timespan. If no unit is specified, the value is parsed as nanoseconds. The value + must not exceed 4294967295 ns (about 4.29 seconds). This configures the maximum time a + coalesced CQE or writeback can be delayed after the first packet arrives. If unset, the + kernel's default will be used. + + + + MDI= diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c index 44e9c49e817..bdb2b9668f7 100644 --- a/src/shared/ethtool-util.c +++ b/src/shared/ethtool-util.c @@ -1,10 +1,13 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include #include #include +#include "sd-netlink.h" + #include "alloc-util.h" #include "conf-parser.h" #include "errno-util.h" @@ -1000,6 +1003,69 @@ int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const return RET_NERRNO(ioctl(*ethtool_fd, SIOCETHTOOL, &ifr)); } +int ethtool_set_nic_cqe_coalesce_settings( + sd_netlink **genl, + int ifindex, + const netdev_coalesce_param *coalesce) { + + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + int r; + + assert(genl); + assert(ifindex > 0); + assert(coalesce); + + /* The settings below are not supported by the ioctl interface. The kernel merges the + * passed attributes with the current settings, so we do not need to fill in + * all the attributes in the set request. */ + + if (!coalesce->rx_cqe_frames.set && !coalesce->rx_cqe_nsecs.set) + return 0; + + if (!*genl) { + r = sd_genl_socket_open(genl); + if (r < 0) + return r; + } + + r = sd_genl_message_new(*genl, ETHTOOL_GENL_NAME, ETHTOOL_MSG_COALESCE_SET, &m); + if (r < 0) + return r; + + r = sd_netlink_message_open_container(m, ETHTOOL_A_COALESCE_HEADER); + if (r < 0) + return r; + + r = sd_netlink_message_append_u32(m, ETHTOOL_A_HEADER_DEV_INDEX, ifindex); + if (r < 0) + return r; + + /* ETHTOOL_MSG_COALESCE_SET does not send a reply, but make sure we only ever get the ACK. */ + r = sd_netlink_message_append_u32(m, ETHTOOL_A_HEADER_FLAGS, ETHTOOL_FLAG_OMIT_REPLY); + if (r < 0) + return r; + + r = sd_netlink_message_close_container(m); + if (r < 0) + return r; + + if (coalesce->rx_cqe_frames.set) { + r = sd_netlink_message_append_u32(m, ETHTOOL_A_COALESCE_RX_CQE_FRAMES, + coalesce->rx_cqe_frames.value); + if (r < 0) + return r; + } + + if (coalesce->rx_cqe_nsecs.set) { + r = sd_netlink_message_append_u32(m, ETHTOOL_A_COALESCE_RX_CQE_NSECS, + coalesce->rx_cqe_nsecs.value); + if (r < 0) + return r; + } + + return sd_netlink_call(*genl, m, /* timeout= */ 0, /* ret= */ NULL); +} + int ethtool_set_eee_settings( int *ethtool_fd, const char *ifname, @@ -1313,7 +1379,8 @@ int config_parse_coalesce_sec( void *data, void *userdata) { u32_opt *dst = data; - usec_t usec; + bool nsec = ltype; + uint64_t t; int r; if (isempty(rvalue)) { @@ -1322,26 +1389,26 @@ int config_parse_coalesce_sec( return 0; } - r = parse_sec(rvalue, &usec); + r = nsec ? parse_nsec(rvalue, &t) : parse_sec(rvalue, &t); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse coalesce setting value, ignoring: %s", rvalue); return 0; } - if (usec > UINT32_MAX) { + if (t > UINT32_MAX) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Too large %s= value, ignoring: %s", lvalue, rvalue); return 0; } - if (STR_IN_SET(lvalue, "StatisticsBlockCoalesceSec", "CoalescePacketRateSampleIntervalSec") && usec < 1) { + if (STR_IN_SET(lvalue, "StatisticsBlockCoalesceSec", "CoalescePacketRateSampleIntervalSec") && t < 1) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s= value, ignoring: %s", lvalue, rvalue); return 0; } - dst->value = (uint32_t) usec; + dst->value = (uint32_t) t; dst->set = true; return 0; diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h index 0c8cf85c132..7209c2af25f 100644 --- a/src/shared/ethtool-util.h +++ b/src/shared/ethtool-util.h @@ -142,6 +142,8 @@ typedef struct netdev_coalesce_param { u32_opt tx_coalesce_usecs_high; u32_opt tx_max_coalesced_frames_high; u32_opt rate_sample_interval; + u32_opt rx_cqe_frames; + u32_opt rx_cqe_nsecs; } netdev_coalesce_param; int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret); @@ -164,6 +166,10 @@ int ethtool_set_link_settings( int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels); int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg); int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce); +int ethtool_set_nic_cqe_coalesce_settings( + sd_netlink **genl, + int ifindex, + const netdev_coalesce_param *coalesce); int ethtool_set_eee_settings( int *ethtool_fd, const char *ifname, diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf index 535c9e9dbb7..4af27166e18 100644 --- a/src/udev/net/link-config-gperf.gperf +++ b/src/udev/net/link-config-gperf.gperf @@ -131,6 +131,8 @@ Link.RxMaxCoalescedHighFrames, config_parse_coalesce_u32, Link.TxCoalesceHighSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high) Link.TxMaxCoalescedHighFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high) Link.CoalescePacketRateSampleIntervalSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rate_sample_interval) +Link.RxCoalesceCQENSec, config_parse_coalesce_sec, /* nsec= */ true, offsetof(LinkConfig, coalesce.rx_cqe_nsecs) +Link.RxMaxCoalescedCQEFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_cqe_frames) /* Rx RPS CPU mask */ Link.ReceivePacketSteeringCPUMask, config_parse_rps_cpu_mask, 0, offsetof(LinkConfig, rps_cpu_mask) /* IRQ affinity settings */ diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index ec50a155acd..9354a44850e 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -58,6 +58,7 @@ static const Specifier link_specifier_table[] = { struct LinkConfigContext { LIST_HEAD(LinkConfig, configs); int ethtool_fd; + sd_netlink *genl; Hashmap *stats_by_path; }; @@ -106,6 +107,7 @@ LinkConfigContext *link_config_ctx_free(LinkConfigContext *ctx) { return NULL; safe_close(ctx->ethtool_fd); + sd_netlink_unref(ctx->genl); link_configs_free(ctx); return mfree(ctx); } @@ -488,13 +490,14 @@ int link_get_config(LinkConfigContext *ctx, Link *link) { return -ENOENT; } -static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) { +static int link_apply_ethtool_settings(Link *link, int *ethtool_fd, sd_netlink **genl) { LinkConfig *config = ASSERT_PTR(ASSERT_PTR(link)->config); const char *name = ASSERT_PTR(link->ifname); int r; assert(link->event); assert(ethtool_fd); + assert(genl); if (link->event->event_mode != EVENT_UDEV_WORKER) { log_link_debug(link, "Running in test mode, skipping application of ethtool settings."); @@ -558,6 +561,10 @@ static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) { if (r < 0) log_link_warning_errno(link, r, "Could not set coalesce settings, ignoring: %m"); + r = ethtool_set_nic_cqe_coalesce_settings(genl, link->ifindex, &config->coalesce); + if (r < 0) + log_link_warning_errno(link, r, "Could not set CQE coalesce settings, ignoring: %m"); + r = ethtool_set_eee_settings(ethtool_fd, name, config->eee_enabled, config->eee_tx_lpi_enabled, config->eee_tx_lpi_timer_usec, config->eee_advertise[0]); if (r < 0) log_link_warning_errno(link, r, "Could not set energy efficient ethernet settings, ignoring: %m"); @@ -1769,7 +1776,7 @@ int link_apply_config(LinkConfigContext *ctx, Link *link) { assert(ctx); assert(link); - r = link_apply_ethtool_settings(link, &ctx->ethtool_fd); + r = link_apply_ethtool_settings(link, &ctx->ethtool_fd, &ctx->genl); if (r < 0) return r;