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.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 93b0e91cbf98..b69c3a4d1e9e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -56,11 +56,51 @@ static int ring_size = 128;
56module_param(ring_size, int, S_IRUGO); 56module_param(ring_size, int, S_IRUGO);
57MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); 57MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
58 58
59/* no-op so the netdev core doesn't return -EINVAL when modifying the the 59struct set_multicast_work {
60 * multicast address list in SIOCADDMULTI. hv is setup to get all multicast 60 struct work_struct work;
61 * when it calls RndisFilterOnOpen() */ 61 struct net_device *net;
62};
63
64static void do_set_multicast(struct work_struct *w)
65{
66 struct set_multicast_work *swk =
67 container_of(w, struct set_multicast_work, work);
68 struct net_device *net = swk->net;
69
70 struct net_device_context *ndevctx = netdev_priv(net);
71 struct netvsc_device *nvdev;
72 struct rndis_device *rdev;
73
74 nvdev = hv_get_drvdata(ndevctx->device_ctx);
75 if (nvdev == NULL)
76 return;
77
78 rdev = nvdev->extension;
79 if (rdev == NULL)
80 return;
81
82 if (net->flags & IFF_PROMISC)
83 rndis_filter_set_packet_filter(rdev,
84 NDIS_PACKET_TYPE_PROMISCUOUS);
85 else
86 rndis_filter_set_packet_filter(rdev,
87 NDIS_PACKET_TYPE_BROADCAST |
88 NDIS_PACKET_TYPE_ALL_MULTICAST |
89 NDIS_PACKET_TYPE_DIRECTED);
90
91 kfree(w);
92}
93
62static void netvsc_set_multicast_list(struct net_device *net) 94static void netvsc_set_multicast_list(struct net_device *net)
63{ 95{
96 struct set_multicast_work *swk =
97 kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
98 if (swk == NULL)
99 return;
100
101 swk->net = net;
102 INIT_WORK(&swk->work, do_set_multicast);
103 schedule_work(&swk->work);
64} 104}
65 105
66static int netvsc_open(struct net_device *net) 106static int netvsc_open(struct net_device *net)