Commit f09ea6fb authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

ethtool: add a new command for reading standard stats



Add an interface for reading standard stats, including
stats which don't have a corresponding control interface.

Start with IEEE 802.3 PHY stats. There seems to be only
one stat to expose there.

Define API to not require user space changes when new
stats or groups are added. Groups are based on bitset,
stats have a string set associated.

v1: wrap stats in a nest

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ddc78b36
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -250,6 +250,13 @@ static inline void ethtool_stats_init(u64 *stats, unsigned int n)
		stats[n] = ETHTOOL_STAT_NOT_SET;
}

/* Basic IEEE 802.3 PHY statistics (30.3.2.1.*), not otherwise exposed
 * via a more targeted API.
 */
struct ethtool_eth_phy_stats {
	u64 SymbolErrorDuringCarrier;
};

/**
 * struct ethtool_pause_stats - statistics for IEEE 802.3x pause frames
 * @tx_pause_frames: transmitted pause frame count. Reported to user space
@@ -487,6 +494,7 @@ struct ethtool_module_eeprom {
 * @get_module_eeprom_by_page: Get a region of plug-in module EEPROM data from
 *	specified page. Returns a negative error code or the amount of bytes
 *	read.
 * @get_eth_phy_stats: Query some of the IEEE 802.3 PHY statistics.
 *
 * All operations are optional (i.e. the function pointer may be set
 * to %NULL) and callers must take this into account.  Callers must
@@ -597,6 +605,8 @@ struct ethtool_ops {
	int	(*get_module_eeprom_by_page)(struct net_device *dev,
					     const struct ethtool_module_eeprom *page,
					     struct netlink_ext_ack *extack);
	void	(*get_eth_phy_stats)(struct net_device *dev,
				     struct ethtool_eth_phy_stats *phy_stats);
};

int ethtool_check_ops(const struct ethtool_ops *ops);
+4 −0
Original line number Diff line number Diff line
@@ -669,6 +669,8 @@ enum ethtool_link_ext_substate_cable_issue {
 * @ETH_SS_TS_TX_TYPES: timestamping Tx types
 * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters
 * @ETH_SS_UDP_TUNNEL_TYPES: UDP tunnel types
 * @ETH_SS_STATS_STD: standardized stats
 * @ETH_SS_STATS_ETH_PHY: names of IEEE 802.3 PHY statistics
 *
 * @ETH_SS_COUNT: number of defined string sets
 */
@@ -689,6 +691,8 @@ enum ethtool_stringset {
	ETH_SS_TS_TX_TYPES,
	ETH_SS_TS_RX_FILTERS,
	ETH_SS_UDP_TUNNEL_TYPES,
	ETH_SS_STATS_STD,
	ETH_SS_STATS_ETH_PHY,

	/* add new constants above here */
	ETH_SS_COUNT
+47 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ enum {
	ETHTOOL_MSG_FEC_GET,
	ETHTOOL_MSG_FEC_SET,
	ETHTOOL_MSG_MODULE_EEPROM_GET,
	ETHTOOL_MSG_STATS_GET,

	/* add new constants above here */
	__ETHTOOL_MSG_USER_CNT,
@@ -86,6 +87,7 @@ enum {
	ETHTOOL_MSG_FEC_GET_REPLY,
	ETHTOOL_MSG_FEC_NTF,
	ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY,
	ETHTOOL_MSG_STATS_GET_REPLY,

	/* add new constants above here */
	__ETHTOOL_MSG_KERNEL_CNT,
@@ -679,6 +681,51 @@ enum {
	ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1)
};

/* STATS */

enum {
	ETHTOOL_A_STATS_UNSPEC,
	ETHTOOL_A_STATS_PAD,
	ETHTOOL_A_STATS_HEADER,			/* nest - _A_HEADER_* */
	ETHTOOL_A_STATS_GROUPS,			/* bitset */

	ETHTOOL_A_STATS_GRP,			/* nest - _A_STATS_GRP_* */

	/* add new constants above here */
	__ETHTOOL_A_STATS_CNT,
	ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1)
};

enum {
	ETHTOOL_STATS_ETH_PHY,

	/* add new constants above here */
	__ETHTOOL_STATS_CNT
};

enum {
	ETHTOOL_A_STATS_GRP_UNSPEC,
	ETHTOOL_A_STATS_GRP_PAD,

	ETHTOOL_A_STATS_GRP_ID,			/* u32 */
	ETHTOOL_A_STATS_GRP_SS_ID,		/* u32 */

	ETHTOOL_A_STATS_GRP_STAT,		/* nest */

	/* add new constants above here */
	__ETHTOOL_A_STATS_GRP_CNT,
	ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1)
};

enum {
	/* 30.3.2.1.5 aSymbolErrorDuringCarrier */
	ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR,

	/* add new constants above here */
	__ETHTOOL_A_STATS_ETH_PHY_CNT,
	ETHTOOL_A_STATS_ETH_PHY_MAX = (__ETHTOOL_A_STATS_ETH_PHY_CNT - 1)
};

/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
+1 −1
Original line number Diff line number Diff line
@@ -7,4 +7,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK) += ethtool_nl.o
ethtool_nl-y	:= netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
		   linkstate.o debug.o wol.o features.o privflags.o rings.o \
		   channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
		   tunnels.o fec.o eeprom.o
		   tunnels.o fec.o eeprom.o stats.o
+10 −0
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = {
	[ETHTOOL_MSG_FEC_GET]		= &ethnl_fec_request_ops,
	[ETHTOOL_MSG_TSINFO_GET]	= &ethnl_tsinfo_request_ops,
	[ETHTOOL_MSG_MODULE_EEPROM_GET]	= &ethnl_module_eeprom_request_ops,
	[ETHTOOL_MSG_STATS_GET]		= &ethnl_stats_request_ops,
};

static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -942,6 +943,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
		.policy = ethnl_module_eeprom_get_policy,
		.maxattr = ARRAY_SIZE(ethnl_module_eeprom_get_policy) - 1,
	},
	{
		.cmd	= ETHTOOL_MSG_STATS_GET,
		.doit	= ethnl_default_doit,
		.start	= ethnl_default_start,
		.dumpit	= ethnl_default_dumpit,
		.done	= ethnl_default_done,
		.policy = ethnl_stats_get_policy,
		.maxattr = ARRAY_SIZE(ethnl_stats_get_policy) - 1,
	},
};

static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
Loading