Commit b0689faa authored by Haiyang Zhang's avatar Haiyang Zhang Committed by David S. Miller

hv_netvsc: Fix unwanted rx_table reset

In existing code, the receive indirection table, rx_table, is in
struct rndis_device, which will be reset when changing MTU, ringparam,
etc. User configured receive indirection table values will be lost.

To fix this, move rx_table to struct net_device_context, and check
netif_is_rxfh_configured(), so rx_table will be set to default only
if no user configured value.

Fixes: ff4a4419 ("netvsc: allow get/set of RSS indirection table")
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7d49a32a
...@@ -169,7 +169,6 @@ struct rndis_device { ...@@ -169,7 +169,6 @@ struct rndis_device {
u8 hw_mac_adr[ETH_ALEN]; u8 hw_mac_adr[ETH_ALEN];
u8 rss_key[NETVSC_HASH_KEYLEN]; u8 rss_key[NETVSC_HASH_KEYLEN];
u16 rx_table[ITAB_NUM];
}; };
...@@ -940,6 +939,8 @@ struct net_device_context { ...@@ -940,6 +939,8 @@ struct net_device_context {
u32 tx_table[VRSS_SEND_TAB_SIZE]; u32 tx_table[VRSS_SEND_TAB_SIZE];
u16 rx_table[ITAB_NUM];
/* Ethtool settings */ /* Ethtool settings */
u8 duplex; u8 duplex;
u32 speed; u32 speed;
......
...@@ -1662,7 +1662,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, ...@@ -1662,7 +1662,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
rndis_dev = ndev->extension; rndis_dev = ndev->extension;
if (indir) { if (indir) {
for (i = 0; i < ITAB_NUM; i++) for (i = 0; i < ITAB_NUM; i++)
indir[i] = rndis_dev->rx_table[i]; indir[i] = ndc->rx_table[i];
} }
if (key) if (key)
...@@ -1692,7 +1692,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir, ...@@ -1692,7 +1692,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
return -EINVAL; return -EINVAL;
for (i = 0; i < ITAB_NUM; i++) for (i = 0; i < ITAB_NUM; i++)
rndis_dev->rx_table[i] = indir[i]; ndc->rx_table[i] = indir[i];
} }
if (!key) { if (!key) {
......
...@@ -773,6 +773,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev, ...@@ -773,6 +773,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
const u8 *rss_key, u16 flag) const u8 *rss_key, u16 flag)
{ {
struct net_device *ndev = rdev->ndev; struct net_device *ndev = rdev->ndev;
struct net_device_context *ndc = netdev_priv(ndev);
struct rndis_request *request; struct rndis_request *request;
struct rndis_set_request *set; struct rndis_set_request *set;
struct rndis_set_complete *set_complete; struct rndis_set_complete *set_complete;
...@@ -812,7 +813,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev, ...@@ -812,7 +813,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
/* Set indirection table entries */ /* Set indirection table entries */
itab = (u32 *)(rssp + 1); itab = (u32 *)(rssp + 1);
for (i = 0; i < ITAB_NUM; i++) for (i = 0; i < ITAB_NUM; i++)
itab[i] = rdev->rx_table[i]; itab[i] = ndc->rx_table[i];
/* Set hask key values */ /* Set hask key values */
keyp = (u8 *)((unsigned long)rssp + rssp->hashkey_offset); keyp = (u8 *)((unsigned long)rssp + rssp->hashkey_offset);
...@@ -1312,6 +1313,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, ...@@ -1312,6 +1313,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
struct netvsc_device_info *device_info) struct netvsc_device_info *device_info)
{ {
struct net_device *net = hv_get_drvdata(dev); struct net_device *net = hv_get_drvdata(dev);
struct net_device_context *ndc = netdev_priv(net);
struct netvsc_device *net_device; struct netvsc_device *net_device;
struct rndis_device *rndis_device; struct rndis_device *rndis_device;
struct ndis_recv_scale_cap rsscap; struct ndis_recv_scale_cap rsscap;
...@@ -1398,9 +1400,11 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, ...@@ -1398,9 +1400,11 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
/* We will use the given number of channels if available. */ /* We will use the given number of channels if available. */
net_device->num_chn = min(net_device->max_chn, device_info->num_chn); net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
for (i = 0; i < ITAB_NUM; i++) if (!netif_is_rxfh_configured(net)) {
rndis_device->rx_table[i] = ethtool_rxfh_indir_default( for (i = 0; i < ITAB_NUM; i++)
ndc->rx_table[i] = ethtool_rxfh_indir_default(
i, net_device->num_chn); i, net_device->num_chn);
}
atomic_set(&net_device->open_chn, 1); atomic_set(&net_device->open_chn, 1);
vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open); vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment