aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv/netvsc_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
-rw-r--r--drivers/net/hyperv/netvsc_drv.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c5584c2d440e..cdb78eefab67 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -66,10 +66,36 @@ static int debug = -1;
66module_param(debug, int, S_IRUGO); 66module_param(debug, int, S_IRUGO);
67MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); 67MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
68 68
69static void netvsc_set_multicast_list(struct net_device *net) 69static 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
89static 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}
@@ -91,12 +117,11 @@ static int netvsc_open(struct net_device *net)
91 return ret; 117 return ret;
92 } 118 }
93 119
94 netif_tx_wake_all_queues(net);
95
96 rdev = nvdev->extension; 120 rdev = nvdev->extension;
97 121 if (!rdev->link_state) {
98 if (!rdev->link_state)
99 netif_carrier_on(net); 122 netif_carrier_on(net);
123 netif_tx_wake_all_queues(net);
124 }
100 125
101 if (vf_netdev) { 126 if (vf_netdev) {
102 /* Setting synthetic device up transparently sets 127 /* Setting synthetic device up transparently sets
@@ -299,8 +324,19 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
299 rcu_read_lock(); 324 rcu_read_lock();
300 vf_netdev = rcu_dereference(ndc->vf_netdev); 325 vf_netdev = rcu_dereference(ndc->vf_netdev);
301 if (vf_netdev) { 326 if (vf_netdev) {
302 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; 327 const struct net_device_ops *vf_ops = vf_netdev->netdev_ops;
303 qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; 328
329 if (vf_ops->ndo_select_queue)
330 txq = vf_ops->ndo_select_queue(vf_netdev, skb,
331 accel_priv, fallback);
332 else
333 txq = fallback(vf_netdev, skb);
334
335 /* Record the queue selected by VF so that it can be
336 * used for common case where VF has more queues than
337 * the synthetic device.
338 */
339 qdisc_skb_cb(skb)->slave_dev_queue_mapping = txq;
304 } else { 340 } else {
305 txq = netvsc_pick_tx(ndev, skb); 341 txq = netvsc_pick_tx(ndev, skb);
306 } 342 }
@@ -1576,7 +1612,8 @@ static const struct net_device_ops device_ops = {
1576 .ndo_open = netvsc_open, 1612 .ndo_open = netvsc_open,
1577 .ndo_stop = netvsc_close, 1613 .ndo_stop = netvsc_close,
1578 .ndo_start_xmit = netvsc_start_xmit, 1614 .ndo_start_xmit = netvsc_start_xmit,
1579 .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,
1580 .ndo_change_mtu = netvsc_change_mtu, 1617 .ndo_change_mtu = netvsc_change_mtu,
1581 .ndo_validate_addr = eth_validate_addr, 1618 .ndo_validate_addr = eth_validate_addr,
1582 .ndo_set_mac_address = netvsc_set_mac_addr, 1619 .ndo_set_mac_address = netvsc_set_mac_addr,
@@ -1807,6 +1844,11 @@ static void __netvsc_vf_setup(struct net_device *ndev,
1807 netdev_warn(vf_netdev, 1844 netdev_warn(vf_netdev,
1808 "unable to change mtu to %u\n", ndev->mtu); 1845 "unable to change mtu to %u\n", ndev->mtu);
1809 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
1810 if (netif_running(ndev)) { 1852 if (netif_running(ndev)) {
1811 ret = dev_open(vf_netdev); 1853 ret = dev_open(vf_netdev);
1812 if (ret) 1854 if (ret)