Add set_multicast_list callback. The version of set_multicast_list in struct net_device cannot be used by a driver, because the driver is interested in cumulative flags and cumulative multicast list from all interfaces.
Signed-off-by: Jiri Benc <[EMAIL PROTECTED]> Index: dscape/include/net/d80211.h =================================================================== --- dscape.orig/include/net/d80211.h 2006-03-06 14:10:41.000000000 +0100 +++ dscape/include/net/d80211.h 2006-03-06 14:18:01.000000000 +0100 @@ -481,6 +481,13 @@ struct ieee80211_hw { * function to change hardware configuration, e.g., channel. */ int (*config)(struct net_device *dev, struct ieee80211_conf *conf); + /* ieee80211 drivers should use this and not the function in + * net_device. dev->flags, dev->mc_count and dev->mc_list must not + * be used; use passed parameters and ieee80211_get_mc_list_item + * instead. */ + void (*set_multicast_list)(struct net_device *dev, + unsigned short flags, int mc_count); + /* Set TIM bit handler. If the hardware/firmware takes care of beacon * generation, IEEE 802.11 code uses this function to tell the * low-level to set (or clear if set==0) TIM bit for the given aid. If @@ -708,6 +715,13 @@ typedef enum { } Netif_Oper; int ieee80211_netif_oper(struct net_device *dev, Netif_Oper op); +/* Iteration over items in multicast list of given device. To get the first + * item, pass NULL in prev and in *ptr. In subsequent calls, pass the value + * returned by previous call in prev. Don't alter *ptr during iteration. + * When there are no more items, NULL is returned. */ +struct dev_mc_list *ieee80211_get_mc_list_item(struct net_device *dev, + struct dev_mc_list *prev, + void **ptr); /* * Function to get hardware configuration information Index: dscape/net/d80211/ieee80211.c =================================================================== --- dscape.orig/net/d80211/ieee80211.c 2006-03-06 14:17:50.000000000 +0100 +++ dscape/net/d80211/ieee80211.c 2006-03-06 14:18:01.000000000 +0100 @@ -1793,6 +1793,75 @@ static int ieee80211_set_mac_address(str return 0; } +static void ieee80211_set_multicast_list(struct net_device *dev) +{ + struct ieee80211_local *local = dev->priv; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + unsigned short flags; + + if (((dev->flags & IFF_ALLMULTI) != 0) ^ (sdata->allmulti != 0)) { + if (sdata->allmulti) { + sdata->allmulti = 0; + local->iff_allmultis--; + } else { + sdata->allmulti = 1; + local->iff_allmultis++; + } + } + if (((dev->flags & IFF_PROMISC) != 0) ^ (sdata->promisc != 0)) { + if (sdata->promisc) { + sdata->promisc = 0; + local->iff_promiscs--; + } else { + sdata->promisc = 1; + local->iff_promiscs++; + } + } + if (dev->mc_count != sdata->mc_count) { + local->mc_count = local->mc_count - sdata->mc_count + + dev->mc_count; + sdata->mc_count = dev->mc_count; + } + if (local->hw->set_multicast_list) { + flags = sdata->master->flags; + if (local->iff_allmultis) + flags |= IFF_ALLMULTI; + if (local->iff_promiscs) + flags |= IFF_PROMISC; + local->hw->set_multicast_list(sdata->master, flags, + local->mc_count); + } +} + +struct dev_mc_list *ieee80211_get_mc_list_item(struct net_device *dev, + struct dev_mc_list *prev, + void **ptr) +{ + struct ieee80211_local *local = dev->priv; + struct ieee80211_sub_if_data *sdata = *ptr; + struct dev_mc_list *mc; + + if (!prev) { + WARN_ON(sdata); + sdata = NULL; + } + if (!prev || !prev->next) { + if (sdata) + sdata = list_entry(sdata->list.next, + struct ieee80211_sub_if_data, list); + else + sdata = list_entry(local->sub_if_list.next, + struct ieee80211_sub_if_data, list); + if (&sdata->list != &local->sub_if_list) + mc = sdata->dev->mc_list; + else + mc = NULL; + } else + mc = prev->next; + + *ptr = sdata; + return mc; +} static struct net_device_stats *ieee80211_get_stats(struct net_device *dev) { @@ -3868,6 +3937,7 @@ void ieee80211_if_setup(struct net_devic (struct iw_handler_def *) &ieee80211_iw_handler_def; dev->do_ioctl = ieee80211_ioctl; dev->set_mac_address = ieee80211_set_mac_address; + dev->set_multicast_list = ieee80211_set_multicast_list; dev->change_mtu = ieee80211_change_mtu; dev->tx_timeout = ieee80211_tx_timeout; dev->get_stats = ieee80211_get_stats; @@ -4427,6 +4497,7 @@ EXPORT_SYMBOL(ieee80211_rate_control_unr EXPORT_SYMBOL(sta_info_get); EXPORT_SYMBOL(sta_info_release); EXPORT_SYMBOL(ieee80211_radar_status); +EXPORT_SYMBOL(ieee80211_get_mc_list_item); module_init(ieee80211_init); module_exit(ieee80211_exit); Index: dscape/net/d80211/ieee80211_i.h =================================================================== --- dscape.orig/net/d80211/ieee80211_i.h 2006-03-06 14:10:41.000000000 +0100 +++ dscape/net/d80211/ieee80211_i.h 2006-03-06 14:18:01.000000000 +0100 @@ -264,6 +264,10 @@ struct ieee80211_sub_if_data { struct net_device *master; struct ieee80211_local *local; + int mc_count; + unsigned allmulti:1; + unsigned promisc:1; + struct net_device_stats stats; int drop_unencrypted; int eapol; /* 0 = process EAPOL frames as normal data frames, @@ -327,6 +331,10 @@ struct ieee80211_local { struct sta_info *sta_hash[STA_HASH_SIZE]; struct timer_list sta_cleanup; + int mc_count; /* total count of multicast entries in all interfaces */ + int iff_allmultis, iff_promiscs; + /* number of interfaces with corresponding IFF_ flags */ + /* Current rate table. This is a pointer to hw->modes structure. */ struct ieee80211_rate *curr_rates; int num_curr_rates; Index: dscape/net/d80211/ieee80211_iface.c =================================================================== --- dscape.orig/net/d80211/ieee80211_iface.c 2006-03-06 14:17:06.000000000 +0100 +++ dscape/net/d80211/ieee80211_iface.c 2006-03-06 14:18:01.000000000 +0100 @@ -62,6 +62,7 @@ int ieee80211_if_add(struct net_device * ndev->irq = dev->irq; ndev->mem_start = dev->mem_start; ndev->mem_end = dev->mem_end; + ndev->flags = dev->flags & IFF_MULTICAST; ieee80211_if_setup(ndev); sdata = IEEE80211_DEV_TO_SUB_IF(ndev); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html