From d69f71b5613bce6faafd47291688661e5616bb8a Mon Sep 17 00:00:00 2001 From: Julien Coloos Date: Sun, 12 Jul 2026 20:20:32 +0200 Subject: [PATCH] Reduce network device speed to 10M for WoL In previous Arch/kernel versions, the network device speed was automatically set to the lowest possible upon poweroff when WoL was enabled. Latest versions do keep the network device to its standard speed (1000M for example), which consumes some useless power when computer is powered off and WoL enabled. Force speed lowering for WoL. But restore it before continuing boot, when devices are unlocked, otherwise it remains as-is. Make it an option, to select the wanted speed, or leave it as-is. --- README.md | 6 ++++++ src/hooks/ssh-cryptsetup | 12 +++++++++++- src/hooks/ssh-cryptsetup-tools | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 88ba52d..ed23c34 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ Some options can be set in `/etc/initcpio/sshcs_env` (file is sourced in initram - default: `g` (MagicPacketâ„¢) - usually WoL is disabled once in initramfs shell - set empty to not change network device WoL setting + * `sshcs_opt_net_speed`: speed to set on network device + - default: `10` + - full duplex is enabled, and auto-negociation disabled + - latest Arch/kernel tend to keep the speed at 1000M even during WoL + - this only applies to boot phase and persists for WoL: when unlocking devices, the network is reconfigured before the OS is fully ready + - set `0` to not change network device speed * `sshcs_opt_timeout_ipconfig`: time (in seconds) to configure IP - default: `10` * `sshcs_opt_listen`: SSH listening port diff --git a/src/hooks/ssh-cryptsetup b/src/hooks/ssh-cryptsetup index f5ddd84..895a760 100644 --- a/src/hooks/ssh-cryptsetup +++ b/src/hooks/ssh-cryptsetup @@ -18,6 +18,8 @@ sshcs_net_start() { return 1 } + # Note: ethtool can access WoL settings right now, but not other settings + # until the network is setup. if [ "${sshcs_opt_net_wol:-d}" != "d" ]; then log_dbg "Setting network device=${net_device} wol=${sshcs_opt_net_wol}" ethtool -s "${net_device}" wol "${sshcs_opt_net_wol}" @@ -60,7 +62,15 @@ sshcs_net_start() { log_msg "IP-Config: device=${net_device} ip=${net_address}/${net_netmask} gw=${net_gateway} dns0=${net_dns0} dns1=${net_dns1}" - [ -n "${net_address}" ] + # Ensure we have an address + [ -n "${net_address}" ] || return 1 + + # Note: We cannot change the device settings, other than WoL, before the + # network is setup. + if [ ${sshcs_opt_net_speed} != 0 ]; then + log_dbg "Setting network device=${net_device} speed=${sshcs_opt_net_speed}" + ethtool -s "${net_device}" speed "${sshcs_opt_net_speed}" duplex full autoneg off + fi } sshcs_net_done() { diff --git a/src/hooks/ssh-cryptsetup-tools b/src/hooks/ssh-cryptsetup-tools index c77f3a9..4ee346c 100644 --- a/src/hooks/ssh-cryptsetup-tools +++ b/src/hooks/ssh-cryptsetup-tools @@ -33,6 +33,7 @@ sshcs_env_load() { local log_kmsg_default=1 local debug_default=0 local net_wol_default=g + local net_speed_default=10 local timeout_ipconfig_default=10 local timeout_poweroff_min=120 local use_shell_default=0 @@ -43,6 +44,7 @@ sshcs_env_load() { [ -z "${sshcs_opt_log_kmsg}" ] && sshcs_opt_log_kmsg=${log_kmsg_default} [ -z "${sshcs_opt_debug}" ] && sshcs_opt_debug=${debug_default} [ -z "${sshcs_opt_net_wol}" ] && sshcs_opt_net_wol=${net_wol_default} + [ -z "${sshcs_opt_net_speed}" ] && sshcs_opt_net_speed=${net_speed_default} [ -z "${sshcs_opt_timeout_ipconfig}" ] && sshcs_opt_timeout_ipconfig=${timeout_ipconfig_default} [ -n "${sshcs_opt_listen}" ] && sshcs_opt_listen="-p ${sshcs_opt_listen}" [ -z "${sshcs_opt_timeout_poweroff}" ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min} @@ -104,6 +106,12 @@ sshcs_cleanup() { # Thus as long as all devices have been unlocked, we don't expect any script # to be stuck on 'cryptsetup' calls. + # If we did change the network speed, time to reset it. + if [ -n "${net_device}" ] && [ ${sshcs_opt_net_speed} != 0 ]; then + log_dbg "Restoring network device=${net_device} speed" + ethtool -s "${net_device}" autoneg on + fi + if proc_is_console; then # We are in the console. # It is time to properly end the processes we started and files we created.