summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/netlink/specs/ethtool.yaml1
-rw-r--r--Documentation/networking/ethtool-netlink.rst1
-rw-r--r--net/ethtool/rss.c12
3 files changed, 13 insertions, 1 deletions
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 1eca88a508a0..0d02d8342e4c 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -2654,6 +2654,7 @@ operations:
attributes:
- header
- context
+ - hfunc
- indir
-
name: rss-ntf
diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 27db7540e60e..f6e4439caa94 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1999,6 +1999,7 @@ Request contents:
===================================== ====== ==============================
``ETHTOOL_A_RSS_HEADER`` nested request header
``ETHTOOL_A_RSS_CONTEXT`` u32 context number
+ ``ETHTOOL_A_RSS_HFUNC`` u32 RSS hash func
``ETHTOOL_A_RSS_INDIR`` binary Indir table bytes
===================================== ====== ==============================
diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
index c8db523671de..bc9025cfcf1c 100644
--- a/net/ethtool/rss.c
+++ b/net/ethtool/rss.c
@@ -475,6 +475,7 @@ void ethtool_rss_notify(struct net_device *dev, u32 rss_context)
const struct nla_policy ethnl_rss_set_policy[ETHTOOL_A_RSS_START_CONTEXT + 1] = {
[ETHTOOL_A_RSS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
[ETHTOOL_A_RSS_CONTEXT] = { .type = NLA_U32, },
+ [ETHTOOL_A_RSS_HFUNC] = NLA_POLICY_MIN(NLA_U32, 1),
[ETHTOOL_A_RSS_INDIR] = { .type = NLA_BINARY, },
};
@@ -489,6 +490,9 @@ ethnl_rss_set_validate(struct ethnl_req_info *req_info, struct genl_info *info)
if (request->rss_context && !ops->create_rxfh_context)
bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_CONTEXT];
+ if (request->rss_context && !ops->rxfh_per_ctx_key)
+ bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HFUNC];
+
if (bad_attr) {
NL_SET_BAD_ATTR(info->extack, bad_attr);
return -EOPNOTSUPP;
@@ -588,6 +592,8 @@ rss_set_ctx_update(struct ethtool_rxfh_context *ctx, struct nlattr **tb,
ethtool_rxfh_context_indir(ctx)[i] = rxfh->indir[i];
ctx->indir_configured = !!nla_len(tb[ETHTOOL_A_RSS_INDIR]);
}
+ if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE)
+ ctx->hfunc = rxfh->hfunc;
}
static int
@@ -618,7 +624,11 @@ ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
goto exit_clean_data;
indir_mod = !!tb[ETHTOOL_A_RSS_INDIR];
- rxfh.hfunc = ETH_RSS_HASH_NO_CHANGE;
+ rxfh.hfunc = data.hfunc;
+ ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod);
+ if (rxfh.hfunc == data.hfunc)
+ rxfh.hfunc = ETH_RSS_HASH_NO_CHANGE;
+
rxfh.input_xfrm = RXH_XFRM_NO_CHANGE;
mutex_lock(&dev->ethtool->rss_lock);