1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-22 06:50:18 +03:00

udev/net: add support for configuring EEE feature (#36302)

Closes #36278.
This commit is contained in:
Lennart Poettering 2025-02-07 12:38:06 +01:00 committed by GitHub
commit d7ad56bcb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 173 additions and 7 deletions

View File

@ -1361,6 +1361,58 @@
</variablelist>
</refsect1>
<refsect1>
<title>[EnergyEfficientEthernet] Section Options</title>
<para>The [EnergyEfficientEthernet] section controls the Energy Efficient Ethernet (EEE) feature of the
interface, and accepts the following keys.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Enabled=</varname></term>
<listitem>
<para>Takes a boolean argument. When true, the Energy Efficient Ethernet (EEE) feature will be
enabled on the interface. Defaults to unset, and the enablement of EEE will be unchanged.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TxLowPowerIdle=</varname></term>
<listitem>
<para>Takes a boolean argument. When true, the transmit Low Power Idle (Tx-LPI) mode of the Energy
Efficient Ethernet feature will be enabled on the interface. Defaults to unset, and the enablement
of the mode will be unchanged.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TxLowPowerIdleSec=</varname></term>
<listitem>
<para>Takes a timespan. This configures how long the interface should not enter the Low Power Idle
mode after transmission. If it is too short, may decrease performance. If it is too long, may not
gain energy saving. Defaults to unset, and the timespan will be unchanged.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>LinkMode=</varname></term>
<listitem>
<para>Takes a list of link modes, e.g. <literal>1000baset-full</literal>. See the table for
<varname>Advertise=</varname> setting in [Link] section in the above for possible values. This
configures the Energy Efficient Ethernet capable connection modes to be advertised. Defaults to
unset, and the advertised modes will be unchanged.</para>
<xi:include href="version-info.xml" xpointer="v258"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Specifiers</title>

View File

@ -1123,6 +1123,62 @@ int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const
return RET_NERRNO(ioctl(*ethtool_fd, SIOCETHTOOL, &ifr));
}
int ethtool_set_eee_settings(
int *ethtool_fd,
const char *ifname,
int enabled,
int tx_lpi_enabled,
usec_t tx_lpi_timer_usec,
uint32_t advertise) {
int r;
assert(ethtool_fd);
assert(ifname);
if (enabled < 0 &&
tx_lpi_enabled < 0 &&
tx_lpi_timer_usec == USEC_INFINITY &&
advertise == 0)
return 0; /* Nothing requested. */
r = ethtool_connect(ethtool_fd);
if (r < 0)
return r;
struct ethtool_eee ecmd = {
.cmd = ETHTOOL_GEEE,
};
struct ifreq ifr = {
.ifr_data = (void*) &ecmd,
};
strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
return -errno;
if (ecmd.supported == 0)
return 0; /* Unsupported. */
bool need_update = false;
if (enabled >= 0)
UPDATE(ecmd.eee_enabled, (uint32_t) enabled, need_update);
if (tx_lpi_enabled >= 0)
UPDATE(ecmd.tx_lpi_enabled, (uint32_t) tx_lpi_enabled, need_update);
if (tx_lpi_timer_usec != USEC_INFINITY)
UPDATE(ecmd.tx_lpi_timer, (uint32_t) MIN(DIV_ROUND_UP(tx_lpi_timer_usec, USEC_PER_MSEC), (usec_t) UINT32_MAX), need_update);
if (advertise != 0)
UPDATE(ecmd.advertised, advertise & ecmd.supported, need_update);
if (!need_update)
return 0; /* Nothing changed. */
ecmd.cmd = ETHTOOL_SEEE;
return RET_NERRNO(ioctl(*ethtool_fd, SIOCETHTOOL, &ifr));
}
int config_parse_advertise(
const char *unit,
const char *filename,

View File

@ -7,6 +7,7 @@
#include "conf-parser.h"
#include "ether-addr-util.h"
#include "time-util.h"
#define N_ADVERTISE 4
@ -180,6 +181,13 @@ int ethtool_set_glinksettings(
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_eee_settings(
int *ethtool_fd,
const char *ifname,
int enabled,
int tx_lpi_enabled,
usec_t tx_lpi_timer_usec,
uint32_t advertise);
const char* duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;

View File

@ -39,9 +39,11 @@ Match.Credential, config_parse_net_condition,
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(LinkConfig, conditions)
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
/* udev property */
Link.Property, config_parse_udev_property, 0, offsetof(LinkConfig, properties)
Link.ImportProperty, config_parse_udev_property_name, 0, offsetof(LinkConfig, import_properties)
Link.UnsetProperty, config_parse_udev_property_name, 0, offsetof(LinkConfig, unset_properties)
/* rtnl setlink */
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
Link.MACAddress, config_parse_hw_addr, 0, offsetof(LinkConfig, hw_addr)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
@ -53,12 +55,19 @@ Link.TransmitQueues, config_parse_rx_tx_queues,
Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, rxqueues)
Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(LinkConfig, txqueuelen)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(LinkConfig, mtu)
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
/* ethtool link settings */
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(LinkConfig, speed)
Link.Duplex, config_parse_duplex, 0, offsetof(LinkConfig, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(LinkConfig, autonegotiation)
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
Link.MDI, config_parse_mdi, 0, offsetof(LinkConfig, mdi)
/* ethtool WoL settings */
Link.WakeOnLan, config_parse_wol, 0, offsetof(LinkConfig, wol)
Link.WakeOnLanPassword, config_parse_wol_password, 0, 0
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
/* ethtool features */
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RXCSUM])
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TXCSUM])
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
@ -76,20 +85,21 @@ Link.TransmitVLANSTAGHardwareAcceleration, config_parse_tristate,
Link.NTupleFilter, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_NTUPLE])
Link.ReceiveFCS, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RXFCS])
Link.ReceiveAll, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RXALL])
/* ethtool channels */
Link.RxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.rx)
Link.TxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.tx)
Link.OtherChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.other)
Link.CombinedChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.combined)
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
/* ethtool ring parameters */
Link.RxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx)
Link.RxMiniBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_mini)
Link.RxJumboBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_jumbo)
Link.TxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.tx)
/* ethtool pause parameters */
Link.RxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, rx_flow_control)
Link.TxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, tx_flow_control)
Link.AutoNegotiationFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, autoneg_flow_control)
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
/* ethtool coalesce settings */
Link.RxCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
Link.RxMaxCoalescedFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
Link.RxCoalesceIrqSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
@ -112,8 +122,9 @@ 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)
/* Rx RPS CPU mask */
Link.ReceivePacketSteeringCPUMask, config_parse_rps_cpu_mask, 0, offsetof(LinkConfig, rps_cpu_mask)
Link.MDI, config_parse_mdi, 0, offsetof(LinkConfig, mdi)
/* SR-IOV settings */
Link.SR-IOVVirtualFunctions, config_parse_sr_iov_num_vfs, 0, offsetof(LinkConfig, sr_iov_num_vfs)
SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, offsetof(LinkConfig, sr_iov_by_section)
SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, offsetof(LinkConfig, sr_iov_by_section)
@ -124,3 +135,8 @@ SR-IOV.QueryReceiveSideScaling, config_parse_sr_iov_boolean,
SR-IOV.Trust, config_parse_sr_iov_boolean, 0, offsetof(LinkConfig, sr_iov_by_section)
SR-IOV.LinkState, config_parse_sr_iov_link_state, 0, offsetof(LinkConfig, sr_iov_by_section)
SR-IOV.MACAddress, config_parse_sr_iov_mac, 0, offsetof(LinkConfig, sr_iov_by_section)
/* ethtool EEE settings */
EnergyEfficientEthernet.Enable, config_parse_tristate, 0, offsetof(LinkConfig, eee_enabled)
EnergyEfficientEthernet.TxLowPowerIdle, config_parse_tristate, 0, offsetof(LinkConfig, eee_tx_lpi_enabled)
EnergyEfficientEthernet.TxLowPowerIdleSec, config_parse_sec, 0, offsetof(LinkConfig, eee_tx_lpi_timer_usec)
EnergyEfficientEthernet.LinkMode, config_parse_advertise, 0, offsetof(LinkConfig, eee_advertise)

