From: Jiri Benc <jbenc@suse.cz>
To: netdev@vger.kernel.org
Cc: "John W. Linville" <linville@tuxdriver.com>
Subject: [PATCH 14/17] d80211: set_multicast_list
Date: Fri, 21 Apr 2006 22:11:45 +0200 (CEST) [thread overview]
Message-ID: <20060421201145.BF3D1482CD@silver.suse.cz> (raw)
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
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 <jbenc@suse.cz>
---
include/net/d80211.h | 24 ++++++++++++++
net/d80211/ieee80211.c | 71 ++++++++++++++++++++++++++++++++++++++++++
net/d80211/ieee80211_i.h | 8 +++++
net/d80211/ieee80211_iface.c | 1 +
4 files changed, 104 insertions(+), 0 deletions(-)
9ada6736d81619ac81ea1ce283f47c365fe3b24f
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 6894745..7bc66b5 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -532,6 +532,13 @@ struct ieee80211_hw {
int (*config_interface)(struct net_device *dev, int if_id,
struct ieee80211_if_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
@@ -775,6 +782,23 @@ typedef enum {
} Netif_Oper;
int ieee80211_netif_oper(struct net_device *dev, Netif_Oper op);
+/**
+ * ieee80211_get_mc_list_item - iteration over items in multicast list
+ * @dev: pointer to &struct net_device as obtained from
+ * ieee80211_alloc_hw().
+ * @prev: value returned by previous call to ieee80211_get_mc_list_item() or
+ * NULL to start a new iteration.
+ * @ptr: pointer to buffer of void * type for internal usage of
+ * ieee80211_get_mc_list_item().
+ *
+ * Iterates 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
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index ea71b6c..fbca700 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1812,6 +1812,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)
{
@@ -3889,6 +3958,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;
@@ -4449,6 +4519,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);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 5116a88..37d533d 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -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 @@ #define IEEE80211_IRQSAFE_QUEUE_LIMIT 12
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;
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 917428e..2151bd9 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -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);
--
1.3.0
next prev parent reply other threads:[~2006-04-21 20:11 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-21 20:11 [PATCH 0/17] d80211 patches Jiri Benc
2006-04-21 20:11 ` [PATCH 1/17] d80211: Replace MODULE_PARM with module_param Jiri Benc
2006-04-21 20:11 ` [PATCH 2/17] d80211: symlinks to wiphy in sysfs Jiri Benc
2006-04-21 20:11 ` [PATCH 3/17] d80211: allow WDS remote to by set by WE Jiri Benc
2006-04-21 20:11 ` [PATCH 4/17] d80211: add IBSS and monitor interface types Jiri Benc
2006-04-21 20:11 ` [PATCH 5/17] d80211: non-shared " Jiri Benc
2006-04-21 20:11 ` [PATCH 6/17] d80211: remove local->bssid variable Jiri Benc
2006-04-21 20:11 ` [PATCH 7/17] d80211: rename IEEE80211_SUB_IF_TYPE_ constants Jiri Benc
2006-04-21 20:11 ` [PATCH 8/17] d80211: ask driver for allowed iface combinations Jiri Benc
2006-04-21 20:11 ` [PATCH 9/17] d80211: remove obsolete stuff Jiri Benc
2006-04-21 20:11 ` [PATCH 10/17] d80211: fix interface configuration Jiri Benc
2006-04-21 20:11 ` [PATCH 11/17] d80211: rename adm_status to radio_enabled Jiri Benc
2006-04-21 20:11 ` [PATCH 12/17] d80211: interface types changeable by SIOCSIWMODE Jiri Benc
2006-04-21 20:11 ` [PATCH 13/17] d80211: master interface auto up/down Jiri Benc
2006-04-21 20:11 ` Jiri Benc [this message]
2006-04-21 20:11 ` [PATCH 15/17] d80211: fix handling of received frames Jiri Benc
2006-04-21 20:11 ` [PATCH 16/17] d80211: fix monitor interfaces Jiri Benc
2006-04-21 20:29 ` Johannes Berg
2006-04-21 20:49 ` Jiri Benc
2006-04-21 20:52 ` Johannes Berg
2006-04-21 20:57 ` Jiri Benc
2006-04-21 21:01 ` Johannes Berg
2006-04-21 21:05 ` Jiri Benc
2006-04-21 21:05 ` Johannes Berg
2006-04-21 20:11 ` [PATCH 17/17] d80211: fix AP interfaces Jiri Benc
2006-04-21 20:52 ` [PATCH 0/17] d80211 patches Michael Buesch
2006-04-21 20:52 ` Jiri Benc
2006-04-26 19:39 ` John W. Linville
2006-04-26 21:27 ` Ivo van Doorn
2006-04-27 12:49 ` Michael Buesch
2006-04-28 15:45 ` [PATCH] bcm43xx_d80211: fix bug in open Jiri Benc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060421201145.BF3D1482CD@silver.suse.cz \
--to=jbenc@suse.cz \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).