summaryrefslogtreecommitdiff
path: root/drivers/net/hyperv
diff options
context:
space:
mode:
authorstephen hemminger <stephen@networkplumber.org>2017-03-22 14:50:58 -0700
committerDavid S. Miller <davem@davemloft.net>2017-03-22 19:38:55 -0700
commit163891d7d42935e7499daa0646a8eb3c44504300 (patch)
treecad7641b0019b4955124fa00ec7e4ba142ad91aa /drivers/net/hyperv
parentf4f1c23d6e41f5ee4973a6da65cba1e1c536ec29 (diff)
netvsc: handle offline mtu and channel change
If device is not up, then changing MTU (or number of channels) should not re-enable the device. Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r--drivers/net/hyperv/netvsc_drv.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 191372486a87..b3a7f508434b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -743,6 +743,7 @@ static int netvsc_set_channels(struct net_device *net,
struct hv_device *dev = net_device_ctx->device_ctx;
struct netvsc_device *nvdev = net_device_ctx->nvdev;
unsigned int count = channels->combined_count;
+ bool was_running;
int ret;
/* We do not support separate count for rx, tx, or other */
@@ -762,9 +763,12 @@ static int netvsc_set_channels(struct net_device *net,
if (count > nvdev->max_chn)
return -EINVAL;
- ret = netvsc_close(net);
- if (ret)
- return ret;
+ was_running = netif_running(net);
+ if (was_running) {
+ ret = netvsc_close(net);
+ if (ret)
+ return ret;
+ }
net_device_ctx->start_remove = true;
rndis_filter_device_remove(dev, nvdev);
@@ -775,9 +779,11 @@ static int netvsc_set_channels(struct net_device *net,
else
netvsc_set_queues(net, dev, nvdev->num_chn);
- netvsc_open(net);
net_device_ctx->start_remove = false;
+ if (was_running)
+ ret = netvsc_open(net);
+
/* We may have missed link change notifications */
schedule_delayed_work(&net_device_ctx->dwork, 0);
@@ -845,14 +851,18 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
struct netvsc_device *nvdev = ndevctx->nvdev;
struct hv_device *hdev = ndevctx->device_ctx;
struct netvsc_device_info device_info;
+ bool was_running;
int ret;
if (ndevctx->start_remove || !nvdev || nvdev->destroy)
return -ENODEV;
- ret = netvsc_close(ndev);
- if (ret)
- goto out;
+ was_running = netif_running(ndev);
+ if (was_running) {
+ ret = netvsc_close(ndev);
+ if (ret)
+ return ret;
+ }
memset(&device_info, 0, sizeof(device_info));
device_info.ring_size = ring_size;
@@ -872,10 +882,11 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
rndis_filter_device_add(hdev, &device_info);
-out:
- netvsc_open(ndev);
ndevctx->start_remove = false;
+ if (was_running)
+ ret = netvsc_open(ndev);
+
/* We may have missed link change notifications */
schedule_delayed_work(&ndevctx->dwork, 0);