static int netvsc_open(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); struct hv_device *device_obj = net_device_ctx->device_ctx; struct netvsc_device *nvdev; struct rndis_device *rdev; int ret = 0; netif_carrier_off(net); /* Open up the device */ ret = rndis_filter_open(device_obj); if (ret != 0) { netdev_err(net, "unable to open device (ret %d).\n", ret); return ret; } netif_start_queue(net);; nvdev = hv_get_drvdata(device_obj); rdev = nvdev->extension; if (!rdev->link_state) netif_carrier_on(net); return ret; }
static int netvsc_set_channels(struct net_device *net, struct ethtool_channels *channels) { struct net_device_context *net_device_ctx = netdev_priv(net); struct hv_device *dev = net_device_ctx->device_ctx; struct netvsc_device *nvdev = net_device_ctx->nvdev; unsigned int orig, count = channels->combined_count; struct netvsc_device_info device_info; bool was_opened; int ret = 0; /* We do not support separate count for rx, tx, or other */ if (count == 0 || channels->rx_count || channels->tx_count || channels->other_count) return -EINVAL; if (count > net->num_tx_queues || count > VRSS_CHANNEL_MAX) return -EINVAL; if (!nvdev || nvdev->destroy) return -ENODEV; if (nvdev->nvsp_version < NVSP_PROTOCOL_VERSION_5) return -EINVAL; if (count > nvdev->max_chn) return -EINVAL; orig = nvdev->num_chn; was_opened = rndis_filter_opened(nvdev); if (was_opened) rndis_filter_close(nvdev); rndis_filter_device_remove(dev, nvdev); memset(&device_info, 0, sizeof(device_info)); device_info.num_chn = count; device_info.ring_size = ring_size; nvdev = rndis_filter_device_add(dev, &device_info); if (!IS_ERR(nvdev)) { netif_set_real_num_tx_queues(net, nvdev->num_chn); netif_set_real_num_rx_queues(net, nvdev->num_chn); ret = PTR_ERR(nvdev); } else { device_info.num_chn = orig; rndis_filter_device_add(dev, &device_info); } if (was_opened) rndis_filter_open(nvdev); /* We may have missed link change notifications */ net_device_ctx->last_reconfig = 0; schedule_delayed_work(&net_device_ctx->dwork, 0); return ret; }
static int netvsc_change_mtu(struct net_device *ndev, int mtu) { struct net_device_context *ndevctx = netdev_priv(ndev); struct netvsc_device *nvdev = ndevctx->nvdev; struct hv_device *hdev = ndevctx->device_ctx; int orig_mtu = ndev->mtu; struct netvsc_device_info device_info; int limit = ETH_DATA_LEN; bool was_opened; int ret = 0; if (!nvdev || nvdev->destroy) return -ENODEV; if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) limit = NETVSC_MTU - ETH_HLEN; if (mtu < NETVSC_MTU_MIN || mtu > limit) return -EINVAL; netif_device_detach(ndev); was_opened = rndis_filter_opened(nvdev); if (was_opened) rndis_filter_close(nvdev); memset(&device_info, 0, sizeof(device_info)); device_info.ring_size = ring_size; device_info.num_chn = nvdev->num_chn; rndis_filter_device_remove(hdev, nvdev); ndev->mtu = mtu; nvdev = rndis_filter_device_add(hdev, &device_info); if (IS_ERR(nvdev)) { ret = PTR_ERR(nvdev); /* Attempt rollback to original MTU */ ndev->mtu = orig_mtu; rndis_filter_device_add(hdev, &device_info); } if (was_opened) rndis_filter_open(nvdev); netif_device_attach(ndev); /* We may have missed link change notifications */ schedule_delayed_work(&ndevctx->dwork, 0); return ret; }
static int netvsc_open(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; int ret = 0; if (netif_carrier_ok(net)) { /* Open up the device */ ret = rndis_filter_open(device_obj); if (ret != 0) { DPRINT_ERR(NETVSC_DRV, "unable to open device (ret %d).", ret); return ret; } netif_start_queue(net); } else { DPRINT_ERR(NETVSC_DRV, "unable to open device...link is down."); } return ret; }
static int netvsc_open(struct net_device *net) { struct netvsc_device *nvdev = net_device_to_netvsc_device(net); struct rndis_device *rdev; int ret = 0; netif_carrier_off(net); /* Open up the device */ ret = rndis_filter_open(nvdev); if (ret != 0) { netdev_err(net, "unable to open device (ret %d).\n", ret); return ret; } netif_tx_wake_all_queues(net); rdev = nvdev->extension; if (!rdev->link_state) netif_carrier_on(net); return ret; }