Skip to content

Commit

Permalink
net: mvneta: add ethtool statistics
Browse files Browse the repository at this point in the history
Add support for the ethtool statistic interface, returning the full set
of statistics which both Armada 370, 38x and Armada XP can support.

Tested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Oct 26, 2015
1 parent 1586a58 commit 9b0cdef
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,50 @@

#define MVNETA_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD)

struct mvneta_statistic {
unsigned short offset;
unsigned short type;
const char name[ETH_GSTRING_LEN];
};

#define T_REG_32 32
#define T_REG_64 64

static const struct mvneta_statistic mvneta_statistics[] = {
{ 0x3000, T_REG_64, "good_octets_received", },
{ 0x3010, T_REG_32, "good_frames_received", },
{ 0x3008, T_REG_32, "bad_octets_received", },
{ 0x3014, T_REG_32, "bad_frames_received", },
{ 0x3018, T_REG_32, "broadcast_frames_received", },
{ 0x301c, T_REG_32, "multicast_frames_received", },
{ 0x3050, T_REG_32, "unrec_mac_control_received", },
{ 0x3058, T_REG_32, "good_fc_received", },
{ 0x305c, T_REG_32, "bad_fc_received", },
{ 0x3060, T_REG_32, "undersize_received", },
{ 0x3064, T_REG_32, "fragments_received", },
{ 0x3068, T_REG_32, "oversize_received", },
{ 0x306c, T_REG_32, "jabber_received", },
{ 0x3070, T_REG_32, "mac_receive_error", },
{ 0x3074, T_REG_32, "bad_crc_event", },
{ 0x3078, T_REG_32, "collision", },
{ 0x307c, T_REG_32, "late_collision", },
{ 0x2484, T_REG_32, "rx_discard", },
{ 0x2488, T_REG_32, "rx_overrun", },
{ 0x3020, T_REG_32, "frames_64_octets", },
{ 0x3024, T_REG_32, "frames_65_to_127_octets", },
{ 0x3028, T_REG_32, "frames_128_to_255_octets", },
{ 0x302c, T_REG_32, "frames_256_to_511_octets", },
{ 0x3030, T_REG_32, "frames_512_to_1023_octets", },
{ 0x3034, T_REG_32, "frames_1024_to_max_octets", },
{ 0x3038, T_REG_64, "good_octets_sent", },
{ 0x3040, T_REG_32, "good_frames_sent", },
{ 0x3044, T_REG_32, "excessive_collision", },
{ 0x3048, T_REG_32, "multicast_frames_sent", },
{ 0x304c, T_REG_32, "broadcast_frames_sent", },
{ 0x3054, T_REG_32, "fc_sent", },
{ 0x300c, T_REG_32, "internal_mac_transmit_err", },
};

struct mvneta_pcpu_stats {
struct u64_stats_sync syncp;
u64 rx_packets;
Expand Down Expand Up @@ -324,6 +368,8 @@ struct mvneta_port {
unsigned int speed;
unsigned int tx_csum_limit;
int use_inband_status:1;

u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
};

/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
Expand Down Expand Up @@ -2982,6 +3028,65 @@ static int mvneta_ethtool_set_ringparam(struct net_device *dev,
return 0;
}

static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset,
u8 *data)
{
if (sset == ETH_SS_STATS) {
int i;

for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++)
memcpy(data + i * ETH_GSTRING_LEN,
mvneta_statistics[i].name, ETH_GSTRING_LEN);
}
}

static void mvneta_ethtool_update_stats(struct mvneta_port *pp)
{
const struct mvneta_statistic *s;
void __iomem *base = pp->base;
u32 high, low, val;
int i;

for (i = 0, s = mvneta_statistics;
s < mvneta_statistics + ARRAY_SIZE(mvneta_statistics);
s++, i++) {
val = 0;

switch (s->type) {
case T_REG_32:
val = readl_relaxed(base + s->offset);
break;
case T_REG_64:
/* Docs say to read low 32-bit then high */
low = readl_relaxed(base + s->offset);
high = readl_relaxed(base + s->offset + 4);
val = (u64)high << 32 | low;
break;
}

pp->ethtool_stats[i] += val;
}
}

static void mvneta_ethtool_get_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct mvneta_port *pp = netdev_priv(dev);
int i;

mvneta_ethtool_update_stats(pp);

for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++)
*data++ = pp->ethtool_stats[i];
}

static int mvneta_ethtool_get_sset_count(struct net_device *dev, int sset)
{
if (sset == ETH_SS_STATS)
return ARRAY_SIZE(mvneta_statistics);
return -EOPNOTSUPP;
}

static const struct net_device_ops mvneta_netdev_ops = {
.ndo_open = mvneta_open,
.ndo_stop = mvneta_stop,
Expand All @@ -3003,6 +3108,9 @@ const struct ethtool_ops mvneta_eth_tool_ops = {
.get_drvinfo = mvneta_ethtool_get_drvinfo,
.get_ringparam = mvneta_ethtool_get_ringparam,
.set_ringparam = mvneta_ethtool_set_ringparam,
.get_strings = mvneta_ethtool_get_strings,
.get_ethtool_stats = mvneta_ethtool_get_stats,
.get_sset_count = mvneta_ethtool_get_sset_count,
};

/* Initialize hw */
Expand Down

0 comments on commit 9b0cdef

Please sign in to comment.