// SPDX-License-Identifier: GPL-2.0
// Copyright 2017 Ben Whitten <ben.whitten@gmail.com>
// Copyright 2007 Oliver Jowett <oliver@opencloud.com>
//
// LED Kernel Netdev Trigger
//
// Toggles the LED to reflect the link and traffic state of a named net device
//
// Derived from ledtrig-timer.c which is:
//  Copyright 2005-2006 Openedhand Ltd.
//  Author: Richard Purdie <rpurdie@openedhand.com>

#include <linux/atomic.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/linkmode.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/mutex.h>
#include <linux/phy.h>
#include <linux/rtnetlink.h>
#include <linux/timer.h>
#include "../leds.h"

#define NETDEV_LED_DEFAULT_INTERVAL	50

/*
 * Configurable sysfs attributes:
 *
 * device_name - network device name to monitor
 * interval - duration of LED blink, in milliseconds
 * link -  LED's normal state reflects whether the link is up
 *         (has carrier) or not
 * tx -  LED blinks on transmitted data
 * rx -  LED blinks on receive data
 *
 * Note: If the user selects a mode that is not supported by hw, default
 * behavior is to fall back to software control of the LED. However not every
 * hw supports software control. LED callbacks brightness_set() and
 * brightness_set_blocking() are NULL in this case. hw_control_is_supported()
 * should use available means supported by hw to inform the user that selected
 * mode isn't supported by hw. This could be switching off the LED or any
 * hw blink mode. If software control fallback isn't possible, we return
 * -EOPNOTSUPP to the user, but still store the selected mode. This is needed
 * in case an intermediate unsupported mode is necessary to switch from one
 * supported mode to another.
 */

struct led_netdev_data {
	struct mutex lock;

	struct delayed_work work;
	struct notifier_block notifier;

	struct led_classdev *led_cdev;
	struct net_device *net_dev;

	char device_name[IFNAMSIZ];
	atomic_t interval;
	unsigned int last_activity;

	unsigned long mode;
	int link_speed;
	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported_link_modes);
	u8 duplex;

	bool carrier_link_up;
	bool hw_control;
};

static const struct attribute_group netdev_trig_link_speed_attrs_group;

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;
	if (!led_cdev->blink_brightness)
		led_cdev->blink_brightness = led_cdev->max_brightness;

	if (!trigger_data->carrier_link_up) {
		led_set_brightness(led_cdev, LED_OFF);
	} else {
		bool blink_on = false;

		if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode))
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_10)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_100)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_1000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_2500)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_5000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_10000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
		    trigger_data->duplex == DUPLEX_HALF)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode) &&
		    trigger_data->duplex == DUPLEX_FULL)
			blink_on = true;

		if (blink_on)
			led_set_brightness(led_cdev,
					   led_cdev->blink_brightness);
		else
			led_set_brightness(led_cdev, LED_OFF);

		/* If we are looking for RX/TX start periodically
		 * checking stats
		 */
		if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
		    test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
			schedule_delayed_work(&trigger_data->work, 0);
	}
}

static bool supports_hw_control(struct led_classdev *led_cdev)
{
	if (!led_cdev->hw_control_get || !led_cdev->hw_control_set ||
	    !led_cdev->hw_control_is_supported)
		return false;

	return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
}

/*
 * Validate the configured netdev is the same as the one associated with
 * the LED driver in hw control.
 */
static bool validate_net_dev(struct led_classdev *led_cdev,
			     struct net_device *net_dev)
{
	struct device *dev = led_cdev->hw_control_get_device(led_cdev);
	struct net_device *ndev;

	if (!dev)
		return false;

	ndev = to_net_dev(dev);

	return ndev == net_dev;
}

