// 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
 * tx_err -  LED blinks on transmit error
 * rx_err -  LED blinks on receive error
 *
 * 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) ||
		    test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) ||
		    test_bit(TRIGGER_NETDEV_RX_ERR, &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:
	case TRIGGER_NETDEV_TX_ERR:
	case TRIGGER_NETDEV_RX_ERR:
		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:
	case TRIGGER_NETDEV_TX_ERR:
	case TRIGGER_NETDEV_RX_ERR:
		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);
DEFINE_NETDEV_TRIGGER(tx_err, TRIGGER_NETDEV_TX_ERR);
DEFINE_NETDEV_TRIGGER(rx_err, TRIGGER_NETDEV_RX_ERR);

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_rx_err.attr,
	&dev_attr_tx_err.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:
		trigger_data->hw_control = can_hw_control(trigger_data);
		fallthrough;
	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) &&
	    !test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) &&
	    !test_bit(TRIGGER_NETDEV_RX_ERR, &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) +
	    (test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) ?
		dev_stats->tx_errors : 0) +
	    (test_bit(TRIGGER_NETDEV_RX_ERR, &trigger_data->mode) ?
		dev_stats->rx_errors : 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);

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