@@ -73,6 +73,7 @@ enum {
* struct kernel_ethtool_ringparam - RX/TX ring configuration
* @rx_buf_len: Current length of buffers on the rx ring.
* @tcp_data_split: Scatter packet headers and data to separate buffers
+ * @tcp_data_split_mod: Updated tcp-data-split from user
* @tx_push: The flag of tx push mode
* @rx_push: The flag of rx push mode
* @cqe_size: Size of TX/RX completion queue event
@@ -82,6 +83,7 @@ enum {
struct kernel_ethtool_ringparam {
u32 rx_buf_len;
u8 tcp_data_split;
+ bool tcp_data_split_mod;
u8 tx_push;
u8 rx_push;
u32 cqe_size;
@@ -250,6 +250,9 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
return -EINVAL;
}
+ if (tb[ETHTOOL_A_RINGS_TCP_DATA_SPLIT])
+ kernel_ringparam.tcp_data_split_mod = true;
+
ret = dev->ethtool_ops->set_ringparam(dev, &ringparam,
&kernel_ringparam, info->extack);
return ret < 0 ? ret : 1;
When tcp-data-split is UNKNOWN mode, drivers arbitrarily handle it. For example, bnxt_en driver automatically enables if at least one of LRO/GRO/JUMBO is enabled. If tcp-data-split is UNKNOWN and LRO is enabled, a driver returns ENABLES of tcp-data-split, not UNKNOWN. So, `ethtool -g eth0` shows tcp-data-split is enabled. The problem is in the setting situation. In the ethnl_set_rings(), it first calls get_ringparam() to get the current driver's config. At that moment, if driver's tcp-data-split config is UNKNOWN, it returns ENABLE if LRO/GRO/JUMBO is enabled. Then, it sets values from the user and driver's current config to kernel_ethtool_ringparam. Last it calls .set_ringparam(). The driver, especially bnxt_en driver receives ETHTOOL_TCP_DATA_SPLIT_ENABLED. But it can't distinguish whether it is set by the user or just the current config. The new tcp_data_split_mod member indicates the tcp-data-split value is explicitly set by the user. So the driver can handle ETHTOOL_TCP_DATA_SPLIT_ENABLED properly. Signed-off-by: Taehee Yoo <ap420073@gmail.com> --- v5: - Patch added. include/linux/ethtool.h | 2 ++ net/ethtool/rings.c | 3 +++ 2 files changed, 5 insertions(+)