aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-01-07 00:12:09 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-01-24 03:13:37 -0500
commit67fd4fcb78a7ced369a6bd8a131ec8c65ebd2bbb (patch)
tree53747c0e34152d47c440f9dbb8318301747ccbab /drivers/net/e1000e
parentbb134d2298b49f50cf6d9388410fba96272905dc (diff)
e1000e: convert to stats64
Based on the patch provided by Flavio Leitner <fleitner@redhat.com> Provides accurate stats at the time user reads them. v2: fixed whitespace/merging issues (by Jeff Kirsher) v3: fixed namespacing issues (by Bruce Allan) CC: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Flavio Leitner <fleitner@redhat.com>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/e1000.h5
-rw-r--r--drivers/net/e1000e/ethtool.c37
-rw-r--r--drivers/net/e1000e/netdev.c72
3 files changed, 80 insertions, 34 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index e610e1369053..00bf595ebd67 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -364,6 +364,7 @@ struct e1000_adapter {
364 /* structs defined in e1000_hw.h */ 364 /* structs defined in e1000_hw.h */
365 struct e1000_hw hw; 365 struct e1000_hw hw;
366 366
367 spinlock_t stats64_lock;
367 struct e1000_hw_stats stats; 368 struct e1000_hw_stats stats;
368 struct e1000_phy_info phy_info; 369 struct e1000_phy_info phy_info;
369 struct e1000_phy_stats phy_stats; 370 struct e1000_phy_stats phy_stats;
@@ -494,7 +495,9 @@ extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter);
494extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter); 495extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
495extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); 496extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
496extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); 497extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
497extern void e1000e_update_stats(struct e1000_adapter *adapter); 498extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
499 struct rtnl_link_stats64
500 *stats);
498extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); 501extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
499extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); 502extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
500extern void e1000e_get_hw_control(struct e1000_adapter *adapter); 503extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index fa08b6336cfb..dfa44de9cf0d 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -46,15 +46,15 @@ struct e1000_stats {
46}; 46};
47 47
48#define E1000_STAT(str, m) { \ 48#define E1000_STAT(str, m) { \
49 .stat_string = str, \ 49 .stat_string = str, \
50 .type = E1000_STATS, \ 50 .type = E1000_STATS, \
51 .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ 51 .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \
52 .stat_offset = offsetof(struct e1000_adapter, m) } 52 .stat_offset = offsetof(struct e1000_adapter, m) }
53#define E1000_NETDEV_STAT(str, m) { \ 53#define E1000_NETDEV_STAT(str, m) { \
54 .stat_string = str, \ 54 .stat_string = str, \
55 .type = NETDEV_STATS, \ 55 .type = NETDEV_STATS, \
56 .sizeof_stat = sizeof(((struct net_device *)0)->m), \ 56 .sizeof_stat = sizeof(((struct rtnl_link_stats64 *)0)->m), \
57 .stat_offset = offsetof(struct net_device, m) } 57 .stat_offset = offsetof(struct rtnl_link_stats64, m) }
58 58
59static const struct e1000_stats e1000_gstrings_stats[] = { 59static const struct e1000_stats e1000_gstrings_stats[] = {
60 E1000_STAT("rx_packets", stats.gprc), 60 E1000_STAT("rx_packets", stats.gprc),
@@ -65,21 +65,21 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
65 E1000_STAT("tx_broadcast", stats.bptc), 65 E1000_STAT("tx_broadcast", stats.bptc),
66 E1000_STAT("rx_multicast", stats.mprc), 66 E1000_STAT("rx_multicast", stats.mprc),
67 E1000_STAT("tx_multicast", stats.mptc), 67 E1000_STAT("tx_multicast", stats.mptc),
68 E1000_NETDEV_STAT("rx_errors", stats.rx_errors), 68 E1000_NETDEV_STAT("rx_errors", rx_errors),
69 E1000_NETDEV_STAT("tx_errors", stats.tx_errors), 69 E1000_NETDEV_STAT("tx_errors", tx_errors),
70 E1000_NETDEV_STAT("tx_dropped", stats.tx_dropped), 70 E1000_NETDEV_STAT("tx_dropped", tx_dropped),
71 E1000_STAT("multicast", stats.mprc), 71 E1000_STAT("multicast", stats.mprc),
72 E1000_STAT("collisions", stats.colc), 72 E1000_STAT("collisions", stats.colc),
73 E1000_NETDEV_STAT("rx_length_errors", stats.rx_length_errors), 73 E1000_NETDEV_STAT("rx_length_errors", rx_length_errors),
74 E1000_NETDEV_STAT("rx_over_errors", stats.rx_over_errors), 74 E1000_NETDEV_STAT("rx_over_errors", rx_over_errors),
75 E1000_STAT("rx_crc_errors", stats.crcerrs), 75 E1000_STAT("rx_crc_errors", stats.crcerrs),
76 E1000_NETDEV_STAT("rx_frame_errors", stats.rx_frame_errors), 76 E1000_NETDEV_STAT("rx_frame_errors", rx_frame_errors),
77 E1000_STAT("rx_no_buffer_count", stats.rnbc), 77 E1000_STAT("rx_no_buffer_count", stats.rnbc),
78 E1000_STAT("rx_missed_errors", stats.mpc), 78 E1000_STAT("rx_missed_errors", stats.mpc),
79 E1000_STAT("tx_aborted_errors", stats.ecol), 79 E1000_STAT("tx_aborted_errors", stats.ecol),
80 E1000_STAT("tx_carrier_errors", stats.tncrs), 80 E1000_STAT("tx_carrier_errors", stats.tncrs),
81 E1000_NETDEV_STAT("tx_fifo_errors", stats.tx_fifo_errors), 81 E1000_NETDEV_STAT("tx_fifo_errors", tx_fifo_errors),
82 E1000_NETDEV_STAT("tx_heartbeat_errors", stats.tx_heartbeat_errors), 82 E1000_NETDEV_STAT("tx_heartbeat_errors", tx_heartbeat_errors),
83 E1000_STAT("tx_window_errors", stats.latecol), 83 E1000_STAT("tx_window_errors", stats.latecol),
84 E1000_STAT("tx_abort_late_coll", stats.latecol), 84 E1000_STAT("tx_abort_late_coll", stats.latecol),
85 E1000_STAT("tx_deferred_ok", stats.dc), 85 E1000_STAT("tx_deferred_ok", stats.dc),
@@ -1982,14 +1982,15 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
1982 u64 *data) 1982 u64 *data)
1983{ 1983{
1984 struct e1000_adapter *adapter = netdev_priv(netdev); 1984 struct e1000_adapter *adapter = netdev_priv(netdev);
1985 struct rtnl_link_stats64 net_stats;
1985 int i; 1986 int i;
1986 char *p = NULL; 1987 char *p = NULL;
1987 1988
1988 e1000e_update_stats(adapter); 1989 e1000e_get_stats64(netdev, &net_stats);
1989 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { 1990 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
1990 switch (e1000_gstrings_stats[i].type) { 1991 switch (e1000_gstrings_stats[i].type) {
1991 case NETDEV_STATS: 1992 case NETDEV_STATS:
1992 p = (char *) netdev + 1993 p = (char *) &net_stats +
1993 e1000_gstrings_stats[i].stat_offset; 1994 e1000_gstrings_stats[i].stat_offset;
1994 break; 1995 break;
1995 case E1000_STATS: 1996 case E1000_STATS:
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 1c18f26b0812..1c2f33dd0633 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -900,8 +900,6 @@ next_desc:
900 900
901 adapter->total_rx_bytes += total_rx_bytes; 901 adapter->total_rx_bytes += total_rx_bytes;
902 adapter->total_rx_packets += total_rx_packets; 902 adapter->total_rx_packets += total_rx_packets;
903 netdev->stats.rx_bytes += total_rx_bytes;
904 netdev->stats.rx_packets += total_rx_packets;
905 return cleaned; 903 return cleaned;
906} 904}
907 905
@@ -1057,8 +1055,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
1057 } 1055 }
1058 adapter->total_tx_bytes += total_tx_bytes; 1056 adapter->total_tx_bytes += total_tx_bytes;
1059 adapter->total_tx_packets += total_tx_packets; 1057 adapter->total_tx_packets += total_tx_packets;
1060 netdev->stats.tx_bytes += total_tx_bytes;
1061 netdev->stats.tx_packets += total_tx_packets;
1062 return count < tx_ring->count; 1058 return count < tx_ring->count;
1063} 1059}
1064 1060
@@ -1245,8 +1241,6 @@ next_desc:
1245 1241
1246 adapter->total_rx_bytes += total_rx_bytes; 1242 adapter->total_rx_bytes += total_rx_bytes;
1247 adapter->total_rx_packets += total_rx_packets; 1243 adapter->total_rx_packets += total_rx_packets;
1248 netdev->stats.rx_bytes += total_rx_bytes;
1249 netdev->stats.rx_packets += total_rx_packets;
1250 return cleaned; 1244 return cleaned;
1251} 1245}
1252 1246
@@ -1426,8 +1420,6 @@ next_desc:
1426 1420
1427 adapter->total_rx_bytes += total_rx_bytes; 1421 adapter->total_rx_bytes += total_rx_bytes;
1428 adapter->total_rx_packets += total_rx_packets; 1422 adapter->total_rx_packets += total_rx_packets;
1429 netdev->stats.rx_bytes += total_rx_bytes;
1430 netdev->stats.rx_packets += total_rx_packets;
1431 return cleaned; 1423 return cleaned;
1432} 1424}
1433 1425
@@ -3338,6 +3330,8 @@ int e1000e_up(struct e1000_adapter *adapter)
3338 return 0; 3330 return 0;
3339} 3331}
3340 3332
3333static void e1000e_update_stats(struct e1000_adapter *adapter);
3334
3341void e1000e_down(struct e1000_adapter *adapter) 3335void e1000e_down(struct e1000_adapter *adapter)
3342{ 3336{
3343 struct net_device *netdev = adapter->netdev; 3337 struct net_device *netdev = adapter->netdev;
@@ -3372,6 +3366,11 @@ void e1000e_down(struct e1000_adapter *adapter)
3372 del_timer_sync(&adapter->phy_info_timer); 3366 del_timer_sync(&adapter->phy_info_timer);
3373 3367
3374 netif_carrier_off(netdev); 3368 netif_carrier_off(netdev);
3369
3370 spin_lock(&adapter->stats64_lock);
3371 e1000e_update_stats(adapter);
3372 spin_unlock(&adapter->stats64_lock);
3373
3375 adapter->link_speed = 0; 3374 adapter->link_speed = 0;
3376 adapter->link_duplex = 0; 3375 adapter->link_duplex = 0;
3377 3376
@@ -3413,6 +3412,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
3413 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 3412 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
3414 adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; 3413 adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
3415 3414
3415 spin_lock_init(&adapter->stats64_lock);
3416
3416 e1000e_set_interrupt_capability(adapter); 3417 e1000e_set_interrupt_capability(adapter);
3417 3418
3418 if (e1000_alloc_queues(adapter)) 3419 if (e1000_alloc_queues(adapter))
@@ -3886,7 +3887,7 @@ release:
3886 * e1000e_update_stats - Update the board statistics counters 3887 * e1000e_update_stats - Update the board statistics counters
3887 * @adapter: board private structure 3888 * @adapter: board private structure
3888 **/ 3889 **/
3889void e1000e_update_stats(struct e1000_adapter *adapter) 3890static void e1000e_update_stats(struct e1000_adapter *adapter)
3890{ 3891{
3891 struct net_device *netdev = adapter->netdev; 3892 struct net_device *netdev = adapter->netdev;
3892 struct e1000_hw *hw = &adapter->hw; 3893 struct e1000_hw *hw = &adapter->hw;
@@ -4285,7 +4286,9 @@ static void e1000_watchdog_task(struct work_struct *work)
4285 } 4286 }
4286 4287
4287link_up: 4288link_up:
4289 spin_lock(&adapter->stats64_lock);
4288 e1000e_update_stats(adapter); 4290 e1000e_update_stats(adapter);
4291 spin_unlock(&adapter->stats64_lock);
4289 4292
4290 mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; 4293 mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
4291 adapter->tpt_old = adapter->stats.tpt; 4294 adapter->tpt_old = adapter->stats.tpt;
@@ -4897,16 +4900,55 @@ static void e1000_reset_task(struct work_struct *work)
4897} 4900}
4898 4901
4899/** 4902/**
4900 * e1000_get_stats - Get System Network Statistics 4903 * e1000_get_stats64 - Get System Network Statistics
4901 * @netdev: network interface device structure 4904 * @netdev: network interface device structure
4905 * @stats: rtnl_link_stats64 pointer
4902 * 4906 *
4903 * Returns the address of the device statistics structure. 4907 * Returns the address of the device statistics structure.
4904 * The statistics are actually updated from the timer callback.
4905 **/ 4908 **/
4906static struct net_device_stats *e1000_get_stats(struct net_device *netdev) 4909struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
4910 struct rtnl_link_stats64 *stats)
4907{ 4911{
4908 /* only return the current stats */ 4912 struct e1000_adapter *adapter = netdev_priv(netdev);
4909 return &netdev->stats; 4913
4914 memset(stats, 0, sizeof(struct rtnl_link_stats64));
4915 spin_lock(&adapter->stats64_lock);
4916 e1000e_update_stats(adapter);
4917 /* Fill out the OS statistics structure */
4918 stats->rx_bytes = adapter->stats.gorc;
4919 stats->rx_packets = adapter->stats.gprc;
4920 stats->tx_bytes = adapter->stats.gotc;
4921 stats->tx_packets = adapter->stats.gptc;
4922 stats->multicast = adapter->stats.mprc;
4923 stats->collisions = adapter->stats.colc;
4924
4925 /* Rx Errors */
4926
4927 /*
4928 * RLEC on some newer hardware can be incorrect so build
4929 * our own version based on RUC and ROC
4930 */
4931 stats->rx_errors = adapter->stats.rxerrc +
4932 adapter->stats.crcerrs + adapter->stats.algnerrc +
4933 adapter->stats.ruc + adapter->stats.roc +
4934 adapter->stats.cexterr;
4935 stats->rx_length_errors = adapter->stats.ruc +
4936 adapter->stats.roc;
4937 stats->rx_crc_errors = adapter->stats.crcerrs;
4938 stats->rx_frame_errors = adapter->stats.algnerrc;
4939 stats->rx_missed_errors = adapter->stats.mpc;
4940
4941 /* Tx Errors */
4942 stats->tx_errors = adapter->stats.ecol +
4943 adapter->stats.latecol;
4944 stats->tx_aborted_errors = adapter->stats.ecol;
4945 stats->tx_window_errors = adapter->stats.latecol;
4946 stats->tx_carrier_errors = adapter->stats.tncrs;
4947
4948 /* Tx Dropped needs to be maintained elsewhere */
4949
4950 spin_unlock(&adapter->stats64_lock);
4951 return stats;
4910} 4952}
4911 4953
4912/** 4954/**
@@ -5675,7 +5717,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
5675 .ndo_open = e1000_open, 5717 .ndo_open = e1000_open,
5676 .ndo_stop = e1000_close, 5718 .ndo_stop = e1000_close,
5677 .ndo_start_xmit = e1000_xmit_frame, 5719 .ndo_start_xmit = e1000_xmit_frame,
5678 .ndo_get_stats = e1000_get_stats, 5720 .ndo_get_stats64 = e1000e_get_stats64,
5679 .ndo_set_multicast_list = e1000_set_multi, 5721 .ndo_set_multicast_list = e1000_set_multi,
5680 .ndo_set_mac_address = e1000_set_mac, 5722 .ndo_set_mac_address = e1000_set_mac,
5681 .ndo_change_mtu = e1000_change_mtu, 5723 .ndo_change_mtu = e1000_change_mtu,