Skip to content

Commit a59f8c5

Browse files
WoojungHuhdavem330
authored andcommitted
lan78xx: add ndo_get_stats64
Add lan78xx_get_stats64 of ndo_get_stats64 to report all statistics counters including errors from HW statistics. Read from HW when auto suspend is disabled, use saved counter when auto suspend is enabled because periodic call to ndo_get_stats64 prevents USB auto suspend. Signed-off-by: Woojung Huh <woojung.huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 20ff556 commit a59f8c5

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

drivers/net/usb/lan78xx.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,6 +3261,54 @@ void lan78xx_tx_timeout(struct net_device *net)
32613261
tasklet_schedule(&dev->bh);
32623262
}
32633263

3264+
struct rtnl_link_stats64 *lan78xx_get_stats64(struct net_device *netdev,
3265+
struct rtnl_link_stats64 *storage)
3266+
{
3267+
struct lan78xx_net *dev = netdev_priv(netdev);
3268+
struct lan78xx_statstage64 stats;
3269+
3270+
/* curr_stat is updated by timer.
3271+
* periodic reading from HW will prevent from entering USB auto suspend.
3272+
* if autosuspend is disabled, read from HW.
3273+
*/
3274+
if (!dev->udev->dev.power.runtime_auto)
3275+
lan78xx_update_stats(dev);
3276+
3277+
mutex_lock(&dev->stats.access_lock);
3278+
memcpy(&stats, &dev->stats.curr_stat, sizeof(stats));
3279+
mutex_unlock(&dev->stats.access_lock);
3280+
3281+
/* calc by driver */
3282+
storage->rx_packets = (__u64)netdev->stats.rx_packets;
3283+
storage->tx_packets = (__u64)netdev->stats.tx_packets;
3284+
storage->rx_bytes = (__u64)netdev->stats.rx_bytes;
3285+
storage->tx_bytes = (__u64)netdev->stats.tx_bytes;
3286+
3287+
/* use counter */
3288+
storage->rx_length_errors = stats.rx_undersize_frame_errors +
3289+
stats.rx_oversize_frame_errors;
3290+
storage->rx_crc_errors = stats.rx_fcs_errors;
3291+
storage->rx_frame_errors = stats.rx_alignment_errors;
3292+
storage->rx_fifo_errors = stats.rx_dropped_frames;
3293+
storage->rx_over_errors = stats.rx_oversize_frame_errors;
3294+
storage->rx_errors = stats.rx_fcs_errors +
3295+
stats.rx_alignment_errors +
3296+
stats.rx_fragment_errors +
3297+
stats.rx_jabber_errors +
3298+
stats.rx_undersize_frame_errors +
3299+
stats.rx_oversize_frame_errors +
3300+
stats.rx_dropped_frames;
3301+
3302+
storage->tx_carrier_errors = stats.tx_carrier_errors;
3303+
storage->tx_errors = stats.tx_fcs_errors +
3304+
stats.tx_excess_deferral_errors +
3305+
stats.tx_carrier_errors;
3306+
3307+
storage->multicast = stats.rx_multicast_frames;
3308+
3309+
return storage;
3310+
}
3311+
32643312
static const struct net_device_ops lan78xx_netdev_ops = {
32653313
.ndo_open = lan78xx_open,
32663314
.ndo_stop = lan78xx_stop,
@@ -3274,6 +3322,7 @@ static const struct net_device_ops lan78xx_netdev_ops = {
32743322
.ndo_set_features = lan78xx_set_features,
32753323
.ndo_vlan_rx_add_vid = lan78xx_vlan_rx_add_vid,
32763324
.ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid,
3325+
.ndo_get_stats64 = lan78xx_get_stats64,
32773326
};
32783327

32793328
static void lan78xx_stat_monitor(unsigned long param)

0 commit comments

Comments
 (0)