diff options
author | Andrew Schwartzmeyer <andrew@schwartzmeyer.com> | 2015-02-26 19:27:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-28 16:51:36 -0500 |
commit | 59995370dbca7636c105ddadc0447fab86ad3887 (patch) | |
tree | 99f9469b129665f94333926f397f4288bf1aacbf /drivers/net/hyperv | |
parent | f9c7ce18538ed9c099818a9335d7e427d60e97ae (diff) |
hyperv: Implement netvsc_get_channels() ethool op
This adds support for reporting the actual and maximum combined channels
count of the hv_netvsc driver via 'ethtool --show-channels'.
This required adding 'max_chn' to 'struct netvsc_device', and assigning
it 'rsscap.num_recv_que' in 'rndis_filter_device_add'. Now we can access
the combined maximum channel count via 'struct netvsc_device' in the
ethtool callback.
Signed-off-by: Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 1 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 14 | ||||
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 6 |
3 files changed, 20 insertions, 1 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 384ca4f4de4a..4815843a6019 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -634,6 +634,7 @@ struct netvsc_device { | |||
634 | 634 | ||
635 | struct vmbus_channel *chn_table[NR_CPUS]; | 635 | struct vmbus_channel *chn_table[NR_CPUS]; |
636 | u32 send_table[VRSS_SEND_TAB_SIZE]; | 636 | u32 send_table[VRSS_SEND_TAB_SIZE]; |
637 | u32 max_chn; | ||
637 | u32 num_chn; | 638 | u32 num_chn; |
638 | atomic_t queue_sends[NR_CPUS]; | 639 | atomic_t queue_sends[NR_CPUS]; |
639 | 640 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 15d82eda0baf..a06bd6614007 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -687,6 +687,19 @@ static void netvsc_get_drvinfo(struct net_device *net, | |||
687 | strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); | 687 | strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
688 | } | 688 | } |
689 | 689 | ||
690 | static void netvsc_get_channels(struct net_device *net, | ||
691 | struct ethtool_channels *channel) | ||
692 | { | ||
693 | struct net_device_context *net_device_ctx = netdev_priv(net); | ||
694 | struct hv_device *dev = net_device_ctx->device_ctx; | ||
695 | struct netvsc_device *nvdev = hv_get_drvdata(dev); | ||
696 | |||
697 | if (nvdev) { | ||
698 | channel->max_combined = nvdev->max_chn; | ||
699 | channel->combined_count = nvdev->num_chn; | ||
700 | } | ||
701 | } | ||
702 | |||
690 | static int netvsc_change_mtu(struct net_device *ndev, int mtu) | 703 | static int netvsc_change_mtu(struct net_device *ndev, int mtu) |
691 | { | 704 | { |
692 | struct net_device_context *ndevctx = netdev_priv(ndev); | 705 | struct net_device_context *ndevctx = netdev_priv(ndev); |
@@ -760,6 +773,7 @@ static void netvsc_poll_controller(struct net_device *net) | |||
760 | static const struct ethtool_ops ethtool_ops = { | 773 | static const struct ethtool_ops ethtool_ops = { |
761 | .get_drvinfo = netvsc_get_drvinfo, | 774 | .get_drvinfo = netvsc_get_drvinfo, |
762 | .get_link = ethtool_op_get_link, | 775 | .get_link = ethtool_op_get_link, |
776 | .get_channels = netvsc_get_channels, | ||
763 | }; | 777 | }; |
764 | 778 | ||
765 | static const struct net_device_ops device_ops = { | 779 | static const struct net_device_ops device_ops = { |
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 7816d98bdddc..ca81de04bc76 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -1027,6 +1027,7 @@ int rndis_filter_device_add(struct hv_device *dev, | |||
1027 | 1027 | ||
1028 | /* Initialize the rndis device */ | 1028 | /* Initialize the rndis device */ |
1029 | net_device = hv_get_drvdata(dev); | 1029 | net_device = hv_get_drvdata(dev); |
1030 | net_device->max_chn = 1; | ||
1030 | net_device->num_chn = 1; | 1031 | net_device->num_chn = 1; |
1031 | 1032 | ||
1032 | net_device->extension = rndis_device; | 1033 | net_device->extension = rndis_device; |
@@ -1094,6 +1095,7 @@ int rndis_filter_device_add(struct hv_device *dev, | |||
1094 | if (ret || rsscap.num_recv_que < 2) | 1095 | if (ret || rsscap.num_recv_que < 2) |
1095 | goto out; | 1096 | goto out; |
1096 | 1097 | ||
1098 | net_device->max_chn = rsscap.num_recv_que; | ||
1097 | net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ? | 1099 | net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ? |
1098 | num_online_cpus() : rsscap.num_recv_que; | 1100 | num_online_cpus() : rsscap.num_recv_que; |
1099 | if (net_device->num_chn == 1) | 1101 | if (net_device->num_chn == 1) |
@@ -1140,8 +1142,10 @@ int rndis_filter_device_add(struct hv_device *dev, | |||
1140 | ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn); | 1142 | ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn); |
1141 | 1143 | ||
1142 | out: | 1144 | out: |
1143 | if (ret) | 1145 | if (ret) { |
1146 | net_device->max_chn = 1; | ||
1144 | net_device->num_chn = 1; | 1147 | net_device->num_chn = 1; |
1148 | } | ||
1145 | return 0; /* return 0 because primary channel can be used alone */ | 1149 | return 0; /* return 0 because primary channel can be used alone */ |
1146 | 1150 | ||
1147 | err_dev_remv: | 1151 | err_dev_remv: |