Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 299573
b: refs/heads/master
c: 792df87
h: refs/heads/master
i:
  299571: 98d481b
v: v3
  • Loading branch information
Wenqi Ma authored and David S. Miller committed Apr 21, 2012
1 parent 6330d8c commit d4301d1
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c5a99937a9cf74a623384023201a7d98b51e7e3b
refs/heads/master: 792df87228965c58c307877af00498641584bd47
38 changes: 14 additions & 24 deletions trunk/drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,59 +44,44 @@ struct net_device_context {
/* point back to our device context */
struct hv_device *device_ctx;
struct delayed_work dwork;
struct work_struct work;
};


static int ring_size = 128;
module_param(ring_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");

struct set_multicast_work {
struct work_struct work;
struct net_device *net;
};

static void do_set_multicast(struct work_struct *w)
{
struct set_multicast_work *swk =
container_of(w, struct set_multicast_work, work);
struct net_device *net = swk->net;

struct net_device_context *ndevctx = netdev_priv(net);
struct net_device_context *ndevctx =
container_of(w, struct net_device_context, work);
struct netvsc_device *nvdev;
struct rndis_device *rdev;

nvdev = hv_get_drvdata(ndevctx->device_ctx);
if (nvdev == NULL)
goto out;
if (nvdev == NULL || nvdev->ndev == NULL)
return;

rdev = nvdev->extension;
if (rdev == NULL)
goto out;
return;

if (net->flags & IFF_PROMISC)
if (nvdev->ndev->flags & IFF_PROMISC)
rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_PROMISCUOUS);
else
rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);

out:
kfree(w);
}

static void netvsc_set_multicast_list(struct net_device *net)
{
struct set_multicast_work *swk =
kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
if (swk == NULL)
return;
struct net_device_context *net_device_ctx = netdev_priv(net);

swk->net = net;
INIT_WORK(&swk->work, do_set_multicast);
schedule_work(&swk->work);
schedule_work(&net_device_ctx->work);
}

static int netvsc_open(struct net_device *net)
Expand Down Expand Up @@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)

netif_tx_disable(net);

/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
cancel_work_sync(&net_device_ctx->work);
ret = rndis_filter_close(device_obj);
if (ret != 0)
netdev_err(net, "unable to close device (ret %d).\n", ret);
Expand Down Expand Up @@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)

nvdev->start_remove = true;
cancel_delayed_work_sync(&ndevctx->dwork);
cancel_work_sync(&ndevctx->work);
netif_tx_disable(ndev);
rndis_filter_device_remove(hdev);

Expand Down Expand Up @@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,
net_device_ctx->device_ctx = dev;
hv_set_drvdata(dev, net);
INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
INIT_WORK(&net_device_ctx->work, do_set_multicast);

net->netdev_ops = &device_ops;

Expand Down Expand Up @@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)

ndev_ctx = netdev_priv(net);
cancel_delayed_work_sync(&ndev_ctx->dwork);
cancel_work_sync(&ndev_ctx->work);

/* Stop outbound asap */
netif_tx_disable(net);
Expand Down

0 comments on commit d4301d1

Please sign in to comment.