15
15
static void ionic_lif_rx_mode (struct ionic_lif * lif , unsigned int rx_mode );
16
16
static int ionic_lif_addr_add (struct ionic_lif * lif , const u8 * addr );
17
17
static int ionic_lif_addr_del (struct ionic_lif * lif , const u8 * addr );
18
+ static void ionic_link_status_check (struct ionic_lif * lif );
18
19
19
20
static void ionic_lif_deferred_work (struct work_struct * work )
20
21
{
@@ -41,6 +42,9 @@ static void ionic_lif_deferred_work(struct work_struct *work)
41
42
case IONIC_DW_TYPE_RX_ADDR_DEL :
42
43
ionic_lif_addr_del (lif , w -> addr );
43
44
break ;
45
+ case IONIC_DW_TYPE_LINK_STATUS :
46
+ ionic_link_status_check (lif );
47
+ break ;
44
48
default :
45
49
break ;
46
50
}
@@ -58,6 +62,54 @@ static void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
58
62
schedule_work (& def -> work );
59
63
}
60
64
65
+ static void ionic_link_status_check (struct ionic_lif * lif )
66
+ {
67
+ struct net_device * netdev = lif -> netdev ;
68
+ u16 link_status ;
69
+ bool link_up ;
70
+
71
+ link_status = le16_to_cpu (lif -> info -> status .link_status );
72
+ link_up = link_status == IONIC_PORT_OPER_STATUS_UP ;
73
+
74
+ /* filter out the no-change cases */
75
+ if (link_up == netif_carrier_ok (netdev ))
76
+ goto link_out ;
77
+
78
+ if (link_up ) {
79
+ netdev_info (netdev , "Link up - %d Gbps\n" ,
80
+ le32_to_cpu (lif -> info -> status .link_speed ) / 1000 );
81
+
82
+ } else {
83
+ netdev_info (netdev , "Link down\n" );
84
+
85
+ /* carrier off first to avoid watchdog timeout */
86
+ netif_carrier_off (netdev );
87
+ }
88
+
89
+ link_out :
90
+ clear_bit (IONIC_LIF_LINK_CHECK_REQUESTED , lif -> state );
91
+ }
92
+
93
+ static void ionic_link_status_check_request (struct ionic_lif * lif )
94
+ {
95
+ struct ionic_deferred_work * work ;
96
+
97
+ /* we only need one request outstanding at a time */
98
+ if (test_and_set_bit (IONIC_LIF_LINK_CHECK_REQUESTED , lif -> state ))
99
+ return ;
100
+
101
+ if (in_interrupt ()) {
102
+ work = kzalloc (sizeof (* work ), GFP_ATOMIC );
103
+ if (!work )
104
+ return ;
105
+
106
+ work -> type = IONIC_DW_TYPE_LINK_STATUS ;
107
+ ionic_lif_deferred_enqueue (& lif -> deferred , work );
108
+ } else {
109
+ ionic_link_status_check (lif );
110
+ }
111
+ }
112
+
61
113
static irqreturn_t ionic_isr (int irq , void * data )
62
114
{
63
115
struct napi_struct * napi = data ;
@@ -381,12 +433,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
381
433
382
434
switch (le16_to_cpu (comp -> event .ecode )) {
383
435
case IONIC_EVENT_LINK_CHANGE :
384
- netdev_info (netdev , "Notifyq IONIC_EVENT_LINK_CHANGE eid=%lld\n" ,
385
- eid );
386
- netdev_info (netdev ,
387
- " link_status=%d link_speed=%d\n" ,
388
- le16_to_cpu (comp -> link_change .link_status ),
389
- le32_to_cpu (comp -> link_change .link_speed ));
436
+ ionic_link_status_check_request (lif );
390
437
break ;
391
438
case IONIC_EVENT_RESET :
392
439
netdev_info (netdev , "Notifyq IONIC_EVENT_RESET eid=%lld\n" ,
@@ -445,6 +492,59 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
445
492
return max (n_work , a_work );
446
493
}
447
494
495
+ static void ionic_get_stats64 (struct net_device * netdev ,
496
+ struct rtnl_link_stats64 * ns )
497
+ {
498
+ struct ionic_lif * lif = netdev_priv (netdev );
499
+ struct ionic_lif_stats * ls ;
500
+
501
+ memset (ns , 0 , sizeof (* ns ));
502
+ ls = & lif -> info -> stats ;
503
+
504
+ ns -> rx_packets = le64_to_cpu (ls -> rx_ucast_packets ) +
505
+ le64_to_cpu (ls -> rx_mcast_packets ) +
506
+ le64_to_cpu (ls -> rx_bcast_packets );
507
+
508
+ ns -> tx_packets = le64_to_cpu (ls -> tx_ucast_packets ) +
509
+ le64_to_cpu (ls -> tx_mcast_packets ) +
510
+ le64_to_cpu (ls -> tx_bcast_packets );
511
+
512
+ ns -> rx_bytes = le64_to_cpu (ls -> rx_ucast_bytes ) +
513
+ le64_to_cpu (ls -> rx_mcast_bytes ) +
514
+ le64_to_cpu (ls -> rx_bcast_bytes );
515
+
516
+ ns -> tx_bytes = le64_to_cpu (ls -> tx_ucast_bytes ) +
517
+ le64_to_cpu (ls -> tx_mcast_bytes ) +
518
+ le64_to_cpu (ls -> tx_bcast_bytes );
519
+
520
+ ns -> rx_dropped = le64_to_cpu (ls -> rx_ucast_drop_packets ) +
521
+ le64_to_cpu (ls -> rx_mcast_drop_packets ) +
522
+ le64_to_cpu (ls -> rx_bcast_drop_packets );
523
+
524
+ ns -> tx_dropped = le64_to_cpu (ls -> tx_ucast_drop_packets ) +
525
+ le64_to_cpu (ls -> tx_mcast_drop_packets ) +
526
+ le64_to_cpu (ls -> tx_bcast_drop_packets );
527
+
528
+ ns -> multicast = le64_to_cpu (ls -> rx_mcast_packets );
529
+
530
+ ns -> rx_over_errors = le64_to_cpu (ls -> rx_queue_empty );
531
+
532
+ ns -> rx_missed_errors = le64_to_cpu (ls -> rx_dma_error ) +
533
+ le64_to_cpu (ls -> rx_queue_disabled ) +
534
+ le64_to_cpu (ls -> rx_desc_fetch_error ) +
535
+ le64_to_cpu (ls -> rx_desc_data_error );
536
+
537
+ ns -> tx_aborted_errors = le64_to_cpu (ls -> tx_dma_error ) +
538
+ le64_to_cpu (ls -> tx_queue_disabled ) +
539
+ le64_to_cpu (ls -> tx_desc_fetch_error ) +
540
+ le64_to_cpu (ls -> tx_desc_data_error );
541
+
542
+ ns -> rx_errors = ns -> rx_over_errors +
543
+ ns -> rx_missed_errors ;
544
+
545
+ ns -> tx_errors = ns -> tx_aborted_errors ;
546
+ }
547
+
448
548
static int ionic_lif_addr_add (struct ionic_lif * lif , const u8 * addr )
449
549
{
450
550
struct ionic_admin_ctx ctx = {
@@ -982,6 +1082,8 @@ int ionic_open(struct net_device *netdev)
982
1082
983
1083
set_bit (IONIC_LIF_UP , lif -> state );
984
1084
1085
+ ionic_link_status_check_request (lif );
1086
+
985
1087
return 0 ;
986
1088
}
987
1089
@@ -1007,6 +1109,7 @@ int ionic_stop(struct net_device *netdev)
1007
1109
static const struct net_device_ops ionic_netdev_ops = {
1008
1110
.ndo_open = ionic_open ,
1009
1111
.ndo_stop = ionic_stop ,
1112
+ .ndo_get_stats64 = ionic_get_stats64 ,
1010
1113
.ndo_set_rx_mode = ionic_set_rx_mode ,
1011
1114
.ndo_set_features = ionic_set_features ,
1012
1115
.ndo_set_mac_address = ionic_set_mac_address ,
@@ -1447,6 +1550,7 @@ int ionic_lifs_register(struct ionic *ionic)
1447
1550
return err ;
1448
1551
}
1449
1552
1553
+ ionic_link_status_check_request (ionic -> master_lif );
1450
1554
ionic -> master_lif -> registered = true;
1451
1555
1452
1556
return 0 ;
0 commit comments