/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005-2006 Fen Systems Ltd.
* Copyright 2006-2010 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
#include <linux/in.h>
#include "net_driver.h"
#include "workarounds.h"
#include "selftest.h"
#include "efx.h"
#include "filter.h"
#include "nic.h"
struct ethtool_string {
char name[ETH_GSTRING_LEN];
};
struct efx_ethtool_stat {
const char *name;
enum {
EFX_ETHTOOL_STAT_SOURCE_mac_stats,
EFX_ETHTOOL_STAT_SOURCE_nic,
EFX_ETHTOOL_STAT_SOURCE_channel,
EFX_ETHTOOL_STAT_SOURCE_tx_queue
} source;
unsigned offset;
u64(*get_stat) (void *field); /* Reader function */
};
/* Initialiser for a struct #efx_ethtool_stat with type-checking */
#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \
get_stat_function) { \
.name = #stat_name, \
.source = EFX_ETHTOOL_STAT_SOURCE_##source_name, \
.offset = ((((field_type *) 0) == \
&((struct efx_##source_name *)0)->field) ? \
offsetof(struct efx_##source_name, field) : \
offsetof(struct efx_##source_name, field)), \
.get_stat = get_stat_function, \
}
static u64 efx_get_uint_stat(void *field)
{
return *(unsigned int *)field;
}
static u64 efx_get_u64_stat(void *field)
{
return *(u64 *) field;
}
static u64 efx_get_atomic_stat(void *field)
{
return atomic_read((atomic_t *) field);
}
#define EFX_ETHTOOL_U64_MAC_STAT(field) \
EFX_ETHTOOL_STAT(field, mac_stats, field, \
u64, efx_get_u64_stat)
#define EFX_ETHTOOL_UINT_NIC_STAT(name) \
EFX_ETHTOOL_STAT(name, nic, n_##name, \
unsigned int, efx_get_uint_stat)
#define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \
EFX_ETHTOOL_STAT(field, nic, field, \
atomic_t, efx_get_atomic_stat)
#define EFX_ETHTOOL_UINT_CHANNEL_STAT(field) \
EFX_ETHTOOL_STAT(field, channel, n_##field, \
unsigned int, efx_get_uint_stat)
#define EFX_ETHTOOL_UINT_TXQ_STAT(field) \
EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \
unsigned int, efx_get_uint_stat)
static const struct efx_ethtool_stat efx_ethtool_stats[] = {
EFX_ETHTOOL_U64_MAC_STAT(tx_bytes),
EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes),
EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes),
EFX_ETHTOOL_U64_MAC_STAT(tx_packets),
EFX_ETHTOOL_U64_MAC_STAT(tx_bad),
EFX_ETHTOOL_U64_MAC_STAT(tx_pause),
EFX_ETHTOOL_U64_MAC_STAT(tx_control),
EFX_ETHTOOL_U64_MAC_STAT(tx_unicast),
EFX_ETHTOOL_U64_MAC_STAT(tx_multicast),
EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast),
EFX_ETHTOOL_U64_MAC_STAT(tx_lt64),
EFX_ETHTOOL_U64_MAC_STAT(tx_64),
EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127),
EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255),
EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511),
EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023),
EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx),
EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo),
EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo),
EFX_ETHTOOL_U64_MAC_STAT(tx_collision),
EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision),
EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision),
EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision),
EFX_ETHTOOL_U64_MAC_STAT(tx_deferred),
EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision),
EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred),
EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp),
EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error),
EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error),
EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts),
EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers),
EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets),
EFX_ETHTOOL_UINT_TXQ_STAT(pushes),
EFX_ETHTOOL_U64_MAC_STAT(rx_bytes),
EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes),
EFX_ETHTOOL_U64_MAC_STAT(rx_packets),
EFX_ETHTOOL_U64_MAC_STAT(rx_good),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad),
EFX_ETHTOOL_U64_MAC_STAT(rx_pause),
EFX_ETHTOOL_U64_MAC_STAT(rx_control),
EFX_ETHTOOL_U64_MAC_STAT(rx_unicast),
EFX_ETHTOOL_U64_MAC_STAT(rx_multicast),
EFX_ETHTOOL_U64_MAC_STAT(rx_broadcast),
EFX_ETHTOOL_U64_MAC_STAT(rx_lt64),
EFX_ETHTOOL_U64_MAC_STAT(rx_64),
EFX_ETHTOOL_U64_MAC_STAT(rx_65_to_127),
EFX_ETHTOOL_U64_MAC_STAT(rx_128_to_255),
EFX_ETHTOOL_U64_MAC_STAT(rx_256_to_511),
EFX_ETHTOOL_U64_MAC_STAT(rx_512_to_1023),
EFX_ETHTOOL_U64_MAC_STAT(rx_1024_to_15xx),
EFX_ETHTOOL_U64_MAC_STAT(rx_15xx_to_jumbo),
EFX_ETHTOOL_U64_MAC_STAT(rx_gtjumbo),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad_lt64),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad_64_to_15xx),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad_15xx_to_jumbo),
EFX_ETHTOOL_U64_MAC_STAT(rx_bad_gtjumbo),
EFX_ETHTOOL_U64_MAC_STAT(rx_overflow),
EFX_ETHTOOL_U64_MAC_STAT(rx_missed),
EFX_ETHTOOL_U64_MAC_STAT(rx_false_carrier),
EFX_ETHTOOL_U64_MAC_STAT(rx_symbol_error),
EFX_ETHTOOL_U64_MAC_STAT(rx_align_error),
EFX_ETHTOOL_U64_MAC_STAT(rx_length_error),
EFX_ETHTOOL_U64_MAC_STAT(rx_internal_error),
EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt),
EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_