| From def5bc3f60ba0cdd38011fd638d29a3744311532 Mon Sep 17 00:00:00 2001 |
| From: Haiyang Zhang <haiyangz@microsoft.com> |
| Date: Tue, 15 Jan 2019 00:51:42 +0000 |
| Subject: hv_netvsc: Fix ethtool change hash key error |
| |
| [ Upstream commit b4a10c750424e01b5e37372fef0a574ebf7b56c3 ] |
| |
| Hyper-V hosts require us to disable RSS before changing RSS key, |
| otherwise the changing request will fail. This patch fixes the |
| coding error. |
| |
| Fixes: ff4a44199012 ("netvsc: allow get/set of RSS indirection table") |
| Reported-by: Wei Hu <weh@microsoft.com> |
| Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> |
| Reviewed-by: Michael Kelley <mikelley@microsoft.com> |
| [sl: fix up subject line] |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/hyperv/rndis_filter.c | 25 +++++++++++++++++++------ |
| 1 file changed, 19 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c |
| index 2a5209f23f296..0b05f7ebeb01e 100644 |
| --- a/drivers/net/hyperv/rndis_filter.c |
| +++ b/drivers/net/hyperv/rndis_filter.c |
| @@ -715,8 +715,8 @@ rndis_filter_set_offload_params(struct net_device *ndev, |
| return ret; |
| } |
| |
| -int rndis_filter_set_rss_param(struct rndis_device *rdev, |
| - const u8 *rss_key) |
| +static int rndis_set_rss_param_msg(struct rndis_device *rdev, |
| + const u8 *rss_key, u16 flag) |
| { |
| struct net_device *ndev = rdev->ndev; |
| struct rndis_request *request; |
| @@ -745,7 +745,7 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev, |
| rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS; |
| rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2; |
| rssp->hdr.size = sizeof(struct ndis_recv_scale_param); |
| - rssp->flag = 0; |
| + rssp->flag = flag; |
| rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 | |
| NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 | |
| NDIS_HASH_TCP_IPV6; |
| @@ -770,9 +770,12 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev, |
| |
| wait_for_completion(&request->wait_event); |
| set_complete = &request->response_msg.msg.set_complete; |
| - if (set_complete->status == RNDIS_STATUS_SUCCESS) |
| - memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN); |
| - else { |
| + if (set_complete->status == RNDIS_STATUS_SUCCESS) { |
| + if (!(flag & NDIS_RSS_PARAM_FLAG_DISABLE_RSS) && |
| + !(flag & NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED)) |
| + memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN); |
| + |
| + } else { |
| netdev_err(ndev, "Fail to set RSS parameters:0x%x\n", |
| set_complete->status); |
| ret = -EINVAL; |
| @@ -783,6 +786,16 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev, |
| return ret; |
| } |
| |
| +int rndis_filter_set_rss_param(struct rndis_device *rdev, |
| + const u8 *rss_key) |
| +{ |
| + /* Disable RSS before change */ |
| + rndis_set_rss_param_msg(rdev, rss_key, |
| + NDIS_RSS_PARAM_FLAG_DISABLE_RSS); |
| + |
| + return rndis_set_rss_param_msg(rdev, rss_key, 0); |
| +} |
| + |
| static int rndis_filter_query_device_link_status(struct rndis_device *dev, |
| struct netvsc_device *net_device) |
| { |
| -- |
| 2.19.1 |
| |