Skip to content

Commit 9766e97

Browse files
dsaherndavem330
authored andcommitted
net: rocker: Add support for retrieving port level statistics
Add support for retrieving port level statistics from device. Hook is added for ethtool's stats functionality. For example, $ ethtool -S eth3 NIC statistics: rx_packets: 12 rx_bytes: 2790 rx_dropped: 0 rx_errors: 0 tx_packets: 8 tx_bytes: 728 tx_dropped: 0 tx_errors: 0 Signed-off-by: David Ahern <[email protected]> Acked-by: Scott Feldman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fe3ef61 commit 9766e97

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

drivers/net/ethernet/rocker/rocker.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3833,11 +3833,145 @@ static void rocker_port_get_drvinfo(struct net_device *dev,
38333833
strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
38343834
}
38353835

3836+
static struct rocker_port_stats {
3837+
char str[ETH_GSTRING_LEN];
3838+
int type;
3839+
} rocker_port_stats[] = {
3840+
{ "rx_packets", ROCKER_TLV_CMD_PORT_STATS_RX_PKTS, },
3841+
{ "rx_bytes", ROCKER_TLV_CMD_PORT_STATS_RX_BYTES, },
3842+
{ "rx_dropped", ROCKER_TLV_CMD_PORT_STATS_RX_DROPPED, },
3843+
{ "rx_errors", ROCKER_TLV_CMD_PORT_STATS_RX_ERRORS, },
3844+
3845+
{ "tx_packets", ROCKER_TLV_CMD_PORT_STATS_TX_PKTS, },
3846+
{ "tx_bytes", ROCKER_TLV_CMD_PORT_STATS_TX_BYTES, },
3847+
{ "tx_dropped", ROCKER_TLV_CMD_PORT_STATS_TX_DROPPED, },
3848+
{ "tx_errors", ROCKER_TLV_CMD_PORT_STATS_TX_ERRORS, },
3849+
};
3850+
3851+
#define ROCKER_PORT_STATS_LEN ARRAY_SIZE(rocker_port_stats)
3852+
3853+
static void rocker_port_get_strings(struct net_device *netdev, u32 stringset,
3854+
u8 *data)
3855+
{
3856+
u8 *p = data;
3857+
int i;
3858+
3859+
switch (stringset) {
3860+
case ETH_SS_STATS:
3861+
for (i = 0; i < ARRAY_SIZE(rocker_port_stats); i++) {
3862+
memcpy(p, rocker_port_stats[i].str, ETH_GSTRING_LEN);
3863+
p += ETH_GSTRING_LEN;
3864+
}
3865+
break;
3866+
}
3867+
}
3868+
3869+
static int
3870+
rocker_cmd_get_port_stats_prep(struct rocker *rocker,
3871+
struct rocker_port *rocker_port,
3872+
struct rocker_desc_info *desc_info,
3873+
void *priv)
3874+
{
3875+
struct rocker_tlv *cmd_stats;
3876+
3877+
if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE,
3878+
ROCKER_TLV_CMD_TYPE_GET_PORT_STATS))
3879+
return -EMSGSIZE;
3880+
3881+
cmd_stats = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
3882+
if (!cmd_stats)
3883+
return -EMSGSIZE;
3884+
3885+
if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_CMD_PORT_STATS_LPORT,
3886+
rocker_port->lport))
3887+
return -EMSGSIZE;
3888+
3889+
rocker_tlv_nest_end(desc_info, cmd_stats);
3890+
3891+
return 0;
3892+
}
3893+
3894+
static int
3895+
rocker_cmd_get_port_stats_ethtool_proc(struct rocker *rocker,
3896+
struct rocker_port *rocker_port,
3897+
struct rocker_desc_info *desc_info,
3898+
void *priv)
3899+
{
3900+
struct rocker_tlv *attrs[ROCKER_TLV_CMD_MAX + 1];
3901+
struct rocker_tlv *stats_attrs[ROCKER_TLV_CMD_PORT_STATS_MAX + 1];
3902+
struct rocker_tlv *pattr;
3903+
u32 lport;
3904+
u64 *data = priv;
3905+
int i;
3906+
3907+
rocker_tlv_parse_desc(attrs, ROCKER_TLV_CMD_MAX, desc_info);
3908+
3909+
if (!attrs[ROCKER_TLV_CMD_INFO])
3910+
return -EIO;
3911+
3912+
rocker_tlv_parse_nested(stats_attrs, ROCKER_TLV_CMD_PORT_STATS_MAX,
3913+
attrs[ROCKER_TLV_CMD_INFO]);
3914+
3915+
if (!stats_attrs[ROCKER_TLV_CMD_PORT_STATS_LPORT])
3916+
return -EIO;
3917+
3918+
lport = rocker_tlv_get_u32(stats_attrs[ROCKER_TLV_CMD_PORT_STATS_LPORT]);
3919+
if (lport != rocker_port->lport)
3920+
return -EIO;
3921+
3922+
for (i = 0; i < ARRAY_SIZE(rocker_port_stats); i++) {
3923+
pattr = stats_attrs[rocker_port_stats[i].type];
3924+
if (!pattr)
3925+
continue;
3926+
3927+
data[i] = rocker_tlv_get_u64(pattr);
3928+
}
3929+
3930+
return 0;
3931+
}
3932+
3933+
static int rocker_cmd_get_port_stats_ethtool(struct rocker_port *rocker_port,
3934+
void *priv)
3935+
{
3936+
return rocker_cmd_exec(rocker_port->rocker, rocker_port,
3937+
rocker_cmd_get_port_stats_prep, NULL,
3938+
rocker_cmd_get_port_stats_ethtool_proc,
3939+
priv, false);
3940+
}
3941+
3942+
static void rocker_port_get_stats(struct net_device *dev,
3943+
struct ethtool_stats *stats, u64 *data)
3944+
{
3945+
struct rocker_port *rocker_port = netdev_priv(dev);
3946+
3947+
if (rocker_cmd_get_port_stats_ethtool(rocker_port, data) != 0) {
3948+
int i;
3949+
3950+
for (i = 0; i < ARRAY_SIZE(rocker_port_stats); ++i)
3951+
data[i] = 0;
3952+
}
3953+
3954+
return;
3955+
}
3956+
3957+
static int rocker_port_get_sset_count(struct net_device *netdev, int sset)
3958+
{
3959+
switch (sset) {
3960+
case ETH_SS_STATS:
3961+
return ROCKER_PORT_STATS_LEN;
3962+
default:
3963+
return -EOPNOTSUPP;
3964+
}
3965+
}
3966+
38363967
static const struct ethtool_ops rocker_port_ethtool_ops = {
38373968
.get_settings = rocker_port_get_settings,
38383969
.set_settings = rocker_port_set_settings,
38393970
.get_drvinfo = rocker_port_get_drvinfo,
38403971
.get_link = ethtool_op_get_link,
3972+
.get_strings = rocker_port_get_strings,
3973+
.get_ethtool_stats = rocker_port_get_stats,
3974+
.get_sset_count = rocker_port_get_sset_count,
38413975
};
38423976

