0
votes

What would I like to achieve?

A GPIO connected LED should be

  • ON if the interface's link is UP and
  • OFF if the link is DOWN.

Configure this logic via the device-tree.

Status-Quo : Functionality achieved with extra script

This is achievable with Kconfig's CONFIG_LEDS_TRIGGER_NETDEV=y, a DTS entry, and a small script in userspace.

leds {
        compatible = "gpio-leds";
        eth1_link {
                gpios = <&pioD 9 GPIO_ACTIVE_LOW>;
                default-state = "off";
                linux,default-trigger = "netdev";
        };
};


echo eth1 > /sys/class/leds/eth1_link/device_name
echo 1 > /sys/class/leds/eth1_link/link

Question : Isn't this already possible through the DTS?

The documentation from Documentation/devicetree/bindings/leds/common.txt, suggests that this should be already available, but I cannot find a working example, and what I have tried doesn't work so far.

* Trigger source providers

Each trigger source should be represented by a device tree node. It may be e.g.
a USB port or an Ethernet device.

I tried adding trigger-sources = <&macb1>; with no success. (macb1 because of my board's config arch/arm/boot/dts/sama5d3_emac.dtsi)

As a kernel-newbie I ask myself what the action in kernel-dev-land would be?

Is sending such question to [email protected] or [email protected] the thing to do or contact directly some maintainer?

===

UPDATE-1

I was missing a PHY node from the macb1 node. I re-tried with the phy node's phandle but didn't yet succeed. (But instead of the generic driver, the matching one is now selected.)

I will try further.

===

UPDATE-2

With the link from 0audriy I could more-or-less backtrack where the phy gets registered:

phylink_of_phy_connect
  of_phy_attach
    phy_attach_direct
      phy_led_triggers_register
        phy_led_trigger_register
          led_trigger_register

Here there are 3 ways the code try to parse out the phy node:

    phy_node = of_parse_phandle(dn, "phy-handle", 0);
    if (!phy_node)
        phy_node = of_parse_phandle(dn, "phy", 0);
    if (!phy_node)
        phy_node = of_parse_phandle(dn, "phy-device", 0);

So I added the phy-handle = <&phywan>; attribute. Still no success :/

I suppose for the micrel,ksz8081 this path is not even taken.

Maybe needs porting from PHYLIB to PHYLINK...

(Another solution which I am lamenting on, is to extend the micrel.c driver so that the link based IRQs can be turned on excusively and control the LED based on that interrupts...)

1
According to the code macb driver registers PHY and that, if device node is defined, will register the LED trigger. That said, you have to specify the name of the phy device as trigger - 0andriy
@0andriy thank you for helping! I was missing the PHY node. - lnksz
@0andriy Did you reference the code in of_mdio.c ? if (of_mdiobus_child_is_phy(child)) rc = of_mdiobus_register_phy(mdio, child, addr); I do not see, where the trigger registration is taking place... - lnksz
Thank you very much. I suppose that is only available through phylink and not phylib :/ - lnksz

1 Answers

1
votes

Finally:

A last search for 'phy' in xconfig revealed the right setting: CONFIG_LED_TRIGGER_PHY=y

With that various trigger options are added to the led:

cat /sys/class/leds/eth1_link/trigger
none fixed-0:00:link fixed-0:00:100Mbps [f802c000.ethernet-ffffffff:00:link] f802c000.ethernet-ffffffff:00:100Mbps f802c000.ethernet-ffffffff:00:10Mbps timer heartbeat gpio netdev dsa-0.0:00:link dsa-0.0:00:100Mbps dsa-0.0:00:10Mbps dsa-0.0:01:link dsa-0.0:01:100Mbps dsa-0.0:01:10Mbps

And with a device tree entry:

leds {
        compatible = "gpio-leds";
        eth1_link {
                gpios = <&pioD 9 GPIO_ACTIVE_LOW>;
                default-state = "off";
                linux,default-trigger = "f802c000.ethernet-ffffffff:00:link";
        };
};

Exactly my desired logic can be configured, without any user-space scripts. (and kernel source changes.)

It may be just my perception, but I think the "netdev" based solution was also slower. Now with ip link set down/up dev X the SW and the HW controlled LEDs doesn't have a disturbingly big delay between them.