static bool can_hw_control(struct led_netdev_data *trigger_data)
{
	unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
	unsigned int interval = atomic_read(&trigger_data->interval);
	struct led_classdev *led_cdev = trigger_data->led_cdev;
	int ret;

	if (!supports_hw_control(led_cdev))
		return false;

	/*
	 * Interval must be set to the default
	 * value. Any different value is rejected if in hw
	 * control.
	 */
	if (interval != default_interval)
		return false;

	/*
	 * net_dev must be set with hw control, otherwise no
	 * blinking can be happening and there is nothing to
	 * offloaded. Additionally, for hw control to be
	 * valid, the configured netdev must be the same as
	 * netdev associated to the LED.
	 */
	if (!validate_net_dev(led_cdev, trigger_data->net_dev))
		return false;

	/* Check if the requested mode is supported */
	ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode);
	/* Fall back to software blinking if not supported */
	if (ret == -EOPNOTSUPP)
		return false;
	if (ret) {
		dev_warn(led_cdev->dev,
			 "Current mode check failed with error %d\n", ret);
		return false;
	}

	return true;
}

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);

	if (__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd))
		return;

	if (trigger_data->carrier_link_up) {
		trigger_data->link_speed = cmd.base.speed;
		trigger_data->duplex = cmd.base.duplex;
	}

	/*
	 * Have a local copy of the link speed supported to avoid rtnl lock every time
	 * modes are refreshed on any change event
	 */
	linkmode_copy(trigger_data->supported_link_modes, cmd.link_modes.supported);
}

static ssize_t device_name_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
	ssize_t len;

	mutex_lock(&trigger_data->lock);
	len = sprintf(buf, "%s\n", trigger_data->device_name);
	mutex_unlock(&trigger_data->lock);

	return len;
}

static int set_device_name(struct led_netdev_data *trigger_data,
			   const char *name, size_t size)
{
	if (size >= IFNAMSIZ)
		return -EINVAL;

	cancel_delayed_work_sync(&trigger_data->work);

	/*
	 * Take RTNL lock before trigger_data lock to prevent potential
	 * deadlock with netdev notifier registration.
	 */
	rtnl_lock();
	mutex_lock(&trigger_data->lock);

	if (trigger_data->net_dev) {
		dev_put(trigger_data->net_dev);
		trigger_data->net_dev = NULL;
	}

	memcpy(trigger_data->device_name, name, size);
	trigger_data->device_name[size] = 0;
	if (size > 0 && trigger_data->device_name[size - 1] == '\n')
		trigger_data->device_name[size - 1] = 0;

	if (trigger_data->device_name[0] != 0)
		trigger_data->net_dev =
		    dev_get_by_name(&init_net, trigger_data->device_name);

	trigger_data->carrier_link_up = false;
	trigger_data->link_speed = SPEED_UNKNOWN;
	trigger_data->duplex = DUPLEX_UNKNOWN;
	if (trigger_data->net_dev)
		get_device_state(trigger_data);

	trigger_data->last_activity = 0;

	/* Skip if we're called from netdev_trig_activate() and hw_control is true */
	if (!trigger_data->hw_control || led_get_trigger_data(trigger_data->led_cdev))
		set_baseline_state(trigger_data);

	mutex_unlock(&trigger_data->lock);
	rtnl_unlock();

	return 0;
}

static ssize_t device_name_store(struct device *dev,
				 struct device_attribute *attr, const char *buf,
				 size_t size)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
	int ret;

	ret = set_device_name(trigger_data, buf, size);

	if (ret < 0)
		return ret;

	/* Refresh link_speed visibility */
	sysfs_update_group(&dev->kobj, &netdev_trig_link_speed_attrs_group);

	return size;
}

static DEVICE_ATTR_RW(device_name);

