示例#1
0
static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
			       struct net_device *dev, int nr_addrs)
{
	int i = nr_addrs;
	struct netdev_hw_addr *ha;
	int cnt;

	if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
		return nr_addrs;

	netif_addr_lock_bh(dev);
	cnt = netdev_mc_count(dev);
	netdev_for_each_mc_addr(ha, dev) {
		if (mac_in_list(cmd->maclist, nr_addrs, ha->addr)) {
			lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
				    ha->addr);
			cnt--;
			continue;
		}

		if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
			break;
		memcpy(&cmd->maclist[6*i], ha->addr, ETH_ALEN);
		lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
			    ha->addr);
		i++;
		cnt--;
	}
	netif_addr_unlock_bh(dev);
	if (cnt)
		return -EOVERFLOW;

	return i;
}
示例#2
0
/**
* set_mc_list
*
* This function sets the multicast filter if event is received
*
* @work: pointer to the Work Queue work_struct
*/
static void set_mc_list(struct work_struct *work)
{
	struct CW1200_priv *priv ;
	struct net_device *dev ;
	UMI_OID_802_11_MULTICAST_ADDR_FILTER *lmcfilter;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
	struct dev_mc_list *macaddr;
#else
	struct netdev_hw_addr *macaddr;
#endif
	int naddr = 0, i = 0;
	priv  = container_of(work, struct CW1200_priv, mc_work);
	lmcfilter = &(priv->ste_mc_filter);
	dev = priv->netdev;
	netif_addr_lock_bh(dev);
	naddr = netdev_mc_count(dev);
	DEBUG(DBG_EIL, "%s: no. of mc addrs %d\n", __func__, naddr);

	if(naddr > MCADDR_LIST_MAXSIZE)
		lmcfilter->numOfAddresses= MCADDR_LIST_MAXSIZE;
	else
		lmcfilter->numOfAddresses= naddr;
	netdev_for_each_mc_addr(macaddr, dev) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
		memcpy(&(lmcfilter->AddressList[i]), macaddr->dmi_addr, ETH_ALEN);
#else
		memcpy(&(lmcfilter->AddressList[i]), macaddr->addr, ETH_ALEN);
#endif
		DEBUG(DBG_EIL, "adding mc address %pM \n"
			, lmcfilter->AddressList[i]);
		i = (i+1)%MCADDR_LIST_MAXSIZE;
		naddr--;
	}
示例#3
0
static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
			       struct net_device *dev, int nr_addrs)
{
	int i = nr_addrs;
	struct dev_mc_list *mc_list;

	if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
		return nr_addrs;

	netif_addr_lock_bh(dev);
	for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
		if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
			lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
				    mc_list->dmi_addr);
			continue;
		}

		if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
			break;
		memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
		lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
			    mc_list->dmi_addr);
		i++;
	}
	netif_addr_unlock_bh(dev);
	if (mc_list)
		return -EOVERFLOW;

	return i;
}
int dev_mc_add_excl(struct net_device *dev, unsigned char *addr)
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
	struct netdev_hw_addr *ha;
#else
	struct dev_addr_list *ha;
#endif
	int err;

	netif_addr_lock_bh(dev);
	netdev_for_each_mc_addr(ha, dev) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
		if (!memcmp(ha->addr, addr, dev->addr_len)) {
#else
		if (!memcmp(ha->da_addr, addr, dev->addr_len)) {
#endif
			err = -EEXIST;
			goto out;
		}
	}
	netif_addr_unlock_bh(dev);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
	return dev_mc_add(dev, addr);
#else
	return dev_mc_add(dev, addr, ETH_ALEN, true);
#endif

out:
	netif_addr_unlock_bh(dev);
	return err;
}
EXPORT_SYMBOL(dev_mc_add_excl);
int dev_uc_add_excl(struct net_device *dev, unsigned char *addr)
#endif
{
	struct netdev_hw_addr *ha;
	int err;

	netif_addr_lock_bh(dev);
	netdev_for_each_uc_addr(ha, dev) {
		if (!memcmp(ha->addr, addr, dev->addr_len) &&
		    ha->type == NETDEV_HW_ADDR_T_UNICAST) {
			err = -EEXIST;
			goto out;
		}
	}
	netif_addr_unlock_bh(dev);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
	return dev_uc_add(dev, addr);
#else
	return dev_unicast_add(dev, addr);
#endif

out:
	netif_addr_unlock_bh(dev);
	return err;
}
示例#6
0
/**
 * 	dev_mc_unsync	- Remove synchronized addresses from the destination
 * 			  device
 *	@to: destination device
 *	@from: source device
 *
 * 	Remove all addresses that were added to the destination device by
 * 	dev_mc_sync(). This function is intended to be called from the
 * 	dev->stop function of layered software devices.
 */
void dev_mc_unsync(struct net_device *to, struct net_device *from)
{
	netif_addr_lock_bh(from);
	netif_addr_lock(to);

	__dev_addr_unsync(&to->mc_list, &to->mc_count,
			  &from->mc_list, &from->mc_count);
	__dev_set_rx_mode(to);

	netif_addr_unlock(to);
	netif_addr_unlock_bh(from);
}
示例#7
0
int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
{
	int err;

	netif_addr_lock_bh(dev);
	if (alen != dev->addr_len)
		return -EINVAL;
	err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
	if (!err)
		__dev_set_rx_mode(dev);
	netif_addr_unlock_bh(dev);
	return err;
}
示例#8
0
/**
 *	dev_mc_sync	- Synchronize device's multicast list to another device
 *	@to: destination device
 *	@from: source device
 *
 * 	Add newly added addresses to the destination device and release
 * 	addresses that have no users left. The source device must be
 * 	locked by netif_tx_lock_bh.
 *
 *	This function is intended to be called from the dev->set_multicast_list
 *	or dev->set_rx_mode function of layered software devices.
 */
int dev_mc_sync(struct net_device *to, struct net_device *from)
{
	int err = 0;

	netif_addr_lock_bh(to);
	err = __dev_addr_sync(&to->mc_list, &to->mc_count,
			      &from->mc_list, &from->mc_count);
	if (!err)
		__dev_set_rx_mode(to);
	netif_addr_unlock_bh(to);

	return err;
}
示例#9
0
int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
{
	int err;

	netif_addr_lock_bh(dev);
	err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
				addr, alen, glbl);
	if (!err) {
		/*
		 *	We have altered the list, so the card
		 *	loaded filter is now wrong. Fix it
		 */

		__dev_set_rx_mode(dev);
	}
	netif_addr_unlock_bh(dev);
	return err;
}
示例#10
0
static int dev_mc_seq_show(struct seq_file *seq, void *v)
{
	struct dev_addr_list *m;
	struct net_device *dev = v;

	if (v == SEQ_START_TOKEN)
		return 0;

	netif_addr_lock_bh(dev);
	for (m = dev->mc_list; m; m = m->next) {
		int i;

		seq_printf(seq, "%-4d %-15s %-5d %-5d ", dev->ifindex,
			   dev->name, m->dmi_users, m->dmi_gusers);

		for (i = 0; i < m->dmi_addrlen; i++)
			seq_printf(seq, "%02x", m->dmi_addr[i]);

		seq_putc(seq, '\n');
	}
	netif_addr_unlock_bh(dev);
	return 0;
}