// 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 <net/netdev_lock.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_LINK_25000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_25000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_40000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_50000)
			blink_on = true;

		if (test_bit(TRIGGER_NETDEV_LINK_100000, &trigger_data->mode) &&
		    trigger_data->link_speed == SPEED_100000)
			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 (netif_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)
{
	struct net_device *new_dev = NULL;
	char device_name[IFNAMSIZ];

	if (size >= IFNAMSIZ)
		return -EINVAL;

	cancel_delayed_work_sync(&trigger_data->work);

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

	/*
	 * Lock order: rtnl_lock -> netdev instance lock -> trigger_data lock.
	 */
	rtnl_lock();
	if (device_name[0]) {
		new_dev = dev_get_by_name(&init_net, device_name);
		if (new_dev)
			netdev_lock_ops(new_dev);
	}
	mutex_lock(&trigger_data->lock);

	dev_put(trigger_data->net_dev);
	trigger_data->net_dev = new_dev;
	strscpy(trigger_data->device_name, 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);
	if (new_dev)
		netdev_unlock_ops(new_dev);
	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_LINK_25000:
	case TRIGGER_NETDEV_LINK_40000:
	case TRIGGER_NETDEV_LINK_50000:
	case TRIGGER_NETDEV_LINK_100000:
	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_LINK_25000:
	case TRIGGER_NETDEV_LINK_40000:
	case TRIGGER_NETDEV_LINK_50000:
	case TRIGGER_NETDEV_LINK_100000:
	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) ||
	     test_bit(TRIGGER_NETDEV_LINK_25000, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_40000, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_50000, &mode) ||
	     test_bit(TRIGGER_NETDEV_LINK_100000, &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(link_25000, TRIGGER_NETDEV_LINK_25000);
DEFINE_NETDEV_TRIGGER(link_40000, TRIGGER_NETDEV_LINK_40000);
DEFINE_NETDEV_TRIGGER(link_50000, TRIGGER_NETDEV_LINK_50000);
DEFINE_NETDEV_TRIGGER(link_100000, TRIGGER_NETDEV_LINK_100000);
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);
		CHECK_LINK_MODE_ATTR(25000);
		CHECK_LINK_MODE_ATTR(40000);
		CHECK_LINK_MODE_ATTR(50000);
		CHECK_LINK_MODE_ATTR(100000);
	}

	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,
	&dev_attr_link_25000.attr,
	&dev_attr_link_40000.attr,
	&dev_attr_link_50000.attr,
	&dev_attr_link_100000.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_LINK_25000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) ||
			 test_bit(TRIGGER_NETDEV_LINK_100000, &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_obj(struct led_netdev_data);
	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");
