Commit 163891d7 authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller

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: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f4f1c23d
...@@ -743,6 +743,7 @@ static int netvsc_set_channels(struct net_device *net, ...@@ -743,6 +743,7 @@ static int netvsc_set_channels(struct net_device *net,
struct hv_device *dev = net_device_ctx->device_ctx; struct hv_device *dev = net_device_ctx->device_ctx;
struct netvsc_device *nvdev = net_device_ctx->nvdev; struct netvsc_device *nvdev = net_device_ctx->nvdev;
unsigned int count = channels->combined_count; unsigned int count = channels->combined_count;
bool was_running;
int ret; int ret;
/* We do not support separate count for rx, tx, or other */ /* We do not support separate count for rx, tx, or other */
...@@ -762,9 +763,12 @@ static int netvsc_set_channels(struct net_device *net, ...@@ -762,9 +763,12 @@ static int netvsc_set_channels(struct net_device *net,
if (count > nvdev->max_chn) if (count > nvdev->max_chn)
return -EINVAL; return -EINVAL;
ret = netvsc_close(net); was_running = netif_running(net);
if (ret) if (was_running) {
return ret; ret = netvsc_close(net);
if (ret)
return ret;
}
net_device_ctx->start_remove = true; net_device_ctx->start_remove = true;
rndis_filter_device_remove(dev, nvdev); rndis_filter_device_remove(dev, nvdev);
...@@ -775,9 +779,11 @@ static int netvsc_set_channels(struct net_device *net, ...@@ -775,9 +779,11 @@ static int netvsc_set_channels(struct net_device *net,
else else
netvsc_set_queues(net, dev, nvdev->num_chn); netvsc_set_queues(net, dev, nvdev->num_chn);
netvsc_open(net);
net_device_ctx->start_remove = false; net_device_ctx->start_remove = false;
if (was_running)
ret = netvsc_open(net);
/* We may have missed link change notifications */ /* We may have missed link change notifications */
schedule_delayed_work(&net_device_ctx->dwork, 0); schedule_delayed_work(&net_device_ctx->dwork, 0);
...@@ -845,14 +851,18 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) ...@@ -845,14 +851,18 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
struct netvsc_device *nvdev = ndevctx->nvdev; struct netvsc_device *nvdev = ndevctx->nvdev;
struct hv_device *hdev = ndevctx->device_ctx; struct hv_device *hdev = ndevctx->device_ctx;
struct netvsc_device_info device_info; struct netvsc_device_info device_info;
bool was_running;
int ret; int ret;
if (ndevctx->start_remove || !nvdev || nvdev->destroy) if (ndevctx->start_remove || !nvdev || nvdev->destroy)
return -ENODEV; return -ENODEV;
ret = netvsc_close(ndev); was_running = netif_running(ndev);
if (ret) if (was_running) {
goto out; ret = netvsc_close(ndev);
if (ret)
return ret;
}
memset(&device_info, 0, sizeof(device_info)); memset(&device_info, 0, sizeof(device_info));
device_info.ring_size = ring_size; device_info.ring_size = ring_size;
...@@ -872,10 +882,11 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) ...@@ -872,10 +882,11 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
rndis_filter_device_add(hdev, &device_info); rndis_filter_device_add(hdev, &device_info);
out:
netvsc_open(ndev);
ndevctx->start_remove = false; ndevctx->start_remove = false;
if (was_running)
ret = netvsc_open(ndev);
/* We may have missed link change notifications */ /* We may have missed link change notifications */
schedule_delayed_work(&ndevctx->dwork, 0); schedule_delayed_work(&ndevctx->dwork, 0);
......
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