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