summaryrefslogtreecommitdiffstats
path: root/drivers/leds/trigger/ledtrig-netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/trigger/ledtrig-netdev.c')
-rw-r--r--drivers/leds/trigger/ledtrig-netdev.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 22bba8e97642..4b0863db901a 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -39,6 +39,8 @@
* (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
@@ -144,7 +146,9 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
* checking stats
*/
if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
- test_bit(TRIGGER_NETDEV_RX, &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);
}
}
@@ -337,6 +341,8 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
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:
@@ -371,6 +377,8 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
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:
@@ -429,6 +437,8 @@ 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)
@@ -538,6 +548,8 @@ static struct attribute *netdev_trig_attrs[] = {
&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
@@ -628,7 +640,9 @@ static void netdev_trig_work(struct work_struct *work)
/* 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_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);
@@ -636,7 +650,11 @@ static void netdev_trig_work(struct work_struct *work)
(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);
+ 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);