52
52
#include <linux/init.h>
53
53
#include <linux/jiffies.h>
54
54
55
+ #include <linux/leds.h>
56
+
55
57
#include "arcdevice.h"
56
58
#include "com9026.h"
57
59
@@ -189,6 +191,71 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
189
191
190
192
#endif
191
193
194
+ /* Trigger a LED event in response to a ARCNET device event */
195
+ void arcnet_led_event (struct net_device * dev , enum arcnet_led_event event )
196
+ {
197
+ struct arcnet_local * lp = netdev_priv (dev );
198
+ unsigned long led_delay = 350 ;
199
+ unsigned long tx_delay = 50 ;
200
+
201
+ switch (event ) {
202
+ case ARCNET_LED_EVENT_RECON :
203
+ led_trigger_blink_oneshot (lp -> recon_led_trig ,
204
+ & led_delay , & led_delay , 0 );
205
+ break ;
206
+ case ARCNET_LED_EVENT_OPEN :
207
+ led_trigger_event (lp -> tx_led_trig , LED_OFF );
208
+ led_trigger_event (lp -> recon_led_trig , LED_OFF );
209
+ break ;
210
+ case ARCNET_LED_EVENT_STOP :
211
+ led_trigger_event (lp -> tx_led_trig , LED_OFF );
212
+ led_trigger_event (lp -> recon_led_trig , LED_OFF );
213
+ break ;
214
+ case ARCNET_LED_EVENT_TX :
215
+ led_trigger_blink_oneshot (lp -> tx_led_trig ,
216
+ & tx_delay , & tx_delay , 0 );
217
+ break ;
218
+ }
219
+ }
220
+ EXPORT_SYMBOL_GPL (arcnet_led_event );
221
+
222
+ static void arcnet_led_release (struct device * gendev , void * res )
223
+ {
224
+ struct arcnet_local * lp = netdev_priv (to_net_dev (gendev ));
225
+
226
+ led_trigger_unregister_simple (lp -> tx_led_trig );
227
+ led_trigger_unregister_simple (lp -> recon_led_trig );
228
+ }
229
+
230
+ /* Register ARCNET LED triggers for a arcnet device
231
+ *
232
+ * This is normally called from a driver's probe function
233
+ */
234
+ void devm_arcnet_led_init (struct net_device * netdev , int index , int subid )
235
+ {
236
+ struct arcnet_local * lp = netdev_priv (netdev );
237
+ void * res ;
238
+
239
+ res = devres_alloc (arcnet_led_release , 0 , GFP_KERNEL );
240
+ if (!res ) {
241
+ netdev_err (netdev , "cannot register LED triggers\n" );
242
+ return ;
243
+ }
244
+
245
+ snprintf (lp -> tx_led_trig_name , sizeof (lp -> tx_led_trig_name ),
246
+ "arc%d-%d-tx" , index , subid );
247
+ snprintf (lp -> recon_led_trig_name , sizeof (lp -> recon_led_trig_name ),
248
+ "arc%d-%d-recon" , index , subid );
249
+
250
+ led_trigger_register_simple (lp -> tx_led_trig_name ,
251
+ & lp -> tx_led_trig );
252
+ led_trigger_register_simple (lp -> recon_led_trig_name ,
253
+ & lp -> recon_led_trig );
254
+
255
+ devres_add (& netdev -> dev , res );
256
+ }
257
+ EXPORT_SYMBOL_GPL (devm_arcnet_led_init );
258
+
192
259
/* Unregister a protocol driver from the arc_proto_map. Protocol drivers
193
260
* are responsible for registering themselves, but the unregister routine
194
261
* is pretty generic so we'll do it here.
@@ -314,6 +381,16 @@ static void arcdev_setup(struct net_device *dev)
314
381
dev -> flags = IFF_BROADCAST ;
315
382
}
316
383
384
+ static void arcnet_timer (unsigned long data )
385
+ {
386
+ struct net_device * dev = (struct net_device * )data ;
387
+
388
+ if (!netif_carrier_ok (dev )) {
389
+ netif_carrier_on (dev );
390
+ netdev_info (dev , "link up\n" );
391
+ }
392
+ }
393
+
317
394
struct net_device * alloc_arcdev (const char * name )
318
395
{
319
396
struct net_device * dev ;
@@ -325,6 +402,9 @@ struct net_device *alloc_arcdev(const char *name)
325
402
struct arcnet_local * lp = netdev_priv (dev );
326
403
327
404
spin_lock_init (& lp -> lock );
405
+ init_timer (& lp -> timer );
406
+ lp -> timer .data = (unsigned long ) dev ;
407
+ lp -> timer .function = arcnet_timer ;
328
408
}
329
409
330
410
return dev ;
@@ -423,8 +503,11 @@ int arcnet_open(struct net_device *dev)
423
503
lp -> hw .intmask (dev , lp -> intmask );
424
504
arc_printk (D_DEBUG , dev , "%s: %d: %s\n" , __FILE__ , __LINE__ , __func__ );
425
505
506
+ netif_carrier_off (dev );
426
507
netif_start_queue (dev );
508
+ mod_timer (& lp -> timer , jiffies + msecs_to_jiffies (1000 ));
427
509
510
+ arcnet_led_event (dev , ARCNET_LED_EVENT_OPEN );
428
511
return 0 ;
429
512
430
513
out_module_put :
@@ -438,7 +521,11 @@ int arcnet_close(struct net_device *dev)
438
521
{
439
522
struct arcnet_local * lp = netdev_priv (dev );
440
523
524
+ arcnet_led_event (dev , ARCNET_LED_EVENT_STOP );
525
+ del_timer_sync (& lp -> timer );
526
+
441
527
netif_stop_queue (dev );
528
+ netif_carrier_off (dev );
442
529
443
530
/* flush TX and disable RX */
444
531
lp -> hw .intmask (dev , 0 );
@@ -515,7 +602,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
515
602
struct ArcProto * proto ;
516
603
int txbuf ;
517
604
unsigned long flags ;
518
- int freeskb , retval ;
605
+ int retval ;
519
606
520
607
arc_printk (D_DURING , dev ,
521
608
"transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n" ,
@@ -554,15 +641,13 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
554
641
* the package later - forget about it now
555
642
*/
556
643
dev -> stats .tx_bytes += skb -> len ;
557
- freeskb = 1 ;
644
+ dev_kfree_skb ( skb ) ;
558
645
} else {
559
646
/* do it the 'split' way */
560
647
lp -> outgoing .proto = proto ;
561
648
lp -> outgoing .skb = skb ;
562
649
lp -> outgoing .pkt = pkt ;
563
650
564
- freeskb = 0 ;
565
-
566
651
if (proto -> continue_tx &&
567
652
proto -> continue_tx (dev , txbuf )) {
568
653
arc_printk (D_NORMAL , dev ,
@@ -574,7 +659,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
574
659
lp -> next_tx = txbuf ;
575
660
} else {
576
661
retval = NETDEV_TX_BUSY ;
577
- freeskb = 0 ;
578
662
}
579
663
580
664
arc_printk (D_DEBUG , dev , "%s: %d: %s, status: %x\n" ,
@@ -588,10 +672,9 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
588
672
arc_printk (D_DEBUG , dev , "%s: %d: %s, status: %x\n" ,
589
673
__FILE__ , __LINE__ , __func__ , lp -> hw .status (dev ));
590
674
591
- spin_unlock_irqrestore (& lp -> lock , flags );
592
- if (freeskb )
593
- dev_kfree_skb (skb );
675
+ arcnet_led_event (dev , ARCNET_LED_EVENT_TX );
594
676
677
+ spin_unlock_irqrestore (& lp -> lock , flags );
595
678
return retval ; /* no need to try again */
596
679
}
597
680
EXPORT_SYMBOL (arcnet_send_packet );
@@ -843,6 +926,13 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
843
926
844
927
arc_printk (D_RECON , dev , "Network reconfiguration detected (status=%Xh)\n" ,
845
928
status );
929
+ if (netif_carrier_ok (dev )) {
930
+ netif_carrier_off (dev );
931
+ netdev_info (dev , "link down\n" );
932
+ }
933
+ mod_timer (& lp -> timer , jiffies + msecs_to_jiffies (1000 ));
934
+
935
+ arcnet_led_event (dev , ARCNET_LED_EVENT_RECON );
846
936
/* MYRECON bit is at bit 7 of diagstatus */
847
937
if (diagstatus & 0x80 )
848
938
arc_printk (D_RECON , dev , "Put out that recon myself\n" );
@@ -893,6 +983,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
893
983
lp -> num_recons = lp -> network_down = 0 ;
894
984
895
985
arc_printk (D_DURING , dev , "not recon: clearing counters anyway.\n" );
986
+ netif_carrier_on (dev );
896
987
}
897
988
898
989
if (didsomething )
0 commit comments