static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
				    enum led_trigger_netdev_modes attr)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
	int bit;

	switch (attr) {
	case TRIGGER_NETDEV_LINK:
	case TRIGGER_NETDEV_LINK_10:
	case TRIGGER_NETDEV_LINK_100:
	case TRIGGER_NETDEV_LINK_1000:
	case TRIGGER_NETDEV_LINK_2500:
	case TRIGGER_NETDEV_LINK_5000:
	case TRIGGER_NETDEV_LINK_10000:
	case TRIGGER_NETDEV_HALF_DUPLEX:
	case TRIGGER_NETDEV_FULL_DUPLEX:
	case TRIGGER_NETDEV_TX:
	case TRIGGER_NETDEV_RX:
		bit = attr;
		break;
	default:
		return -EINVAL;
	}

	return sprintf(buf, "%u\n", test_bit(bit, &trigger_data->mode));
}

static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
				     size_t size, enum led_trigger_netdev_modes attr)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
	struct led_classdev *led_cdev = trigger_data->led_cdev;
	unsigned long state, mode = trigger_data->mode;
	int ret;
	int bit;

	ret = kstrtoul(buf, 0, &state);
	if (ret)
		return ret;

	switch (attr) {
	case TRIGGER_NETDEV_LINK:
	case TRIGGER_NETDEV_LINK_10:
	case TRIGGER_NETDEV_LINK_100:
	case TRIGGER_NETDEV_LINK_1000:
	case TRIGGER_NETDEV_LINK_2500:
	case TRIGGER_NETDEV_LINK_5000:
	case TRIGGER_NETDEV_LINK_10000:
	case TRIGGER_NETDEV_HALF_DUPLEX:
	case TRIGGER_NETDEV_FULL_DUPLEX:
	case TRIGGER_NETDEV_TX:
	case TRIGGER_NETDEV_RX:
		bit = attr;
		break;
	default:
		return -EINVAL;
	}

	if (state)
		set_bit(bit, &mode);
	else
		clear_bit(bit, &mode);

	if (test_bit(TRIGGER_NETDEV_LINK, &mode) &&
	    (test_bit(TRIGGER_NETDEV_LINK_10, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_100, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
		return -EINVAL;

	cancel_delayed_work_sync(&trigger_data->work);

	trigger_data->mode = mode;
	trigger_data->hw_control = can_hw_control(trigger_data);

	if (!led_cdev->brightness_set && !led_cdev->brightness_set_blocking &&
	    !trigger_data->hw_control)
		return -EOPNOTSUPP;

	set_baseline_state(trigger_data);

	return size;
}

#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \
	static ssize_t trigger_name##_show(struct device *dev, \
		struct device_attribute *attr, char *buf) \
	{ \
		return netdev_led_attr_show(dev, buf, trigger); \
	} \
	static ssize_t trigger_name##_store(struct device *dev, \
		struct device_attribute *attr, const char *buf, size_t size) \
	{ \
		return netdev_led_attr_store(dev, buf, size, trigger); \
	} \
	static DEVICE_ATTR_RW(trigger_name)

DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10);
DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100);
DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);

static ssize_t interval_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);

	return sprintf(buf, "%u\n",
		       jiffies_to_msecs(atomic_read(&trigger_data->interval)));
}

static ssize_t interval_store(struct device *dev,
			      struct device_attribute *attr, const char *buf,
			      size_t size)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
	unsigned long value;
	int ret;

	if (trigger_data->hw_control)
		return -EINVAL;

	ret = kstrtoul(buf, 0, &value);
	if (ret)
		return ret;

	/* impose some basic bounds on the timer interval */
	if (value >= 5 && value <= 10000) {
		cancel_delayed_work_sync(&trigger_data->work);

		atomic_set(&trigger_data->interval, msecs_to_jiffies(value));
		set_baseline_state(trigger_data);	/* resets timer */
	}

	return size;
}

static DEVICE_ATTR_RW(interval);

static ssize_t offloaded_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);

	return sprintf(buf, "%d\n", trigger_data->hw_control);
}

static DEVICE_ATTR_RO(offloaded);

