Hi,
I have a Compex WPJ419 board (https://compex.com.sg/shop/embedded-board/802-11ac/wpj419/) for which I can't seem to configure the LED behaviour of its two built-in wired Ethernet interfaces, despite doing low-level MDIO commands directly to the switch chip, and I can't figure out why?
The board has only two physical ethernet interfaces and only one link status LED for each interface. If I plug any of the interfaces into a Gigabit peer, then the link status LED for the interface lights up solidly and blinks whenever traffic passes over the interface. This is exactly what I want. However, when I connect to a 100Mbps peer, then the LED stays solidly off even while traffic passes. I would like it to also light up and blink when connected at 100MBps like it does at 1Gbps, but can't seem to achieve this behaviour.
The vendor firmware the board ships with drives the LEDs the way I want (so it is possible!), but this firmware is based on the old Qualcomm SDK firmware derived from Chaos Chalmer, and I want to use a more recent OpenWRT build. Sidenote: With the vendor firmware, the LAN link indicator LEDs only light up quite late in the boot process at the same time as the SSDK utility outputs some log messages to the console. I've futzed around with the proprietary-looking ssdk_sh utility, but not yet managed to figure out if/how it configures LED behaviour for the interfaces.
== Hardware details ==
The Compex WPJ419 board uses a Qualcomm IPQ4019 SoC. I've de-lidded the SoC and traced the LAN indicator LEDs (labelled DS10 and DS11 on the silkscreen and confirmed as such in the rather limited hardware guide at https://compex.com.sg/wp-content/uploads/2020/04/wpj419-7a04-hwg-sl-135.pdf) to pins on a QCA8075 switch chip. Using the QCA8075 switch chip's datasheet at https://github.com/Deoptim/atheros/blob/master/QCA8075-device-specs.pdf, the physical pins that I've traced correspond to pins named LED_100_1 and LED_100_2, which looks good. There is continuity with almost zero resistance from the switch pins to the ~330 ohm resistor connected to each LED, and the LEDs look to be driven active-low (ie: the positive side of LED seems connected directly to 3.3V, and the negative side connects through a resistor to the switch pin. When the LED is off I measure 2.7V at the switch pin, and 0V when it is on).
So it looks to me that the LEDs get directly driven by this switch chip, and that I should be able to configure this chip directly to change the behaviour right?
Some reading of Ethernet MDIO and SMI ensued, as well as eyeballing of the switch programming reference at https://github.com/Deoptim/atheros/blob/master/QCA8075-programming-ref.pdf; but none of my MDIO commands have changed the LED behaviour in any way, even though the configs are accepted by the switch chip.
== Software details ==
I am using OpenWRT v22.0.3.7 as this appears to be the most recent version that supports the WPJ419 as a target. I am compiling from source on a clean Ubuntu 24.04.01 LTS server inside virtualbox.
I have git cloned standard OpenWRT then done a git checkout 22.03
The first line of git log --oneline is:
4e1d1b7df0 (HEAD, origin/openwrt-22.03) OpenWrt v22.03.7: revert to branch defaults
Inside make menuconfig, I have made the following changes from defaults:
Target System -> Qualcomm Atheros IPQ40xx
Target Profile -> Compex WPJ419
To speak MDIO to the switch chip, I have included as built-ins the following packages:
Kernel Modules/Network Devices/kmod-mdio-gpio and kmod-libphy
Kernel Modules/Network Support/kmod-mdio-netlink
Utilities/mdio-tools
root@OpenWrt:/# uname -a
Linux OpenWrt 5.10.221 #0 SMP Mon Jul 22 22:56:41 2024 armv7l GNU/Linux
root@OpenWrt:/# cat /etc/os-release
NAME="OpenWrt"
VERSION="22.03-SNAPSHOT"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 22.03-SNAPSHOT"
VERSION_ID="22.03-snapshot"
HOME_URL="https://openwrt.org/"
BUG_URL="https://bugs.openwrt.org/"
SUPPORT_URL="https://forum.openwrt.org/"
BUILD_ID="r20343-4e1d1b7df0"
OPENWRT_BOARD="ipq40xx/generic"
OPENWRT_ARCH="arm_cortex-a7_neon-vfpv4"
OPENWRT_TAINTS="no-all"
OPENWRT_DEVICE_MANUFACTURER="OpenWrt"
OPENWRT_DEVICE_MANUFACTURER_URL="https://openwrt.org/"
OPENWRT_DEVICE_PRODUCT="Generic"
OPENWRT_DEVICE_REVISION="v0"
OPENWRT_RELEASE="OpenWrt 22.03-SNAPSHOT r20343-4e1d1b7df0"
== Debugging details ==
Trying to turn on leds via sysfs doesn't seem to do anything
root@OpenWrt:/# ls /sys/class/leds/
ath10k-phy0
root@OpenWrt:/# echo 1 > /sys/class/leds/ath10k-phy0/brightness
root@OpenWrt:/# echo "default-on" > /sys/class/leds/ath10k-phy0/trigger
root@OpenWrt:/# cat /sys/class/leds/ath10k-phy0/trigger
none switch0 90000.mdio-1:03:link 90000.mdio-1:03:1Gbps 90000.mdio-1:03:100Mbps 90000.mdio-1:03:10Mbps 90000.mdio-1:04:link 90000.mdio-1:04:1Gbps 90000.mdio-1:04:100Mbps 90000.mdio-1:04:10Mbps timer heartbeat [default-on] netdev phy0rx phy0tx phy0assoc phy0radio phy0tpt phy1rx phy1tx phy1assoc phy1radio phy1tpt phy2rx phy2tx phy2assoc phy2radio phy2tpt
mdio
Low-level MDIO seems to work as it show the two LAN interfaces as up
root@OpenWrt:/# mdio
90000.mdio-1
fixed-0
root@OpenWrt:/# mdio 90000.mdio-1
DEV PHY-ID LINK
0x00 0x004dd0b1 down
0x01 0x004dd0b1 down
0x02 0x004dd0b1 down
0x03 0x004dd0b1 up
0x04 0x004dd0b1 up
0x05 0x06820805 down
Dev 0x03 is my 100MBps connection, and eth0 (and mdio) change state when I plug and unplug this cable. No link LEDs are lit ever
Dev 0x04 is my 1GBps connection, and eth1 (and mdio) change state when I plug and unplg this cable. Its status LEDs work fine
Lets look at the low-level switch status registers with mdio ...
17.2.23 of the switch programming reference (https://github.com/Deoptim/atheros/blob/master/QCA8075-programming-ref.pdf) says the 'PHY specific status register - copper page' is at Offset: 0x11.
So lets look at PHY 0x03 ..
root@OpenWrt:/# mdio 90000.mdio-1 0x03 0x11
0x7c10 // In binary this is 0111 1100 0001 0000
Bits 15:14 are 01 which corresponds to 100Mbps in the programming ref. So we are seeing the correct link status with mdio
... and PHY 0x04 ...
root@OpenWrt:/# mdio 90000.mdio-1 0x04 0x11
0xbc5c // In binary this is 1011 1100 0101 1100
Bits 15:14 are 10 which corresponds to 1Gbps
So it seems MDIO is working, and that I can see link status. So lets look at LED behaviour ...
mdio LED config
In the programming ref I find a Global LED control register in section 17.6.21. But this is just to define blink rates, so not directly useful
17.6.22 at offset 0x8074 is the MMD 7: LED_100_n control 1 register (and a reminder that the hardware datasheet said I'm connected to LED_100_1 and LED_100_2)
17.6.22 at offset 0x8075 is the MMD 7: LED_100_n control 2 register
Accessing these higher MMD registers requires us to indirectly access them via another register as described in 3.2.3 of the programming ref.
So lets look at the current configuration of the LED_100_n control 1 at offset 0x8074 for PHYs 0x03 and 0x04:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE 0x8074
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE
0x0630
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE 0x8074
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE
0x0630
They are the same. 0x0630 is 0000 0110 0011 0000. Bit 5 sets LED_100_n to on when 100BASE-TX link is up. Bit 6 is the same for 1000BASE-T. Bit 10 blinks LED_100_n when copper Tx is active and LED_100 is on, and 9 blinks when copper Rx is active and LED_100 is on.
So already things are weird, since my understanding of this register is that with bit 5 set and my one interface up at 100Mbps, then the link LED should be lit. Instead, only the 1Gbps link led gets lit, even though it seems to be identically configured to the 100Mbps link???
Lets look at the control 2 register at 0x8075:
For PHY 0x03 we have:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE
0x0000
and PHY 4 is:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE
0x0602 // 011000000010
They are different, and that 0x0 for PHY 0x03 seems odd. But looking at the control 2 register, it seems to be about forcing LED behaviour or the 'port 4 fiber link', which doesn't apply to me (although I wonder about this 'port 4' vs device/phy 0x04).
So lets use control port 2 to force the LED on by setting bit 15 to 1 (force mode) and 14:13 to 01 (Force LED_100_n on) to 0xA000 (1010 0000 0000 0000):
First on PHY 0x3:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE 0xA000
and read back the value to confirm it was actually set:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x3 raw 0xE
0xa000
... so the 0x0000 for control port 2 has been changed to 0xa000 which I expect to force the LED on. But nothing happens.
Lets try turn off the LED on PHY 0x4 with the gigabit link by sending 0x800 (force mode enable, force LED_100_n off):
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE 0x8000
... and read it back to confirm:
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x7
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE 0x8075
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xD 0x4007
root@OpenWrt:/# mdio 90000.mdio-1 phy 0x4 raw 0xE
0x8000
... so I believe we've forced the LED off for phy0x4 regardless of link status - and yet the link stays lit for the connected 1Gbps link.
== Conclusion ==
I am confused by fact that the switch chip seems to accept my mdio config commands, but doesn't seem to actually apply them. I really thought that since the LEDs are wired directly to the switch chip, that I should be able to just configure the switch chip?! But perhaps I'm fundamentally misunderstanding something like, for example, how the lan/wan interfaces relate to PHYs and relate to 'ports' in the qualcomm docs?
I'd appreciate anyone pointing out what I'm misunderstanding or doing wrong, and/or how to configure the link LEDs!
Even ideas about what to look at next would be appreciated since I'm stuck. It seems that this MDIO interface is showing me status, but doesn't let me change configs. So perhaps there's a different interface I should be doing the configurations through, or perhaps the configurations are overriden by some other component (the MAC?), but this seems less likely since reading back the config values from the switch chip shows them not changing, or perhaps some other register I should be changing?
Thanks!
Cheers!