Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 187935
b: refs/heads/master
c: 12c3400
h: refs/heads/master
i:
  187933: 4a7ee9d
  187931: 716fe5c
  187927: a9cfb25
  187919: bef795d
  187903: 163ff86
v: v3
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Mar 4, 2010
1 parent 64a9db4 commit 53c2a20
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 26 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: 4c32531324b83672f100692354b680625bcd7fba
refs/heads/master: 12c3400a84742f8bb0e4edc822e9ccba58781e0c
66 changes: 41 additions & 25 deletions trunk/drivers/net/wireless/rndis_wlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct dev_mc_list *mclist;
__le32 filter;
int ret, i, size;
char *buf;
__le32 filter, basefilter;
int ret;
char *mc_addrs = NULL;
int mc_count;

filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
RNDIS_PACKET_TYPE_BROADCAST;

netif_addr_lock_bh(usbdev->net);
if (usbdev->net->flags & IFF_PROMISC) {
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
RNDIS_PACKET_TYPE_ALL_LOCAL;
} else if (usbdev->net->flags & IFF_ALLMULTI ||
netdev_mc_count(usbdev->net) > priv->multicast_size) {
} else if (usbdev->net->flags & IFF_ALLMULTI) {
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
}

if (filter != basefilter)
goto set_filter;

/*
* mc_list should be accessed holding the lock, so copy addresses to
* local buffer first.
*/
netif_addr_lock_bh(usbdev->net);
mc_count = netdev_mc_count(usbdev->net);
if (mc_count > priv->multicast_size) {
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
} else if (!netdev_mc_empty(usbdev->net)) {
size = min(priv->multicast_size, netdev_mc_count(usbdev->net));
buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
if (!buf) {
} else if (mc_count) {
int i = 0;

mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
if (!mc_addrs) {
netdev_warn(usbdev->net,
"couldn't alloc %d bytes of memory\n",
size * ETH_ALEN);
mc_count * ETH_ALEN);
netif_addr_unlock_bh(usbdev->net);
return;
}

i = 0;
netdev_for_each_mc_addr(mclist, usbdev->net) {
if (i == size)
break;
memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
}
netdev_for_each_mc_addr(mclist, usbdev->net)
memcpy(mc_addrs + i++ * ETH_ALEN,
mclist->dmi_addr, ETH_ALEN);
}
netif_addr_unlock_bh(usbdev->net);

ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
i * ETH_ALEN);
if (ret == 0 && i > 0)
if (filter != basefilter)
goto set_filter;

if (mc_count) {
ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
mc_count * ETH_ALEN);
kfree(mc_addrs);
if (ret == 0)
filter |= RNDIS_PACKET_TYPE_MULTICAST;
else
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;

netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
i, priv->multicast_size, ret);

kfree(buf);
mc_count, priv->multicast_size, ret);
}
netif_addr_unlock_bh(usbdev->net);

set_filter:
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter));
if (ret < 0) {
Expand Down

0 comments on commit 53c2a20

Please sign in to comment.