stats.c (03ab8e6297acd1bc0eedaa050e2a1635c576fd11) | stats.c (04692c9020b76939715d6f2b4ff84d832246e0fc) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2 3#include "netlink.h" 4#include "common.h" 5#include "bitset.h" 6 7struct stats_req_info { 8 struct ethnl_req_info base; 9 DECLARE_BITMAP(stat_mask, __ETHTOOL_STATS_CNT); | 1// SPDX-License-Identifier: GPL-2.0-only 2 3#include "netlink.h" 4#include "common.h" 5#include "bitset.h" 6 7struct stats_req_info { 8 struct ethnl_req_info base; 9 DECLARE_BITMAP(stat_mask, __ETHTOOL_STATS_CNT); |
10 enum ethtool_mac_stats_src src; |
|
10}; 11 12#define STATS_REQINFO(__req_base) \ 13 container_of(__req_base, struct stats_req_info, base) 14 15struct stats_reply_data { 16 struct ethnl_reply_data base; 17 struct_group(stats, --- 52 unchanged lines hidden (view full) --- 70 71const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN] = { 72 [ETHTOOL_A_STATS_RMON_UNDERSIZE] = "etherStatsUndersizePkts", 73 [ETHTOOL_A_STATS_RMON_OVERSIZE] = "etherStatsOversizePkts", 74 [ETHTOOL_A_STATS_RMON_FRAG] = "etherStatsFragments", 75 [ETHTOOL_A_STATS_RMON_JABBER] = "etherStatsJabbers", 76}; 77 | 11}; 12 13#define STATS_REQINFO(__req_base) \ 14 container_of(__req_base, struct stats_req_info, base) 15 16struct stats_reply_data { 17 struct ethnl_reply_data base; 18 struct_group(stats, --- 52 unchanged lines hidden (view full) --- 71 72const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN] = { 73 [ETHTOOL_A_STATS_RMON_UNDERSIZE] = "etherStatsUndersizePkts", 74 [ETHTOOL_A_STATS_RMON_OVERSIZE] = "etherStatsOversizePkts", 75 [ETHTOOL_A_STATS_RMON_FRAG] = "etherStatsFragments", 76 [ETHTOOL_A_STATS_RMON_JABBER] = "etherStatsJabbers", 77}; 78 |
78const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1] = { | 79const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_SRC + 1] = { |
79 [ETHTOOL_A_STATS_HEADER] = 80 NLA_POLICY_NESTED(ethnl_header_policy), 81 [ETHTOOL_A_STATS_GROUPS] = { .type = NLA_NESTED }, | 80 [ETHTOOL_A_STATS_HEADER] = 81 NLA_POLICY_NESTED(ethnl_header_policy), 82 [ETHTOOL_A_STATS_GROUPS] = { .type = NLA_NESTED }, |
83 [ETHTOOL_A_STATS_SRC] = 84 NLA_POLICY_MAX(NLA_U32, ETHTOOL_MAC_STATS_SRC_PMAC), |
|
82}; 83 84static int stats_parse_request(struct ethnl_req_info *req_base, 85 struct nlattr **tb, 86 struct netlink_ext_ack *extack) 87{ | 85}; 86 87static int stats_parse_request(struct ethnl_req_info *req_base, 88 struct nlattr **tb, 89 struct netlink_ext_ack *extack) 90{ |
91 enum ethtool_mac_stats_src src = ETHTOOL_MAC_STATS_SRC_AGGREGATE; |
|
88 struct stats_req_info *req_info = STATS_REQINFO(req_base); 89 bool mod = false; 90 int err; 91 92 err = ethnl_update_bitset(req_info->stat_mask, __ETHTOOL_STATS_CNT, 93 tb[ETHTOOL_A_STATS_GROUPS], stats_std_names, 94 extack, &mod); 95 if (err) 96 return err; 97 98 if (!mod) { 99 NL_SET_ERR_MSG(extack, "no stats requested"); 100 return -EINVAL; 101 } 102 | 92 struct stats_req_info *req_info = STATS_REQINFO(req_base); 93 bool mod = false; 94 int err; 95 96 err = ethnl_update_bitset(req_info->stat_mask, __ETHTOOL_STATS_CNT, 97 tb[ETHTOOL_A_STATS_GROUPS], stats_std_names, 98 extack, &mod); 99 if (err) 100 return err; 101 102 if (!mod) { 103 NL_SET_ERR_MSG(extack, "no stats requested"); 104 return -EINVAL; 105 } 106 |
107 if (tb[ETHTOOL_A_STATS_SRC]) 108 src = nla_get_u32(tb[ETHTOOL_A_STATS_SRC]); 109 110 req_info->src = src; 111 |
|
103 return 0; 104} 105 106static int stats_prepare_data(const struct ethnl_req_info *req_base, 107 struct ethnl_reply_data *reply_base, 108 struct genl_info *info) 109{ 110 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 111 struct stats_reply_data *data = STATS_REPDATA(reply_base); | 112 return 0; 113} 114 115static int stats_prepare_data(const struct ethnl_req_info *req_base, 116 struct ethnl_reply_data *reply_base, 117 struct genl_info *info) 118{ 119 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 120 struct stats_reply_data *data = STATS_REPDATA(reply_base); |
121 enum ethtool_mac_stats_src src = req_info->src; 122 struct netlink_ext_ack *extack = info->extack; |
|
112 struct net_device *dev = reply_base->dev; 113 int ret; 114 115 ret = ethnl_ops_begin(dev); 116 if (ret < 0) 117 return ret; 118 | 123 struct net_device *dev = reply_base->dev; 124 int ret; 125 126 ret = ethnl_ops_begin(dev); 127 if (ret < 0) 128 return ret; 129 |
130 if ((src == ETHTOOL_MAC_STATS_SRC_EMAC || 131 src == ETHTOOL_MAC_STATS_SRC_PMAC) && 132 !__ethtool_dev_mm_supported(dev)) { 133 NL_SET_ERR_MSG_MOD(extack, 134 "Device does not support MAC merge layer"); 135 ethnl_ops_complete(dev); 136 return -EOPNOTSUPP; 137 } 138 |
|
119 /* Mark all stats as unset (see ETHTOOL_STAT_NOT_SET) to prevent them 120 * from being reported to user space in case driver did not set them. 121 */ 122 memset(&data->stats, 0xff, sizeof(data->stats)); 123 | 139 /* Mark all stats as unset (see ETHTOOL_STAT_NOT_SET) to prevent them 140 * from being reported to user space in case driver did not set them. 141 */ 142 memset(&data->stats, 0xff, sizeof(data->stats)); 143 |
144 data->phy_stats.src = src; 145 data->mac_stats.src = src; 146 data->ctrl_stats.src = src; 147 data->rmon_stats.src = src; 148 |
|
124 if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) && 125 dev->ethtool_ops->get_eth_phy_stats) 126 dev->ethtool_ops->get_eth_phy_stats(dev, &data->phy_stats); 127 if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) && 128 dev->ethtool_ops->get_eth_mac_stats) 129 dev->ethtool_ops->get_eth_mac_stats(dev, &data->mac_stats); 130 if (test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask) && 131 dev->ethtool_ops->get_eth_ctrl_stats) --- 9 unchanged lines hidden (view full) --- 141 142static int stats_reply_size(const struct ethnl_req_info *req_base, 143 const struct ethnl_reply_data *reply_base) 144{ 145 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 146 unsigned int n_grps = 0, n_stats = 0; 147 int len = 0; 148 | 149 if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) && 150 dev->ethtool_ops->get_eth_phy_stats) 151 dev->ethtool_ops->get_eth_phy_stats(dev, &data->phy_stats); 152 if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) && 153 dev->ethtool_ops->get_eth_mac_stats) 154 dev->ethtool_ops->get_eth_mac_stats(dev, &data->mac_stats); 155 if (test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask) && 156 dev->ethtool_ops->get_eth_ctrl_stats) --- 9 unchanged lines hidden (view full) --- 166 167static int stats_reply_size(const struct ethnl_req_info *req_base, 168 const struct ethnl_reply_data *reply_base) 169{ 170 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 171 unsigned int n_grps = 0, n_stats = 0; 172 int len = 0; 173 |
174 len += nla_total_size(sizeof(u32)); /* _STATS_SRC */ 175 |
|
149 if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask)) { 150 n_stats += sizeof(struct ethtool_eth_phy_stats) / sizeof(u64); 151 n_grps++; 152 } 153 if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask)) { 154 n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64); 155 n_grps++; 156 } --- 217 unchanged lines hidden (view full) --- 374static int stats_fill_reply(struct sk_buff *skb, 375 const struct ethnl_req_info *req_base, 376 const struct ethnl_reply_data *reply_base) 377{ 378 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 379 const struct stats_reply_data *data = STATS_REPDATA(reply_base); 380 int ret = 0; 381 | 176 if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask)) { 177 n_stats += sizeof(struct ethtool_eth_phy_stats) / sizeof(u64); 178 n_grps++; 179 } 180 if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask)) { 181 n_stats += sizeof(struct ethtool_eth_mac_stats) / sizeof(u64); 182 n_grps++; 183 } --- 217 unchanged lines hidden (view full) --- 401static int stats_fill_reply(struct sk_buff *skb, 402 const struct ethnl_req_info *req_base, 403 const struct ethnl_reply_data *reply_base) 404{ 405 const struct stats_req_info *req_info = STATS_REQINFO(req_base); 406 const struct stats_reply_data *data = STATS_REPDATA(reply_base); 407 int ret = 0; 408 |
409 if (nla_put_u32(skb, ETHTOOL_A_STATS_SRC, req_info->src)) 410 return -EMSGSIZE; 411 |
|
382 if (!ret && test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask)) 383 ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_PHY, 384 ETH_SS_STATS_ETH_PHY, 385 stats_put_phy_stats); 386 if (!ret && test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask)) 387 ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC, 388 ETH_SS_STATS_ETH_MAC, 389 stats_put_mac_stats); --- 23 unchanged lines hidden --- | 412 if (!ret && test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask)) 413 ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_PHY, 414 ETH_SS_STATS_ETH_PHY, 415 stats_put_phy_stats); 416 if (!ret && test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask)) 417 ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC, 418 ETH_SS_STATS_ETH_MAC, 419 stats_put_mac_stats); --- 23 unchanged lines hidden --- |