linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Marek Behún" <marek.behun@nic.cz>
To: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Cc: "Marek Behún" <kabel@kernel.org>,
	linuxarm@huawei.com, mauro.chehab@huawei.com,
	"Pavel Machek" <pavel@ucw.cz>,
	gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
	linux-leds@vger.kernel.org
Subject: Re: [PATCH v2 16/17] leds: leds-nuc: add support for changing the ethernet type indicator
Date: Thu, 20 May 2021 13:00:14 +0200	[thread overview]
Message-ID: <20210520130014.7189a315@dellmb> (raw)
In-Reply-To: <20210519203014.1838de3a@coco.lan>

On Wed, 19 May 2021 20:30:14 +0200
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> wrote:

> Em Wed, 19 May 2021 17:55:03 +0200
> Marek Behún <kabel@kernel.org> escreveu:
> 
> > On Wed, 19 May 2021 16:24:13 +0200
> > Mauro Carvalho Chehab <mchehab+huawei@kernel.org> wrote:
> >   
> > > On other words, if no extra care is taken, it could have bad side 
> > > effects at the machine's performance and affect system's latency,
> > > eventually resulting on things like audio clicks and pops, if some
> > > audio is playing while such calls keep happening.    
> > 
> > In general we want for every LED that is registered into kernel as
> > a LED classdev to be possible to control the brightness by
> > software. If the hardware supports it, it should be available.   
> 
> This is supported, but maybe not the same way as on other drivers.
> 
> There are two separate things: ON/OFF and LED brightness, when turned
> ON.
> 
> On other words, NUC leds allow to set the brightness ranging from 0
> to 100, but if the brightness is, let's say 50%, it means that, when
> the LED is triggered by the hardware:
> 
> 	- ON would mean 50%; and 
> 	- OFF would mean 0%.

Not a problem, there are other controller which also work this way,
leds-turris-omnia for example. Also LED triggers are supposed to work
this way: if a LED supports non-binary brightness (for exmaple 0-100),
and the user sets brightness 50, and then a trigger, then the trigger
should blink the LED with brightness 50.

> On other words, it actually adjusts the maximum brightness level.
> 
> Btw, this also applies to software control, as the hardware can still
> blink the LED, the available properties for software control indicator
> are:
> 	- brightness.
> 	- blink behavior and frequency;
> 	- led color (available only if BIOS says that it is a 
> 	  multi-colored led);

- if the hw supports setting the LED to blink with a specific frequency
  (not depending on any other HW like disk or ethernet, just blinking),
  you should also implement the .blink_set method (look at
  Documentation/leds/leds-class.rst section Hardware accelerated blink
  of LEDs)
- if BIOS says the LED is multi-colored, you should register it as
  multi-colored LED via multicolor framework

> > There is a _blocking
> > .brightness_set_blocking callback for LEDs which may block when
> > setting brightness.
> > But even if we did not want to support software control, the
> > transparent trigger offloading is still relevant. See below.
> >   
> > > So, IMO, there's very little sense on trying to re-implement the
> > > already existing hardware-controlled events via software
> > > emulation.    
> > 
> > We have a misunderstanding here, probably because of my bad
> > explanation, I will try to clarify.
> >   
> > > Sorry, but I guess I missed something here. Are you meaning to use
> > > the code under "ledtrig-netdev.c" or something else? 
> > > 
> > > The code at ledtrig-netdev.c allocates a trigger data,
> > > initializes a spin lock, initializes a delayed work, registers a
> > > notifier, sets a trigger interval, etc. It is perfectly fine for
> > > software-controlled LEDs, but none of those will ever be used by
> > > the NUC driver, if it only implements HW blinking for the
> > > Ethernet interfaces (and, as said before, there's little sense
> > > emulating it via software on such devices).    
> > 
> > The idea of transparent offloading of LED triggers to HW (if HW
> > supports it) is to have a consistent and unified interface.  
> 
> Makes sense, but not sure if the current API will work.
> 
> > Currently we have a driver (leds-ns2 I think) which allows putting
> > the LED into HW controlled mode (to blink on SATA disk activity).
> > This is done by writing 1 into /sys/class/leds/<LED>/sata.
> > 
> > In your proposal you are creating several sysfs files:
> >   indicator
> >   hdd_default (notice difference from "sata" sysfs file in leds-ns2
> >                driver)
> >   ethernet_type
> > 
> > So the problem here is that this API is not unified. This is
> > different from how leds-ns2 driver does this, and both of these
> > solutions are wrong, because they are not extendable.  
> 
> Partially agreed, but I'm not so sure if the reverse is not true ;-)
> 
> I mean, the current LED API was designed and tested on drivers that
> allow direct control of the LED (and then extended to some cases
> where the hardware allows offloading).
> 
> The NUC API is just the opposite: there, the BIOS has full control of
> the hardware, but it provides an interface that allows changing
> the LED behavior, up to some extend. It also allows controlling the
> LED hardware and make it blink while it is suspended/hibernating, 
> which is something that a direct LED control wouldn't allow.

