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; }
/** * 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--; }
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; }
/** * 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); }
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; }
/** * 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; }
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; }
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; }