aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-12-14 16:52:56 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-08-27 17:25:55 -0400
commitcd0ecc9a6d279c8c5c5336f576330c45f5c80939 (patch)
treedb74cbf4e4e4e46e413d9d8cf53ce9f804670380
parentb681e57c38d81eee45f8bd7465d2a2af872800e3 (diff)
sfc: Delegate MAC/NIC statistic description to efx_nic_type
Various hardware statistics that are available for Siena are unavailable or meaningless for Falcon. Huntington adds further to the NIC-type-specific statistics, as it has different MAC blocks from Falcon/Siena. All NIC types still provide most statistics by DMA, and use little-endian byte order. Therefore: 1. Add some general utility functions for reporting hardware statistics, efx_nic_describe_stats() and efx_nic_update_stats(). 2. Add an efx_nic_type::describe_stats operation to get the number and names of statistics, implemented using efx_nic_describe_stats() 3. Change efx_nic_type::update_stats to store the core statistics (struct rtnl_link_stats64) or full statistics (array of u64) in a caller-provided buffer. Use efx_nic_update_stats() to aid in the implementation. 4. Rename struct efx_ethtool_stat to struct efx_sw_stat_desc and EFX_ETHTOOL_NUM_STATS to EFX_ETHTOOL_SW_STAT_COUNT. 5. Remove efx_nic::mac_stats and struct efx_mac_stats. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/efx.c27
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c117
-rw-r--r--drivers/net/ethernet/sfc/falcon.c212
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c13
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h96
-rw-r--r--drivers/net/ethernet/sfc/nic.c83
-rw-r--r--drivers/net/ethernet/sfc/nic.h124
-rw-r--r--drivers/net/ethernet/sfc/siena.c215
8 files changed, 498 insertions, 389 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 1d4f38895b9f..9fe375f1710a 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1920,34 +1920,9 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev,
1920 struct rtnl_link_stats64 *stats) 1920 struct rtnl_link_stats64 *stats)
1921{ 1921{
1922 struct efx_nic *efx = netdev_priv(net_dev); 1922 struct efx_nic *efx = netdev_priv(net_dev);
1923 struct efx_mac_stats *mac_stats = &efx->mac_stats;
1924 1923
1925 spin_lock_bh(&efx->stats_lock); 1924 spin_lock_bh(&efx->stats_lock);
1926 1925 efx->type->update_stats(efx, NULL, stats);
1927 efx->type->update_stats(efx);
1928
1929 stats->rx_packets = mac_stats->rx_packets;
1930 stats->tx_packets = mac_stats->tx_packets;
1931 stats->rx_bytes = mac_stats->rx_bytes;
1932 stats->tx_bytes = mac_stats->tx_bytes;
1933 stats->rx_dropped = efx->n_rx_nodesc_drop_cnt;
1934 stats->multicast = mac_stats->rx_multicast;
1935 stats->collisions = mac_stats->tx_collision;
1936 stats->rx_length_errors = (mac_stats->rx_gtjumbo +
1937 mac_stats->rx_length_error);
1938 stats->rx_crc_errors = mac_stats->rx_bad;
1939 stats->rx_frame_errors = mac_stats->rx_align_error;
1940 stats->rx_fifo_errors = mac_stats->rx_overflow;
1941 stats->rx_missed_errors = mac_stats->rx_missed;
1942 stats->tx_window_errors = mac_stats->tx_late_collision;
1943
1944 stats->rx_errors = (stats->rx_length_errors +
1945 stats->rx_crc_errors +
1946 stats->rx_frame_errors +
1947 mac_stats->rx_symbol_error);
1948 stats->tx_errors = (stats->tx_window_errors +
1949 mac_stats->tx_bad);
1950
1951 spin_unlock_bh(&efx->stats_lock); 1926 spin_unlock_bh(&efx->stats_lock);
1952 1927
1953 return stats; 1928 return stats;
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 86b439185446..0b8ffdfba3d8 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -19,10 +19,9 @@
19#include "filter.h" 19#include "filter.h"
20#include "nic.h" 20#include "nic.h"
21 21
22struct efx_ethtool_stat { 22struct efx_sw_stat_desc {
23 const char *name; 23 const char *name;
24 enum { 24 enum {
25 EFX_ETHTOOL_STAT_SOURCE_mac_stats,
26 EFX_ETHTOOL_STAT_SOURCE_nic, 25 EFX_ETHTOOL_STAT_SOURCE_nic,
27 EFX_ETHTOOL_STAT_SOURCE_channel, 26 EFX_ETHTOOL_STAT_SOURCE_channel,
28 EFX_ETHTOOL_STAT_SOURCE_tx_queue 27 EFX_ETHTOOL_STAT_SOURCE_tx_queue
@@ -31,7 +30,7 @@ struct efx_ethtool_stat {
31 u64(*get_stat) (void *field); /* Reader function */ 30 u64(*get_stat) (void *field); /* Reader function */
32}; 31};
33 32
34/* Initialiser for a struct #efx_ethtool_stat with type-checking */ 33/* Initialiser for a struct efx_sw_stat_desc with type-checking */
35#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \ 34#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \
36 get_stat_function) { \ 35 get_stat_function) { \
37 .name = #stat_name, \ 36 .name = #stat_name, \
@@ -48,24 +47,11 @@ static u64 efx_get_uint_stat(void *field)
48 return *(unsigned int *)field; 47 return *(unsigned int *)field;
49} 48}
50 49
51static u64 efx_get_u64_stat(void *field)
52{
53 return *(u64 *) field;
54}
55
56static u64 efx_get_atomic_stat(void *field) 50static u64 efx_get_atomic_stat(void *field)
57{ 51{
58 return atomic_read((atomic_t *) field); 52 return atomic_read((atomic_t *) field);
59} 53}
60 54
61#define EFX_ETHTOOL_U64_MAC_STAT(field) \
62 EFX_ETHTOOL_STAT(field, mac_stats, field, \
63 u64, efx_get_u64_stat)
64
65#define EFX_ETHTOOL_UINT_NIC_STAT(name) \
66 EFX_ETHTOOL_STAT(name, nic, n_##name, \
67 unsigned int, efx_get_uint_stat)
68
69#define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \ 55#define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \
70 EFX_ETHTOOL_STAT(field, nic, field, \ 56 EFX_ETHTOOL_STAT(field, nic, field, \
71 atomic_t, efx_get_atomic_stat) 57 atomic_t, efx_get_atomic_stat)
@@ -78,72 +64,11 @@ static u64 efx_get_atomic_stat(void *field)
78 EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \ 64 EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \
79 unsigned int, efx_get_uint_stat) 65 unsigned int, efx_get_uint_stat)
80 66
81static const struct efx_ethtool_stat efx_ethtool_stats[] = { 67static const struct efx_sw_stat_desc efx_sw_stat_desc[] = {
82 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes),
83 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes),
84 EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes),
85 EFX_ETHTOOL_U64_MAC_STAT(tx_packets),
86 EFX_ETHTOOL_U64_MAC_STAT(tx_bad),
87 EFX_ETHTOOL_U64_MAC_STAT(tx_pause),
88 EFX_ETHTOOL_U64_MAC_STAT(tx_control),
89 EFX_ETHTOOL_U64_MAC_STAT(tx_unicast),
90 EFX_ETHTOOL_U64_MAC_STAT(tx_multicast),
91 EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast),
92 EFX_ETHTOOL_U64_MAC_STAT(tx_lt64),
93 EFX_ETHTOOL_U64_MAC_STAT(tx_64),
94 EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127),
95 EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255),
96 EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511),
97 EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023),
98 EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx),
99 EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo),
100 EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo),
101 EFX_ETHTOOL_U64_MAC_STAT(tx_collision),
102 EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision),
103 EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision),
104 EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision),
105 EFX_ETHTOOL_U64_MAC_STAT(tx_deferred),
106 EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision),
107 EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred),
108 EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp),
109 EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error),
110 EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error),
111 EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts), 68 EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts),
112 EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), 69 EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers),
113 EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), 70 EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets),
114 EFX_ETHTOOL_UINT_TXQ_STAT(pushes), 71 EFX_ETHTOOL_UINT_TXQ_STAT(pushes),
115 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes),
116 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes),
117 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes),
118 EFX_ETHTOOL_U64_MAC_STAT(rx_packets),
119 EFX_ETHTOOL_U64_MAC_STAT(rx_good),
120 EFX_ETHTOOL_U64_MAC_STAT(rx_bad),
121 EFX_ETHTOOL_U64_MAC_STAT(rx_pause),
122 EFX_ETHTOOL_U64_MAC_STAT(rx_control),
123 EFX_ETHTOOL_U64_MAC_STAT(rx_unicast),
124 EFX_ETHTOOL_U64_MAC_STAT(rx_multicast),
125 EFX_ETHTOOL_U64_MAC_STAT(rx_broadcast),
126 EFX_ETHTOOL_U64_MAC_STAT(rx_lt64),
127 EFX_ETHTOOL_U64_MAC_STAT(rx_64),
128 EFX_ETHTOOL_U64_MAC_STAT(rx_65_to_127),
129 EFX_ETHTOOL_U64_MAC_STAT(rx_128_to_255),
130 EFX_ETHTOOL_U64_MAC_STAT(rx_256_to_511),
131 EFX_ETHTOOL_U64_MAC_STAT(rx_512_to_1023),
132 EFX_ETHTOOL_U64_MAC_STAT(rx_1024_to_15xx),
133 EFX_ETHTOOL_U64_MAC_STAT(rx_15xx_to_jumbo),
134 EFX_ETHTOOL_U64_MAC_STAT(rx_gtjumbo),
135 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_lt64),
136 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_64_to_15xx),
137 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_15xx_to_jumbo),
138 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_gtjumbo),
139 EFX_ETHTOOL_U64_MAC_STAT(rx_overflow),
140 EFX_ETHTOOL_U64_MAC_STAT(rx_missed),
141 EFX_ETHTOOL_U64_MAC_STAT(rx_false_carrier),
142 EFX_ETHTOOL_U64_MAC_STAT(rx_symbol_error),
143 EFX_ETHTOOL_U64_MAC_STAT(rx_align_error),
144 EFX_ETHTOOL_U64_MAC_STAT(rx_length_error),
145 EFX_ETHTOOL_U64_MAC_STAT(rx_internal_error),
146 EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt),
147 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), 72 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset),
148 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), 73 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc),
149 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err), 74 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err),
@@ -153,8 +78,7 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = {
153 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_nodesc_trunc), 78 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_nodesc_trunc),
154}; 79};
155 80
156/* Number of ethtool statistics */ 81#define EFX_ETHTOOL_SW_STAT_COUNT ARRAY_SIZE(efx_sw_stat_desc)
157#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
158 82
159#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB 83#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
160 84
@@ -424,12 +348,14 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
424static int efx_ethtool_get_sset_count(struct net_device *net_dev, 348static int efx_ethtool_get_sset_count(struct net_device *net_dev,
425 int string_set) 349 int string_set)
426{ 350{
351 struct efx_nic *efx = netdev_priv(net_dev);
352
427 switch (string_set) { 353 switch (string_set) {
428 case ETH_SS_STATS: 354 case ETH_SS_STATS:
429 return EFX_ETHTOOL_NUM_STATS; 355 return efx->type->describe_stats(efx, NULL) +
356 EFX_ETHTOOL_SW_STAT_COUNT;
430 case ETH_SS_TEST: 357 case ETH_SS_TEST:
431 return efx_ethtool_fill_self_tests(netdev_priv(net_dev), 358 return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
432 NULL, NULL, NULL);
433 default: 359 default:
434 return -EINVAL; 360 return -EINVAL;
435 } 361 }
@@ -443,9 +369,11 @@ static void efx_ethtool_get_strings(struct net_device *net_dev,
443 369
444 switch (string_set) { 370 switch (string_set) {
445 case ETH_SS_STATS: 371 case ETH_SS_STATS:
446 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) 372 strings += (efx->type->describe_stats(efx, strings) *
373 ETH_GSTRING_LEN);
374 for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++)
447 strlcpy(strings + i * ETH_GSTRING_LEN, 375 strlcpy(strings + i * ETH_GSTRING_LEN,
448 efx_ethtool_stats[i].name, ETH_GSTRING_LEN); 376 efx_sw_stat_desc[i].name, ETH_GSTRING_LEN);
449 break; 377 break;
450 case ETH_SS_TEST: 378 case ETH_SS_TEST:
451 efx_ethtool_fill_self_tests(efx, NULL, strings, NULL); 379 efx_ethtool_fill_self_tests(efx, NULL, strings, NULL);
@@ -461,27 +389,20 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
461 u64 *data) 389 u64 *data)
462{ 390{
463 struct efx_nic *efx = netdev_priv(net_dev); 391 struct efx_nic *efx = netdev_priv(net_dev);
464 struct efx_mac_stats *mac_stats = &efx->mac_stats; 392 const struct efx_sw_stat_desc *stat;
465 const struct efx_ethtool_stat *stat;
466 struct efx_channel *channel; 393 struct efx_channel *channel;
467 struct efx_tx_queue *tx_queue; 394 struct efx_tx_queue *tx_queue;
468 int i; 395 int i;
469 396
470 EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS);
471
472 spin_lock_bh(&efx->stats_lock); 397 spin_lock_bh(&efx->stats_lock);
473 398
474 /* Update MAC and NIC statistics */ 399 /* Get NIC statistics */
475 efx->type->update_stats(efx); 400 data += efx->type->update_stats(efx, data, NULL);
476 401
477 /* Fill detailed statistics buffer */ 402 /* Get software statistics */
478 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { 403 for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) {
479 stat = &efx_ethtool_stats[i]; 404 stat = &efx_sw_stat_desc[i];
480 switch (stat->source) { 405 switch (stat->source) {
481 case EFX_ETHTOOL_STAT_SOURCE_mac_stats:
482 data[i] = stat->get_stat((void *)mac_stats +
483 stat->offset);
484 break;
485 case EFX_ETHTOOL_STAT_SOURCE_nic: 406 case EFX_ETHTOOL_STAT_SOURCE_nic:
486 data[i] = stat->get_stat((void *)efx + stat->offset); 407 data[i] = stat->get_stat((void *)efx + stat->offset);
487 break; 408 break;
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index 76a9e0dd2308..0be1f3711c89 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -31,7 +31,7 @@
31 31
32/************************************************************************** 32/**************************************************************************
33 * 33 *
34 * MAC stats DMA format 34 * NIC stats
35 * 35 *
36 ************************************************************************** 36 **************************************************************************
37 */ 37 */
@@ -134,27 +134,67 @@
134#define FALCON_XMAC_STATS_DMA_FLAG(efx) \ 134#define FALCON_XMAC_STATS_DMA_FLAG(efx) \
135 (*(u32 *)((efx)->stats_buffer.addr + XgDmaDone_offset)) 135 (*(u32 *)((efx)->stats_buffer.addr + XgDmaDone_offset))
136 136
137#define FALCON_STAT_OFFSET(falcon_stat) EFX_VAL(falcon_stat, offset) 137#define FALCON_DMA_STAT(ext_name, hw_name) \
138#define FALCON_STAT_WIDTH(falcon_stat) EFX_VAL(falcon_stat, WIDTH) 138 [FALCON_STAT_ ## ext_name] = \
139 139 { #ext_name, \
140/* Retrieve statistic from statistics block */ 140 /* 48-bit stats are zero-padded to 64 on DMA */ \
141#define FALCON_STAT(efx, falcon_stat, efx_stat) do { \ 141 hw_name ## _ ## WIDTH == 48 ? 64 : hw_name ## _ ## WIDTH, \
142 if (FALCON_STAT_WIDTH(falcon_stat) == 16) \ 142 hw_name ## _ ## offset }
143 (efx)->mac_stats.efx_stat += le16_to_cpu( \ 143#define FALCON_OTHER_STAT(ext_name) \
144 *((__force __le16 *) \ 144 [FALCON_STAT_ ## ext_name] = { #ext_name, 0, 0 }
145 (efx->stats_buffer.addr + \ 145
146 FALCON_STAT_OFFSET(falcon_stat)))); \ 146static const struct efx_hw_stat_desc falcon_stat_desc[FALCON_STAT_COUNT] = {
147 else if (FALCON_STAT_WIDTH(falcon_stat) == 32) \ 147 FALCON_DMA_STAT(tx_bytes, XgTxOctets),
148 (efx)->mac_stats.efx_stat += le32_to_cpu( \ 148 FALCON_DMA_STAT(tx_packets, XgTxPkts),
149 *((__force __le32 *) \ 149 FALCON_DMA_STAT(tx_pause, XgTxPausePkts),
150 (efx->stats_buffer.addr + \ 150 FALCON_DMA_STAT(tx_control, XgTxControlPkts),
151 FALCON_STAT_OFFSET(falcon_stat)))); \ 151 FALCON_DMA_STAT(tx_unicast, XgTxUnicastPkts),
152 else \ 152 FALCON_DMA_STAT(tx_multicast, XgTxMulticastPkts),
153 (efx)->mac_stats.efx_stat += le64_to_cpu( \ 153 FALCON_DMA_STAT(tx_broadcast, XgTxBroadcastPkts),
154 *((__force __le64 *) \ 154 FALCON_DMA_STAT(tx_lt64, XgTxUndersizePkts),
155 (efx->stats_buffer.addr + \ 155 FALCON_DMA_STAT(tx_64, XgTxPkts64Octets),
156 FALCON_STAT_OFFSET(falcon_stat)))); \ 156 FALCON_DMA_STAT(tx_65_to_127, XgTxPkts65to127Octets),
157 } while (0) 157 FALCON_DMA_STAT(tx_128_to_255, XgTxPkts128to255Octets),
158 FALCON_DMA_STAT(tx_256_to_511, XgTxPkts256to511Octets),
159 FALCON_DMA_STAT(tx_512_to_1023, XgTxPkts512to1023Octets),
160 FALCON_DMA_STAT(tx_1024_to_15xx, XgTxPkts1024to15xxOctets),
161 FALCON_DMA_STAT(tx_15xx_to_jumbo, XgTxPkts1519toMaxOctets),
162 FALCON_DMA_STAT(tx_gtjumbo, XgTxOversizePkts),
163 FALCON_DMA_STAT(tx_non_tcpudp, XgTxNonTcpUdpPkt),
164 FALCON_DMA_STAT(tx_mac_src_error, XgTxMacSrcErrPkt),
165 FALCON_DMA_STAT(tx_ip_src_error, XgTxIpSrcErrPkt),
166 FALCON_DMA_STAT(rx_bytes, XgRxOctets),
167 FALCON_DMA_STAT(rx_good_bytes, XgRxOctetsOK),
168 FALCON_OTHER_STAT(rx_bad_bytes),
169 FALCON_DMA_STAT(rx_packets, XgRxPkts),
170 FALCON_DMA_STAT(rx_good, XgRxPktsOK),
171 FALCON_DMA_STAT(rx_bad, XgRxFCSerrorPkts),
172 FALCON_DMA_STAT(rx_pause, XgRxPausePkts),
173 FALCON_DMA_STAT(rx_control, XgRxControlPkts),
174 FALCON_DMA_STAT(rx_unicast, XgRxUnicastPkts),
175 FALCON_DMA_STAT(rx_multicast, XgRxMulticastPkts),
176 FALCON_DMA_STAT(rx_broadcast, XgRxBroadcastPkts),
177 FALCON_DMA_STAT(rx_lt64, XgRxUndersizePkts),
178 FALCON_DMA_STAT(rx_64, XgRxPkts64Octets),
179 FALCON_DMA_STAT(rx_65_to_127, XgRxPkts65to127Octets),
180 FALCON_DMA_STAT(rx_128_to_255, XgRxPkts128to255Octets),
181 FALCON_DMA_STAT(rx_256_to_511, XgRxPkts256to511Octets),
182 FALCON_DMA_STAT(rx_512_to_1023, XgRxPkts512to1023Octets),
183 FALCON_DMA_STAT(rx_1024_to_15xx, XgRxPkts1024to15xxOctets),
184 FALCON_DMA_STAT(rx_15xx_to_jumbo, XgRxPkts15xxtoMaxOctets),
185 FALCON_DMA_STAT(rx_gtjumbo, XgRxOversizePkts),
186 FALCON_DMA_STAT(rx_bad_lt64, XgRxUndersizeFCSerrorPkts),
187 FALCON_DMA_STAT(rx_bad_gtjumbo, XgRxJabberPkts),
188 FALCON_DMA_STAT(rx_overflow, XgRxDropEvents),
189 FALCON_DMA_STAT(rx_symbol_error, XgRxSymbolError),
190 FALCON_DMA_STAT(rx_align_error, XgRxAlignError),
191 FALCON_DMA_STAT(rx_length_error, XgRxLengthError),
192 FALCON_DMA_STAT(rx_internal_error, XgRxInternalMACError),
193 FALCON_OTHER_STAT(rx_nodesc_drop_cnt),
194};
195static const unsigned long falcon_stat_mask[] = {
196 [0 ... BITS_TO_LONGS(FALCON_STAT_COUNT) - 1] = ~0UL,
197};
158 198
159/************************************************************************** 199/**************************************************************************
160 * 200 *
@@ -1159,66 +1199,6 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx)
1159 return 0; 1199 return 0;
1160} 1200}
1161 1201
1162static void falcon_update_stats_xmac(struct efx_nic *efx)
1163{
1164 struct efx_mac_stats *mac_stats = &efx->mac_stats;
1165
1166 /* Update MAC stats from DMAed values */
1167 FALCON_STAT(efx, XgRxOctets, rx_bytes);
1168 FALCON_STAT(efx, XgRxOctetsOK, rx_good_bytes);
1169 FALCON_STAT(efx, XgRxPkts, rx_packets);
1170 FALCON_STAT(efx, XgRxPktsOK, rx_good);
1171 FALCON_STAT(efx, XgRxBroadcastPkts, rx_broadcast);
1172 FALCON_STAT(efx, XgRxMulticastPkts, rx_multicast);
1173 FALCON_STAT(efx, XgRxUnicastPkts, rx_unicast);
1174 FALCON_STAT(efx, XgRxUndersizePkts, rx_lt64);
1175 FALCON_STAT(efx, XgRxOversizePkts, rx_gtjumbo);
1176 FALCON_STAT(efx, XgRxJabberPkts, rx_bad_gtjumbo);
1177 FALCON_STAT(efx, XgRxUndersizeFCSerrorPkts, rx_bad_lt64);
1178 FALCON_STAT(efx, XgRxDropEvents, rx_overflow);
1179 FALCON_STAT(efx, XgRxFCSerrorPkts, rx_bad);
1180 FALCON_STAT(efx, XgRxAlignError, rx_align_error);
1181 FALCON_STAT(efx, XgRxSymbolError, rx_symbol_error);
1182 FALCON_STAT(efx, XgRxInternalMACError, rx_internal_error);
1183 FALCON_STAT(efx, XgRxControlPkts, rx_control);
1184 FALCON_STAT(efx, XgRxPausePkts, rx_pause);
1185 FALCON_STAT(efx, XgRxPkts64Octets, rx_64);
1186 FALCON_STAT(efx, XgRxPkts65to127Octets, rx_65_to_127);
1187 FALCON_STAT(efx, XgRxPkts128to255Octets, rx_128_to_255);
1188 FALCON_STAT(efx, XgRxPkts256to511Octets, rx_256_to_511);
1189 FALCON_STAT(efx, XgRxPkts512to1023Octets, rx_512_to_1023);
1190 FALCON_STAT(efx, XgRxPkts1024to15xxOctets, rx_1024_to_15xx);
1191 FALCON_STAT(efx, XgRxPkts15xxtoMaxOctets, rx_15xx_to_jumbo);
1192 FALCON_STAT(efx, XgRxLengthError, rx_length_error);
1193 FALCON_STAT(efx, XgTxPkts, tx_packets);
1194 FALCON_STAT(efx, XgTxOctets, tx_bytes);
1195 FALCON_STAT(efx, XgTxMulticastPkts, tx_multicast);
1196 FALCON_STAT(efx, XgTxBroadcastPkts, tx_broadcast);
1197 FALCON_STAT(efx, XgTxUnicastPkts, tx_unicast);
1198 FALCON_STAT(efx, XgTxControlPkts, tx_control);
1199 FALCON_STAT(efx, XgTxPausePkts, tx_pause);
1200 FALCON_STAT(efx, XgTxPkts64Octets, tx_64);
1201 FALCON_STAT(efx, XgTxPkts65to127Octets, tx_65_to_127);
1202 FALCON_STAT(efx, XgTxPkts128to255Octets, tx_128_to_255);
1203 FALCON_STAT(efx, XgTxPkts256to511Octets, tx_256_to_511);
1204 FALCON_STAT(efx, XgTxPkts512to1023Octets, tx_512_to_1023);
1205 FALCON_STAT(efx, XgTxPkts1024to15xxOctets, tx_1024_to_15xx);
1206 FALCON_STAT(efx, XgTxPkts1519toMaxOctets, tx_15xx_to_jumbo);
1207 FALCON_STAT(efx, XgTxUndersizePkts, tx_lt64);
1208 FALCON_STAT(efx, XgTxOversizePkts, tx_gtjumbo);
1209 FALCON_STAT(efx, XgTxNonTcpUdpPkt, tx_non_tcpudp);
1210 FALCON_STAT(efx, XgTxMacSrcErrPkt, tx_mac_src_error);
1211 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error);
1212
1213 /* Update derived statistics */
1214 efx_update_diff_stat(&mac_stats->tx_good_bytes,
1215 mac_stats->tx_bytes - mac_stats->tx_bad_bytes -
1216 mac_stats->tx_control * 64);
1217 efx_update_diff_stat(&mac_stats->rx_bad_bytes,
1218 mac_stats->rx_bytes - mac_stats->rx_good_bytes -
1219 mac_stats->rx_control * 64);
1220}
1221
1222static void falcon_poll_xmac(struct efx_nic *efx) 1202static void falcon_poll_xmac(struct efx_nic *efx)
1223{ 1203{
1224 struct falcon_nic_data *nic_data = efx->nic_data; 1204 struct falcon_nic_data *nic_data = efx->nic_data;
@@ -1422,7 +1402,9 @@ static void falcon_stats_complete(struct efx_nic *efx)
1422 nic_data->stats_pending = false; 1402 nic_data->stats_pending = false;
1423 if (FALCON_XMAC_STATS_DMA_FLAG(efx)) { 1403 if (FALCON_XMAC_STATS_DMA_FLAG(efx)) {
1424 rmb(); /* read the done flag before the stats */ 1404 rmb(); /* read the done flag before the stats */
1425 falcon_update_stats_xmac(efx); 1405 efx_nic_update_stats(falcon_stat_desc, FALCON_STAT_COUNT,
1406 falcon_stat_mask, nic_data->stats,
1407 efx->stats_buffer.addr, true);
1426 } else { 1408 } else {
1427 netif_err(efx, hw, efx->net_dev, 1409 netif_err(efx, hw, efx->net_dev,
1428 "timed out waiting for statistics\n"); 1410 "timed out waiting for statistics\n");
@@ -2538,23 +2520,65 @@ static void falcon_remove_nic(struct efx_nic *efx)
2538 efx->nic_data = NULL; 2520 efx->nic_data = NULL;
2539} 2521}
2540 2522
2541static void falcon_update_nic_stats(struct efx_nic *efx) 2523static size_t falcon_describe_nic_stats(struct efx_nic *efx, u8 *names)
2524{
2525 return efx_nic_describe_stats(falcon_stat_desc, FALCON_STAT_COUNT,
2526 falcon_stat_mask, names);
2527}
2528
2529static size_t falcon_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
2530 struct rtnl_link_stats64 *core_stats)
2542{ 2531{
2543 struct falcon_nic_data *nic_data = efx->nic_data; 2532 struct falcon_nic_data *nic_data = efx->nic_data;
2533 u64 *stats = nic_data->stats;
2544 efx_oword_t cnt; 2534 efx_oword_t cnt;
2545 2535
2546 if (nic_data->stats_disable_count) 2536 if (!nic_data->stats_disable_count) {
2547 return; 2537 efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP);
2538 stats[FALCON_STAT_rx_nodesc_drop_cnt] +=
2539 EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT);
2540
2541 if (nic_data->stats_pending &&
2542 FALCON_XMAC_STATS_DMA_FLAG(efx)) {
2543 nic_data->stats_pending = false;
2544 rmb(); /* read the done flag before the stats */
2545 efx_nic_update_stats(
2546 falcon_stat_desc, FALCON_STAT_COUNT,
2547 falcon_stat_mask,
2548 stats, efx->stats_buffer.addr, true);
2549 }
2548 2550
2549 efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP); 2551 /* Update derived statistic */
2550 efx->n_rx_nodesc_drop_cnt += 2552 efx_update_diff_stat(&stats[FALCON_STAT_rx_bad_bytes],
2551 EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT); 2553 stats[FALCON_STAT_rx_bytes] -
2554 stats[FALCON_STAT_rx_good_bytes] -
2555 stats[FALCON_STAT_rx_control] * 64);
2556 }
2552 2557
2553 if (nic_data->stats_pending && FALCON_XMAC_STATS_DMA_FLAG(efx)) { 2558 if (full_stats)
2554 nic_data->stats_pending = false; 2559 memcpy(full_stats, stats, sizeof(u64) * FALCON_STAT_COUNT);
2555 rmb(); /* read the done flag before the stats */ 2560
2556 falcon_update_stats_xmac(efx); 2561 if (core_stats) {
2562 core_stats->rx_packets = stats[FALCON_STAT_rx_packets];
2563 core_stats->tx_packets = stats[FALCON_STAT_tx_packets];
2564 core_stats->rx_bytes = stats[FALCON_STAT_rx_bytes];
2565 core_stats->tx_bytes = stats[FALCON_STAT_tx_bytes];
2566 core_stats->rx_dropped = stats[FALCON_STAT_rx_nodesc_drop_cnt];
2567 core_stats->multicast = stats[FALCON_STAT_rx_multicast];
2568 core_stats->rx_length_errors =
2569 stats[FALCON_STAT_rx_gtjumbo] +
2570 stats[FALCON_STAT_rx_length_error];
2571 core_stats->rx_crc_errors = stats[FALCON_STAT_rx_bad];
2572 core_stats->rx_frame_errors = stats[FALCON_STAT_rx_align_error];
2573 core_stats->rx_fifo_errors = stats[FALCON_STAT_rx_overflow];
2574
2575 core_stats->rx_errors = (core_stats->rx_length_errors +
2576 core_stats->rx_crc_errors +
2577 core_stats->rx_frame_errors +
2578 stats[FALCON_STAT_rx_symbol_error]);
2557 } 2579 }
2580
2581 return FALCON_STAT_COUNT;
2558} 2582}
2559 2583
2560void falcon_start_nic_stats(struct efx_nic *efx) 2584void falcon_start_nic_stats(struct efx_nic *efx)
@@ -2643,6 +2667,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
2643 .fini_dmaq = efx_farch_fini_dmaq, 2667 .fini_dmaq = efx_farch_fini_dmaq,
2644 .prepare_flush = falcon_prepare_flush, 2668 .prepare_flush = falcon_prepare_flush,
2645 .finish_flush = efx_port_dummy_op_void, 2669 .finish_flush = efx_port_dummy_op_void,
2670 .describe_stats = falcon_describe_nic_stats,
2646 .update_stats = falcon_update_nic_stats, 2671 .update_stats = falcon_update_nic_stats,
2647 .start_stats = falcon_start_nic_stats, 2672 .start_stats = falcon_start_nic_stats,
2648 .stop_stats = falcon_stop_nic_stats, 2673 .stop_stats = falcon_stop_nic_stats,
@@ -2735,6 +2760,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
2735 .fini_dmaq = efx_farch_fini_dmaq, 2760 .fini_dmaq = efx_farch_fini_dmaq,
2736 .prepare_flush = falcon_prepare_flush, 2761 .prepare_flush = falcon_prepare_flush,
2737 .finish_flush = efx_port_dummy_op_void, 2762 .finish_flush = efx_port_dummy_op_void,
2763 .describe_stats = falcon_describe_nic_stats,
2738 .update_stats = falcon_update_nic_stats, 2764 .update_stats = falcon_update_nic_stats,
2739 .start_stats = falcon_start_nic_stats, 2765 .start_stats = falcon_start_nic_stats,
2740 .stop_stats = falcon_stop_nic_stats, 2766 .stop_stats = falcon_stop_nic_stats,
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 67b07de2c599..ff90ebf51dbd 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -236,21 +236,10 @@ static int efx_mcdi_poll(struct efx_nic *efx)
236 */ 236 */
237int efx_mcdi_poll_reboot(struct efx_nic *efx) 237int efx_mcdi_poll_reboot(struct efx_nic *efx)
238{ 238{
239 int rc;
240
241 if (!efx->mcdi) 239 if (!efx->mcdi)
242 return 0; 240 return 0;
243 241
244 rc = efx->type->mcdi_poll_reboot(efx); 242 return efx->type->mcdi_poll_reboot(efx);
245 if (!rc)
246 return 0;
247
248 /* MAC statistics have been cleared on the NIC; clear our copy
249 * so that efx_update_diff_stat() can continue to work.
250 */
251 memset(&efx->mac_stats, 0, sizeof(efx->mac_stats));
252
253 return rc;
254} 243}
255 244
256static void efx_mcdi_acquire(struct efx_mcdi_iface *mcdi) 245static void efx_mcdi_acquire(struct efx_mcdi_iface *mcdi)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index fa881cdd9dcc..d33656bc4060 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -595,75 +595,17 @@ static inline bool efx_phy_mode_disabled(enum efx_phy_mode mode)
595 return !!(mode & ~PHY_MODE_TX_DISABLED); 595 return !!(mode & ~PHY_MODE_TX_DISABLED);
596} 596}
597 597
598/* 598/**
599 * Efx extended statistics 599 * struct efx_hw_stat_desc - Description of a hardware statistic
600 * 600 * @name: Name of the statistic as visible through ethtool, or %NULL if
601 * Not all statistics are provided by all supported MACs. The purpose 601 * it should not be exposed
602 * is this structure is to contain the raw statistics provided by each 602 * @dma_width: Width in bits (0 for non-DMA statistics)
603 * MAC. 603 * @offset: Offset within stats (ignored for non-DMA statistics)
604 */ 604 */
605struct efx_mac_stats { 605struct efx_hw_stat_desc {
606 u64 tx_bytes; 606 const char *name;
607 u64 tx_good_bytes; 607 u16 dma_width;
608 u64 tx_bad_bytes; 608 u16 offset;
609 u64 tx_packets;
610 u64 tx_bad;
611 u64 tx_pause;
612 u64 tx_control;
613 u64 tx_unicast;
614 u64 tx_multicast;
615 u64 tx_broadcast;
616 u64 tx_lt64;
617 u64 tx_64;
618 u64 tx_65_to_127;
619 u64 tx_128_to_255;
620 u64 tx_256_to_511;
621 u64 tx_512_to_1023;
622 u64 tx_1024_to_15xx;
623 u64 tx_15xx_to_jumbo;
624 u64 tx_gtjumbo;
625 u64 tx_collision;
626 u64 tx_single_collision;
627 u64 tx_multiple_collision;
628 u64 tx_excessive_collision;
629 u64 tx_deferred;
630 u64 tx_late_collision;
631 u64 tx_excessive_deferred;
632 u64 tx_non_tcpudp;
633 u64 tx_mac_src_error;
634 u64 tx_ip_src_error;
635 u64 rx_bytes;
636 u64 rx_good_bytes;
637 u64 rx_bad_bytes;
638 u64 rx_packets;
639 u64 rx_good;
640 u64 rx_bad;
641 u64 rx_pause;
642 u64 rx_control;
643 u64 rx_unicast;
644 u64 rx_multicast;
645 u64 rx_broadcast;
646 u64 rx_lt64;
647 u64 rx_64;
648 u64 rx_65_to_127;
649 u64 rx_128_to_255;
650 u64 rx_256_to_511;
651 u64 rx_512_to_1023;
652 u64 rx_1024_to_15xx;
653 u64 rx_15xx_to_jumbo;
654 u64 rx_gtjumbo;
655 u64 rx_bad_lt64;
656 u64 rx_bad_64_to_15xx;
657 u64 rx_bad_15xx_to_jumbo;
658 u64 rx_bad_gtjumbo;
659 u64 rx_overflow;
660 u64 rx_missed;
661 u64 rx_false_carrier;
662 u64 rx_symbol_error;
663 u64 rx_align_error;
664 u64 rx_length_error;
665 u64 rx_internal_error;
666 u64 rx_good_lt64;
667}; 609};
668 610
669/* Number of bits used in a multicast filter hash address */ 611/* Number of bits used in a multicast filter hash address */
@@ -795,12 +737,8 @@ struct vfdi_status;
795 * @last_irq_cpu: Last CPU to handle a possible test interrupt. This 737 * @last_irq_cpu: Last CPU to handle a possible test interrupt. This
796 * field is used by efx_test_interrupts() to verify that an 738 * field is used by efx_test_interrupts() to verify that an
797 * interrupt has occurred. 739 * interrupt has occurred.
798 * @n_rx_nodesc_drop_cnt: RX no descriptor drop count 740 * @stats_lock: Statistics update lock. Must be held when calling
799 * @mac_stats: MAC statistics. These include all statistics the MACs 741 * efx_nic_type::{update,start,stop}_stats.
800 * can provide. Generic code converts these into a standard
801 * &struct net_device_stats.
802 * @stats_lock: Statistics update lock. Serialises statistics fetches
803 * and access to @mac_stats.
804 * 742 *
805 * This is stored in the private area of the &struct net_device. 743 * This is stored in the private area of the &struct net_device.
806 */ 744 */
@@ -939,8 +877,6 @@ struct efx_nic {
939 struct delayed_work monitor_work ____cacheline_aligned_in_smp; 877 struct delayed_work monitor_work ____cacheline_aligned_in_smp;
940 spinlock_t biu_lock; 878 spinlock_t biu_lock;
941 int last_irq_cpu; 879 int last_irq_cpu;
942 unsigned n_rx_nodesc_drop_cnt;
943 struct efx_mac_stats mac_stats;
944 spinlock_t stats_lock; 880 spinlock_t stats_lock;
945}; 881};
946 882
@@ -984,7 +920,9 @@ struct efx_mtd_partition {
984 * (for Falcon architecture) 920 * (for Falcon architecture)
985 * @finish_flush: Clean up after flushing the DMA queues (for Falcon 921 * @finish_flush: Clean up after flushing the DMA queues (for Falcon
986 * architecture) 922 * architecture)
987 * @update_stats: Update statistics not provided by event handling 923 * @describe_stats: Describe statistics for ethtool
924 * @update_stats: Update statistics not provided by event handling.
925 * Either argument may be %NULL.
988 * @start_stats: Start the regular fetching of statistics 926 * @start_stats: Start the regular fetching of statistics
989 * @stop_stats: Stop the regular fetching of statistics 927 * @stop_stats: Stop the regular fetching of statistics
990 * @set_id_led: Set state of identifying LED or revert to automatic function 928 * @set_id_led: Set state of identifying LED or revert to automatic function
@@ -1098,7 +1036,9 @@ struct efx_nic_type {
1098 int (*fini_dmaq)(struct efx_nic *efx); 1036 int (*fini_dmaq)(struct efx_nic *efx);
1099 void (*prepare_flush)(struct efx_nic *efx); 1037 void (*prepare_flush)(struct efx_nic *efx);
1100 void (*finish_flush)(struct efx_nic *efx); 1038 void (*finish_flush)(struct efx_nic *efx);
1101 void (*update_stats)(struct efx_nic *efx); 1039 size_t (*describe_stats)(struct efx_nic *efx, u8 *names);
1040 size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats,
1041 struct rtnl_link_stats64 *core_stats);
1102 void (*start_stats)(struct efx_nic *efx); 1042 void (*start_stats)(struct efx_nic *efx);
1103 void (*stop_stats)(struct efx_nic *efx); 1043 void (*stop_stats)(struct efx_nic *efx);
1104 void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); 1044 void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 66c71ede3a98..b9b127743a07 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -429,3 +429,86 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf)
429 } 429 }
430 } 430 }
431} 431}
432
433/**
434 * efx_nic_describe_stats - Describe supported statistics for ethtool
435 * @desc: Array of &struct efx_hw_stat_desc describing the statistics
436 * @count: Length of the @desc array
437 * @mask: Bitmask of which elements of @desc are enabled
438 * @names: Buffer to copy names to, or %NULL. The names are copied
439 * starting at intervals of %ETH_GSTRING_LEN bytes.
440 *
441 * Returns the number of visible statistics, i.e. the number of set
442 * bits in the first @count bits of @mask for which a name is defined.
443 */
444size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
445 const unsigned long *mask, u8 *names)
446{
447 size_t visible = 0;
448 size_t index;
449
450 for_each_set_bit(index, mask, count) {
451 if (desc[index].name) {
452 if (names) {
453 strlcpy(names, desc[index].name,
454 ETH_GSTRING_LEN);
455 names += ETH_GSTRING_LEN;
456 }
457 ++visible;
458 }
459 }
460
461 return visible;
462}
463
464/**
465 * efx_nic_update_stats - Convert statistics DMA buffer to array of u64
466 * @desc: Array of &struct efx_hw_stat_desc describing the DMA buffer
467 * layout. DMA widths of 0, 16, 32 and 64 are supported; where
468 * the width is specified as 0 the corresponding element of
469 * @stats is not updated.
470 * @count: Length of the @desc array
471 * @mask: Bitmask of which elements of @desc are enabled
472 * @stats: Buffer to update with the converted statistics. The length
473 * of this array must be at least the number of set bits in the
474 * first @count bits of @mask.
475 * @dma_buf: DMA buffer containing hardware statistics
476 * @accumulate: If set, the converted values will be added rather than
477 * directly stored to the corresponding elements of @stats
478 */
479void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
480 const unsigned long *mask,
481 u64 *stats, const void *dma_buf, bool accumulate)
482{
483 size_t index;
484
485 for_each_set_bit(index, mask, count) {
486 if (desc[index].dma_width) {
487 const void *addr = dma_buf + desc[index].offset;
488 u64 val;
489
490 switch (desc[index].dma_width) {
491 case 16:
492 val = le16_to_cpup((__le16 *)addr);
493 break;
494 case 32:
495 val = le32_to_cpup((__le32 *)addr);
496 break;
497 case 64:
498 val = le64_to_cpup((__le64 *)addr);
499 break;
500 default:
501 WARN_ON(1);
502 val = 0;
503 break;
504 }
505
506 if (accumulate)
507 *stats += val;
508 else
509 *stats = val;
510 }
511
512 ++stats;
513 }
514}
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index c3e0f1fd5047..9afbf3616b4b 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -191,10 +191,62 @@ static inline bool falcon_spi_present(const struct falcon_spi_device *spi)
191 return spi->size != 0; 191 return spi->size != 0;
192} 192}
193 193
194enum {
195 FALCON_STAT_tx_bytes,
196 FALCON_STAT_tx_packets,
197 FALCON_STAT_tx_pause,
198 FALCON_STAT_tx_control,
199 FALCON_STAT_tx_unicast,
200 FALCON_STAT_tx_multicast,
201 FALCON_STAT_tx_broadcast,
202 FALCON_STAT_tx_lt64,
203 FALCON_STAT_tx_64,
204 FALCON_STAT_tx_65_to_127,
205 FALCON_STAT_tx_128_to_255,
206 FALCON_STAT_tx_256_to_511,
207 FALCON_STAT_tx_512_to_1023,
208 FALCON_STAT_tx_1024_to_15xx,
209 FALCON_STAT_tx_15xx_to_jumbo,
210 FALCON_STAT_tx_gtjumbo,
211 FALCON_STAT_tx_non_tcpudp,
212 FALCON_STAT_tx_mac_src_error,
213 FALCON_STAT_tx_ip_src_error,
214 FALCON_STAT_rx_bytes,
215 FALCON_STAT_rx_good_bytes,
216 FALCON_STAT_rx_bad_bytes,
217 FALCON_STAT_rx_packets,
218 FALCON_STAT_rx_good,
219 FALCON_STAT_rx_bad,
220 FALCON_STAT_rx_pause,
221 FALCON_STAT_rx_control,
222 FALCON_STAT_rx_unicast,
223 FALCON_STAT_rx_multicast,
224 FALCON_STAT_rx_broadcast,
225 FALCON_STAT_rx_lt64,
226 FALCON_STAT_rx_64,
227 FALCON_STAT_rx_65_to_127,
228 FALCON_STAT_rx_128_to_255,
229 FALCON_STAT_rx_256_to_511,
230 FALCON_STAT_rx_512_to_1023,
231 FALCON_STAT_rx_1024_to_15xx,
232 FALCON_STAT_rx_15xx_to_jumbo,
233 FALCON_STAT_rx_gtjumbo,
234 FALCON_STAT_rx_bad_lt64,
235 FALCON_STAT_rx_bad_gtjumbo,
236 FALCON_STAT_rx_overflow,
237 FALCON_STAT_rx_symbol_error,
238 FALCON_STAT_rx_align_error,
239 FALCON_STAT_rx_length_error,
240 FALCON_STAT_rx_internal_error,
241 FALCON_STAT_rx_nodesc_drop_cnt,
242 FALCON_STAT_COUNT
243};
244
194/** 245/**
195 * struct falcon_nic_data - Falcon NIC state 246 * struct falcon_nic_data - Falcon NIC state
196 * @pci_dev2: Secondary function of Falcon A 247 * @pci_dev2: Secondary function of Falcon A
197 * @board: Board state and functions 248 * @board: Board state and functions
249 * @stats: Hardware statistics
198 * @stats_disable_count: Nest count for disabling statistics fetches 250 * @stats_disable_count: Nest count for disabling statistics fetches
199 * @stats_pending: Is there a pending DMA of MAC statistics. 251 * @stats_pending: Is there a pending DMA of MAC statistics.
200 * @stats_timer: A timer for regularly fetching MAC statistics. 252 * @stats_timer: A timer for regularly fetching MAC statistics.
@@ -207,6 +259,7 @@ static inline bool falcon_spi_present(const struct falcon_spi_device *spi)
207struct falcon_nic_data { 259struct falcon_nic_data {
208 struct pci_dev *pci_dev2; 260 struct pci_dev *pci_dev2;
209 struct falcon_board board; 261 struct falcon_board board;
262 u64 stats[FALCON_STAT_COUNT];
210 unsigned int stats_disable_count; 263 unsigned int stats_disable_count;
211 bool stats_pending; 264 bool stats_pending;
212 struct timer_list stats_timer; 265 struct timer_list stats_timer;
@@ -223,12 +276,75 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
223 return &data->board; 276 return &data->board;
224} 277}
225 278
279enum {
280 SIENA_STAT_tx_bytes,
281 SIENA_STAT_tx_good_bytes,
282 SIENA_STAT_tx_bad_bytes,
283 SIENA_STAT_tx_packets,
284 SIENA_STAT_tx_bad,
285 SIENA_STAT_tx_pause,
286 SIENA_STAT_tx_control,
287 SIENA_STAT_tx_unicast,
288 SIENA_STAT_tx_multicast,
289 SIENA_STAT_tx_broadcast,
290 SIENA_STAT_tx_lt64,
291 SIENA_STAT_tx_64,
292 SIENA_STAT_tx_65_to_127,
293 SIENA_STAT_tx_128_to_255,
294 SIENA_STAT_tx_256_to_511,
295 SIENA_STAT_tx_512_to_1023,
296 SIENA_STAT_tx_1024_to_15xx,
297 SIENA_STAT_tx_15xx_to_jumbo,
298 SIENA_STAT_tx_gtjumbo,
299 SIENA_STAT_tx_collision,
300 SIENA_STAT_tx_single_collision,
301 SIENA_STAT_tx_multiple_collision,
302 SIENA_STAT_tx_excessive_collision,
303 SIENA_STAT_tx_deferred,
304 SIENA_STAT_tx_late_collision,
305 SIENA_STAT_tx_excessive_deferred,
306 SIENA_STAT_tx_non_tcpudp,
307 SIENA_STAT_tx_mac_src_error,
308 SIENA_STAT_tx_ip_src_error,
309 SIENA_STAT_rx_bytes,
310 SIENA_STAT_rx_good_bytes,
311 SIENA_STAT_rx_bad_bytes,
312 SIENA_STAT_rx_packets,
313 SIENA_STAT_rx_good,
314 SIENA_STAT_rx_bad,
315 SIENA_STAT_rx_pause,
316 SIENA_STAT_rx_control,
317 SIENA_STAT_rx_unicast,
318 SIENA_STAT_rx_multicast,
319 SIENA_STAT_rx_broadcast,
320 SIENA_STAT_rx_lt64,
321 SIENA_STAT_rx_64,
322 SIENA_STAT_rx_65_to_127,
323 SIENA_STAT_rx_128_to_255,
324 SIENA_STAT_rx_256_to_511,
325 SIENA_STAT_rx_512_to_1023,
326 SIENA_STAT_rx_1024_to_15xx,
327 SIENA_STAT_rx_15xx_to_jumbo,
328 SIENA_STAT_rx_gtjumbo,
329 SIENA_STAT_rx_bad_gtjumbo,
330 SIENA_STAT_rx_overflow,
331 SIENA_STAT_rx_false_carrier,
332 SIENA_STAT_rx_symbol_error,
333 SIENA_STAT_rx_align_error,
334 SIENA_STAT_rx_length_error,
335 SIENA_STAT_rx_internal_error,
336 SIENA_STAT_rx_nodesc_drop_cnt,
337 SIENA_STAT_COUNT
338};
339
226/** 340/**
227 * struct siena_nic_data - Siena NIC state 341 * struct siena_nic_data - Siena NIC state
228 * @wol_filter_id: Wake-on-LAN packet filter id 342 * @wol_filter_id: Wake-on-LAN packet filter id
343 * @stats: Hardware statistics
229 */ 344 */
230struct siena_nic_data { 345struct siena_nic_data {
231 int wol_filter_id; 346 int wol_filter_id;
347 u64 stats[SIENA_STAT_COUNT];
232}; 348};
233 349
234/* 350/*
@@ -533,6 +649,14 @@ extern int efx_farch_test_registers(struct efx_nic *efx,
533extern size_t efx_nic_get_regs_len(struct efx_nic *efx); 649extern size_t efx_nic_get_regs_len(struct efx_nic *efx);
534extern void efx_nic_get_regs(struct efx_nic *efx, void *buf); 650extern void efx_nic_get_regs(struct efx_nic *efx, void *buf);
535 651
652extern size_t
653efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
654 const unsigned long *mask, u8 *names);
655extern void
656efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
657 const unsigned long *mask,
658 u64 *stats, const void *dma_buf, bool accumulate);
659
536#define EFX_MAX_FLUSH_TIME 5000 660#define EFX_MAX_FLUSH_TIME 5000
537 661
538extern void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq, 662extern void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq,
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 11b4739b1705..a51d90c4c6cf 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -380,117 +380,160 @@ static void siena_remove_nic(struct efx_nic *efx)
380 efx_mcdi_fini(efx); 380 efx_mcdi_fini(efx);
381} 381}
382 382
383#define SIENA_DMA_STAT(ext_name, mcdi_name) \
384 [SIENA_STAT_ ## ext_name] = \
385 { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
386#define SIENA_OTHER_STAT(ext_name) \
387 [SIENA_STAT_ ## ext_name] = { #ext_name, 0, 0 }
388
389static const struct efx_hw_stat_desc siena_stat_desc[SIENA_STAT_COUNT] = {
390 SIENA_DMA_STAT(tx_bytes, TX_BYTES),
391 SIENA_OTHER_STAT(tx_good_bytes),
392 SIENA_DMA_STAT(tx_bad_bytes, TX_BAD_BYTES),
393 SIENA_DMA_STAT(tx_packets, TX_PKTS),
394 SIENA_DMA_STAT(tx_bad, TX_BAD_FCS_PKTS),
395 SIENA_DMA_STAT(tx_pause, TX_PAUSE_PKTS),
396 SIENA_DMA_STAT(tx_control, TX_CONTROL_PKTS),
397 SIENA_DMA_STAT(tx_unicast, TX_UNICAST_PKTS),
398 SIENA_DMA_STAT(tx_multicast, TX_MULTICAST_PKTS),
399 SIENA_DMA_STAT(tx_broadcast, TX_BROADCAST_PKTS),
400 SIENA_DMA_STAT(tx_lt64, TX_LT64_PKTS),
401 SIENA_DMA_STAT(tx_64, TX_64_PKTS),
402 SIENA_DMA_STAT(tx_65_to_127, TX_65_TO_127_PKTS),
403 SIENA_DMA_STAT(tx_128_to_255, TX_128_TO_255_PKTS),
404 SIENA_DMA_STAT(tx_256_to_511, TX_256_TO_511_PKTS),
405 SIENA_DMA_STAT(tx_512_to_1023, TX_512_TO_1023_PKTS),
406 SIENA_DMA_STAT(tx_1024_to_15xx, TX_1024_TO_15XX_PKTS),
407 SIENA_DMA_STAT(tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS),
408 SIENA_DMA_STAT(tx_gtjumbo, TX_GTJUMBO_PKTS),
409 SIENA_OTHER_STAT(tx_collision),
410 SIENA_DMA_STAT(tx_single_collision, TX_SINGLE_COLLISION_PKTS),
411 SIENA_DMA_STAT(tx_multiple_collision, TX_MULTIPLE_COLLISION_PKTS),
412 SIENA_DMA_STAT(tx_excessive_collision, TX_EXCESSIVE_COLLISION_PKTS),
413 SIENA_DMA_STAT(tx_deferred, TX_DEFERRED_PKTS),
414 SIENA_DMA_STAT(tx_late_collision, TX_LATE_COLLISION_PKTS),
415 SIENA_DMA_STAT(tx_excessive_deferred, TX_EXCESSIVE_DEFERRED_PKTS),
416 SIENA_DMA_STAT(tx_non_tcpudp, TX_NON_TCPUDP_PKTS),
417 SIENA_DMA_STAT(tx_mac_src_error, TX_MAC_SRC_ERR_PKTS),
418 SIENA_DMA_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS),
419 SIENA_DMA_STAT(rx_bytes, RX_BYTES),
420 SIENA_OTHER_STAT(rx_good_bytes),
421 SIENA_DMA_STAT(rx_bad_bytes, RX_BAD_BYTES),
422 SIENA_DMA_STAT(rx_packets, RX_PKTS),
423 SIENA_DMA_STAT(rx_good, RX_GOOD_PKTS),
424 SIENA_DMA_STAT(rx_bad, RX_BAD_FCS_PKTS),
425 SIENA_DMA_STAT(rx_pause, RX_PAUSE_PKTS),
426 SIENA_DMA_STAT(rx_control, RX_CONTROL_PKTS),
427 SIENA_DMA_STAT(rx_unicast, RX_UNICAST_PKTS),
428 SIENA_DMA_STAT(rx_multicast, RX_MULTICAST_PKTS),
429 SIENA_DMA_STAT(rx_broadcast, RX_BROADCAST_PKTS),
430 SIENA_DMA_STAT(rx_lt64, RX_UNDERSIZE_PKTS),
431 SIENA_DMA_STAT(rx_64, RX_64_PKTS),
432 SIENA_DMA_STAT(rx_65_to_127, RX_65_TO_127_PKTS),
433 SIENA_DMA_STAT(rx_128_to_255, RX_128_TO_255_PKTS),
434 SIENA_DMA_STAT(rx_256_to_511, RX_256_TO_511_PKTS),
435 SIENA_DMA_STAT(rx_512_to_1023, RX_512_TO_1023_PKTS),
436 SIENA_DMA_STAT(rx_1024_to_15xx, RX_1024_TO_15XX_PKTS),
437 SIENA_DMA_STAT(rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS),
438 SIENA_DMA_STAT(rx_gtjumbo, RX_GTJUMBO_PKTS),
439 SIENA_DMA_STAT(rx_bad_gtjumbo, RX_JABBER_PKTS),
440 SIENA_DMA_STAT(rx_overflow, RX_OVERFLOW_PKTS),
441 SIENA_DMA_STAT(rx_false_carrier, RX_FALSE_CARRIER_PKTS),
442 SIENA_DMA_STAT(rx_symbol_error, RX_SYMBOL_ERROR_PKTS),
443 SIENA_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS),
444 SIENA_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS),
445 SIENA_DMA_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS),
446 SIENA_DMA_STAT(rx_nodesc_drop_cnt, RX_NODESC_DROPS),
447};
448static const unsigned long siena_stat_mask[] = {
449 [0 ... BITS_TO_LONGS(SIENA_STAT_COUNT) - 1] = ~0UL,
450};
451
452static size_t siena_describe_nic_stats(struct efx_nic *efx, u8 *names)
453{
454 return efx_nic_describe_stats(siena_stat_desc, SIENA_STAT_COUNT,
455 siena_stat_mask, names);
456}
457
383static int siena_try_update_nic_stats(struct efx_nic *efx) 458static int siena_try_update_nic_stats(struct efx_nic *efx)
384{ 459{
460 struct siena_nic_data *nic_data = efx->nic_data;
461 u64 *stats = nic_data->stats;
385 __le64 *dma_stats; 462 __le64 *dma_stats;
386 struct efx_mac_stats *mac_stats;
387 __le64 generation_start, generation_end; 463 __le64 generation_start, generation_end;
388 464
389 mac_stats = &efx->mac_stats;
390 dma_stats = efx->stats_buffer.addr; 465 dma_stats = efx->stats_buffer.addr;
391 466
392 generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; 467 generation_end = dma_stats[MC_CMD_MAC_GENERATION_END];
393 if (generation_end == EFX_MC_STATS_GENERATION_INVALID) 468 if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
394 return 0; 469 return 0;
395 rmb(); 470 rmb();
396 471 efx_nic_update_stats(siena_stat_desc, SIENA_STAT_COUNT, siena_stat_mask,
397#define MAC_STAT(M, D) \ 472 stats, efx->stats_buffer.addr, false);
398 mac_stats->M = le64_to_cpu(dma_stats[MC_CMD_MAC_ ## D])
399
400 MAC_STAT(tx_bytes, TX_BYTES);
401 MAC_STAT(tx_bad_bytes, TX_BAD_BYTES);
402 efx_update_diff_stat(&mac_stats->tx_good_bytes,
403 mac_stats->tx_bytes - mac_stats->tx_bad_bytes);
404 MAC_STAT(tx_packets, TX_PKTS);
405 MAC_STAT(tx_bad, TX_BAD_FCS_PKTS);
406 MAC_STAT(tx_pause, TX_PAUSE_PKTS);
407 MAC_STAT(tx_control, TX_CONTROL_PKTS);
408 MAC_STAT(tx_unicast, TX_UNICAST_PKTS);
409 MAC_STAT(tx_multicast, TX_MULTICAST_PKTS);
410 MAC_STAT(tx_broadcast, TX_BROADCAST_PKTS);
411 MAC_STAT(tx_lt64, TX_LT64_PKTS);
412 MAC_STAT(tx_64, TX_64_PKTS);
413 MAC_STAT(tx_65_to_127, TX_65_TO_127_PKTS);
414 MAC_STAT(tx_128_to_255, TX_128_TO_255_PKTS);
415 MAC_STAT(tx_256_to_511, TX_256_TO_511_PKTS);
416 MAC_STAT(tx_512_to_1023, TX_512_TO_1023_PKTS);
417 MAC_STAT(tx_1024_to_15xx, TX_1024_TO_15XX_PKTS);
418 MAC_STAT(tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS);
419 MAC_STAT(tx_gtjumbo, TX_GTJUMBO_PKTS);
420 mac_stats->tx_collision = 0;
421 MAC_STAT(tx_single_collision, TX_SINGLE_COLLISION_PKTS);
422 MAC_STAT(tx_multiple_collision, TX_MULTIPLE_COLLISION_PKTS);
423 MAC_STAT(tx_excessive_collision, TX_EXCESSIVE_COLLISION_PKTS);
424 MAC_STAT(tx_deferred, TX_DEFERRED_PKTS);
425 MAC_STAT(tx_late_collision, TX_LATE_COLLISION_PKTS);
426 mac_stats->tx_collision = (mac_stats->tx_single_collision +
427 mac_stats->tx_multiple_collision +
428 mac_stats->tx_excessive_collision +
429 mac_stats->tx_late_collision);
430 MAC_STAT(tx_excessive_deferred, TX_EXCESSIVE_DEFERRED_PKTS);
431 MAC_STAT(tx_non_tcpudp, TX_NON_TCPUDP_PKTS);
432 MAC_STAT(tx_mac_src_error, TX_MAC_SRC_ERR_PKTS);
433 MAC_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS);
434 MAC_STAT(rx_bytes, RX_BYTES);
435 MAC_STAT(rx_bad_bytes, RX_BAD_BYTES);
436 efx_update_diff_stat(&mac_stats->rx_good_bytes,
437 mac_stats->rx_bytes - mac_stats->rx_bad_bytes);
438 MAC_STAT(rx_packets, RX_PKTS);
439 MAC_STAT(rx_good, RX_GOOD_PKTS);
440 MAC_STAT(rx_bad, RX_BAD_FCS_PKTS);
441 MAC_STAT(rx_pause, RX_PAUSE_PKTS);
442 MAC_STAT(rx_control, RX_CONTROL_PKTS);
443 MAC_STAT(rx_unicast, RX_UNICAST_PKTS);
444 MAC_STAT(rx_multicast, RX_MULTICAST_PKTS);
445 MAC_STAT(rx_broadcast, RX_BROADCAST_PKTS);
446 MAC_STAT(rx_lt64, RX_UNDERSIZE_PKTS);
447 MAC_STAT(rx_64, RX_64_PKTS);
448 MAC_STAT(rx_65_to_127, RX_65_TO_127_PKTS);
449 MAC_STAT(rx_128_to_255, RX_128_TO_255_PKTS);
450 MAC_STAT(rx_256_to_511, RX_256_TO_511_PKTS);
451 MAC_STAT(rx_512_to_1023, RX_512_TO_1023_PKTS);
452 MAC_STAT(rx_1024_to_15xx, RX_1024_TO_15XX_PKTS);
453 MAC_STAT(rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS);
454 MAC_STAT(rx_gtjumbo, RX_GTJUMBO_PKTS);
455 mac_stats->rx_bad_lt64 = 0;
456 mac_stats->rx_bad_64_to_15xx = 0;
457 mac_stats->rx_bad_15xx_to_jumbo = 0;
458 MAC_STAT(rx_bad_gtjumbo, RX_JABBER_PKTS);
459 MAC_STAT(rx_overflow, RX_OVERFLOW_PKTS);
460 mac_stats->rx_missed = 0;
461 MAC_STAT(rx_false_carrier, RX_FALSE_CARRIER_PKTS);
462 MAC_STAT(rx_symbol_error, RX_SYMBOL_ERROR_PKTS);
463 MAC_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS);
464 MAC_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS);
465 MAC_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS);
466 mac_stats->rx_good_lt64 = 0;
467
468 efx->n_rx_nodesc_drop_cnt =
469 le64_to_cpu(dma_stats[MC_CMD_MAC_RX_NODESC_DROPS]);
470
471#undef MAC_STAT
472
473 rmb(); 473 rmb();
474 generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; 474 generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
475 if (generation_end != generation_start) 475 if (generation_end != generation_start)
476 return -EAGAIN; 476 return -EAGAIN;
477 477
478 /* Update derived statistics */
479 efx_update_diff_stat(&stats[SIENA_STAT_tx_good_bytes],
480 stats[SIENA_STAT_tx_bytes] -
481 stats[SIENA_STAT_tx_bad_bytes]);
482 stats[SIENA_STAT_tx_collision] =
483 stats[SIENA_STAT_tx_single_collision] +
484 stats[SIENA_STAT_tx_multiple_collision] +
485 stats[SIENA_STAT_tx_excessive_collision] +
486 stats[SIENA_STAT_tx_late_collision];
487 efx_update_diff_stat(&stats[SIENA_STAT_rx_good_bytes],
488 stats[SIENA_STAT_rx_bytes] -
489 stats[SIENA_STAT_rx_bad_bytes]);
478 return 0; 490 return 0;
479} 491}
480 492
481static void siena_update_nic_stats(struct efx_nic *efx) 493static size_t siena_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
494 struct rtnl_link_stats64 *core_stats)
482{ 495{
496 struct siena_nic_data *nic_data = efx->nic_data;
497 u64 *stats = nic_data->stats;
483 int retry; 498 int retry;
484 499
485 /* If we're unlucky enough to read statistics wduring the DMA, wait 500 /* If we're unlucky enough to read statistics wduring the DMA, wait
486 * up to 10ms for it to finish (typically takes <500us) */ 501 * up to 10ms for it to finish (typically takes <500us) */
487 for (retry = 0; retry < 100; ++retry) { 502 for (retry = 0; retry < 100; ++retry) {
488 if (siena_try_update_nic_stats(efx) == 0) 503 if (siena_try_update_nic_stats(efx) == 0)
489 return; 504 break;
490 udelay(100); 505 udelay(100);
491 } 506 }
492 507
493 /* Use the old values instead */ 508 if (full_stats)
509 memcpy(full_stats, stats, sizeof(u64) * SIENA_STAT_COUNT);
510
511 if (core_stats) {
512 core_stats->rx_packets = stats[SIENA_STAT_rx_packets];
513 core_stats->tx_packets = stats[SIENA_STAT_tx_packets];
514 core_stats->rx_bytes = stats[SIENA_STAT_rx_bytes];
515 core_stats->tx_bytes = stats[SIENA_STAT_tx_bytes];
516 core_stats->rx_dropped = stats[SIENA_STAT_rx_nodesc_drop_cnt];
517 core_stats->multicast = stats[SIENA_STAT_rx_multicast];
518 core_stats->collisions = stats[SIENA_STAT_tx_collision];
519 core_stats->rx_length_errors =
520 stats[SIENA_STAT_rx_gtjumbo] +
521 stats[SIENA_STAT_rx_length_error];
522 core_stats->rx_crc_errors = stats[SIENA_STAT_rx_bad];
523 core_stats->rx_frame_errors = stats[SIENA_STAT_rx_align_error];
524 core_stats->rx_fifo_errors = stats[SIENA_STAT_rx_overflow];
525 core_stats->tx_window_errors =
526 stats[SIENA_STAT_tx_late_collision];
527
528 core_stats->rx_errors = (core_stats->rx_length_errors +
529 core_stats->rx_crc_errors +
530 core_stats->rx_frame_errors +
531 stats[SIENA_STAT_rx_symbol_error]);
532 core_stats->tx_errors = (core_stats->tx_window_errors +
533 stats[SIENA_STAT_tx_bad]);
534 }
535
536 return SIENA_STAT_COUNT;
494} 537}
495 538
496static int siena_mac_reconfigure(struct efx_nic *efx) 539static int siena_mac_reconfigure(struct efx_nic *efx)
@@ -652,6 +695,7 @@ static void siena_mcdi_read_response(struct efx_nic *efx, efx_dword_t *outbuf,
652 695
653static int siena_mcdi_poll_reboot(struct efx_nic *efx) 696static int siena_mcdi_poll_reboot(struct efx_nic *efx)
654{ 697{
698 struct siena_nic_data *nic_data = efx->nic_data;
655 unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx); 699 unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx);
656 efx_dword_t reg; 700 efx_dword_t reg;
657 u32 value; 701 u32 value;
@@ -665,6 +709,12 @@ static int siena_mcdi_poll_reboot(struct efx_nic *efx)
665 EFX_ZERO_DWORD(reg); 709 EFX_ZERO_DWORD(reg);
666 efx_writed(efx, &reg, addr); 710 efx_writed(efx, &reg, addr);
667 711
712 /* MAC statistics have been cleared on the NIC; clear the local
713 * copies that we update with efx_update_diff_stat().
714 */
715 nic_data->stats[SIENA_STAT_tx_good_bytes] = 0;
716 nic_data->stats[SIENA_STAT_rx_good_bytes] = 0;
717
668 if (value == MC_STATUS_DWORD_ASSERT) 718 if (value == MC_STATUS_DWORD_ASSERT)
669 return -EINTR; 719 return -EINTR;
670 else 720 else
@@ -830,6 +880,7 @@ const struct efx_nic_type siena_a0_nic_type = {
830 .fini_dmaq = efx_farch_fini_dmaq, 880 .fini_dmaq = efx_farch_fini_dmaq,
831 .prepare_flush = siena_prepare_flush, 881 .prepare_flush = siena_prepare_flush,
832 .finish_flush = siena_finish_flush, 882 .finish_flush = siena_finish_flush,
883 .describe_stats = siena_describe_nic_stats,
833 .update_stats = siena_update_nic_stats, 884 .update_stats = siena_update_nic_stats,
834 .start_stats = efx_mcdi_mac_start_stats, 885 .start_stats = efx_mcdi_mac_start_stats,
835 .stop_stats = efx_mcdi_mac_stop_stats, 886 .stop_stats = efx_mcdi_mac_stop_stats,