1313#include <linux/atomic.h>
1414#include <linux/ctype.h>
1515#include <linux/device.h>
16+ #include <linux/ethtool.h>
1617#include <linux/init.h>
1718#include <linux/jiffies.h>
1819#include <linux/kernel.h>
2122#include <linux/module.h>
2223#include <linux/netdevice.h>
2324#include <linux/mutex.h>
25+ #include <linux/rtnetlink.h>
2426#include <linux/timer.h>
2527#include "../leds.h"
2628
@@ -52,6 +54,8 @@ struct led_netdev_data {
5254 unsigned int last_activity ;
5355
5456 unsigned long mode ;
57+ int link_speed ;
58+
5559 bool carrier_link_up ;
5660 bool hw_control ;
5761};
@@ -77,7 +81,24 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
7781 if (!trigger_data -> carrier_link_up ) {
7882 led_set_brightness (led_cdev , LED_OFF );
7983 } else {
84+ bool blink_on = false;
85+
8086 if (test_bit (TRIGGER_NETDEV_LINK , & trigger_data -> mode ))
87+ blink_on = true;
88+
89+ if (test_bit (TRIGGER_NETDEV_LINK_10 , & trigger_data -> mode ) &&
90+ trigger_data -> link_speed == SPEED_10 )
91+ blink_on = true;
92+
93+ if (test_bit (TRIGGER_NETDEV_LINK_100 , & trigger_data -> mode ) &&
94+ trigger_data -> link_speed == SPEED_100 )
95+ blink_on = true;
96+
97+ if (test_bit (TRIGGER_NETDEV_LINK_1000 , & trigger_data -> mode ) &&
98+ trigger_data -> link_speed == SPEED_1000 )
99+ blink_on = true;
100+
101+ if (blink_on )
81102 led_set_brightness (led_cdev ,
82103 led_cdev -> blink_brightness );
83104 else
@@ -161,6 +182,18 @@ static bool can_hw_control(struct led_netdev_data *trigger_data)
161182 return true;
162183}
163184
185+ static void get_device_state (struct led_netdev_data * trigger_data )
186+ {
187+ struct ethtool_link_ksettings cmd ;
188+
189+ trigger_data -> carrier_link_up = netif_carrier_ok (trigger_data -> net_dev );
190+ if (!trigger_data -> carrier_link_up )
191+ return ;
192+
193+ if (!__ethtool_get_link_ksettings (trigger_data -> net_dev , & cmd ))
194+ trigger_data -> link_speed = cmd .base .speed ;
195+ }
196+
164197static ssize_t device_name_show (struct device * dev ,
165198 struct device_attribute * attr , char * buf )
166199{
@@ -196,8 +229,12 @@ static int set_device_name(struct led_netdev_data *trigger_data,
196229 dev_get_by_name (& init_net , trigger_data -> device_name );
197230
198231 trigger_data -> carrier_link_up = false;
199- if (trigger_data -> net_dev != NULL )
200- trigger_data -> carrier_link_up = netif_carrier_ok (trigger_data -> net_dev );
232+ trigger_data -> link_speed = SPEED_UNKNOWN ;
233+ if (trigger_data -> net_dev != NULL ) {
234+ rtnl_lock ();
235+ get_device_state (trigger_data );
236+ rtnl_unlock ();
237+ }
201238
202239 trigger_data -> last_activity = 0 ;
203240
@@ -234,6 +271,9 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
234271
235272 switch (attr ) {
236273 case TRIGGER_NETDEV_LINK :
274+ case TRIGGER_NETDEV_LINK_10 :
275+ case TRIGGER_NETDEV_LINK_100 :
276+ case TRIGGER_NETDEV_LINK_1000 :
237277 case TRIGGER_NETDEV_TX :
238278 case TRIGGER_NETDEV_RX :
239279 bit = attr ;
@@ -249,7 +289,7 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
249289 size_t size , enum led_trigger_netdev_modes attr )
250290{
251291 struct led_netdev_data * trigger_data = led_trigger_get_drvdata (dev );
252- unsigned long state ;
292+ unsigned long state , mode = trigger_data -> mode ;
253293 int ret ;
254294 int bit ;
255295
@@ -259,6 +299,9 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
259299
260300 switch (attr ) {
261301 case TRIGGER_NETDEV_LINK :
302+ case TRIGGER_NETDEV_LINK_10 :
303+ case TRIGGER_NETDEV_LINK_100 :
304+ case TRIGGER_NETDEV_LINK_1000 :
262305 case TRIGGER_NETDEV_TX :
263306 case TRIGGER_NETDEV_RX :
264307 bit = attr ;
@@ -267,13 +310,20 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
267310 return - EINVAL ;
268311 }
269312
270- cancel_delayed_work_sync (& trigger_data -> work );
271-
272313 if (state )
273- set_bit (bit , & trigger_data -> mode );
314+ set_bit (bit , & mode );
274315 else
275- clear_bit (bit , & trigger_data -> mode );
316+ clear_bit (bit , & mode );
317+
318+ if (test_bit (TRIGGER_NETDEV_LINK , & mode ) &&
319+ (test_bit (TRIGGER_NETDEV_LINK_10 , & mode ) ||
320+ test_bit (TRIGGER_NETDEV_LINK_100 , & mode ) ||
321+ test_bit (TRIGGER_NETDEV_LINK_1000 , & mode )))
322+ return - EINVAL ;
323+
324+ cancel_delayed_work_sync (& trigger_data -> work );
276325
326+ trigger_data -> mode = mode ;
277327 trigger_data -> hw_control = can_hw_control (trigger_data );
278328
279329 set_baseline_state (trigger_data );
@@ -295,6 +345,9 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
295345 static DEVICE_ATTR_RW(trigger_name)
296346
297347DEFINE_NETDEV_TRIGGER (link , TRIGGER_NETDEV_LINK );
348+ DEFINE_NETDEV_TRIGGER (link_10 , TRIGGER_NETDEV_LINK_10 );
349+ DEFINE_NETDEV_TRIGGER (link_100 , TRIGGER_NETDEV_LINK_100 );
350+ DEFINE_NETDEV_TRIGGER (link_1000 , TRIGGER_NETDEV_LINK_1000 );
298351DEFINE_NETDEV_TRIGGER (tx , TRIGGER_NETDEV_TX );
299352DEFINE_NETDEV_TRIGGER (rx , TRIGGER_NETDEV_RX );
300353
@@ -338,6 +391,9 @@ static DEVICE_ATTR_RW(interval);
338391static struct attribute * netdev_trig_attrs [] = {
339392 & dev_attr_device_name .attr ,
340393 & dev_attr_link .attr ,
394+ & dev_attr_link_10 .attr ,
395+ & dev_attr_link_100 .attr ,
396+ & dev_attr_link_1000 .attr ,
341397 & dev_attr_rx .attr ,
342398 & dev_attr_tx .attr ,
343399 & dev_attr_interval .attr ,
@@ -368,9 +424,10 @@ static int netdev_trig_notify(struct notifier_block *nb,
368424 mutex_lock (& trigger_data -> lock );
369425
370426 trigger_data -> carrier_link_up = false;
427+ trigger_data -> link_speed = SPEED_UNKNOWN ;
371428 switch (evt ) {
372429 case NETDEV_CHANGENAME :
373- trigger_data -> carrier_link_up = netif_carrier_ok ( dev );
430+ get_device_state ( trigger_data );
374431 fallthrough ;
375432 case NETDEV_REGISTER :
376433 if (trigger_data -> net_dev )
@@ -384,7 +441,7 @@ static int netdev_trig_notify(struct notifier_block *nb,
384441 break ;
385442 case NETDEV_UP :
386443 case NETDEV_CHANGE :
387- trigger_data -> carrier_link_up = netif_carrier_ok ( dev );
444+ get_device_state ( trigger_data );
388445 break ;
389446 }
390447
@@ -427,7 +484,10 @@ static void netdev_trig_work(struct work_struct *work)
427484 if (trigger_data -> last_activity != new_activity ) {
428485 led_stop_software_blink (trigger_data -> led_cdev );
429486
430- invert = test_bit (TRIGGER_NETDEV_LINK , & trigger_data -> mode );
487+ invert = test_bit (TRIGGER_NETDEV_LINK , & trigger_data -> mode ) ||
488+ test_bit (TRIGGER_NETDEV_LINK_10 , & trigger_data -> mode ) ||
489+ test_bit (TRIGGER_NETDEV_LINK_100 , & trigger_data -> mode ) ||
490+ test_bit (TRIGGER_NETDEV_LINK_1000 , & trigger_data -> mode );
431491 interval = jiffies_to_msecs (
432492 atomic_read (& trigger_data -> interval ));
433493 /* base state is ON (link present) */
0 commit comments