If the controller can make the LED to do a specific behaviour when the
system is suspended, please use the private LED trigger API and register
a LED private trigger (a trigger that is only available for that
specific LED) with a name like "suspend-indicator" or something.

> So, for instance, if we stick with the current LED API, there's no
> way to tell that the power LED should:
> 
> 	- blink on every 5 seconds, using up to 20% of brightness
> 	  when the system is suspended;

There is. Implement the .blink_set method.

> 	- strobe on every 10 seconds using up to 50% of brightness
> 	  when the system is hibernated;

Implement a LED private trigger.

> 	- use 100% of brigntness and don't blink when powered up.

Implement a LED private trigger.

> > The correct way to do this is via LED triggers, i.e. if I want a
> > LED to blink on network activity, then I should use netdev trigger
> > and nothing else. The netdev trigger should determine whether the
> > underlying LED driver can set the LED to blink on network activity
> > in HW. If HW supports it, netdev trigger should use this, otherwise
> > netdev trigger should blink the LED in software.  
> 
> I understand the desire of exposing the same API, but the current
> trigger code doesn't seem to be fit. I mean, the init sequence
> done at netdev_trig_activate():
> 
> 	trigger_data = kzalloc(sizeof(struct led_netdev_data),
> GFP_KERNEL); if (!trigger_data)
> 		return -ENOMEM;
> 
> 	spin_lock_init(&trigger_data->lock);
> 
> 	trigger_data->notifier.notifier_call = netdev_trig_notify;
> 	trigger_data->notifier.priority = 10;
> 
> 	INIT_DELAYED_WORK(&trigger_data->work, netdev_trig_work);
> 
> 	trigger_data->led_cdev = led_cdev;
> 	trigger_data->net_dev = NULL;
> 	trigger_data->device_name[0] = 0;
> 
> 	trigger_data->mode = 0;
> 	atomic_set(&trigger_data->interval, msecs_to_jiffies(50));
> 	trigger_data->last_activity = 0;
> 
> 	led_set_trigger_data(led_cdev, trigger_data);
> 
> 	rc = register_netdevice_notifier(&trigger_data->notifier);
> 	if (rc)
> 		kfree(trigger_data);
> 
> doesn't make sense when the LED will be trigged by the hardware,
> and registering a notifier for netdevice is overkill.
> 
> The exported attributes:
> 
> 	static struct attribute *netdev_trig_attrs[] = {
> 		&dev_attr_device_name.attr,
> 		&dev_attr_link.attr,
> 		&dev_attr_rx.attr,
> 		&dev_attr_tx.attr,
> 		&dev_attr_interval.attr,
> 		NULL
> 	};
> 	ATTRIBUTE_GROUPS(netdev_trig);
> 
> also won't apply, as the NUC API doesn't support setting device_name, 
> RX, TX, link or interval.
> 
> Instead, it allows to set:
> - the maximum brightness;
> - the color (if the LED is multi-colored);
> - the physical port(s) that will be monitored:
> 	- LAN1
> 	- LAN2
> 	- LAN1+LAN2
> 
> where LAN1 and LAN2 are two physical ports behind the NUC device.
> The netdev layer knows those as "eno1" and "enp5s0" (not 
> necessarily at the same order).

The only problem I see with trigger_data in this case is that only one
netdevice can be set, while your LED can be configured to blink on
activity on two netdevices.

Otherwise all these settings are relevant.
What your driver offload callback should do (once HW offloading of LED
triggers is merged) is this:
  - the offload method is called by the netdev trigger
  - the offload method looks at the trigger_data structure. This
    contains settings rx, tx, link, interval, device_name/device. If the
    device_name is "eno1" or "end5s0" (or better, if the device points
    to one of the 2 netdevices that are supported by the HW), and if
    the rx, tx, link and interval parameters are configured to values
    that can be done by the LED controller, than put the LED into HW
    controlled state (to blink with these parameters on network
    activity on that netdevice) and return 0
  - otherwise the offload method should return -EOPNOTSUPP, and the
    netdev trigger will know that the requested settings are not
    supported by the HW, and the netdev trigger will blink the LED in
    SW


> Also, while netdev trigger seems to use just one device name,
> the NUC allows to monitor both interfaces at the same time.

Yes. This can be solved in the future by extending netdev trigger to
support blinking on activity on multiple netdevices. I also thought
about this for use with another HW (mv88e6xxx switch).

> See, unfortunately I can't see a common API that would fit
> nicely on both cases.

Well I can.

The only problem here is that it is not supported yet. I will try to
send patches ASAP and poke Pavel to review them.