#define CHECK_LINK_MODE_ATTR(link_speed) \
	do { \
		if (attr == &dev_attr_link_##link_speed.attr && \
		    link_ksettings.base.speed == SPEED_##link_speed) \
			return attr->mode; \
	} while (0)

static umode_t netdev_trig_link_speed_visible(struct kobject *kobj,
					      struct attribute *attr, int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct led_netdev_data *trigger_data;
	unsigned long *supported_link_modes;
	u32 mode;

	trigger_data = led_trigger_get_drvdata(dev);
	supported_link_modes = trigger_data->supported_link_modes;

	/*
	 * Search in the supported link mode mask a matching supported mode.
	 * Stop at the first matching entry as we care only to check if a particular
	 * speed is supported and not the kind.
	 */
	for_each_set_bit(mode, supported_link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS) {
		struct ethtool_link_ksettings link_ksettings;

		ethtool_params_from_link_mode(&link_ksettings, mode);

		CHECK_LINK_MODE_ATTR(10);
		CHECK_LINK_MODE_ATTR(100);
		CHECK_LINK_MODE_ATTR(1000);
		CHECK_LINK_MODE_ATTR(2500);
		CHECK_LINK_MODE_ATTR(5000);
		CHECK_LINK_MODE_ATTR(10000);
	}

	return 0;
}

static struct attribute *netdev_trig_link_speed_attrs[] = {
	&dev_attr_link_10.attr,
	&dev_attr_link_100.attr,
	&dev_attr_link_1000.attr,
	&dev_attr_link_2500.attr,
	&dev_attr_link_5000.attr,
	&dev_attr_link_10000.attr,
	NULL
};

static const struct attribute_group netdev_trig_link_speed_attrs_group = {
	.attrs = netdev_trig_link_speed_attrs,
	.is_visible = netdev_trig_link_speed_visible,
};

static struct attribute *netdev_trig_attrs[] = {
	&dev_attr_device_name.attr,
	&dev_attr_link.attr,
	&dev_attr_full_duplex.attr,
	&dev_attr_half_duplex.attr,
	&dev_attr_rx.attr,
	&dev_attr_tx.attr,
	&dev_attr_interval.attr,
	&dev_attr_offloaded.attr,
	NULL
};

static const struct attribute_group netdev_trig_attrs_group = {
	.attrs = netdev_trig_attrs,
};

static const struct attribute_group *netdev_trig_groups[] = {
	&netdev_trig_attrs_group,
	&netdev_trig_link_speed_attrs_group,
	NULL,
};

static int netdev_trig_notify(struct notifier_block *nb,
			      unsigned long evt, void *dv)
{
	struct net_device *dev =
		netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv);
	struct led_netdev_data *trigger_data =
		container_of(nb, struct led_netdev_data, notifier);
	struct led_classdev *led_cdev = trigger_data->led_cdev;

	if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE
	    && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER
	    && evt != NETDEV_CHANGENAME)
		return NOTIFY_DONE;

	if (!(dev == trigger_data->net_dev ||
	      (evt == NETDEV_CHANGENAME && !strcmp(dev->name, trigger_data->device_name)) ||
	      (evt == NETDEV_REGISTER && !strcmp(dev->name, trigger_data->device_name))))
		return NOTIFY_DONE;

	cancel_delayed_work_sync(&trigger_data->work);

	mutex_lock(&trigger_data->lock);

	trigger_data->carrier_link_up = false;
	trigger_data->link_speed = SPEED_UNKNOWN;
	trigger_data->duplex = DUPLEX_UNKNOWN;
	switch (evt) {
	case NETDEV_CHANGENAME:
	case NETDEV_REGISTER:
		dev_put(trigger_data->net_dev);
		dev_hold(dev);
		trigger_data->net_dev = dev;
		if (evt == NETDEV_CHANGENAME)
			get_device_state(trigger_data);
		break;
	case NETDEV_UNREGISTER:
		dev_put(trigger_data->net_dev);
		trigger_data->net_dev = NULL;
		break;
	case NETDEV_UP:
	case NETDEV_CHANGE:
		get_device_state(trigger_data);
		/* Refresh link_speed visibility */
		if (evt == NETDEV_CHANGE)
			sysfs_update_group(&led_cdev->dev->kobj,
					   &netdev_trig_link_speed_attrs_group);
		break;
	}

	set_baseline_state(trigger_data);

	mutex_unlock(&trigger_data->lock);

	return NOTIFY_DONE;
}

