Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andrew Schwartzmeyer and committed by
David S. Miller
59995370 f9c7ce18

+20 -1
+1
drivers/net/hyperv/hyperv_net.h
··· 634 634 635 635 struct vmbus_channel *chn_table[NR_CPUS]; 636 636 u32 send_table[VRSS_SEND_TAB_SIZE]; 637 + u32 max_chn; 637 638 u32 num_chn; 638 639 atomic_t queue_sends[NR_CPUS]; 639 640
+14
drivers/net/hyperv/netvsc_drv.c
··· 687 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 703 static int netvsc_change_mtu(struct net_device *ndev, int mtu) 691 704 { 692 705 struct net_device_context *ndevctx = netdev_priv(ndev); ··· 773 760 static const struct ethtool_ops ethtool_ops = { 774 761 .get_drvinfo = netvsc_get_drvinfo, 775 762 .get_link = ethtool_op_get_link, 763 + .get_channels = netvsc_get_channels, 776 764 }; 777 765 778 766 static const struct net_device_ops device_ops = {
+5 -1
drivers/net/hyperv/rndis_filter.c
··· 1027 1027 1028 1028 /* Initialize the rndis device */ 1029 1029 net_device = hv_get_drvdata(dev); 1030 + net_device->max_chn = 1; 1030 1031 net_device->num_chn = 1; 1031 1032 1032 1033 net_device->extension = rndis_device; ··· 1095 1094 if (ret || rsscap.num_recv_que < 2) 1096 1095 goto out; 1097 1096 1097 + net_device->max_chn = rsscap.num_recv_que; 1098 1098 net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ? 1099 1099 num_online_cpus() : rsscap.num_recv_que; 1100 1100 if (net_device->num_chn == 1) ··· 1142 1140 ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn); 1143 1141 1144 1142 out: 1145 - if (ret) 1143 + if (ret) { 1144 + net_device->max_chn = 1; 1146 1145 net_device->num_chn = 1; 1146 + } 1147 1147 return 0; /* return 0 because primary channel can be used alone */ 1148 1148 1149 1149 err_dev_remv: