ethtool: add interface to read RMON stats

Most devices maintain RMON (RFC 2819) stats - particularly
the "histogram" of packets received by size. Unlike other
RFCs which duplicate IEEE stats, the short/oversized frame
counters in RMON don't seem to match IEEE stats 1-to-1 either,
so expose those, too. Do not expose basic packet, CRC errors
etc - those are already otherwise covered.

Because standard defines packet ranges only up to 1518, and
everything above that should theoretically be "oversized"
- devices often create their own ranges.

Going beyond what the RFC defines - expose the "histogram"
in the Tx direction (assume for now that the ranges will
be the same).

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jakub Kicinski 2021-04-16 12:27:42 -07:00 committed by David S. Miller
parent bfad2b979d
commit a8b06e9d40
6 changed files with 161 additions and 0 deletions

View file

@ -346,6 +346,44 @@ struct ethtool_fec_stats {
} corrected_blocks, uncorrectable_blocks, corrected_bits;
};
/**
* struct ethtool_rmon_hist_range - byte range for histogram statistics
* @low: low bound of the bucket (inclusive)
* @high: high bound of the bucket (inclusive)
*/
struct ethtool_rmon_hist_range {
u16 low;
u16 high;
};
#define ETHTOOL_RMON_HIST_MAX 10
/**
* struct ethtool_rmon_stats - selected RMON (RFC 2819) statistics
* @undersize_pkts: Equivalent to `etherStatsUndersizePkts` from the RFC.
* @oversize_pkts: Equivalent to `etherStatsOversizePkts` from the RFC.
* @fragments: Equivalent to `etherStatsFragments` from the RFC.
* @jabbers: Equivalent to `etherStatsJabbers` from the RFC.
* @hist: Packet counter for packet length buckets (e.g.
* `etherStatsPkts128to255Octets` from the RFC).
* @hist_tx: Tx counters in similar form to @hist, not defined in the RFC.
*
* Selection of RMON (RFC 2819) statistics which are not exposed via different
* APIs, primarily the packet-length-based counters.
* Unfortunately different designs choose different buckets beyond
* the 1024B mark (jumbo frame teritory), so the definition of the bucket
* ranges is left to the driver.
*/
struct ethtool_rmon_stats {
u64 undersize_pkts;
u64 oversize_pkts;
u64 fragments;
u64 jabbers;
u64 hist[ETHTOOL_RMON_HIST_MAX];
u64 hist_tx[ETHTOOL_RMON_HIST_MAX];
};
#define ETH_MODULE_EEPROM_PAGE_LEN 128
#define ETH_MODULE_MAX_I2C_ADDRESS 0x7f
@ -534,6 +572,8 @@ struct ethtool_module_eeprom {
* @get_eth_phy_stats: Query some of the IEEE 802.3 PHY statistics.
* @get_eth_mac_stats: Query some of the IEEE 802.3 MAC statistics.
* @get_eth_ctrl_stats: Query some of the IEEE 802.3 MAC Ctrl statistics.
* @get_rmon_stats: Query some of the RMON (RFC 2819) statistics.
* Set %ranges to a pointer to zero-terminated array of byte ranges.
*
* All operations are optional (i.e. the function pointer may be set
* to %NULL) and callers must take this into account. Callers must
@ -650,6 +690,9 @@ struct ethtool_ops {
struct ethtool_eth_mac_stats *mac_stats);
void (*get_eth_ctrl_stats)(struct net_device *dev,
struct ethtool_eth_ctrl_stats *ctrl_stats);
void (*get_rmon_stats)(struct net_device *dev,
struct ethtool_rmon_stats *rmon_stats,
const struct ethtool_rmon_hist_range **ranges);
};
int ethtool_check_ops(const struct ethtool_ops *ops);