lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 27 Apr 2023 02:15:38 +0200
From:   Christian Marangi <ansuelsmth@...il.com>
To:     Jonathan Corbet <corbet@....net>, Pavel Machek <pavel@....cz>,
        Lee Jones <lee@...nel.org>, Andrew Lunn <andrew@...n.ch>,
        Florian Fainelli <f.fainelli@...il.com>,
        Vladimir Oltean <olteanv@...il.com>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>,
        Christian Marangi <ansuelsmth@...il.com>,
        linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-leds@...r.kernel.org, netdev@...r.kernel.org
Subject: [PATCH 08/11] leds: trigger: netdev: add support for LED hw control

Add support for LED hw control for the netdev trigger.

The trigger on calling set_baseline_state to configure a new mode, will
do various check to verify if hw control can be used for the requested
mode in the validate_requested_mode() function.

It will first check if the LED driver supports hw control for the netdev
trigger, then will check if the requested mode are in the trigger mode
mask and finally will call hw_control_set() to apply the requested mode.

To use such mode, interval MUST be set to the default value and net_dev
MUST be empty. If one of these 2 value are not valid, hw control will
never be used and normal software fallback is used.

Signed-off-by: Christian Marangi <ansuelsmth@...il.com>
---
 drivers/leds/trigger/ledtrig-netdev.c | 52 +++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 8cd876647a27..61bc19fd0c7a 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -68,6 +68,13 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
 	int current_brightness;
 	struct led_classdev *led_cdev = trigger_data->led_cdev;
 
+	/* Already validated, hw control is possible with the requested mode */
+	if (trigger_data->hw_control) {
+		led_cdev->hw_control_set(led_cdev, trigger_data->mode);
+
+		return;
+	}
+
 	current_brightness = led_cdev->brightness;
 	if (current_brightness)
 		led_cdev->blink_brightness = current_brightness;
@@ -95,6 +102,51 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
 static int validate_requested_mode(struct led_netdev_data *trigger_data,
 				   unsigned long mode, bool *can_use_hw_control)
 {
+	unsigned int interval = atomic_read(&trigger_data->interval);
+	unsigned long hw_supported_mode, hw_mode = 0, sw_mode = 0;
+	struct led_classdev *led_cdev = trigger_data->led_cdev;
+	unsigned long default_interval = msecs_to_jiffies(50);
+	bool force_sw = false;
+	int i, ret;
+
+	hw_supported_mode = led_cdev->trigger_supported_flags_mask;
+
+	/* Check if trigger can use hw control */
+	if (!led_trigger_can_hw_control(led_cdev))
+		force_sw = true;
+
+	/* Compose a list of mode that can run in hw or sw */
+	for (i = 0; i < __TRIGGER_NETDEV_MAX; i++) {
+		/* Skip checking mode not active */
+		if (!test_bit(i, &mode))
+			continue;
+
+		/* net_dev is not supported and must be empty for hw control.
+		 * interval must be set to the default value. Any different
+		 * value is rejected if in hw control.
+		 */
+		if (interval == default_interval && !trigger_data->net_dev &&
+		    !force_sw && test_bit(i, &hw_supported_mode))
+			set_bit(i, &hw_mode);
+		else
+			set_bit(i, &sw_mode);
+	}
+
+	/* We can't run modes handled by both sw and hw */
+	if (sw_mode && hw_mode)
+		return -EINVAL;
+
+	/* Exit early if we are using software fallback */
+	if (sw_mode)
+		return 0;
+
+	/* Check if the requested mode is supported */
+	ret = led_cdev->hw_control_is_supported(led_cdev, hw_mode);
+	if (ret)
+		return ret;
+
+	*can_use_hw_control = true;
+
 	return 0;
 }
 
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