diff options
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 5299cfb16ce2..cdb78eefab67 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -66,10 +66,36 @@ static int debug = -1; | |||
66 | module_param(debug, int, S_IRUGO); | 66 | module_param(debug, int, S_IRUGO); |
67 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | 67 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); |
68 | 68 | ||
69 | static void netvsc_set_multicast_list(struct net_device *net) | 69 | static void netvsc_change_rx_flags(struct net_device *net, int change) |
70 | { | 70 | { |
71 | struct net_device_context *net_device_ctx = netdev_priv(net); | 71 | struct net_device_context *ndev_ctx = netdev_priv(net); |
72 | struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); | 72 | struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); |
73 | int inc; | ||
74 | |||
75 | if (!vf_netdev) | ||
76 | return; | ||
77 | |||
78 | if (change & IFF_PROMISC) { | ||
79 | inc = (net->flags & IFF_PROMISC) ? 1 : -1; | ||
80 | dev_set_promiscuity(vf_netdev, inc); | ||
81 | } | ||
82 | |||
83 | if (change & IFF_ALLMULTI) { | ||
84 | inc = (net->flags & IFF_ALLMULTI) ? 1 : -1; | ||
85 | dev_set_allmulti(vf_netdev, inc); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | static void netvsc_set_rx_mode(struct net_device *net) | ||
90 | { | ||
91 | struct net_device_context *ndev_ctx = netdev_priv(net); | ||
92 | struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); | ||
93 | struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev); | ||
94 | |||
95 | if (vf_netdev) { | ||
96 | dev_uc_sync(vf_netdev, net); | ||
97 | dev_mc_sync(vf_netdev, net); | ||
98 | } | ||
73 | 99 | ||
74 | rndis_filter_update(nvdev); | 100 | rndis_filter_update(nvdev); |
75 | } | 101 | } |
@@ -1586,7 +1612,8 @@ static const struct net_device_ops device_ops = { | |||
1586 | .ndo_open = netvsc_open, | 1612 | .ndo_open = netvsc_open, |
1587 | .ndo_stop = netvsc_close, | 1613 | .ndo_stop = netvsc_close, |
1588 | .ndo_start_xmit = netvsc_start_xmit, | 1614 | .ndo_start_xmit = netvsc_start_xmit, |
1589 | .ndo_set_rx_mode = netvsc_set_multicast_list, | 1615 | .ndo_change_rx_flags = netvsc_change_rx_flags, |
1616 | .ndo_set_rx_mode = netvsc_set_rx_mode, | ||
1590 | .ndo_change_mtu = netvsc_change_mtu, | 1617 | .ndo_change_mtu = netvsc_change_mtu, |
1591 | .ndo_validate_addr = eth_validate_addr, | 1618 | .ndo_validate_addr = eth_validate_addr, |
1592 | .ndo_set_mac_address = netvsc_set_mac_addr, | 1619 | .ndo_set_mac_address = netvsc_set_mac_addr, |
@@ -1817,6 +1844,11 @@ static void __netvsc_vf_setup(struct net_device *ndev, | |||
1817 | netdev_warn(vf_netdev, | 1844 | netdev_warn(vf_netdev, |
1818 | "unable to change mtu to %u\n", ndev->mtu); | 1845 | "unable to change mtu to %u\n", ndev->mtu); |
1819 | 1846 | ||
1847 | /* set multicast etc flags on VF */ | ||
1848 | dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE); | ||
1849 | dev_uc_sync(vf_netdev, ndev); | ||
1850 | dev_mc_sync(vf_netdev, ndev); | ||
1851 | |||
1820 | if (netif_running(ndev)) { | 1852 | if (netif_running(ndev)) { |
1821 | ret = dev_open(vf_netdev); | 1853 | ret = dev_open(vf_netdev); |
1822 | if (ret) | 1854 | if (ret) |