Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/bwh/sfc-next

Ben Hutchings says:

====================
1. Further cleanup and refactoring in preparation for EF10.
2. Remove ethtool stats that are always zero on Falcon boards.
3. Add an ethtool stat for merged TX completions.
4. Prepare to support merged RX completions.
5. Prepare to support more hwmon sensors.
6. Add support for new events that are generated by EF10 firmware.
7. Update MC reboot detection for EF10.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 29, 2013
2 parents cc328de + d4fbdcf commit 4c9d546
Show file tree
Hide file tree
Showing 20 changed files with 1,536 additions and 1,326 deletions.
37 changes: 6 additions & 31 deletions drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ const char *const efx_reset_type_names[] = {
[RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG",
[RESET_TYPE_INT_ERROR] = "INT_ERROR",
[RESET_TYPE_RX_RECOVERY] = "RX_RECOVERY",
[RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH",
[RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH",
[RESET_TYPE_DMA_ERROR] = "DMA_ERROR",
[RESET_TYPE_TX_SKIP] = "TX_SKIP",
[RESET_TYPE_MC_FAILURE] = "MC_FAILURE",
};
Expand Down Expand Up @@ -574,7 +573,7 @@ static void efx_start_datapath(struct efx_nic *efx)
* support the current MTU, including padding for header
* alignment and overruns.
*/
efx->rx_dma_len = (efx->type->rx_buffer_hash_size +
efx->rx_dma_len = (efx->rx_prefix_size +
EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
efx->type->rx_buffer_padding);
rx_buf_len = (sizeof(struct efx_rx_page_state) +
Expand Down Expand Up @@ -1920,34 +1919,9 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev,
struct rtnl_link_stats64 *stats)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_mac_stats *mac_stats = &efx->mac_stats;

spin_lock_bh(&efx->stats_lock);

efx->type->update_stats(efx);

stats->rx_packets = mac_stats->rx_packets;
stats->tx_packets = mac_stats->tx_packets;
stats->rx_bytes = mac_stats->rx_bytes;
stats->tx_bytes = mac_stats->tx_bytes;
stats->rx_dropped = efx->n_rx_nodesc_drop_cnt;
stats->multicast = mac_stats->rx_multicast;
stats->collisions = mac_stats->tx_collision;
stats->rx_length_errors = (mac_stats->rx_gtjumbo +
mac_stats->rx_length_error);
stats->rx_crc_errors = mac_stats->rx_bad;
stats->rx_frame_errors = mac_stats->rx_align_error;
stats->rx_fifo_errors = mac_stats->rx_overflow;
stats->rx_missed_errors = mac_stats->rx_missed;
stats->tx_window_errors = mac_stats->tx_late_collision;

stats->rx_errors = (stats->rx_length_errors +
stats->rx_crc_errors +
stats->rx_frame_errors +
mac_stats->rx_symbol_error);
stats->tx_errors = (stats->tx_window_errors +
mac_stats->tx_bad);

efx->type->update_stats(efx, NULL, stats);
spin_unlock_bh(&efx->stats_lock);

return stats;
Expand Down Expand Up @@ -2228,8 +2202,6 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
"could not restore PHY settings\n");
}

efx->type->reconfigure_mac(efx);

efx_enable_interrupts(efx);
efx_restore_filters(efx);
efx_sriov_reset(efx);
Expand Down Expand Up @@ -2484,6 +2456,9 @@ static int efx_init_struct(struct efx_nic *efx,
strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));

efx->net_dev = net_dev;
efx->rx_prefix_size = efx->type->rx_prefix_size;
efx->rx_packet_hash_offset =
efx->type->rx_hash_offset - efx->type->rx_prefix_size;
spin_lock_init(&efx->stats_lock);
mutex_init(&efx->mac_lock);
efx->phy_op = &efx_dummy_phy_operations;
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/ethernet/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ extern void efx_port_dummy_op_void(struct efx_nic *efx);

/* MTD */
#ifdef CONFIG_SFC_MTD
extern int efx_mtd_probe(struct efx_nic *efx);
extern int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
size_t n_parts, size_t sizeof_part);
static inline int efx_mtd_probe(struct efx_nic *efx)
{
return efx->type->mtd_probe(efx);
}
extern void efx_mtd_rename(struct efx_nic *efx);
extern void efx_mtd_remove(struct efx_nic *efx);
#else
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/ethernet/sfc/enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ enum efx_loopback_mode {
* @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog
* @RESET_TYPE_INT_ERROR: reset due to internal error
* @RESET_TYPE_RX_RECOVERY: reset to recover from RX datapath errors
* @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch
* @RESET_TYPE_TX_DESC_FETCH: pcie error during tx descriptor fetch
* @RESET_TYPE_DMA_ERROR: DMA error
* @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors
* @RESET_TYPE_MC_FAILURE: MC reboot/assertion
*/
Expand All @@ -163,8 +162,7 @@ enum reset_type {
RESET_TYPE_TX_WATCHDOG,
RESET_TYPE_INT_ERROR,
RESET_TYPE_RX_RECOVERY,
RESET_TYPE_RX_DESC_FETCH,
RESET_TYPE_TX_DESC_FETCH,
RESET_TYPE_DMA_ERROR,
RESET_TYPE_TX_SKIP,
RESET_TYPE_MC_FAILURE,
RESET_TYPE_MAX,
Expand Down
155 changes: 32 additions & 123 deletions drivers/net/ethernet/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,9 @@
#include "filter.h"
#include "nic.h"

struct ethtool_string {
char name[ETH_GSTRING_LEN];
};

struct efx_ethtool_stat {
struct efx_sw_stat_desc {
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
Expand All @@ -35,7 +30,7 @@ struct efx_ethtool_stat {
u64(*get_stat) (void *field); /* Reader function */
};

/* Initialiser for a struct #efx_ethtool_stat with type-checking */
/* Initialiser for a struct efx_sw_stat_desc with type-checking */
#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \
get_stat_function) { \
.name = #stat_name, \
Expand All @@ -52,24 +47,11 @@ 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)
Expand All @@ -82,72 +64,12 @@ static u64 efx_get_atomic_stat(void *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),
static const struct efx_sw_stat_desc efx_sw_stat_desc[] = {
EFX_ETHTOOL_UINT_TXQ_STAT(merge_events),
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),
Expand All @@ -157,8 +79,7 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = {
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_nodesc_trunc),
};

/* Number of ethtool statistics */
#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
#define EFX_ETHTOOL_SW_STAT_COUNT ARRAY_SIZE(efx_sw_stat_desc)

#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB

Expand Down Expand Up @@ -205,8 +126,6 @@ static int efx_ethtool_get_settings(struct net_device *net_dev,
efx->phy_op->get_settings(efx, ecmd);
mutex_unlock(&efx->mac_lock);

/* GMAC does not support 1000Mbps HD */
ecmd->supported &= ~SUPPORTED_1000baseT_Half;
/* Both MACs support pause frames (bidirectional and respond-only) */
ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;

Expand Down Expand Up @@ -291,12 +210,11 @@ static void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable)
*
* Fill in an individual self-test entry.
*/
static void efx_fill_test(unsigned int test_index,
struct ethtool_string *strings, u64 *data,
static void efx_fill_test(unsigned int test_index, u8 *strings, u64 *data,
int *test, const char *unit_format, int unit_id,
const char *test_format, const char *test_id)
{
struct ethtool_string unit_str, test_str;
char unit_str[ETH_GSTRING_LEN], test_str[ETH_GSTRING_LEN];

/* Fill data value, if applicable */
if (data)
Expand All @@ -305,15 +223,14 @@ static void efx_fill_test(unsigned int test_index,
/* Fill string, if applicable */
if (strings) {
if (strchr(unit_format, '%'))
snprintf(unit_str.name, sizeof(unit_str.name),
snprintf(unit_str, sizeof(unit_str),
unit_format, unit_id);
else
strcpy(unit_str.name, unit_format);
snprintf(test_str.name, sizeof(test_str.name),
test_format, test_id);
snprintf(strings[test_index].name,
sizeof(strings[test_index].name),
"%-6s %-24s", unit_str.name, test_str.name);
strcpy(unit_str, unit_format);
snprintf(test_str, sizeof(test_str), test_format, test_id);
snprintf(strings + test_index * ETH_GSTRING_LEN,
ETH_GSTRING_LEN,
"%-6s %-24s", unit_str, test_str);
}
}

Expand All @@ -336,7 +253,7 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
struct efx_loopback_self_tests *lb_tests,
enum efx_loopback_mode mode,
unsigned int test_index,
struct ethtool_string *strings, u64 *data)
u8 *strings, u64 *data)
{
struct efx_channel *channel =
efx_get_channel(efx, efx->tx_channel_offset);
Expand Down Expand Up @@ -373,8 +290,7 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
*/
static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
struct efx_self_tests *tests,
struct ethtool_string *strings,
u64 *data)
u8 *strings, u64 *data)
{
struct efx_channel *channel;
unsigned int n = 0, i;
Expand Down Expand Up @@ -433,12 +349,14 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
static int efx_ethtool_get_sset_count(struct net_device *net_dev,
int string_set)
{
struct efx_nic *efx = netdev_priv(net_dev);

switch (string_set) {
case ETH_SS_STATS:
return EFX_ETHTOOL_NUM_STATS;
return efx->type->describe_stats(efx, NULL) +
EFX_ETHTOOL_SW_STAT_COUNT;
case ETH_SS_TEST:
return efx_ethtool_fill_self_tests(netdev_priv(net_dev),
NULL, NULL, NULL);
return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
default:
return -EINVAL;
}
Expand All @@ -448,20 +366,18 @@ static void efx_ethtool_get_strings(struct net_device *net_dev,
u32 string_set, u8 *strings)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct ethtool_string *ethtool_strings =
(struct ethtool_string *)strings;
int i;

switch (string_set) {
case ETH_SS_STATS:
for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++)
strlcpy(ethtool_strings[i].name,
efx_ethtool_stats[i].name,
sizeof(ethtool_strings[i].name));
strings += (efx->type->describe_stats(efx, strings) *
ETH_GSTRING_LEN);
for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++)
strlcpy(strings + i * ETH_GSTRING_LEN,
efx_sw_stat_desc[i].name, ETH_GSTRING_LEN);
break;
case ETH_SS_TEST:
efx_ethtool_fill_self_tests(efx, NULL,
ethtool_strings, NULL);
efx_ethtool_fill_self_tests(efx, NULL, strings, NULL);
break;
default:
/* No other string sets */
Expand All @@ -474,27 +390,20 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
u64 *data)
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_mac_stats *mac_stats = &efx->mac_stats;
const struct efx_ethtool_stat *stat;
const struct efx_sw_stat_desc *stat;
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
int i;

EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS);

spin_lock_bh(&efx->stats_lock);

/* Update MAC and NIC statistics */
efx->type->update_stats(efx);
/* Get NIC statistics */
data += efx->type->update_stats(efx, data, NULL);

/* Fill detailed statistics buffer */
for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) {
stat = &efx_ethtool_stats[i];
/* Get software statistics */
for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) {
stat = &efx_sw_stat_desc[i];
switch (stat->source) {
case EFX_ETHTOOL_STAT_SOURCE_mac_stats:
data[i] = stat->get_stat((void *)mac_stats +
stat->offset);
break;
case EFX_ETHTOOL_STAT_SOURCE_nic:
data[i] = stat->get_stat((void *)efx + stat->offset);
break;
Expand Down
Loading

0 comments on commit 4c9d546

Please sign in to comment.