38433977
/*****************

drivers/net/ethernet/rocker/rocker.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ enum {
127127
ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL,
128128
ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_GET_STATS,
129129

130+
ROCKER_TLV_CMD_TYPE_CLEAR_PORT_STATS,
131+
ROCKER_TLV_CMD_TYPE_GET_PORT_STATS,
132+
130133
__ROCKER_TLV_CMD_TYPE_MAX,
131134
ROCKER_TLV_CMD_TYPE_MAX = __ROCKER_TLV_CMD_TYPE_MAX - 1,
132135
};
@@ -146,6 +149,24 @@ enum {
146149
__ROCKER_TLV_CMD_PORT_SETTINGS_MAX - 1,
147150
};
148151

152+
enum {
153+
ROCKER_TLV_CMD_PORT_STATS_UNSPEC,
154+
ROCKER_TLV_CMD_PORT_STATS_LPORT, /* u32 */
155+
156+
ROCKER_TLV_CMD_PORT_STATS_RX_PKTS, /* u64 */
157+
ROCKER_TLV_CMD_PORT_STATS_RX_BYTES, /* u64 */
158+
ROCKER_TLV_CMD_PORT_STATS_RX_DROPPED, /* u64 */
159+
ROCKER_TLV_CMD_PORT_STATS_RX_ERRORS, /* u64 */
160+
161+
ROCKER_TLV_CMD_PORT_STATS_TX_PKTS, /* u64 */
162+
ROCKER_TLV_CMD_PORT_STATS_TX_BYTES, /* u64 */
163+
ROCKER_TLV_CMD_PORT_STATS_TX_DROPPED, /* u64 */
164+
ROCKER_TLV_CMD_PORT_STATS_TX_ERRORS, /* u64 */
165+
166+
__ROCKER_TLV_CMD_PORT_STATS_MAX,
167+
ROCKER_TLV_CMD_PORT_STATS_MAX = __ROCKER_TLV_CMD_PORT_STATS_MAX - 1,
168+
};
169+
149170
enum rocker_port_mode {
150171
ROCKER_PORT_MODE_OF_DPA,
151172
};

0 commit comments

Comments
 (0)