/* here's the real work! */
static void netdev_trig_work(struct work_struct *work)
{
	struct led_netdev_data *trigger_data =
		container_of(work, struct led_netdev_data, work.work);
	struct rtnl_link_stats64 *dev_stats;
	unsigned int new_activity;
	struct rtnl_link_stats64 temp;
	unsigned long interval;
	int invert;

	/* If we dont have a device, insure we are off */
	if (!trigger_data->net_dev) {
		led_set_brightness(trigger_data->led_cdev, LED_OFF);
		return;
	}

	/* If we are not looking for RX/TX then return  */
	if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) &&
	    !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
		return;

	dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
	new_activity =
	    (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ?
		dev_stats->tx_packets : 0) +
	    (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ?
		dev_stats->rx_packets : 0);

	if (trigger_data->last_activity != new_activity) {
		led_stop_software_blink(trigger_data->led_cdev);

		invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
		interval = jiffies_to_msecs(
				atomic_read(&trigger_data->interval));
		/* base state is ON (link present) */
		led_blink_set_oneshot(trigger_data->led_cdev,
				      &interval,
				      &interval,
				      invert);
		trigger_data->last_activity = new_activity;
	}

	schedule_delayed_work(&trigger_data->work,
			(atomic_read(&trigger_data->interval)*2));
}

static int netdev_trig_activate(struct led_classdev *led_cdev)
{
	struct led_netdev_data *trigger_data;
	unsigned long mode = 0;
	struct device *dev;
	int rc;

	trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
	if (!trigger_data)
		return -ENOMEM;

	mutex_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(NETDEV_LED_DEFAULT_INTERVAL));
	trigger_data->last_activity = 0;

	/* Check if hw control is active by default on the LED.
	 * Init already enabled mode in hw control.
	 */
	if (supports_hw_control(led_cdev)) {
		dev = led_cdev->hw_control_get_device(led_cdev);
		if (dev) {
			const char *name = dev_name(dev);

			trigger_data->hw_control = true;
			set_device_name(trigger_data, name, strlen(name));

			rc = led_cdev->hw_control_get(led_cdev, &mode);
			if (!rc)
				trigger_data->mode = mode;
		}
	}

	led_set_trigger_data(led_cdev, trigger_data);

	rc = register_netdevice_notifier(&trigger_data->notifier);
	if (rc)
		kfree(trigger_data);

	return rc;
}

static void netdev_trig_deactivate(struct led_classdev *led_cdev)
{
	struct led_netdev_data *trigger_data = led_get_trigger_data(led_cdev);

	unregister_netdevice_notifier(&trigger_data->notifier);

	cancel_delayed_work_sync(&trigger_data->work);

	led_set_brightness(led_cdev, LED_OFF);

	dev_put(trigger_data->net_dev);

	kfree(trigger_data);
}

static struct led_trigger netdev_led_trigger = {
	.name = "netdev",
	.activate = netdev_trig_activate,
	.deactivate = netdev_trig_deactivate,
	.groups = netdev_trig_groups,
};

module_led_trigger(netdev_led_trigger);

MODULE_AUTHOR("Ben Whitten <ben.whitten@gmail.com>");
MODULE_AUTHOR("Oliver Jowett <oliver@opencloud.com>");
MODULE_DESCRIPTION("Netdev LED trigger");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("ledtrig:netdev");
