Ethernet LEDs control for TP-Link TL-WR1043ND v2/v3

Long story short, I had to turn off all LEDs for a TP-Link TL-WR1043ND v3 model, but encountered two issues:

  • Newer versions of OpenWrt (ath79) don't support ethernet LEDs control through MDIO.
  • Older versions of OpenWrt (ar71xx) support it, but their LED control device files are only linked to one of three possible states.

Each LED has three states linked to the interface's speed (1000, 100 and 10 mbps). Each state has a two bits value (00 = off, 01 = blink, 10 = on, 11 = hardware controlled).

Older versions of OpenWrt only manage the 1000 mbps state.
When a device connected to one of the ethernet ports shutdown its network interface or power off, the state may change. In my case, it started reading the two bits value from the 10 mbps state, defaulted at 11 (hardware controlled), with the behavior of "on" if the network interface is down but the endpoint device is powered on, and "off" if the cable is disconnected or the endpoint device is powered off.
This utility makes sure to change all three values.

Current options are as follow:
off: Turn all ethernet LEDs off.
on: Turn all ethernet LEDs on.
blink: Set all ethernet LEDs to blinking.
default: Revert all ethernet LEDs to default (hardware controlled).

The options above affect every single ethernet LED as that's what my needs required, however, you can easily add new options by using the template macros to only affect specific LED(s).

Here is an example on how to set up a LAN1 toggle (on/off) option.

LEDS_ROUTINE_BEGIN(lan1_toggle)
    /* LAN1 values are stored in CTRL 3 */
    if (CTRL_INDEX != 3)
        CTRL_SKIP;

    /* LAN1 values are stored in the higher bits */
    /* bits [4, 10) */
    CTRL_HI_VALUE &= ~0x0150; /* 0x0150: 0b0000000101010000, zero first bits */
    CTRL_HI_VALUE ^= 0x02A0;  /* 0x02A0: 0b0000001010100000, toggle second bits */
LEDS_ROUTINE_END("Toggled LAN1 LED.")

OPTIONS_BEGIN
    ... (other options)
    OPTION(lan1_toggle)
OPTIONS_END

The pre-compiled binary file was linked against uClibc for the older versions of OpenWrt, therefore, you will probably have to compile the source code in order to use it on the newer versions.

  1. opkg update
  2. opkg install gcc (this model doesn't have enough disk space to install it, you will need to install it in the RAM or in a disk connected through the USB port)
  3. gcc -std=c89 -O2 -Wall -Wextra -Wpedantic -o eth-leds eth-leds.c

Related: /sys/class/leds/tp-link:green:lan1 missing on WR1043ND

Binary and Source Code: https://mega.nz/file/JY8TFbzA#FnYDH7_RPB1wxYFYTDSwivc329k_KeYuSroGgQHV8QI