aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWoojung Huh <woojung.huh@microchip.com>2016-03-16 18:10:42 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-18 22:27:48 -0400
commita59f8c5b048dc938fb958c91c282c865cd845705 (patch)
tree29ee9a71fe1aa64be2b2cf18252dd7cbddfd1a32
parent20ff55655a93554611fb7790c8a2d29ee4598d24 (diff)
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>
-rw-r--r--drivers/net/usb/lan78xx.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index f20890ee03f3..d36d5ebf37f3 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -3261,6 +3261,54 @@ void lan78xx_tx_timeout(struct net_device *net)
3261 tasklet_schedule(&dev->bh); 3261 tasklet_schedule(&dev->bh);
3262} 3262}
3263 3263
3264struct 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
3264static const struct net_device_ops lan78xx_netdev_ops = { 3312static const struct net_device_ops lan78xx_netdev_ops = {
3265 .ndo_open = lan78xx_open, 3313 .ndo_open = lan78xx_open,
3266 .ndo_stop = lan78xx_stop, 3314 .ndo_stop = lan78xx_stop,
@@ -3274,6 +3322,7 @@ static const struct net_device_ops lan78xx_netdev_ops = {
3274 .ndo_set_features = lan78xx_set_features, 3322 .ndo_set_features = lan78xx_set_features,
3275 .ndo_vlan_rx_add_vid = lan78xx_vlan_rx_add_vid, 3323 .ndo_vlan_rx_add_vid = lan78xx_vlan_rx_add_vid,
3276 .ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid, 3324 .ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid,
3325 .ndo_get_stats64 = lan78xx_get_stats64,
3277}; 3326};
3278 3327
3279static void lan78xx_stat_monitor(unsigned long param) 3328static void lan78xx_stat_monitor(unsigned long param)