Skip to content

Commit 6167c0b

Browse files
kuba-mooPaolo Abeni
authored andcommitted
net: ethtool: add support for structured PHY statistics
Introduce a new way to report PHY statistics in a structured and standardized format using the netlink API. This new method does not replace the old driver-specific stats, which can still be accessed with `ethtool -S <eth name>`. The structured stats are available with `ethtool -S <eth name> --all-groups`. This new method makes it easier to diagnose problems by organizing stats in a consistent and documented way. Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Oleksij Rempel <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent b7a2c1f commit 6167c0b

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ the ``ETHTOOL_A_STATS_GROUPS`` bitset. Currently defined values are:
16161616
ETHTOOL_STATS_ETH_PHY eth-phy Basic IEEE 802.3 PHY statistics (30.3.2.1.*)
16171617
ETHTOOL_STATS_ETH_CTRL eth-ctrl Basic IEEE 802.3 MAC Ctrl statistics (30.3.3.*)
16181618
ETHTOOL_STATS_RMON rmon RMON (RFC 2819) statistics
1619+
ETHTOOL_STATS_PHY phy Additional PHY statistics, not defined by IEEE
16191620
====================== ======== ===============================================
16201621

16211622
Each group should have a corresponding ``ETHTOOL_A_STATS_GRP`` in the reply.

include/uapi/linux/ethtool.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ enum ethtool_link_ext_substate_module {
681681
* @ETH_SS_STATS_ETH_MAC: names of IEEE 802.3 MAC statistics
682682
* @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics
683683
* @ETH_SS_STATS_RMON: names of RMON statistics
684+
* @ETH_SS_STATS_PHY: names of PHY(dev) statistics
684685
*
685686
* @ETH_SS_COUNT: number of defined string sets
686687
*/
@@ -706,6 +707,7 @@ enum ethtool_stringset {
706707
ETH_SS_STATS_ETH_MAC,
707708
ETH_SS_STATS_ETH_CTRL,
708709
ETH_SS_STATS_RMON,
710+
ETH_SS_STATS_PHY,
709711

710712
/* add new constants above here */
711713
ETH_SS_COUNT

include/uapi/linux/ethtool_netlink.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ enum {
9999
ETHTOOL_STATS_ETH_MAC,
100100
ETHTOOL_STATS_ETH_CTRL,
101101
ETHTOOL_STATS_RMON,
102+
ETHTOOL_STATS_PHY,
102103

103104
/* add new constants above here */
104105
__ETHTOOL_STATS_CNT
@@ -193,6 +194,19 @@ enum {
193194
ETHTOOL_A_STATS_RMON_MAX = (__ETHTOOL_A_STATS_RMON_CNT - 1)
194195
};
195196

197+
enum {
198+
/* Basic packet counters if PHY has separate counters from the MAC */
199+
ETHTOOL_A_STATS_PHY_RX_PKTS,
200+
ETHTOOL_A_STATS_PHY_RX_BYTES,
201+
ETHTOOL_A_STATS_PHY_RX_ERRORS,
202+
ETHTOOL_A_STATS_PHY_TX_PKTS,
203+
ETHTOOL_A_STATS_PHY_TX_BYTES,
204+
ETHTOOL_A_STATS_PHY_TX_ERRORS,
205+
206+
/* add new constants above here */
207+
__ETHTOOL_A_STATS_PHY_CNT,
208+
ETHTOOL_A_STATS_PHY_MAX = (__ETHTOOL_A_STATS_PHY_CNT - 1)
209+
};
196210

197211
/* generic netlink info */
198212
#define ETHTOOL_GENL_NAME "ethtool"

net/ethtool/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,5 +511,6 @@ extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING
511511
extern const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN];
512512
extern const char stats_eth_ctrl_names[__ETHTOOL_A_STATS_ETH_CTRL_CNT][ETH_GSTRING_LEN];
513513
extern const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN];
514+
extern const char stats_phy_names[__ETHTOOL_A_STATS_PHY_CNT][ETH_GSTRING_LEN];
514515

515516
#endif /* _NET_ETHTOOL_NETLINK_H */

net/ethtool/stats.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN] = {
3636
[ETHTOOL_STATS_ETH_MAC] = "eth-mac",
3737
[ETHTOOL_STATS_ETH_CTRL] = "eth-ctrl",
3838
[ETHTOOL_STATS_RMON] = "rmon",
39+
[ETHTOOL_STATS_PHY] = "phydev",
3940
};
4041

4142
const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN] = {
@@ -80,6 +81,15 @@ const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN] = {
8081
[ETHTOOL_A_STATS_RMON_JABBER] = "etherStatsJabbers",
8182
};
8283

84+
const char stats_phy_names[__ETHTOOL_A_STATS_PHY_CNT][ETH_GSTRING_LEN] = {
85+
[ETHTOOL_A_STATS_PHY_RX_PKTS] = "RxFrames",
86+
[ETHTOOL_A_STATS_PHY_RX_BYTES] = "RxOctets",
87+
[ETHTOOL_A_STATS_PHY_RX_ERRORS] = "RxErrors",
88+
[ETHTOOL_A_STATS_PHY_TX_PKTS] = "TxFrames",
89+
[ETHTOOL_A_STATS_PHY_TX_BYTES] = "TxOctets",
90+
[ETHTOOL_A_STATS_PHY_TX_ERRORS] = "TxErrors",
91+
};
92+
8393
const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_SRC + 1] = {
8494
[ETHTOOL_A_STATS_HEADER] =
8595
NLA_POLICY_NESTED(ethnl_header_policy),
@@ -156,7 +166,8 @@ static int stats_prepare_data(const struct ethnl_req_info *req_base,
156166
data->ctrl_stats.src = src;
157167
data->rmon_stats.src = src;
158168

159-
if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) &&
169+
if ((test_bit(ETHTOOL_STATS_PHY, req_info->stat_mask) ||
170+
test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask)) &&
160171
src == ETHTOOL_MAC_STATS_SRC_AGGREGATE) {
161172
if (phydev)
162173
phy_ethtool_get_phy_stats(phydev, &data->phy_stats,
@@ -212,6 +223,10 @@ static int stats_reply_size(const struct ethnl_req_info *req_base,
212223
nla_total_size(4)) * /* _A_STATS_GRP_HIST_BKT_HI */
213224
ETHTOOL_RMON_HIST_MAX * 2;
214225
}
226+
if (test_bit(ETHTOOL_STATS_PHY, req_info->stat_mask)) {
227+
n_stats += sizeof(struct ethtool_phy_stats) / sizeof(u64);
228+
n_grps++;
229+
}
215230

216231
len += n_grps * (nla_total_size(0) + /* _A_STATS_GRP */
217232
nla_total_size(4) + /* _A_STATS_GRP_ID */
@@ -265,6 +280,25 @@ static int stats_put_phy_stats(struct sk_buff *skb,
265280
return 0;
266281
}
267282

283+
static int stats_put_phydev_stats(struct sk_buff *skb,
284+
const struct stats_reply_data *data)
285+
{
286+
if (stat_put(skb, ETHTOOL_A_STATS_PHY_RX_PKTS,
287+
data->phydev_stats.rx_packets) ||
288+
stat_put(skb, ETHTOOL_A_STATS_PHY_RX_BYTES,
289+
data->phydev_stats.rx_bytes) ||
290+
stat_put(skb, ETHTOOL_A_STATS_PHY_RX_ERRORS,
291+
data->phydev_stats.rx_errors) ||
292+
stat_put(skb, ETHTOOL_A_STATS_PHY_TX_PKTS,
293+
data->phydev_stats.tx_packets) ||
294+
stat_put(skb, ETHTOOL_A_STATS_PHY_TX_BYTES,
295+
data->phydev_stats.tx_bytes) ||
296+
stat_put(skb, ETHTOOL_A_STATS_PHY_TX_ERRORS,
297+
data->phydev_stats.tx_errors))
298+
return -EMSGSIZE;
299+
return 0;
300+
}
301+
268302
static int stats_put_mac_stats(struct sk_buff *skb,
269303
const struct stats_reply_data *data)
270304
{
@@ -441,6 +475,9 @@ static int stats_fill_reply(struct sk_buff *skb,
441475
if (!ret && test_bit(ETHTOOL_STATS_RMON, req_info->stat_mask))
442476
ret = stats_put_stats(skb, data, ETHTOOL_STATS_RMON,
443477
ETH_SS_STATS_RMON, stats_put_rmon_stats);
478+
if (!ret && test_bit(ETHTOOL_STATS_PHY, req_info->stat_mask))
479+
ret = stats_put_stats(skb, data, ETHTOOL_STATS_PHY,
480+
ETH_SS_STATS_PHY, stats_put_phydev_stats);
444481

445482
return ret;
446483
}

net/ethtool/strset.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ static const struct strset_info info_template[] = {
105105
.count = __ETHTOOL_A_STATS_RMON_CNT,
106106
.strings = stats_rmon_names,
107107
},
108+
[ETH_SS_STATS_PHY] = {
109+
.per_dev = false,
110+
.count = __ETHTOOL_A_STATS_PHY_CNT,
111+
.strings = stats_phy_names,
112+
},
108113
};
109114

110115
struct strset_req_info {

0 commit comments

Comments
 (0)