mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
ethtool: Add support for configuring tx_push_buf_len
This attribute, which is part of ethtool's ring param configuration allows the user to specify the maximum number of the packet's payload that can be written directly to the device. Example usage: # ethtool -G [interface] tx-push-buf-len [number of bytes] Co-developed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Shay Agroskin <shayagr@amazon.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
3e4d5ba9a3
commit
233eb4e786
@@ -413,7 +413,7 @@ extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANT
|
||||
extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1];
|
||||
extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_RX_PUSH + 1];
|
||||
extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX + 1];
|
||||
extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1];
|
||||
extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1];
|
||||
|
@@ -11,6 +11,7 @@ struct rings_reply_data {
|
||||
struct ethnl_reply_data base;
|
||||
struct ethtool_ringparam ringparam;
|
||||
struct kernel_ethtool_ringparam kernel_ringparam;
|
||||
u32 supported_ring_params;
|
||||
};
|
||||
|
||||
#define RINGS_REPDATA(__reply_base) \
|
||||
@@ -32,6 +33,8 @@ static int rings_prepare_data(const struct ethnl_req_info *req_base,
|
||||
|
||||
if (!dev->ethtool_ops->get_ringparam)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
data->supported_ring_params = dev->ethtool_ops->supported_ring_params;
|
||||
ret = ethnl_ops_begin(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -57,7 +60,9 @@ static int rings_reply_size(const struct ethnl_req_info *req_base,
|
||||
nla_total_size(sizeof(u8)) + /* _RINGS_TCP_DATA_SPLIT */
|
||||
nla_total_size(sizeof(u32) + /* _RINGS_CQE_SIZE */
|
||||
nla_total_size(sizeof(u8)) + /* _RINGS_TX_PUSH */
|
||||
nla_total_size(sizeof(u8))); /* _RINGS_RX_PUSH */
|
||||
nla_total_size(sizeof(u8))) + /* _RINGS_RX_PUSH */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_TX_PUSH_BUF_LEN */
|
||||
nla_total_size(sizeof(u32)); /* _RINGS_TX_PUSH_BUF_LEN_MAX */
|
||||
}
|
||||
|
||||
static int rings_fill_reply(struct sk_buff *skb,
|
||||
@@ -67,6 +72,7 @@ static int rings_fill_reply(struct sk_buff *skb,
|
||||
const struct rings_reply_data *data = RINGS_REPDATA(reply_base);
|
||||
const struct kernel_ethtool_ringparam *kr = &data->kernel_ringparam;
|
||||
const struct ethtool_ringparam *ringparam = &data->ringparam;
|
||||
u32 supported_ring_params = data->supported_ring_params;
|
||||
|
||||
WARN_ON(kr->tcp_data_split > ETHTOOL_TCP_DATA_SPLIT_ENABLED);
|
||||
|
||||
@@ -98,7 +104,12 @@ static int rings_fill_reply(struct sk_buff *skb,
|
||||
(kr->cqe_size &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_CQE_SIZE, kr->cqe_size))) ||
|
||||
nla_put_u8(skb, ETHTOOL_A_RINGS_TX_PUSH, !!kr->tx_push) ||
|
||||
nla_put_u8(skb, ETHTOOL_A_RINGS_RX_PUSH, !!kr->rx_push))
|
||||
nla_put_u8(skb, ETHTOOL_A_RINGS_RX_PUSH, !!kr->rx_push) ||
|
||||
((supported_ring_params & ETHTOOL_RING_USE_TX_PUSH_BUF_LEN) &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
|
||||
kr->tx_push_buf_max_len) ||
|
||||
nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
|
||||
kr->tx_push_buf_len))))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
@@ -117,6 +128,7 @@ const struct nla_policy ethnl_rings_set_policy[] = {
|
||||
[ETHTOOL_A_RINGS_CQE_SIZE] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
[ETHTOOL_A_RINGS_TX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||
[ETHTOOL_A_RINGS_RX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||
[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -158,6 +170,14 @@ ethnl_set_rings_validate(struct ethnl_req_info *req_info,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] &&
|
||||
!(ops->supported_ring_params & ETHTOOL_RING_USE_TX_PUSH_BUF_LEN)) {
|
||||
NL_SET_ERR_MSG_ATTR(info->extack,
|
||||
tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN],
|
||||
"setting tx push buf len is not supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return ops->get_ringparam && ops->set_ringparam ? 1 : -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -189,6 +209,8 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
|
||||
tb[ETHTOOL_A_RINGS_TX_PUSH], &mod);
|
||||
ethnl_update_u8(&kernel_ringparam.rx_push,
|
||||
tb[ETHTOOL_A_RINGS_RX_PUSH], &mod);
|
||||
ethnl_update_u32(&kernel_ringparam.tx_push_buf_len,
|
||||
tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], &mod);
|
||||
if (!mod)
|
||||
return 0;
|
||||
|
||||
@@ -209,6 +231,14 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (kernel_ringparam.tx_push_buf_len > kernel_ringparam.tx_push_buf_max_len) {
|
||||
NL_SET_ERR_MSG_ATTR_FMT(info->extack, tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN],
|
||||
"Requested TX push buffer exceeds the maximum of %u",
|
||||
kernel_ringparam.tx_push_buf_max_len);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = dev->ethtool_ops->set_ringparam(dev, &ringparam,
|
||||
&kernel_ringparam, info->extack);
|
||||
return ret < 0 ? ret : 1;
|
||||
|
Reference in New Issue
Block a user