36
36
#define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>"
37
37
#define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices"
38
38
#define DRIVER_NAME "lan78xx"
39
- #define DRIVER_VERSION "1.0.3 "
39
+ #define DRIVER_VERSION "1.0.4 "
40
40
41
41
#define TX_TIMEOUT_JIFFIES (5 * HZ)
42
42
#define THROTTLE_JIFFIES (HZ / 8)
86
86
/* default autosuspend delay (mSec)*/
87
87
#define DEFAULT_AUTOSUSPEND_DELAY (10 * 1000)
88
88
89
+ /* statistic update interval (mSec) */
90
+ #define STAT_UPDATE_TIMER (1 * 1000)
91
+
89
92
static const char lan78xx_gstrings [][ETH_GSTRING_LEN ] = {
90
93
"RX FCS Errors" ,
91
94
"RX Alignment Errors" ,
@@ -186,6 +189,56 @@ struct lan78xx_statstage {
186
189
u32 eee_tx_lpi_time ;
187
190
};
188
191
192
+ struct lan78xx_statstage64 {
193
+ u64 rx_fcs_errors ;
194
+ u64 rx_alignment_errors ;
195
+ u64 rx_fragment_errors ;
196
+ u64 rx_jabber_errors ;
197
+ u64 rx_undersize_frame_errors ;
198
+ u64 rx_oversize_frame_errors ;
199
+ u64 rx_dropped_frames ;
200
+ u64 rx_unicast_byte_count ;
201
+ u64 rx_broadcast_byte_count ;
202
+ u64 rx_multicast_byte_count ;
203
+ u64 rx_unicast_frames ;
204
+ u64 rx_broadcast_frames ;
205
+ u64 rx_multicast_frames ;
206
+ u64 rx_pause_frames ;
207
+ u64 rx_64_byte_frames ;
208
+ u64 rx_65_127_byte_frames ;
209
+ u64 rx_128_255_byte_frames ;
210
+ u64 rx_256_511_bytes_frames ;
211
+ u64 rx_512_1023_byte_frames ;
212
+ u64 rx_1024_1518_byte_frames ;
213
+ u64 rx_greater_1518_byte_frames ;
214
+ u64 eee_rx_lpi_transitions ;
215
+ u64 eee_rx_lpi_time ;
216
+ u64 tx_fcs_errors ;
217
+ u64 tx_excess_deferral_errors ;
218
+ u64 tx_carrier_errors ;
219
+ u64 tx_bad_byte_count ;
220
+ u64 tx_single_collisions ;
221
+ u64 tx_multiple_collisions ;
222
+ u64 tx_excessive_collision ;
223
+ u64 tx_late_collisions ;
224
+ u64 tx_unicast_byte_count ;
225
+ u64 tx_broadcast_byte_count ;
226
+ u64 tx_multicast_byte_count ;
227
+ u64 tx_unicast_frames ;
228
+ u64 tx_broadcast_frames ;
229
+ u64 tx_multicast_frames ;
230
+ u64 tx_pause_frames ;
231
+ u64 tx_64_byte_frames ;
232
+ u64 tx_65_127_byte_frames ;
233
+ u64 tx_128_255_byte_frames ;
234
+ u64 tx_256_511_bytes_frames ;
235
+ u64 tx_512_1023_byte_frames ;
236
+ u64 tx_1024_1518_byte_frames ;
237
+ u64 tx_greater_1518_byte_frames ;
238
+ u64 eee_tx_lpi_transitions ;
239
+ u64 eee_tx_lpi_time ;
240
+ };
241
+
189
242
struct lan78xx_net ;
190
243
191
244
struct lan78xx_priv {
@@ -232,6 +285,15 @@ struct usb_context {
232
285
#define EVENT_DEV_WAKING 6
233
286
#define EVENT_DEV_ASLEEP 7
234
287
#define EVENT_DEV_OPEN 8
288
+ #define EVENT_STAT_UPDATE 9
289
+
290
+ struct statstage {
291
+ struct mutex access_lock ; /* for stats access */
292
+ struct lan78xx_statstage saved ;
293
+ struct lan78xx_statstage rollover_count ;
294
+ struct lan78xx_statstage rollover_max ;
295
+ struct lan78xx_statstage64 curr_stat ;
296
+ };
235
297
236
298
struct lan78xx_net {
237
299
struct net_device * net ;
@@ -272,6 +334,7 @@ struct lan78xx_net {
272
334
273
335
unsigned maxpacket ;
274
336
struct timer_list delay ;
337
+ struct timer_list stat_monitor ;
275
338
276
339
unsigned long data [5 ];
277
340
@@ -284,6 +347,9 @@ struct lan78xx_net {
284
347
285
348
int fc_autoneg ;
286
349
u8 fc_request_control ;
350
+
351
+ int delta ;
352
+ struct statstage stats ;
287
353
};
288
354
289
355
/* use ethtool to change the level for any given device */
@@ -382,6 +448,93 @@ static int lan78xx_read_stats(struct lan78xx_net *dev,
382
448
return ret ;
383
449
}
384
450
451
+ #define check_counter_rollover (struct1 , dev_stats , member ) { \
452
+ if (struct1->member < dev_stats.saved.member) \
453
+ dev_stats.rollover_count.member++; \
454
+ }
455
+
456
+ static void lan78xx_check_stat_rollover (struct lan78xx_net * dev ,
457
+ struct lan78xx_statstage * stats )
458
+ {
459
+ check_counter_rollover (stats , dev -> stats , rx_fcs_errors );
460
+ check_counter_rollover (stats , dev -> stats , rx_alignment_errors );
461
+ check_counter_rollover (stats , dev -> stats , rx_fragment_errors );
462
+ check_counter_rollover (stats , dev -> stats , rx_jabber_errors );
463
+ check_counter_rollover (stats , dev -> stats , rx_undersize_frame_errors );
464
+ check_counter_rollover (stats , dev -> stats , rx_oversize_frame_errors );
465
+ check_counter_rollover (stats , dev -> stats , rx_dropped_frames );
466
+ check_counter_rollover (stats , dev -> stats , rx_unicast_byte_count );
467
+ check_counter_rollover (stats , dev -> stats , rx_broadcast_byte_count );
468
+ check_counter_rollover (stats , dev -> stats , rx_multicast_byte_count );
469
+ check_counter_rollover (stats , dev -> stats , rx_unicast_frames );
470
+ check_counter_rollover (stats , dev -> stats , rx_broadcast_frames );
471
+ check_counter_rollover (stats , dev -> stats , rx_multicast_frames );
472
+ check_counter_rollover (stats , dev -> stats , rx_pause_frames );
473
+ check_counter_rollover (stats , dev -> stats , rx_64_byte_frames );
474
+ check_counter_rollover (stats , dev -> stats , rx_65_127_byte_frames );
475
+ check_counter_rollover (stats , dev -> stats , rx_128_255_byte_frames );
476
+ check_counter_rollover (stats , dev -> stats , rx_256_511_bytes_frames );
477
+ check_counter_rollover (stats , dev -> stats , rx_512_1023_byte_frames );
478
+ check_counter_rollover (stats , dev -> stats , rx_1024_1518_byte_frames );
479
+ check_counter_rollover (stats , dev -> stats , rx_greater_1518_byte_frames );
480
+ check_counter_rollover (stats , dev -> stats , eee_rx_lpi_transitions );
481
+ check_counter_rollover (stats , dev -> stats , eee_rx_lpi_time );
482
+ check_counter_rollover (stats , dev -> stats , tx_fcs_errors );
483
+ check_counter_rollover (stats , dev -> stats , tx_excess_deferral_errors );
484
+ check_counter_rollover (stats , dev -> stats , tx_carrier_errors );
485
+ check_counter_rollover (stats , dev -> stats , tx_bad_byte_count );
486
+ check_counter_rollover (stats , dev -> stats , tx_single_collisions );
487
+ check_counter_rollover (stats , dev -> stats , tx_multiple_collisions );
488
+ check_counter_rollover (stats , dev -> stats , tx_excessive_collision );
489
+ check_counter_rollover (stats , dev -> stats , tx_late_collisions );
490
+ check_counter_rollover (stats , dev -> stats , tx_unicast_byte_count );
491
+ check_counter_rollover (stats , dev -> stats , tx_broadcast_byte_count );
492
+ check_counter_rollover (stats , dev -> stats , tx_multicast_byte_count );
493
+ check_counter_rollover (stats , dev -> stats , tx_unicast_frames );
494
+ check_counter_rollover (stats , dev -> stats , tx_broadcast_frames );
495
+ check_counter_rollover (stats , dev -> stats , tx_multicast_frames );
496
+ check_counter_rollover (stats , dev -> stats , tx_pause_frames );
497
+ check_counter_rollover (stats , dev -> stats , tx_64_byte_frames );
498
+ check_counter_rollover (stats , dev -> stats , tx_65_127_byte_frames );
499
+ check_counter_rollover (stats , dev -> stats , tx_128_255_byte_frames );
500
+ check_counter_rollover (stats , dev -> stats , tx_256_511_bytes_frames );
501
+ check_counter_rollover (stats , dev -> stats , tx_512_1023_byte_frames );
502
+ check_counter_rollover (stats , dev -> stats , tx_1024_1518_byte_frames );
503
+ check_counter_rollover (stats , dev -> stats , tx_greater_1518_byte_frames );
504
+ check_counter_rollover (stats , dev -> stats , eee_tx_lpi_transitions );
505
+ check_counter_rollover (stats , dev -> stats , eee_tx_lpi_time );
506
+
507
+ memcpy (& dev -> stats .saved , stats , sizeof (struct lan78xx_statstage ));
508
+ }
509
+
510
+ static void lan78xx_update_stats (struct lan78xx_net * dev )
511
+ {
512
+ u32 * p , * count , * max ;
513
+ u64 * data ;
514
+ int i ;
515
+ struct lan78xx_statstage lan78xx_stats ;
516
+
517
+ if (usb_autopm_get_interface (dev -> intf ) < 0 )
518
+ return ;
519
+
520
+ p = (u32 * )& lan78xx_stats ;
521
+ count = (u32 * )& dev -> stats .rollover_count ;
522
+ max = (u32 * )& dev -> stats .rollover_max ;
523
+ data = (u64 * )& dev -> stats .curr_stat ;
524
+
525
+ mutex_lock (& dev -> stats .access_lock );
526
+
527
+ if (lan78xx_read_stats (dev , & lan78xx_stats ) > 0 )
528
+ lan78xx_check_stat_rollover (dev , & lan78xx_stats );
529
+
530
+ for (i = 0 ; i < (sizeof (lan78xx_stats ) / (sizeof (u32 ))); i ++ )
531
+ data [i ] = (u64 )p [i ] + ((u64 )count [i ] * ((u64 )max [i ] + 1 ));
532
+
533
+ mutex_unlock (& dev -> stats .access_lock );
534
+
535
+ usb_autopm_put_interface (dev -> intf );
536
+ }
537
+
385
538
/* Loop until the read is completed with timeout called with phy_mutex held */
386
539
static int lan78xx_phy_wait_not_busy (struct lan78xx_net * dev )
387
540
{
@@ -967,6 +1120,8 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
967
1120
return - EIO ;
968
1121
969
1122
phy_mac_interrupt (phydev , 0 );
1123
+
1124
+ del_timer (& dev -> stat_monitor );
970
1125
} else if (phydev -> link && !dev -> link_on ) {
971
1126
dev -> link_on = true;
972
1127
@@ -1007,6 +1162,12 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
1007
1162
1008
1163
ret = lan78xx_update_flowcontrol (dev , ecmd .duplex , ladv , radv );
1009
1164
phy_mac_interrupt (phydev , 1 );
1165
+
1166
+ if (!timer_pending (& dev -> stat_monitor )) {
1167
+ dev -> delta = 1 ;
1168
+ mod_timer (& dev -> stat_monitor ,
1169
+ jiffies + STAT_UPDATE_TIMER );
1170
+ }
1010
1171
}
1011
1172
1012
1173
return ret ;
@@ -1099,20 +1260,12 @@ static void lan78xx_get_stats(struct net_device *netdev,
1099
1260
struct ethtool_stats * stats , u64 * data )
1100
1261
{
1101
1262
struct lan78xx_net * dev = netdev_priv (netdev );
1102
- struct lan78xx_statstage lan78xx_stat ;
1103
- u32 * p ;
1104
- int i ;
1105
1263
1106
- if (usb_autopm_get_interface (dev -> intf ) < 0 )
1107
- return ;
1264
+ lan78xx_update_stats (dev );
1108
1265
1109
- if (lan78xx_read_stats (dev , & lan78xx_stat ) > 0 ) {
1110
- p = (u32 * )& lan78xx_stat ;
1111
- for (i = 0 ; i < (sizeof (lan78xx_stat ) / (sizeof (u32 ))); i ++ )
1112
- data [i ] = p [i ];
1113
- }
1114
-
1115
- usb_autopm_put_interface (dev -> intf );
1266
+ mutex_lock (& dev -> stats .access_lock );
1267
+ memcpy (data , & dev -> stats .curr_stat , sizeof (dev -> stats .curr_stat ));
1268
+ mutex_unlock (& dev -> stats .access_lock );
1116
1269
}
1117
1270
1118
1271
static void lan78xx_get_wol (struct net_device * netdev ,
@@ -2095,6 +2248,32 @@ static int lan78xx_reset(struct lan78xx_net *dev)
2095
2248
return 0 ;
2096
2249
}
2097
2250
2251
+ static void lan78xx_init_stats (struct lan78xx_net * dev )
2252
+ {
2253
+ u32 * p ;
2254
+ int i ;
2255
+
2256
+ /* initialize for stats update
2257
+ * some counters are 20bits and some are 32bits
2258
+ */
2259
+ p = (u32 * )& dev -> stats .rollover_max ;
2260
+ for (i = 0 ; i < (sizeof (dev -> stats .rollover_max ) / (sizeof (u32 ))); i ++ )
2261
+ p [i ] = 0xFFFFF ;
2262
+
2263
+ dev -> stats .rollover_max .rx_unicast_byte_count = 0xFFFFFFFF ;
2264
+ dev -> stats .rollover_max .rx_broadcast_byte_count = 0xFFFFFFFF ;
2265
+ dev -> stats .rollover_max .rx_multicast_byte_count = 0xFFFFFFFF ;
2266
+ dev -> stats .rollover_max .eee_rx_lpi_transitions = 0xFFFFFFFF ;
2267
+ dev -> stats .rollover_max .eee_rx_lpi_time = 0xFFFFFFFF ;
2268
+ dev -> stats .rollover_max .tx_unicast_byte_count = 0xFFFFFFFF ;
2269
+ dev -> stats .rollover_max .tx_broadcast_byte_count = 0xFFFFFFFF ;
2270
+ dev -> stats .rollover_max .tx_multicast_byte_count = 0xFFFFFFFF ;
2271
+ dev -> stats .rollover_max .eee_tx_lpi_transitions = 0xFFFFFFFF ;
2272
+ dev -> stats .rollover_max .eee_tx_lpi_time = 0xFFFFFFFF ;
2273
+
2274
+ lan78xx_defer_kevent (dev , EVENT_STAT_UPDATE );
2275
+ }
2276
+
2098
2277
static int lan78xx_open (struct net_device * net )
2099
2278
{
2100
2279
struct lan78xx_net * dev = netdev_priv (net );
@@ -2122,6 +2301,8 @@ static int lan78xx_open(struct net_device *net)
2122
2301
}
2123
2302
}
2124
2303
2304
+ lan78xx_init_stats (dev );
2305
+
2125
2306
set_bit (EVENT_DEV_OPEN , & dev -> flags );
2126
2307
2127
2308
netif_start_queue (net );
@@ -2166,6 +2347,9 @@ int lan78xx_stop(struct net_device *net)
2166
2347
{
2167
2348
struct lan78xx_net * dev = netdev_priv (net );
2168
2349
2350
+ if (timer_pending (& dev -> stat_monitor ))
2351
+ del_timer_sync (& dev -> stat_monitor );
2352
+
2169
2353
phy_stop (net -> phydev );
2170
2354
phy_disconnect (net -> phydev );
2171
2355
net -> phydev = NULL ;
@@ -2910,6 +3094,13 @@ static void lan78xx_bh(unsigned long param)
2910
3094
}
2911
3095
2912
3096
if (netif_device_present (dev -> net ) && netif_running (dev -> net )) {
3097
+ /* reset update timer delta */
3098
+ if (timer_pending (& dev -> stat_monitor ) && (dev -> delta != 1 )) {
3099
+ dev -> delta = 1 ;
3100
+ mod_timer (& dev -> stat_monitor ,
3101
+ jiffies + STAT_UPDATE_TIMER );
3102
+ }
3103
+
2913
3104
if (!skb_queue_empty (& dev -> txq_pend ))
2914
3105
lan78xx_tx_bh (dev );
2915
3106
@@ -2984,6 +3175,17 @@ static void lan78xx_delayedwork(struct work_struct *work)
2984
3175
usb_autopm_put_interface (dev -> intf );
2985
3176
}
2986
3177
}
3178
+
3179
+ if (test_bit (EVENT_STAT_UPDATE , & dev -> flags )) {
3180
+ lan78xx_update_stats (dev );
3181
+
3182
+ clear_bit (EVENT_STAT_UPDATE , & dev -> flags );
3183
+
3184
+ mod_timer (& dev -> stat_monitor ,
3185
+ jiffies + (STAT_UPDATE_TIMER * dev -> delta ));
3186
+
3187
+ dev -> delta = min ((dev -> delta * 2 ), 50 );
3188
+ }
2987
3189
}
2988
3190
2989
3191
static void intr_complete (struct urb * urb )
@@ -3074,6 +3276,15 @@ static const struct net_device_ops lan78xx_netdev_ops = {
3074
3276
.ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid ,
3075
3277
};
3076
3278
3279
+ static void lan78xx_stat_monitor (unsigned long param )
3280
+ {
3281
+ struct lan78xx_net * dev ;
3282
+
3283
+ dev = (struct lan78xx_net * )param ;
3284
+
3285
+ lan78xx_defer_kevent (dev , EVENT_STAT_UPDATE );
3286
+ }
3287
+
3077
3288
static int lan78xx_probe (struct usb_interface * intf ,
3078
3289
const struct usb_device_id * id )
3079
3290
{
@@ -3120,6 +3331,13 @@ static int lan78xx_probe(struct usb_interface *intf,
3120
3331
netdev -> watchdog_timeo = TX_TIMEOUT_JIFFIES ;
3121
3332
netdev -> ethtool_ops = & lan78xx_ethtool_ops ;
3122
3333
3334
+ dev -> stat_monitor .function = lan78xx_stat_monitor ;
3335
+ dev -> stat_monitor .data = (unsigned long )dev ;
3336
+ dev -> delta = 1 ;
3337
+ init_timer (& dev -> stat_monitor );
3338
+
3339
+ mutex_init (& dev -> stats .access_lock );
3340
+
3123
3341
ret = lan78xx_bind (dev , intf );
3124
3342
if (ret < 0 )
3125
3343
goto out2 ;
@@ -3397,6 +3615,8 @@ int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
3397
3615
}
3398
3616
3399
3617
if (test_bit (EVENT_DEV_ASLEEP , & dev -> flags )) {
3618
+ del_timer (& dev -> stat_monitor );
3619
+
3400
3620
if (PMSG_IS_AUTO (message )) {
3401
3621
/* auto suspend (selective suspend) */
3402
3622
ret = lan78xx_read_reg (dev , MAC_TX , & buf );
@@ -3457,6 +3677,12 @@ int lan78xx_resume(struct usb_interface *intf)
3457
3677
int ret ;
3458
3678
u32 buf ;
3459
3679
3680
+ if (!timer_pending (& dev -> stat_monitor )) {
3681
+ dev -> delta = 1 ;
3682
+ mod_timer (& dev -> stat_monitor ,
3683
+ jiffies + STAT_UPDATE_TIMER );
3684
+ }
3685
+
3460
3686
if (!-- dev -> suspend_count ) {
3461
3687
/* resume interrupt URBs */
3462
3688
if (dev -> urb_intr && test_bit (EVENT_DEV_OPEN , & dev -> flags ))
0 commit comments