From: Huan Zhao <ms.huan.zhao@gmail.com>
To: Heiner Kallweit <hkallweit1@gmail.com>
Cc: netdev@vger.kernel.org
Subject: r8169: RTL8125B restores default LEDSEL values on Link Up, preventing persistent LED configuration
Date: Sat, 14 Mar 2026 18:46:36 -0700 [thread overview]
Message-ID: <20260315014636.30074-1-ms.huan.zhao@gmail.com> (raw)
Hardware: Beelink SER8 mini PC
NIC: Realtek RTL8125B (XID 0x641, RTL_GIGA_MAC_VER_63, rev 05)
Kernel: 6.19.6-arch1-1
Driver: r8169 (in-tree)
CONFIG_R8169_LEDS=y
CONFIG_LEDS_TRIGGER_NETDEV=m
Problem:
The RTL8125B chip restores its LEDSEL registers to hardware default values
on every Link Up event. The r8169 driver does not reapply the LED
configuration after Link Up, making it impossible to persistently configure
LEDs (e.g. disable them) through the standard kernel LED subsystem.
Details:
The Link Up path in the driver is:
r8169_phylink_handler() [r8169_main.c:4757]
-> rtl_link_chg_patch() [r8169_main.c:1597]
-> rtl_enable_tx_lpi()
-> pm_request_resume()
rtl_link_chg_patch() has no handling for RTL_GIGA_MAC_VER_63 and does not
touch the LEDSEL registers. Similarly, rtl_hw_start_8125b() and
rtl_hw_start_8125_common(), which are called on hardware initialization,
do not write to any LEDSEL register (LEDSEL0=0x18, LEDSEL1=0x86,
LEDSEL2=0x84, LEDSEL3=0x96).
The only driver code that writes LEDSEL registers is rtl8125_set_led_mode()
in r8169_leds.c, called exclusively from the LED classdev hw_control
callbacks. Therefore, any LED configuration applied via sysfs is silently
overwritten by the hardware chip's own firmware on every Link Up event,
before the driver has a chance to reapply it.
This was verified by observing that:
1. Writing 0x0000 to all LEDSEL registers (via BAR0 MMIO) before Link Up
successfully turns off all LEDs.
2. After Link Up completes, the LEDSEL registers revert to their hardware
defaults, turning the LEDs back on.
3. Writing 0x0000 to LEDSEL registers immediately after Link Up (via
NetworkManager dispatcher triggered on dhcp4-change) successfully keeps
the LEDs off persistently.
Original LEDSEL register values (hardware defaults) on this machine:
LEDSEL0 (0x18) = 0x0002 (LINK_100)
LEDSEL1 (0x86) = 0x0028 (LINK_2500 + LINK_1000)
LEDSEL2 (0x84) = 0x022b (ACT + LINK_2500 + LINK_1000 + LINK_100 + LINK_10)
LEDSEL3 (0x96) = 0x0020 (LINK_2500)
Secondary issue: CONFIG_LEDS_TRIGGER_NETDEV=m causes silent failure
On Arch Linux, CONFIG_LEDS_TRIGGER_NETDEV=m (module, not built-in).
The r8169 driver uses /* ignore errors */ when calling
led_classdev_register() in rtl8125_setup_led_ldev(). If ledtrig_netdev
is not loaded when r8169 initializes, the registration fails silently.
The result is that /sys/class/leds/enp2s0-* entries appear to exist but
are dummy stubs with no hardware control capability. Writing to their
trigger or brightness attributes has no effect on the physical LEDs.
This was verified by manually loading ledtrig_netdev before r8169, which
resulted in functional LED classdev entries. The fix was to add
ledtrig_netdev to /etc/modules-load.d/ to ensure it loads before r8169.
However, even with ledtrig_netdev loaded correctly and offloaded=1
confirmed, the LED configuration is still lost on every Link Up due to
the hardware reset described above.
Suggested fix:
In r8169_phylink_handler(), after Link Up is confirmed, reapply the
current LED configuration by notifying the LED classdevs. For example:
if (netif_carrier_ok(ndev)) {
rtl_link_chg_patch(tp);
rtl_enable_tx_lpi(tp, tp->phydev->enable_tx_lpi);
/* Reapply LED configuration after hardware resets LEDSEL on Link Up */
if (tp->leds)
led_classdev_notify_clients(tp->leds); /* or equivalent */
pm_request_resume(d);
}
The exact mechanism for reapplying the LED configuration (whether through
the LED classdev framework or by directly re-calling rtl8125_set_led_mode()
with saved values) is left to your discretion.
Thanks,
Huan Zhao
next reply other threads:[~2026-03-15 1:46 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-15 1:46 Huan Zhao [this message]
2026-03-15 9:32 ` r8169: RTL8125B restores default LEDSEL values on Link Up, preventing persistent LED configuration Heiner Kallweit
2026-03-19 2:35 ` Javen
2026-03-19 6:49 ` Heiner Kallweit
2026-03-15 13:55 ` Heiner Kallweit
2026-03-15 17:41 ` Huan Zhao
2026-03-15 18:06 ` Heiner Kallweit
2026-03-15 23:02 ` Huan Zhao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260315014636.30074-1-ms.huan.zhao@gmail.com \
--to=ms.huan.zhao@gmail.com \
--cc=hkallweit1@gmail.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox