Number of devices maintains the standard-based MAC control counters for control frames. Add a API for those.
Unified · Split
| @@ -285,6 +285,15 @@ struct ethtool_eth_phy_stats { · 284 unmodified lines | ||
| 285 | 285 | u64 SymbolErrorDuringCarrier; |
| 286 | 286 | }; |
| 287 | 287 | |
| 288 | +/* Basic IEEE 802.3 MAC Ctrl statistics (30.3.3.*), not otherwise exposed | |
| 289 | + * via a more targeted API. | |
| 290 | + */ | |
| 291 | +struct ethtool_eth_ctrl_stats { | |
| 292 | + u64 MACControlFramesTransmitted; | |
| 293 | + u64 MACControlFramesReceived; | |
| 294 | + u64 UnsupportedOpcodesReceived; | |
| 295 | +}; | |
| 296 | + | |
| 288 | 297 | /** |
| 289 | 298 | * struct ethtool_pause_stats - statistics for IEEE 802.3x pause frames |
| 290 | 299 | * @tx_pause_frames: transmitted pause frame count. Reported to user space |
| @@ -524,6 +533,7 @@ struct ethtool_module_eeprom { · 233 unmodified lines | ||
| 524 | 533 | * read. |
| 525 | 534 | * @get_eth_phy_stats: Query some of the IEEE 802.3 PHY statistics. |
| 526 | 535 | * @get_eth_mac_stats: Query some of the IEEE 802.3 MAC statistics. |
| 536 | + * @get_eth_ctrl_stats: Query some of the IEEE 802.3 MAC Ctrl statistics. | |
| 527 | 537 | * |
| 528 | 538 | * All operations are optional (i.e. the function pointer may be set |
| 529 | 539 | * to %NULL) and callers must take this into account. Callers must |
| @@ -638,6 +648,8 @@ struct ethtool_ops { · 108 unmodified lines | ||
| 638 | 648 | struct ethtool_eth_phy_stats *phy_stats); |
| 639 | 649 | void (*get_eth_mac_stats)(struct net_device *dev, |
| 640 | 650 | struct ethtool_eth_mac_stats *mac_stats); |
| 651 | + void (*get_eth_ctrl_stats)(struct net_device *dev, | |
| 652 | + struct ethtool_eth_ctrl_stats *ctrl_stats); | |
| 641 | 653 | }; |
| 642 | 654 | |
| 643 | 655 | int ethtool_check_ops(const struct ethtool_ops *ops); |
| @@ -672,6 +672,7 @@ enum ethtool_link_ext_substate_cable_issue { · 671 unmodified lines | ||
| 672 | 672 | * @ETH_SS_STATS_STD: standardized stats |
| 673 | 673 | * @ETH_SS_STATS_ETH_PHY: names of IEEE 802.3 PHY statistics |
| 674 | 674 | * @ETH_SS_STATS_ETH_MAC: names of IEEE 802.3 MAC statistics |
| 675 | + * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics | |
| 675 | 676 | * |
| 676 | 677 | * @ETH_SS_COUNT: number of defined string sets |
| 677 | 678 | */ |
| @@ -695,6 +696,7 @@ enum ethtool_stringset { · 17 unmodified lines | ||
| 695 | 696 | ETH_SS_STATS_STD, |
| 696 | 697 | ETH_SS_STATS_ETH_PHY, |
| 697 | 698 | ETH_SS_STATS_ETH_MAC, |
| 699 | + ETH_SS_STATS_ETH_CTRL, | |
| 698 | 700 | |
| 699 | 701 | /* add new constants above here */ |
| 700 | 702 | ETH_SS_COUNT |
| @@ -699,6 +699,7 @@ enum { · 698 unmodified lines | ||
| 699 | 699 | enum { |
| 700 | 700 | ETHTOOL_STATS_ETH_PHY, |
| 701 | 701 | ETHTOOL_STATS_ETH_MAC, |
| 702 | + ETHTOOL_STATS_ETH_CTRL, | |
| 702 | 703 | |
| 703 | 704 | /* add new constants above here */ |
| 704 | 705 | __ETHTOOL_STATS_CNT |
| @@ -779,6 +780,19 @@ enum { · 74 unmodified lines | ||
| 779 | 780 | ETHTOOL_A_STATS_ETH_MAC_MAX = (__ETHTOOL_A_STATS_ETH_MAC_CNT - 1) |
| 780 | 781 | }; |
| 781 | 782 | |
| 783 | +enum { | |
| 784 | + /* 30.3.3.3 aMACControlFramesTransmitted */ | |
| 785 | + ETHTOOL_A_STATS_ETH_CTRL_3_TX, | |
| 786 | + /* 30.3.3.4 aMACControlFramesReceived */ | |
| 787 | + ETHTOOL_A_STATS_ETH_CTRL_4_RX, | |
| 788 | + /* 30.3.3.5 aUnsupportedOpcodesReceived */ | |
| 789 | + ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP, | |
| 790 | + | |
| 791 | + /* add new constants above here */ | |
| 792 | + __ETHTOOL_A_STATS_ETH_CTRL_CNT, | |
| 793 | + ETHTOOL_A_STATS_ETH_CTRL_MAX = (__ETHTOOL_A_STATS_ETH_CTRL_CNT - 1) | |
| 794 | +}; | |
| 795 | + | |
| 782 | 796 | /* generic netlink info */ |
| 783 | 797 | #define ETHTOOL_GENL_NAME "ethtool" |
| 784 | 798 | #define ETHTOOL_GENL_VERSION 1 |
| @@ -404,5 +404,6 @@ int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info); · 403 unmodified lines | ||
| 404 | 404 | extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN]; |
| 405 | 405 | extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN]; |
| 406 | 406 | extern const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN]; |
| 407 | +extern const char stats_eth_ctrl_names[__ETHTOOL_A_STATS_ETH_CTRL_CNT][ETH_GSTRING_LEN]; | |
| 407 | 408 | |
| 408 | 409 | #endif /* _NET_ETHTOOL_NETLINK_H */ |
| @@ -16,6 +16,7 @@ struct stats_reply_data { · 15 unmodified lines | ||
| 16 | 16 | struct ethnl_reply_data base; |
| 17 | 17 | struct ethtool_eth_phy_stats phy_stats; |
| 18 | 18 | struct ethtool_eth_mac_stats mac_stats; |
| 19 | + struct ethtool_eth_ctrl_stats ctrl_stats; | |
| 19 | 20 | }; |
| 20 | 21 | |
| 21 | 22 | #define STATS_REPDATA(__reply_base) \ |
| @@ -24,6 +25,7 @@ struct stats_reply_data { · 2 unmodified lines | ||
| 24 | 25 | const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN] = { |
| 25 | 26 | [ETHTOOL_STATS_ETH_PHY] = "eth-phy", |
| 26 | 27 | [ETHTOOL_STATS_ETH_MAC] = "eth-mac", |
| 28 | + [ETHTOOL_STATS_ETH_CTRL] = "eth-ctrl", | |
| 27 | 29 | }; |
| 28 | 30 | |
| 29 | 31 | const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN] = { |
| @@ -55,6 +57,12 @@ const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN] = · 25 unmodified lines | ||
| 55 | 57 | [ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR] = "FrameTooLongErrors", |
| 56 | 58 | }; |
| 57 | 59 | |
| 60 | +const char stats_eth_ctrl_names[__ETHTOOL_A_STATS_ETH_CTRL_CNT][ETH_GSTRING_LEN] = { | |
| 61 | + [ETHTOOL_A_STATS_ETH_CTRL_3_TX] = "MACControlFramesTransmitted", | |
| 62 | + [ETHTOOL_A_STATS_ETH_CTRL_4_RX] = "MACControlFramesReceived", | |
| 63 | + [ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP] = "UnsupportedOpcodesReceived", | |
| 64 | +}; | |
| 65 | + | |
| 58 | 66 | const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1] = { |
| 59 | 67 | [ETHTOOL_A_STATS_HEADER] = |
| 60 | 68 | NLA_POLICY_NESTED(ethnl_header_policy), |
| @@ -98,6 +106,7 @@ static int stats_prepare_data(const struct ethnl_req_info *req_base, · 37 unmodified lines | ||
| 98 | 106 | |
| 99 | 107 | memset(&data->phy_stats, 0xff, sizeof(data->phy_stats)); |
| 100 | 108 | memset(&data->mac_stats, 0xff, sizeof(data->mac_stats)); |
| 109 | + memset(&data->ctrl_stats, 0xff, sizeof(data->mac_stats)); | |
| 101 | 110 | |
| 102 | 111 | if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) && |
| 103 | 112 | dev->ethtool_ops->get_eth_phy_stats) |
| @@ -105,6 +114,9 @@ static int stats_prepare_data(const struct ethnl_req_info *req_base, · 1 unmodified line | ||
| 105 | 114 | if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) && |
| 106 | 115 | dev->ethtool_ops->get_eth_mac_stats) |
| 107 | 116 | dev->ethtool_ops->get_eth_mac_stats(dev, &data->mac_stats); |
| 117 | + if (test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask) && | |
| 118 | + dev->ethtool_ops->get_eth_ctrl_stats) | |
| 119 | + dev->ethtool_ops->get_eth_ctrl_stats(dev, &data->ctrl_stats); | |
| 108 | 120 | |
| 109 | 121 | ethnl_ops_complete(dev); |
| 110 | 122 | return 0; |
| @@ -125,6 +137,10 @@ static int stats_reply_size(const struct ethnl_req_info *req_base, · 14 unmodified lines | ||
| 125 | 137 | n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64); |
| 126 | 138 | n_grps++; |
| 127 | 139 | } |
| 140 | + if (test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask)) { | |
| 141 | + n_stats += sizeof(struct ethtool_eth_ctrl_stats) / sizeof(u64); | |
| 142 | + n_grps++; | |
| 143 | + } | |
| 128 | 144 | |
| 129 | 145 | len += n_grps * (nla_total_size(0) + /* _A_STATS_GRP */ |
| 130 | 146 | nla_total_size(4) + /* _A_STATS_GRP_ID */ |
| @@ -229,6 +245,19 @@ static int stats_put_mac_stats(struct sk_buff *skb, · 98 unmodified lines | ||
| 229 | 245 | return 0; |
| 230 | 246 | } |
| 231 | 247 | |
| 248 | +static int stats_put_ctrl_stats(struct sk_buff *skb, | |
| 249 | + const struct stats_reply_data *data) | |
| 250 | +{ | |
| 251 | + if (stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_3_TX, | |
| 252 | + data->ctrl_stats.MACControlFramesTransmitted) || | |
| 253 | + stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_4_RX, | |
| 254 | + data->ctrl_stats.MACControlFramesReceived) || | |
| 255 | + stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP, | |
| 256 | + data->ctrl_stats.UnsupportedOpcodesReceived)) | |
| 257 | + return -EMSGSIZE; | |
| 258 | + return 0; | |
| 259 | +} | |
| 260 | + | |
| 232 | 261 | static int stats_put_stats(struct sk_buff *skb, |
| 233 | 262 | const struct stats_reply_data *data, |
| 234 | 263 | u32 id, u32 ss_id, |
| @@ -272,6 +301,10 @@ static int stats_fill_reply(struct sk_buff *skb, · 37 unmodified lines | ||
| 272 | 301 | ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC, |
| 273 | 302 | ETH_SS_STATS_ETH_MAC, |
| 274 | 303 | stats_put_mac_stats); |
| 304 | + if (!ret && test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask)) | |
| 305 | + ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_CTRL, | |
| 306 | + ETH_SS_STATS_ETH_CTRL, | |
| 307 | + stats_put_ctrl_stats); | |
| 275 | 308 | |
| 276 | 309 | return ret; |
| 277 | 310 | } |
| @@ -95,6 +95,11 @@ static const struct strset_info info_template[] = { · 94 unmodified lines | ||
| 95 | 95 | .count = __ETHTOOL_A_STATS_ETH_MAC_CNT, |
| 96 | 96 | .strings = stats_eth_mac_names, |
| 97 | 97 | }, |
| 98 | + [ETH_SS_STATS_ETH_CTRL] = { | |
| 99 | + .per_dev = false, | |
| 100 | + .count = __ETHTOOL_A_STATS_ETH_CTRL_CNT, | |
| 101 | + .strings = stats_eth_ctrl_names, | |
| 102 | + }, | |
| 98 | 103 | }; |
| 99 | 104 | |
| 100 | 105 | struct strset_req_info { |