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 | u64 SymbolErrorDuringCarrier; | 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 | * struct ethtool_pause_stats - statistics for IEEE 802.3x pause frames | 298 | * struct ethtool_pause_stats - statistics for IEEE 802.3x pause frames |
| 290 | * @tx_pause_frames: transmitted pause frame count. Reported to user space | 299 | * @tx_pause_frames: transmitted pause frame count. Reported to user space |
| @@ -524,6 +533,7 @@ struct ethtool_module_eeprom { · 233 unmodified lines | |||
| 524 | * read. | 533 | * read. |
| 525 | * @get_eth_phy_stats: Query some of the IEEE 802.3 PHY statistics. | 534 | * @get_eth_phy_stats: Query some of the IEEE 802.3 PHY statistics. |
| 526 | * @get_eth_mac_stats: Query some of the IEEE 802.3 MAC statistics. | 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 | * All operations are optional (i.e. the function pointer may be set | 538 | * All operations are optional (i.e. the function pointer may be set |
| 529 | * to %NULL) and callers must take this into account. Callers must | 539 | * to %NULL) and callers must take this into account. Callers must |
| @@ -638,6 +648,8 @@ struct ethtool_ops { · 108 unmodified lines | |||
| 638 | struct ethtool_eth_phy_stats *phy_stats); | 648 | struct ethtool_eth_phy_stats *phy_stats); |
| 639 | void (*get_eth_mac_stats)(struct net_device *dev, | 649 | void (*get_eth_mac_stats)(struct net_device *dev, |
| 640 | struct ethtool_eth_mac_stats *mac_stats); | 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 | int ethtool_check_ops(const struct ethtool_ops *ops); | 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 | * @ETH_SS_STATS_STD: standardized stats | 672 | * @ETH_SS_STATS_STD: standardized stats |
| 673 | * @ETH_SS_STATS_ETH_PHY: names of IEEE 802.3 PHY statistics | 673 | * @ETH_SS_STATS_ETH_PHY: names of IEEE 802.3 PHY statistics |
| 674 | * @ETH_SS_STATS_ETH_MAC: names of IEEE 802.3 MAC statistics | 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 | * @ETH_SS_COUNT: number of defined string sets | 677 | * @ETH_SS_COUNT: number of defined string sets |
| 677 | */ | 678 | */ |
| @@ -695,6 +696,7 @@ enum ethtool_stringset { · 17 unmodified lines | |||
| 695 | ETH_SS_STATS_STD, | 696 | ETH_SS_STATS_STD, |
| 696 | ETH_SS_STATS_ETH_PHY, | 697 | ETH_SS_STATS_ETH_PHY, |
| 697 | ETH_SS_STATS_ETH_MAC, | 698 | ETH_SS_STATS_ETH_MAC, |
| 699 | ETH_SS_STATS_ETH_CTRL, | ||
| 698 | 700 | ||
| 699 | /* add new constants above here */ | 701 | /* add new constants above here */ |
| 700 | ETH_SS_COUNT | 702 | ETH_SS_COUNT |
| @@ -699,6 +699,7 @@ enum { · 698 unmodified lines | |||
| 699 | enum { | 699 | enum { |
| 700 | ETHTOOL_STATS_ETH_PHY, | 700 | ETHTOOL_STATS_ETH_PHY, |
| 701 | ETHTOOL_STATS_ETH_MAC, | 701 | ETHTOOL_STATS_ETH_MAC, |
| 702 | ETHTOOL_STATS_ETH_CTRL, | ||
| 702 | 703 | ||
| 703 | /* add new constants above here */ | 704 | /* add new constants above here */ |
| 704 | __ETHTOOL_STATS_CNT | 705 | __ETHTOOL_STATS_CNT |
| @@ -779,6 +780,19 @@ enum { · 74 unmodified lines | |||
| 779 | ETHTOOL_A_STATS_ETH_MAC_MAX = (__ETHTOOL_A_STATS_ETH_MAC_CNT - 1) | 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 | /* generic netlink info */ | 796 | /* generic netlink info */ |
| 783 | #define ETHTOOL_GENL_NAME "ethtool" | 797 | #define ETHTOOL_GENL_NAME "ethtool" |
| 784 | #define ETHTOOL_GENL_VERSION 1 | 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 | extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN]; | 404 | extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN]; |
| 405 | extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN]; | 405 | extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN]; |
| 406 | extern const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN]; | 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 | #endif /* _NET_ETHTOOL_NETLINK_H */ | 409 | #endif /* _NET_ETHTOOL_NETLINK_H */ |
| @@ -16,6 +16,7 @@ struct stats_reply_data { · 15 unmodified lines | |||
| 16 | struct ethnl_reply_data base; | 16 | struct ethnl_reply_data base; |
| 17 | struct ethtool_eth_phy_stats phy_stats; | 17 | struct ethtool_eth_phy_stats phy_stats; |
| 18 | struct ethtool_eth_mac_stats mac_stats; | 18 | struct ethtool_eth_mac_stats mac_stats; |
| 19 | struct ethtool_eth_ctrl_stats ctrl_stats; | ||
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | #define STATS_REPDATA(__reply_base) \ | 22 | #define STATS_REPDATA(__reply_base) \ |
| @@ -24,6 +25,7 @@ struct stats_reply_data { · 2 unmodified lines | |||
| 24 | const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN] = { | 25 | const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN] = { |
| 25 | [ETHTOOL_STATS_ETH_PHY] = "eth-phy", | 26 | [ETHTOOL_STATS_ETH_PHY] = "eth-phy", |
| 26 | [ETHTOOL_STATS_ETH_MAC] = "eth-mac", | 27 | [ETHTOOL_STATS_ETH_MAC] = "eth-mac", |
| 28 | [ETHTOOL_STATS_ETH_CTRL] = "eth-ctrl", | ||
| 27 | }; | 29 | }; |
| 28 | 30 | ||
| 29 | const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN] = { | 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 | [ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR] = "FrameTooLongErrors", | 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 | const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1] = { | 66 | const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1] = { |
| 59 | [ETHTOOL_A_STATS_HEADER] = | 67 | [ETHTOOL_A_STATS_HEADER] = |
| 60 | NLA_POLICY_NESTED(ethnl_header_policy), | 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 | memset(&data->phy_stats, 0xff, sizeof(data->phy_stats)); | 107 | memset(&data->phy_stats, 0xff, sizeof(data->phy_stats)); |
| 100 | memset(&data->mac_stats, 0xff, sizeof(data->mac_stats)); | 108 | memset(&data->mac_stats, 0xff, sizeof(data->mac_stats)); |
| 109 | memset(&data->ctrl_stats, 0xff, sizeof(data->mac_stats)); | ||
| 101 | 110 | ||
| 102 | if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) && | 111 | if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) && |
| 103 | dev->ethtool_ops->get_eth_phy_stats) | 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 | if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) && | 114 | if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) && |
| 106 | dev->ethtool_ops->get_eth_mac_stats) | 115 | dev->ethtool_ops->get_eth_mac_stats) |
| 107 | dev->ethtool_ops->get_eth_mac_stats(dev, &data->mac_stats); | 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 | ethnl_ops_complete(dev); | 121 | ethnl_ops_complete(dev); |
| 110 | return 0; | 122 | return 0; |
| @@ -125,6 +137,10 @@ static int stats_reply_size(const struct ethnl_req_info *req_base, · 14 unmodified lines | |||
| 125 | n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64); | 137 | n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64); |
| 126 | n_grps++; | 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 | len += n_grps * (nla_total_size(0) + /* _A_STATS_GRP */ | 145 | len += n_grps * (nla_total_size(0) + /* _A_STATS_GRP */ |
| 130 | nla_total_size(4) + /* _A_STATS_GRP_ID */ | 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 | return 0; | 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 | static int stats_put_stats(struct sk_buff *skb, | 261 | static int stats_put_stats(struct sk_buff *skb, |
| 233 | const struct stats_reply_data *data, | 262 | const struct stats_reply_data *data, |
| 234 | u32 id, u32 ss_id, | 263 | u32 id, u32 ss_id, |
| @@ -272,6 +301,10 @@ static int stats_fill_reply(struct sk_buff *skb, · 37 unmodified lines | |||
| 272 | ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC, | 301 | ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC, |
| 273 | ETH_SS_STATS_ETH_MAC, | 302 | ETH_SS_STATS_ETH_MAC, |
| 274 | stats_put_mac_stats); | 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 | return ret; | 309 | return ret; |
| 277 | } | 310 | } |
| @@ -95,6 +95,11 @@ static const struct strset_info info_template[] = { · 94 unmodified lines | |||
| 95 | .count = __ETHTOOL_A_STATS_ETH_MAC_CNT, | 95 | .count = __ETHTOOL_A_STATS_ETH_MAC_CNT, |
| 96 | .strings = stats_eth_mac_names, | 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 | struct strset_req_info { | 105 | struct strset_req_info { |