leds: triggers: netdev: add a check, whether device is up

Message ID 20231104125840.27914-1-klaus.kudielka@gmail.com
State New
Headers
Series leds: triggers: netdev: add a check, whether device is up |

Commit Message

Klaus Kudielka Nov. 4, 2023, 12:58 p.m. UTC
  Some net devices do not report NO-CARRIER, if they haven't been brought
up. In that case, the netdev trigger results in a wrong link state being
displayed. Fix this, by adding a check, whether the device is up.

Signed-off-by: Klaus Kudielka <klaus.kudielka@gmail.com>
---
 drivers/leds/trigger/ledtrig-netdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
  

Comments

Andrew Lunn Nov. 4, 2023, 2:29 p.m. UTC | #1
On Sat, Nov 04, 2023 at 01:58:40PM +0100, Klaus Kudielka wrote:
> Some net devices do not report NO-CARRIER, if they haven't been brought
> up.

Hi Klaus

We should probably fix the driver. What device is it?

> In that case, the netdev trigger results in a wrong link state being
> displayed. Fix this, by adding a check, whether the device is up.

Is it wrong? Maybe the carrier really is up, even if the interface is
admin down. Broadcast packets are being received by the
hardware. Maybe there is a BMC sharing the link and it is active?

It is not a clear cut wrong to me. And its a way to find broken
drivers. We might want to discuss this some more.

	Andrew
  
Klaus Kudielka Nov. 4, 2023, 3:27 p.m. UTC | #2
On Sat, 2023-11-04 at 15:29 +0100, Andrew Lunn wrote:
> On Sat, Nov 04, 2023 at 01:58:40PM +0100, Klaus Kudielka wrote:
> > Some net devices do not report NO-CARRIER, if they haven't been brought
> > up.
> 
> Hi Klaus
> 
> We should probably fix the driver. What device is it?
> 
> > In that case, the netdev trigger results in a wrong link state being
> > displayed. Fix this, by adding a check, whether the device is up.
> 
> Is it wrong? Maybe the carrier really is up, even if the interface is
> admin down. Broadcast packets are being received by the
> hardware. Maybe there is a BMC sharing the link and it is active?

My particular example is Turris Omnia, eth2 (WAN), connected to SFP.
SFP module is inserted, but no fiber connected, so definitely no carrier. 

*Without* the patch:

After booting, the device is down, but netdev trigger reports "link" active.
This looks wrong to me.

I can then "ip link set eth2 up", and the "link" goes away - as I
would have expected it to be from the beginning.

> It is not a clear cut wrong to me. And its a way to find broken
> drivers. We might want to discuss this some more.

Maybe an initialization issue.
Just a guess, I'm really not an expert here:

phylink_start() is the first one that does netif_carrier_off() and thus
sets the NOCARRIER bit, but that only happens when bringing the device up.

Before that, I would not know who cares about setting the NOCARRIER bit.


Anyway, it's only a cosmetic issue, but it has been bugging me for too
long :)


Best regards, Klaus
  
Klaus Kudielka Nov. 4, 2023, 4:32 p.m. UTC | #3
On Sat, 2023-11-04 at 16:27 +0100, Klaus Kudielka wrote:
> 
> phylink_start() is the first one that does netif_carrier_off() and thus
> sets the NOCARRIER bit, but that only happens when bringing the device up.
> 
> Before that, I would not know who cares about setting the NOCARRIER bit.

A different, driver-specific solution could be like this (tested and working):

--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5690,6 +5690,7 @@ static int mvneta_probe(struct platform_device *pdev)
        /* 9676 == 9700 - 20 and rounding to 8 */
        dev->max_mtu = 9676;
 
+       netif_carrier_off(dev);
        err = register_netdev(dev);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to register\n");


Would that be the "correct" approach?

Regards, Klaus
  

Patch

diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index e358e77e4b..bd5e21d0f0 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -195,7 +195,8 @@  static void get_device_state(struct led_netdev_data *trigger_data)
 {
 	struct ethtool_link_ksettings cmd;
 
-	trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
+	trigger_data->carrier_link_up = netif_running(trigger_data->net_dev) &&
+		netif_carrier_ok(trigger_data->net_dev);
 	if (!trigger_data->carrier_link_up)
 		return;