View File

@ -263,6 +263,9 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
.coalesce.use_adaptive_tx_coalesce = -1,
.mdi = ETH_TP_MDI_INVALID,
.sr_iov_num_vfs = UINT32_MAX,
.eee_enabled = -1,
.eee_tx_lpi_enabled = -1,
.eee_tx_lpi_timer_usec = USEC_INFINITY,
};
FOREACH_ELEMENT(feature, config->features)
@ -548,6 +551,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_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");
return 0;
}

View File

@ -56,9 +56,13 @@ struct LinkConfig {
LIST_HEAD(Condition, conditions);
char *description;
/* udev property */
char **properties;
char **import_properties;
char **unset_properties;
/* rtnl setlink */
struct hw_addr_data hw_addr;
MACAddressPolicy mac_address_policy;
NamePolicy *name_policy;
@ -72,24 +76,47 @@ struct LinkConfig {
uint32_t mtu;
uint32_t gso_max_segments;
size_t gso_max_size;
/* ethtool link settings */
uint64_t speed;
Duplex duplex;
int autonegotiation;
uint32_t advertise[N_ADVERTISE];
NetDevPort port;
uint8_t mdi;
/* ethtool WoL */
uint32_t wol;
char *wol_password_file;
uint8_t *wol_password;
NetDevPort port;
/* ethtool features */
int features[_NET_DEV_FEAT_MAX];
/* ethtool channels */
netdev_channels channels;
/* ethtool ring parameters */
netdev_ring_param ring;
/* ethtool pause parameters */
int rx_flow_control;
int tx_flow_control;
int autoneg_flow_control;
/* ethtool coalesce settings */
netdev_coalesce_param coalesce;
uint8_t mdi;
/* ethtool energy efficient ethernet settings */
int eee_enabled;
int eee_tx_lpi_enabled;
usec_t eee_tx_lpi_timer_usec;
uint32_t eee_advertise[N_ADVERTISE];
/* Rx RPS CPU mask */
CPUSet *rps_cpu_mask;
/* SR-IOV */
uint32_t sr_iov_num_vfs;
OrderedHashmap *sr_iov_by_section;