> > Currently the netdev trigger does the blinking in software only
> > (code in "ledtrig-netdev.c" file). There is a WIP to add the
> > necessary support for the netdev trigger to have the ability to
> > offload blinking to HW. I will try to respin this WIP and send
> > patches for review.
> > 
> > Once netdev trigger supports this feature, you can implement your
> > driver in this way. You can even make your driver depend on netdev
> > trigger   
> 
> > and set the specific LED into netdev triggering by default, and
> > even forbidding anything else.   
> 
> This is also probably one of the differences from other hardware:
> In principle, *any* led can monitor *any* hardware event[1].
> 
> [1] There are some bitmaps at the interface that would allow the
>     BIOS to restrict it, but, at least on the device I have
>     (Hades Canyon), there's no such restriction: the same bitmap
>     masks are returned for all LEDs.
> 
> > But this is the corrent way to do this,
> > instead of creating new sysfs API that is non-extendable.
> > 
> > I am sorry that I did not explain this thoroughly in previous mails.
> > Hopefully this explanation is better.  
> 
> Yes, it is a lot better. Thanks for the explanation!
> 
> Still, as I pointed above, I'm so far unable to see much in common 
> with the way the existing LED drivers work and the way NUC LEDS are
> controlled.
> 
> So, as much I would love to just reuse something that already exists,
> perhaps it would make more sense to create a separate class for such
> kind of usage.

The problem is that this API is not yet available in upstream kernel. I
will try to push it and return to you.

In the meantime let's see what others think about your code.

Marek

  reply	other threads:[~2021-05-20 11:21 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-18 15:08 [PATCH v2 00/17] Adding support for controlling the leds found on Intel NUC Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 01/17] docs: describe the API used to set NUC LEDs Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 02/17] leds: add support for NUC WMI LEDs Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 03/17] leds: leds-nuc: detect WMI API detection Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 04/17] leds: leds-nuc: add support for changing S0 brightness Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 05/17] leds: leds-nuc: add all types of brightness Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 06/17] leds: leds-nuc: allow changing the LED colors Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 07/17] leds: leds-nuc: add support for WMI API version 1.0 Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 08/17] leds: leds-nuc: add basic support for NUC6 WMI Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 09/17] leds: leds-nuc: add brightness and color for NUC6 API Mauro Carvalho Chehab
2021-05-18 15:08 ` [PATCH v2 10/17] leds: leds-nuc: Add support to blink behavior for NUC8/10 Mauro Carvalho Chehab
2021-05-19  7:58   ` Marek Behun
2021-05-19 10:09     ` Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 11/17] leds: leds-nuc: get rid of an unused variable Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 12/17] leds: leds-nuc: implement blink control for NUC6 Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 13/17] leds: leds-nuc: better detect NUC6/NUC7 devices Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 14/17] leds: leds-nuc: add support for HDD activity default Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 15/17] leds: leds-nuc: fix software blink behavior logic Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 16/17] leds: leds-nuc: add support for changing the ethernet type indicator Mauro Carvalho Chehab
2021-05-19  8:02   ` Marek Behún
2021-05-19 10:18     ` Mauro Carvalho Chehab
2021-05-19 12:11       ` Marek Behún
2021-05-19 14:24         ` Mauro Carvalho Chehab
2021-05-19 15:55           ` Marek Behún
2021-05-19 18:30             ` Mauro Carvalho Chehab
2021-05-20 11:00               ` Marek Behún [this message]
2021-05-20 16:00                 ` Mauro Carvalho Chehab
2021-05-20 16:36                   ` Marek Behún
2021-05-20 18:59                     ` Mauro Carvalho Chehab
2021-05-20 20:07                       ` Marek Behún
2021-05-21  9:14                         ` Mauro Carvalho Chehab
2021-05-26 14:51                           ` Pavel Machek
2021-05-28 11:33                             ` Mauro Carvalho Chehab
2021-05-26 14:47                       ` Pavel Machek
2021-05-28 11:24                         ` Mauro Carvalho Chehab
2021-05-18 15:09 ` [PATCH v2 17/17] leds: leds-nuc: add support for changing the power limit scheme Mauro Carvalho Chehab
2021-05-19 11:11 ` [PATCH v2 00/17] Adding support for controlling the leds found on Intel NUC Pavel Machek
2021-05-19 12:15   ` Mauro Carvalho Chehab
2021-05-19 19:41     ` Pavel Machek
2021-05-19 23:07       ` Mauro Carvalho Chehab
2021-05-20 16:19         ` Marek Behún
2021-05-20 19:16           ` Mauro Carvalho Chehab
2021-05-20 19:43             ` Marek Behún
2021-05-21  9:57               ` Mauro Carvalho Chehab

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=20210520130014.7189a315@dellmb \
    --to=marek.behun@nic.cz \
    --cc=gregkh@linuxfoundation.org \
    --cc=kabel@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=mauro.chehab@huawei.com \
    --cc=mchehab+huawei@kernel.org \
    --cc=pavel@ucw.cz \
    /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;
as well as URLs for NNTP newsgroup(s).