aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/igb_ethtool.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-11-12 13:37:38 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-13 23:46:51 -0500
commit128e45eb61b90c0c3094139cab6d00f67ff31377 (patch)
tree202d2edd2e4707fc4a0b1d6c2166d7cd335a8b2f /drivers/net/igb/igb_ethtool.c
parenta99955fc067f57cf3b627d4c74bf7952a2d51029 (diff)
igb: Rework how netdev->stats is handled
This patch does some refactoring work that I felt was needed after reviewing the changes recently submitted relating to the replacement of net_stats with netdev->stats. This patch essentially creates two different collections of stats. The first handles the adapter specific states and is stored in gstring_stats, and the second is for netdev specific stats and is stored in gstring_net_stats. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/igb_ethtool.c')
-rw-r--r--drivers/net/igb/igb_ethtool.c171
1 files changed, 88 insertions, 83 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index f2b28254f2a0..c1cde5b44906 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -37,77 +37,88 @@
37 37
38#include "igb.h" 38#include "igb.h"
39 39
40enum {NETDEV_STATS, IGB_STATS};
41
42struct igb_stats { 40struct igb_stats {
43 char stat_string[ETH_GSTRING_LEN]; 41 char stat_string[ETH_GSTRING_LEN];
44 int type;
45 int sizeof_stat; 42 int sizeof_stat;
46 int stat_offset; 43 int stat_offset;
47}; 44};
48 45
49#define IGB_STAT(m) IGB_STATS, \ 46#define IGB_STAT(_name, _stat) { \
50 FIELD_SIZEOF(struct igb_adapter, m), \ 47 .stat_string = _name, \
51 offsetof(struct igb_adapter, m) 48 .sizeof_stat = FIELD_SIZEOF(struct igb_adapter, _stat), \
52#define IGB_NETDEV_STAT(m) NETDEV_STATS, \ 49 .stat_offset = offsetof(struct igb_adapter, _stat) \
53 FIELD_SIZEOF(struct net_device, m), \ 50}
54 offsetof(struct net_device, m)
55
56static const struct igb_stats igb_gstrings_stats[] = { 51static const struct igb_stats igb_gstrings_stats[] = {
57 { "rx_packets", IGB_STAT(stats.gprc) }, 52 IGB_STAT("rx_packets", stats.gprc),
58 { "tx_packets", IGB_STAT(stats.gptc) }, 53 IGB_STAT("tx_packets", stats.gptc),
59 { "rx_bytes", IGB_STAT(stats.gorc) }, 54 IGB_STAT("rx_bytes", stats.gorc),
60 { "tx_bytes", IGB_STAT(stats.gotc) }, 55 IGB_STAT("tx_bytes", stats.gotc),
61 { "rx_broadcast", IGB_STAT(stats.bprc) }, 56 IGB_STAT("rx_broadcast", stats.bprc),
62 { "tx_broadcast", IGB_STAT(stats.bptc) }, 57 IGB_STAT("tx_broadcast", stats.bptc),
63 { "rx_multicast", IGB_STAT(stats.mprc) }, 58 IGB_STAT("rx_multicast", stats.mprc),
64 { "tx_multicast", IGB_STAT(stats.mptc) }, 59 IGB_STAT("tx_multicast", stats.mptc),
65 { "rx_errors", IGB_NETDEV_STAT(stats.rx_errors) }, 60 IGB_STAT("multicast", stats.mprc),
66 { "tx_errors", IGB_NETDEV_STAT(stats.tx_errors) }, 61 IGB_STAT("collisions", stats.colc),
67 { "tx_dropped", IGB_NETDEV_STAT(stats.tx_dropped) }, 62 IGB_STAT("rx_crc_errors", stats.crcerrs),
68 { "multicast", IGB_STAT(stats.mprc) }, 63 IGB_STAT("rx_no_buffer_count", stats.rnbc),
69 { "collisions", IGB_STAT(stats.colc) }, 64 IGB_STAT("rx_missed_errors", stats.mpc),
70 { "rx_length_errors", IGB_NETDEV_STAT(stats.rx_length_errors) }, 65 IGB_STAT("tx_aborted_errors", stats.ecol),
71 { "rx_over_errors", IGB_NETDEV_STAT(stats.rx_over_errors) }, 66 IGB_STAT("tx_carrier_errors", stats.tncrs),
72 { "rx_crc_errors", IGB_STAT(stats.crcerrs) }, 67 IGB_STAT("tx_window_errors", stats.latecol),
73 { "rx_frame_errors", IGB_NETDEV_STAT(stats.rx_frame_errors) }, 68 IGB_STAT("tx_abort_late_coll", stats.latecol),
74 { "rx_no_buffer_count", IGB_STAT(stats.rnbc) }, 69 IGB_STAT("tx_deferred_ok", stats.dc),
75 { "rx_queue_drop_packet_count", IGB_NETDEV_STAT(stats.rx_fifo_errors) }, 70 IGB_STAT("tx_single_coll_ok", stats.scc),
76 { "rx_missed_errors", IGB_STAT(stats.mpc) }, 71 IGB_STAT("tx_multi_coll_ok", stats.mcc),
77 { "tx_aborted_errors", IGB_STAT(stats.ecol) }, 72 IGB_STAT("tx_timeout_count", tx_timeout_count),
78 { "tx_carrier_errors", IGB_STAT(stats.tncrs) }, 73 IGB_STAT("rx_long_length_errors", stats.roc),
79 { "tx_fifo_errors", IGB_NETDEV_STAT(stats.tx_fifo_errors) }, 74 IGB_STAT("rx_short_length_errors", stats.ruc),
80 { "tx_heartbeat_errors", IGB_NETDEV_STAT(stats.tx_heartbeat_errors) }, 75 IGB_STAT("rx_align_errors", stats.algnerrc),
81 { "tx_window_errors", IGB_STAT(stats.latecol) }, 76 IGB_STAT("tx_tcp_seg_good", stats.tsctc),
82 { "tx_abort_late_coll", IGB_STAT(stats.latecol) }, 77 IGB_STAT("tx_tcp_seg_failed", stats.tsctfc),
83 { "tx_deferred_ok", IGB_STAT(stats.dc) }, 78 IGB_STAT("rx_flow_control_xon", stats.xonrxc),
84 { "tx_single_coll_ok", IGB_STAT(stats.scc) }, 79 IGB_STAT("rx_flow_control_xoff", stats.xoffrxc),
85 { "tx_multi_coll_ok", IGB_STAT(stats.mcc) }, 80 IGB_STAT("tx_flow_control_xon", stats.xontxc),
86 { "tx_timeout_count", IGB_STAT(tx_timeout_count) }, 81 IGB_STAT("tx_flow_control_xoff", stats.xofftxc),
87 { "rx_long_length_errors", IGB_STAT(stats.roc) }, 82 IGB_STAT("rx_long_byte_count", stats.gorc),
88 { "rx_short_length_errors", IGB_STAT(stats.ruc) }, 83 IGB_STAT("tx_dma_out_of_sync", stats.doosync),
89 { "rx_align_errors", IGB_STAT(stats.algnerrc) }, 84 IGB_STAT("tx_smbus", stats.mgptc),
90 { "tx_tcp_seg_good", IGB_STAT(stats.tsctc) }, 85 IGB_STAT("rx_smbus", stats.mgprc),
91 { "tx_tcp_seg_failed", IGB_STAT(stats.tsctfc) }, 86 IGB_STAT("dropped_smbus", stats.mgpdc),
92 { "rx_flow_control_xon", IGB_STAT(stats.xonrxc) }, 87};
93 { "rx_flow_control_xoff", IGB_STAT(stats.xoffrxc) }, 88
94 { "tx_flow_control_xon", IGB_STAT(stats.xontxc) }, 89#define IGB_NETDEV_STAT(_net_stat) { \
95 { "tx_flow_control_xoff", IGB_STAT(stats.xofftxc) }, 90 .stat_string = __stringify(_net_stat), \
96 { "rx_long_byte_count", IGB_STAT(stats.gorc) }, 91 .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
97 { "tx_dma_out_of_sync", IGB_STAT(stats.doosync) }, 92 .stat_offset = offsetof(struct net_device_stats, _net_stat) \
98 { "tx_smbus", IGB_STAT(stats.mgptc) }, 93}
99 { "rx_smbus", IGB_STAT(stats.mgprc) }, 94static const struct igb_stats igb_gstrings_net_stats[] = {
100 { "dropped_smbus", IGB_STAT(stats.mgpdc) }, 95 IGB_NETDEV_STAT(rx_errors),
96 IGB_NETDEV_STAT(tx_errors),
97 IGB_NETDEV_STAT(tx_dropped),
98 IGB_NETDEV_STAT(rx_length_errors),
99 IGB_NETDEV_STAT(rx_over_errors),
100 IGB_NETDEV_STAT(rx_frame_errors),
101 IGB_NETDEV_STAT(rx_fifo_errors),
102 IGB_NETDEV_STAT(tx_fifo_errors),
103 IGB_NETDEV_STAT(tx_heartbeat_errors)
101}; 104};
102 105
106#define IGB_GLOBAL_STATS_LEN \
107 (sizeof(igb_gstrings_stats) / sizeof(struct igb_stats))
108#define IGB_NETDEV_STATS_LEN \
109 (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats))
110#define IGB_RX_QUEUE_STATS_LEN \
111 (sizeof(struct igb_rx_queue_stats) / sizeof(u64))
112#define IGB_TX_QUEUE_STATS_LEN \
113 (sizeof(struct igb_tx_queue_stats) / sizeof(u64))
103#define IGB_QUEUE_STATS_LEN \ 114#define IGB_QUEUE_STATS_LEN \
104 ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ 115 ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \
105 (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \ 116 IGB_RX_QUEUE_STATS_LEN) + \
106 (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \ 117 (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \
107 (sizeof(struct igb_tx_queue_stats) / sizeof(u64)))) 118 IGB_TX_QUEUE_STATS_LEN))
108#define IGB_GLOBAL_STATS_LEN \ 119#define IGB_STATS_LEN \
109 (sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)) 120 (IGB_GLOBAL_STATS_LEN + IGB_NETDEV_STATS_LEN + IGB_QUEUE_STATS_LEN)
110#define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN) 121
111static const char igb_gstrings_test[][ETH_GSTRING_LEN] = { 122static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
112 "Register test (offline)", "Eeprom test (offline)", 123 "Register test (offline)", "Eeprom test (offline)",
113 "Interrupt test (offline)", "Loopback test (offline)", 124 "Interrupt test (offline)", "Loopback test (offline)",
@@ -1922,43 +1933,32 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
1922 struct ethtool_stats *stats, u64 *data) 1933 struct ethtool_stats *stats, u64 *data)
1923{ 1934{
1924 struct igb_adapter *adapter = netdev_priv(netdev); 1935 struct igb_adapter *adapter = netdev_priv(netdev);
1936 struct net_device_stats *net_stats = &netdev->stats;
1925 u64 *queue_stat; 1937 u64 *queue_stat;
1926 int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64); 1938 int i, j, k;
1927 int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64); 1939 char *p;
1928 int j;
1929 int i;
1930 char *p = NULL;
1931 1940
1932 igb_update_stats(adapter); 1941 igb_update_stats(adapter);
1933 1942
1934 for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { 1943 for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
1935 switch (igb_gstrings_stats[i].type) { 1944 p = (char *)adapter + igb_gstrings_stats[i].stat_offset;
1936 case NETDEV_STATS:
1937 p = (char *) netdev +
1938 igb_gstrings_stats[i].stat_offset;
1939 break;
1940 case IGB_STATS:
1941 p = (char *) adapter +
1942 igb_gstrings_stats[i].stat_offset;
1943 break;
1944 }
1945
1946 data[i] = (igb_gstrings_stats[i].sizeof_stat == 1945 data[i] = (igb_gstrings_stats[i].sizeof_stat ==
1947 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1946 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1948 } 1947 }
1948 for (j = 0; j < IGB_NETDEV_STATS_LEN; j++, i++) {
1949 p = (char *)net_stats + igb_gstrings_net_stats[j].stat_offset;
1950 data[i] = (igb_gstrings_net_stats[j].sizeof_stat ==
1951 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1952 }
1949 for (j = 0; j < adapter->num_tx_queues; j++) { 1953 for (j = 0; j < adapter->num_tx_queues; j++) {
1950 int k;
1951 queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats; 1954 queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
1952 for (k = 0; k < stat_count_tx; k++) 1955 for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
1953 data[i + k] = queue_stat[k]; 1956 data[i] = queue_stat[k];
1954 i += k;
1955 } 1957 }
1956 for (j = 0; j < adapter->num_rx_queues; j++) { 1958 for (j = 0; j < adapter->num_rx_queues; j++) {
1957 int k;
1958 queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats; 1959 queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
1959 for (k = 0; k < stat_count_rx; k++) 1960 for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
1960 data[i + k] = queue_stat[k]; 1961 data[i] = queue_stat[k];
1961 i += k;
1962 } 1962 }
1963} 1963}
1964 1964
@@ -1979,6 +1979,11 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
1979 ETH_GSTRING_LEN); 1979 ETH_GSTRING_LEN);
1980 p += ETH_GSTRING_LEN; 1980 p += ETH_GSTRING_LEN;
1981 } 1981 }
1982 for (i = 0; i < IGB_NETDEV_STATS_LEN; i++) {
1983 memcpy(p, igb_gstrings_net_stats[i].stat_string,
1984 ETH_GSTRING_LEN);
1985 p += ETH_GSTRING_LEN;
1986 }
1982 for (i = 0; i < adapter->num_tx_queues; i++) { 1987 for (i = 0; i < adapter->num_tx_queues; i++) {
1983 sprintf(p, "tx_queue_%u_packets", i); 1988 sprintf(p, "tx_queue_%u_packets", i);
1984 p += ETH_GSTRING_LEN; 1989 p += ETH_GSTRING_LEN;