* [RFC 0/5] bind filters and multicast list to subif
@ 2012-06-18 10:57 Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 1/5] mac80211: make filter configuration work per subif Lukasz Kucharczyk
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
Hi,
Following patches enables configuring filters and multicast list for
specific interface. That probably might be useful in implementation
of multi-channel operation.
BR,
Lukasz
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 1/5] mac80211: make filter configuration work per subif
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
@ 2012-06-18 10:57 ` Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 2/5] mac80211: bind FIF_* parameters to interface Lukasz Kucharczyk
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
ieee80211_configure_filter takes ieee80211_sub_if_data*
as argument instead of ieee80211_local*.
reconfig_filter work is now bounded to ieee80211_sub_if_data.
Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@tieto.com>
---
net/mac80211/cfg.c | 6 +++---
net/mac80211/ieee80211_i.h | 15 ++++++++-------
net/mac80211/iface.c | 31 ++++++++++++++++++++++---------
net/mac80211/main.c | 21 +++++++--------------
net/mac80211/mesh.c | 4 ++--
net/mac80211/scan.c | 8 +++++---
net/mac80211/util.c | 6 ++----
7 files changed, 49 insertions(+), 42 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 85ac364..d3ae0df 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -69,7 +69,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
sdata->u.mgd.use_4addr = params->use_4addr;
if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
- struct ieee80211_local *local = sdata->local;
if (ieee80211_sdata_running(sdata)) {
/*
@@ -88,7 +87,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
sdata->u.mntr_flags = *flags;
ieee80211_adjust_monitor_flags(sdata, 1);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
} else {
/*
* Because the interface is down, ieee80211_do_stop
@@ -2489,6 +2488,7 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
u16 frame_type, bool reg)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
return;
@@ -2498,7 +2498,7 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
else
local->probe_req_reg--;
- ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+ ieee80211_queue_work(&local->hw, &sdata->reconfig_filter);
}
static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6cbf5b..78fc9cc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -723,6 +723,13 @@ struct ieee80211_sub_if_data {
struct dentry *default_mgmt_key;
} debugfs;
#endif
+
+ /* protects the aggregated multicast list and filter calls */
+ spinlock_t filter_lock;
+
+ /* used for uploading changed mc list */
+ struct work_struct reconfig_filter;
+
/* must be last, dynamically sized area in this! */
struct ieee80211_vif vif;
};
@@ -842,12 +849,6 @@ struct ieee80211_local {
bool wiphy_ciphers_allocated;
- /* protects the aggregated multicast list and filter calls */
- spinlock_t filter_lock;
-
- /* used for uploading changed mc list */
- struct work_struct reconfig_filter;
-
/* used to reconfigure hardware SM PS */
struct work_struct recalc_smps;
@@ -1171,7 +1172,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
u32 changed);
-void ieee80211_configure_filter(struct ieee80211_local *local);
+void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata);
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
/* STA code */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 87aeb4f..059388b 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -385,7 +385,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
}
ieee80211_adjust_monitor_flags(sdata, 1);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
netif_carrier_on(dev);
break;
@@ -405,7 +405,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
local->fif_pspoll++;
local->fif_probe_req++;
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
local->fif_probe_req++;
}
@@ -566,13 +566,13 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
}
netif_addr_lock_bh(sdata->dev);
- spin_lock_bh(&local->filter_lock);
+ spin_lock_bh(&sdata->filter_lock);
__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
sdata->dev->addr_len);
- spin_unlock_bh(&local->filter_lock);
+ spin_unlock_bh(&sdata->filter_lock);
netif_addr_unlock_bh(sdata->dev);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
del_timer_sync(&local->dynamic_ps_timer);
cancel_work_sync(&local->dynamic_ps_enable_work);
@@ -631,7 +631,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
}
ieee80211_adjust_monitor_flags(sdata, -1);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
break;
default:
flush_work(&sdata->work);
@@ -741,10 +741,10 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
atomic_dec(&local->iff_promiscs);
sdata->flags ^= IEEE80211_SDATA_PROMISC;
}
- spin_lock_bh(&local->filter_lock);
+ spin_lock_bh(&sdata->filter_lock);
__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
- spin_unlock_bh(&local->filter_lock);
- ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+ spin_unlock_bh(&sdata->filter_lock);
+ ieee80211_queue_work(&local->hw, &sdata->reconfig_filter);
}
/*
@@ -960,6 +960,14 @@ static void ieee80211_iface_work(struct work_struct *work)
}
}
+static void ieee80211_reconfig_filter(struct work_struct *work)
+{
+ struct ieee80211_sub_if_data *sdata =
+ container_of(work, struct ieee80211_sub_if_data,
+ reconfig_filter);
+
+ ieee80211_configure_filter(sdata);
+}
/*
* Helper function to initialise an interface to a specific type.
@@ -984,8 +992,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
/* only monitor differs */
sdata->dev->type = ARPHRD_ETHER;
+ spin_lock_init(&sdata->filter_lock);
+
skb_queue_head_init(&sdata->skb_queue);
INIT_WORK(&sdata->work, ieee80211_iface_work);
+ INIT_WORK(&sdata->reconfig_filter, ieee80211_reconfig_filter);
switch (type) {
case NL80211_IFTYPE_P2P_GO:
@@ -1373,6 +1384,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
{
ASSERT_RTNL();
+ cancel_work_sync(&sdata->reconfig_filter);
+
mutex_lock(&sdata->local->iflist_mtx);
list_del_rcu(&sdata->list);
mutex_unlock(&sdata->local->iflist_mtx);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d81c178..14c990a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -35,11 +35,15 @@
static struct lock_class_key ieee80211_rx_skb_queue_class;
-void ieee80211_configure_filter(struct ieee80211_local *local)
+void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
{
u64 mc;
unsigned int changed_flags;
unsigned int new_flags = 0;
+ struct ieee80211_local *local = sdata->local;
+
+ if (!ieee80211_sdata_running(sdata))
+ return;
if (atomic_read(&local->iff_promiscs))
new_flags |= FIF_PROMISC_IN_BSS;
@@ -69,11 +73,11 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
if (local->fif_pspoll)
new_flags |= FIF_PSPOLL;
- spin_lock_bh(&local->filter_lock);
+ spin_lock_bh(&sdata->filter_lock);
changed_flags = local->filter_flags ^ new_flags;
mc = drv_prepare_multicast(local, &local->mc_list);
- spin_unlock_bh(&local->filter_lock);
+ spin_unlock_bh(&sdata->filter_lock);
/* be a bit nasty */
new_flags |= (1<<31);
@@ -85,14 +89,6 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
local->filter_flags = new_flags & ~(1<<31);
}
-static void ieee80211_reconfig_filter(struct work_struct *work)
-{
- struct ieee80211_local *local =
- container_of(work, struct ieee80211_local, reconfig_filter);
-
- ieee80211_configure_filter(local);
-}
-
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
{
struct ieee80211_channel *chan;
@@ -610,7 +606,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
mutex_init(&local->mtx);
mutex_init(&local->key_mtx);
- spin_lock_init(&local->filter_lock);
spin_lock_init(&local->queue_stop_reason_lock);
/*
@@ -627,7 +622,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
INIT_WORK(&local->restart_work, ieee80211_restart_work);
- INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work);
local->smps_mode = IEEE80211_SMPS_OFF;
@@ -1015,7 +1009,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
rtnl_unlock();
cancel_work_sync(&local->restart_work);
- cancel_work_sync(&local->reconfig_filter);
ieee80211_clear_tx_pending(local);
rate_control_deinitialize(local);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 7cf1950..94acc1c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -585,7 +585,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
local->fif_other_bss++;
/* mesh ifaces must set allmulti to forward mcast traffic */
atomic_inc(&local->iff_allmultis);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
ifmsh->mesh_cc_id = 0; /* Disabled */
ifmsh->mesh_auth_id = 0; /* Disabled */
@@ -631,7 +631,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
local->fif_other_bss--;
atomic_dec(&local->iff_allmultis);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
}
static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 379f178..9a2cba8 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -277,6 +277,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
bool was_hw_scan)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata;
lockdep_assert_held(&local->mtx);
@@ -304,6 +305,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
if (local->scan_req != local->int_scan_req)
cfg80211_scan_done(local->scan_req, aborted);
local->scan_req = NULL;
+ sdata = local->scan_sdata;
local->scan_sdata = NULL;
local->scanning = 0;
@@ -313,7 +315,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
ieee80211_hw_config(local, 0);
if (!was_hw_scan) {
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(sdata);
drv_sw_scan_complete(local);
ieee80211_offchannel_return(local, true);
}
@@ -362,7 +364,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
ieee80211_offchannel_stop_vifs(local, true);
- ieee80211_configure_filter(local);
+ ieee80211_configure_filter(local->scan_sdata);
/* We need to set power level at maximum rate for scanning. */
ieee80211_hw_config(local, 0);
@@ -494,7 +496,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
* same as normal software scan, in case that matters. */
drv_sw_scan_start(local);
- ieee80211_configure_filter(local); /* accept probe-responses */
+ ieee80211_configure_filter(sdata); /* accept probe-responses */
/* We need to ensure power level is at max for scanning. */
ieee80211_hw_config(local, 0);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1df4019..74aab81 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1193,9 +1193,6 @@ void ieee80211_stop_device(struct ieee80211_local *local)
{
ieee80211_led_radio(local, false);
ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);
-
- cancel_work_sync(&local->reconfig_filter);
-
flush_workqueue(local->workqueue);
drv_stop(local);
}
@@ -1312,7 +1309,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
/* reconfigure hardware */
ieee80211_hw_config(local, ~0);
- ieee80211_configure_filter(local);
+ list_for_each_entry(sdata, &local->interfaces, list)
+ ieee80211_configure_filter(sdata);
/* Finally also reconfigure all the BSS information */
list_for_each_entry(sdata, &local->interfaces, list) {
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC 2/5] mac80211: bind FIF_* parameters to interface.
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 1/5] mac80211: make filter configuration work per subif Lukasz Kucharczyk
@ 2012-06-18 10:57 ` Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 3/5] mac80211: bind driver's filter callback to subif Lukasz Kucharczyk
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
Following flags:
FIF_PROMISC_IN_BSS
FIF_ALLMULTI
FIF_FCSFAIL
FIF_PLCPFAIL
FIF_BCN_PRBRESP_PROMISC
FIF_CONTROL
FIF_OTHER_BSS
FIF_PSPOLL
FIF_PROBE_REQ
are now bound to ieee80211_sub_if_data, not to
ieee80211_local. Requested flags are stored in new
field of ieee80211_sub_if_data: req_filt_flags.
Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@tieto.com>
---
net/mac80211/cfg.c | 4 +-
net/mac80211/ieee80211_i.h | 10 +-----
net/mac80211/iface.c | 73 +++++++++----------------------------------
net/mac80211/main.c | 35 ++++++++-------------
net/mac80211/mesh.c | 8 ++--
5 files changed, 37 insertions(+), 93 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d3ae0df..a4020bd 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2494,9 +2494,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
return;
if (reg)
- local->probe_req_reg++;
+ sdata->req_filt_flags |= FIF_PROBE_REQ;
else
- local->probe_req_reg--;
+ sdata->req_filt_flags &= ~FIF_PROBE_REQ;
ieee80211_queue_work(&local->hw, &sdata->reconfig_filter);
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 78fc9cc..2dc7aa2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -730,6 +730,8 @@ struct ieee80211_sub_if_data {
/* used for uploading changed mc list */
struct work_struct reconfig_filter;
+ unsigned int filter_flags, req_filt_flags; /* FIF_* */
+
/* must be last, dynamically sized area in this! */
struct ieee80211_vif vif;
};
@@ -841,11 +843,6 @@ struct ieee80211_local {
int open_count;
int monitors, cooked_mntrs;
- /* number of interfaces with corresponding FIF_ flags */
- int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
- fif_probe_req;
- int probe_req_reg;
- unsigned int filter_flags; /* FIF_* */
bool wiphy_ciphers_allocated;
@@ -923,9 +920,6 @@ struct ieee80211_local {
atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES];
- /* number of interfaces with corresponding IFF_ flags */
- atomic_t iff_allmultis, iff_promiscs;
-
struct rate_control_ref *rate_ctrl;
struct crypto_cipher *wep_tx_tfm;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 059388b..8e6eebd 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -181,19 +181,22 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
const int offset)
{
- struct ieee80211_local *local = sdata->local;
- u32 flags = sdata->u.mntr_flags;
+ u32 flags = sdata->u.mntr_flags, req_flags = 0;
-#define ADJUST(_f, _s) do { \
- if (flags & MONITOR_FLAG_##_f) \
- local->fif_##_s += offset; \
+#define ADJUST(_f, _s) do {\
+ if (flags & MONITOR_FLAG_##_f)\
+ req_flags |= _s;\
} while (0)
- ADJUST(FCSFAIL, fcsfail);
- ADJUST(PLCPFAIL, plcpfail);
- ADJUST(CONTROL, control);
- ADJUST(CONTROL, pspoll);
- ADJUST(OTHER_BSS, other_bss);
+ ADJUST(PLCPFAIL, FIF_PLCPFAIL);
+ ADJUST(CONTROL, FIF_PSPOLL);
+ ADJUST(CONTROL, FIF_CONTROL);
+ ADJUST(FCSFAIL, FIF_FCSFAIL);
+ ADJUST(OTHER_BSS, FIF_OTHER_BSS);
+ if (offset > 0)
+ sdata->req_filt_flags |= req_flags;
+ else
+ sdata->req_filt_flags &= ~req_flags;
#undef ADJUST
}
@@ -402,12 +405,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
}
if (sdata->vif.type == NL80211_IFTYPE_AP) {
- local->fif_pspoll++;
- local->fif_probe_req++;
-
ieee80211_configure_filter(sdata);
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- local->fif_probe_req++;
}
changed |= ieee80211_reset_erp_info(sdata);
@@ -452,17 +450,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
rate_control_rate_init(sta);
}
- /*
- * set_multicast_list will be invoked by the networking core
- * which will check whether any increments here were done in
- * error and sync them down to the hardware as filter flags.
- */
- if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
- atomic_inc(&local->iff_allmultis);
-
- if (sdata->flags & IEEE80211_SDATA_PROMISC)
- atomic_inc(&local->iff_promiscs);
-
mutex_lock(&local->mtx);
hw_reconf_flags |= __ieee80211_recalc_idle(local);
mutex_unlock(&local->mtx);
@@ -546,25 +533,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
*/
sta_info_flush(local, sdata);
- /*
- * Don't count this interface for promisc/allmulti while it
- * is down. dev_mc_unsync() will invoke set_multicast_list
- * on the master interface which will sync these down to the
- * hardware as filter flags.
- */
- if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
- atomic_dec(&local->iff_allmultis);
-
- if (sdata->flags & IEEE80211_SDATA_PROMISC)
- atomic_dec(&local->iff_promiscs);
-
- if (sdata->vif.type == NL80211_IFTYPE_AP) {
- local->fif_pspoll--;
- local->fif_probe_req--;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- local->fif_probe_req--;
- }
-
netif_addr_lock_bh(sdata->dev);
spin_lock_bh(&sdata->filter_lock);
__hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
@@ -726,21 +694,12 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC);
- if (allmulti != sdata_allmulti) {
- if (dev->flags & IFF_ALLMULTI)
- atomic_inc(&local->iff_allmultis);
- else
- atomic_dec(&local->iff_allmultis);
+ if (allmulti != sdata_allmulti)
sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
- }
- if (promisc != sdata_promisc) {
- if (dev->flags & IFF_PROMISC)
- atomic_inc(&local->iff_promiscs);
- else
- atomic_dec(&local->iff_promiscs);
+ if (promisc != sdata_promisc)
sdata->flags ^= IEEE80211_SDATA_PROMISC;
- }
+
spin_lock_bh(&sdata->filter_lock);
__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
spin_unlock_bh(&sdata->filter_lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 14c990a..6adc1d2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -45,36 +45,27 @@ void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
if (!ieee80211_sdata_running(sdata))
return;
- if (atomic_read(&local->iff_promiscs))
- new_flags |= FIF_PROMISC_IN_BSS;
-
- if (atomic_read(&local->iff_allmultis))
+ if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
new_flags |= FIF_ALLMULTI;
- if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning) ||
- test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning))
+ if (sdata->flags & IEEE80211_SDATA_PROMISC)
+ new_flags |= FIF_PROMISC_IN_BSS;
+
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+ local->scan_sdata == sdata)
new_flags |= FIF_BCN_PRBRESP_PROMISC;
- if (local->fif_probe_req || local->probe_req_reg)
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_ADHOC)
new_flags |= FIF_PROBE_REQ;
- if (local->fif_fcsfail)
- new_flags |= FIF_FCSFAIL;
-
- if (local->fif_plcpfail)
- new_flags |= FIF_PLCPFAIL;
-
- if (local->fif_control)
- new_flags |= FIF_CONTROL;
-
- if (local->fif_other_bss)
- new_flags |= FIF_OTHER_BSS;
-
- if (local->fif_pspoll)
+ if (sdata->vif.type == NL80211_IFTYPE_AP)
new_flags |= FIF_PSPOLL;
+ new_flags |= sdata->req_filt_flags;
+
spin_lock_bh(&sdata->filter_lock);
- changed_flags = local->filter_flags ^ new_flags;
+ changed_flags = sdata->filter_flags ^ new_flags;
mc = drv_prepare_multicast(local, &local->mc_list);
spin_unlock_bh(&sdata->filter_lock);
@@ -86,7 +77,7 @@ void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
WARN_ON(new_flags & (1<<31));
- local->filter_flags = new_flags & ~(1<<31);
+ sdata->filter_flags = new_flags & ~(1<<31);
}
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 94acc1c..28cc48d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -582,9 +582,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
- local->fif_other_bss++;
+ sdata->req_filt_flags |= FIF_OTHER_BSS;
/* mesh ifaces must set allmulti to forward mcast traffic */
- atomic_inc(&local->iff_allmultis);
+ sdata->flags |= IEEE80211_SDATA_ALLMULTI;
ieee80211_configure_filter(sdata);
ifmsh->mesh_cc_id = 0; /* Disabled */
@@ -629,8 +629,8 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
*/
cancel_work_sync(&sdata->work);
- local->fif_other_bss--;
- atomic_dec(&local->iff_allmultis);
+ sdata->req_filt_flags &= ~(FIF_OTHER_BSS);
+ sdata->flags &= ~IEEE80211_SDATA_ALLMULTI;
ieee80211_configure_filter(sdata);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC 3/5] mac80211: bind driver's filter callback to subif
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 1/5] mac80211: make filter configuration work per subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 2/5] mac80211: bind FIF_* parameters to interface Lukasz Kucharczyk
@ 2012-06-18 10:57 ` Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 4/5] mac80211: move multicast list " Lukasz Kucharczyk
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
Driver is now aware for which virtual interface
the RX filter is being configured.
ieee80211_sub_if_data *sdata argument is added to
drv_configure_filter.
ieee80211_vif *vif argument is added to driver's
configure_filter callback.
Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@tieto.com>
---
include/net/mac80211.h | 1 +
net/mac80211/driver-ops.h | 7 ++++---
net/mac80211/driver-trace.h | 9 ++++++---
net/mac80211/main.c | 2 +-
4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6914f99..c515a6f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2282,6 +2282,7 @@ struct ieee80211_ops {
u64 (*prepare_multicast)(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list);
void (*configure_filter)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
unsigned int changed_flags,
unsigned int *total_flags,
u64 multicast);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 6d33a0c..cfc4a35 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -237,16 +237,17 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
}
static inline void drv_configure_filter(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
unsigned int changed_flags,
unsigned int *total_flags,
u64 multicast)
{
might_sleep();
- trace_drv_configure_filter(local, changed_flags, total_flags,
+ trace_drv_configure_filter(local, sdata, changed_flags, total_flags,
multicast);
- local->ops->configure_filter(&local->hw, changed_flags, total_flags,
- multicast);
+ local->ops->configure_filter(&local->hw, &sdata->vif, changed_flags,
+ total_flags, multicast);
trace_drv_return_void(local);
}
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6de00b2..ad99338 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -360,14 +360,16 @@ TRACE_EVENT(drv_prepare_multicast,
TRACE_EVENT(drv_configure_filter,
TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
unsigned int changed_flags,
unsigned int *total_flags,
u64 multicast),
- TP_ARGS(local, changed_flags, total_flags, multicast),
+ TP_ARGS(local, sdata, changed_flags, total_flags, multicast),
TP_STRUCT__entry(
LOCAL_ENTRY
+ VIF_ENTRY
__field(unsigned int, changed)
__field(unsigned int, total)
__field(u64, multicast)
@@ -375,14 +377,15 @@ TRACE_EVENT(drv_configure_filter,
TP_fast_assign(
LOCAL_ASSIGN;
+ VIF_ASSIGN;
__entry->changed = changed_flags;
__entry->total = *total_flags;
__entry->multicast = multicast;
),
TP_printk(
- LOCAL_PR_FMT " changed:%#x total:%#x",
- LOCAL_PR_ARG, __entry->changed, __entry->total
+ LOCAL_PR_FMT VIF_PR_FMT " changed:%#x total:%#x",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed, __entry->total
)
);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 6adc1d2..057e098 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -73,7 +73,7 @@ void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
/* be a bit nasty */
new_flags |= (1<<31);
- drv_configure_filter(local, changed_flags, &new_flags, mc);
+ drv_configure_filter(local, sdata, changed_flags, &new_flags, mc);
WARN_ON(new_flags & (1<<31));
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC 4/5] mac80211: move multicast list to subif.
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
` (2 preceding siblings ...)
2012-06-18 10:57 ` [RFC 3/5] mac80211: bind driver's filter callback to subif Lukasz Kucharczyk
@ 2012-06-18 10:57 ` Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 5/5] mac80211: bind prepare_multicast callback " Lukasz Kucharczyk
2012-06-18 11:45 ` [RFC 0/5] bind filters and multicast list " Johannes Berg
5 siblings, 0 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
Multicast address list is now kept in ieee80211_sub_if_data.
Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@tieto.com>
---
net/mac80211/ieee80211_i.h | 6 +++---
net/mac80211/iface.c | 6 ++++--
net/mac80211/main.c | 4 +---
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 2dc7aa2..54cec8f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -732,6 +732,9 @@ struct ieee80211_sub_if_data {
unsigned int filter_flags, req_filt_flags; /* FIF_* */
+ /* aggregated multicast list */
+ struct netdev_hw_addr_list mc_list;
+
/* must be last, dynamically sized area in this! */
struct ieee80211_vif vif;
};
@@ -849,9 +852,6 @@ struct ieee80211_local {
/* used to reconfigure hardware SM PS */
struct work_struct recalc_smps;
- /* aggregated multicast list */
- struct netdev_hw_addr_list mc_list;
-
bool tim_in_locked_section; /* see ieee80211_beacon_get() */
/*
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8e6eebd..f452c41 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -535,7 +535,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
netif_addr_lock_bh(sdata->dev);
spin_lock_bh(&sdata->filter_lock);
- __hw_addr_unsync(&local->mc_list, &sdata->dev->mc,
+ __hw_addr_unsync(&sdata->mc_list, &sdata->dev->mc,
sdata->dev->addr_len);
spin_unlock_bh(&sdata->filter_lock);
netif_addr_unlock_bh(sdata->dev);
@@ -701,7 +701,7 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
sdata->flags ^= IEEE80211_SDATA_PROMISC;
spin_lock_bh(&sdata->filter_lock);
- __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
+ __hw_addr_sync(&sdata->mc_list, &dev->mc, dev->addr_len);
spin_unlock_bh(&sdata->filter_lock);
ieee80211_queue_work(&local->hw, &sdata->reconfig_filter);
}
@@ -957,6 +957,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
INIT_WORK(&sdata->work, ieee80211_iface_work);
INIT_WORK(&sdata->reconfig_filter, ieee80211_reconfig_filter);
+ __hw_addr_init(&sdata->mc_list);
+
switch (type) {
case NL80211_IFTYPE_P2P_GO:
type = NL80211_IFTYPE_AP;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 057e098..b00eb59 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -67,7 +67,7 @@ void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
spin_lock_bh(&sdata->filter_lock);
changed_flags = sdata->filter_flags ^ new_flags;
- mc = drv_prepare_multicast(local, &local->mc_list);
+ mc = drv_prepare_multicast(local, &sdata->mc_list);
spin_unlock_bh(&sdata->filter_lock);
/* be a bit nasty */
@@ -591,8 +591,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
INIT_LIST_HEAD(&local->interfaces);
- __hw_addr_init(&local->mc_list);
-
mutex_init(&local->iflist_mtx);
mutex_init(&local->mtx);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC 5/5] mac80211: bind prepare_multicast callback to subif.
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
` (3 preceding siblings ...)
2012-06-18 10:57 ` [RFC 4/5] mac80211: move multicast list " Lukasz Kucharczyk
@ 2012-06-18 10:57 ` Lukasz Kucharczyk
2012-06-18 11:45 ` [RFC 0/5] bind filters and multicast list " Johannes Berg
5 siblings, 0 replies; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-18 10:57 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, lukasz.kucharczyk
Driver is now aware for which virtual interace the multicast
is being configured.
ieee80211_sub_if_data *sdata parameter is added to
drv_prepare_multicast.
vieee80211_vif *vif parameter is added to driver's
prepare_multicast callback.
Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@tieto.com>
---
include/net/mac80211.h | 1 +
net/mac80211/driver-ops.h | 6 ++++--
net/mac80211/driver-trace.h | 12 ++++++++----
net/mac80211/main.c | 2 +-
4 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c515a6f..39ebba0 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2280,6 +2280,7 @@ struct ieee80211_ops {
u32 changed);
u64 (*prepare_multicast)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
struct netdev_hw_addr_list *mc_list);
void (*configure_filter)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index cfc4a35..e27dd48 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -222,14 +222,16 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
}
static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
struct netdev_hw_addr_list *mc_list)
{
u64 ret = 0;
- trace_drv_prepare_multicast(local, mc_list->count);
+ trace_drv_prepare_multicast(local, sdata, mc_list->count);
if (local->ops->prepare_multicast)
- ret = local->ops->prepare_multicast(&local->hw, mc_list);
+ ret = local->ops->prepare_multicast(&local->hw, &sdata->vif,
+ mc_list);
trace_drv_return_u64(local, ret);
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index ad99338..2226816 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -338,23 +338,27 @@ TRACE_EVENT(drv_bss_info_changed,
);
TRACE_EVENT(drv_prepare_multicast,
- TP_PROTO(struct ieee80211_local *local, int mc_count),
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ int mc_count),
- TP_ARGS(local, mc_count),
+ TP_ARGS(local, sdata, mc_count),
TP_STRUCT__entry(
LOCAL_ENTRY
+ VIF_ENTRY
__field(int, mc_count)
),
TP_fast_assign(
LOCAL_ASSIGN;
+ VIF_ASSIGN;
__entry->mc_count = mc_count;
),
TP_printk(
- LOCAL_PR_FMT " prepare mc (%d)",
- LOCAL_PR_ARG, __entry->mc_count
+ LOCAL_PR_FMT VIF_PR_FMT " prepare mc (%d)",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->mc_count
)
);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b00eb59..6541c74 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -67,7 +67,7 @@ void ieee80211_configure_filter(struct ieee80211_sub_if_data *sdata)
spin_lock_bh(&sdata->filter_lock);
changed_flags = sdata->filter_flags ^ new_flags;
- mc = drv_prepare_multicast(local, &sdata->mc_list);
+ mc = drv_prepare_multicast(local, sdata, &sdata->mc_list);
spin_unlock_bh(&sdata->filter_lock);
/* be a bit nasty */
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC 0/5] bind filters and multicast list to subif
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
` (4 preceding siblings ...)
2012-06-18 10:57 ` [RFC 5/5] mac80211: bind prepare_multicast callback " Lukasz Kucharczyk
@ 2012-06-18 11:45 ` Johannes Berg
2012-06-19 14:32 ` Lukasz Kucharczyk
5 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2012-06-18 11:45 UTC (permalink / raw)
To: Lukasz Kucharczyk; +Cc: linux-wireless
On Mon, 2012-06-18 at 12:57 +0200, Lukasz Kucharczyk wrote:
> Hi,
>
> Following patches enables configuring filters and multicast list for
> specific interface. That probably might be useful in implementation
> of multi-channel operation.
"Might be useful"?
I guess I can see that, but we need
a) driver updates
b) to keep a global filter setting for drivers that don't have
per-interface settings
johannes
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC 0/5] bind filters and multicast list to subif
2012-06-18 11:45 ` [RFC 0/5] bind filters and multicast list " Johannes Berg
@ 2012-06-19 14:32 ` Lukasz Kucharczyk
2012-06-19 14:38 ` Johannes Berg
0 siblings, 1 reply; 9+ messages in thread
From: Lukasz Kucharczyk @ 2012-06-19 14:32 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 06/18/2012 01:45 PM, Johannes Berg wrote:
> On Mon, 2012-06-18 at 12:57 +0200, Lukasz Kucharczyk wrote:
>> Hi,
>>
>> Following patches enables configuring filters and multicast list for
>> specific interface. That probably might be useful in implementation
>> of multi-channel operation.
>
> "Might be useful"?
>
> I guess I can see that, but we need
> a) driver updates
> b) to keep a global filter setting for drivers that don't have
> per-interface settings
>
Ok, so I will need indication from driver what it supports.
Do you think adding single flag to ieee80211_hw_flags (like
IEEE80211_HW_SUPPORTS_IFCE_FILTERS) would be sufficient for that purpose?
Lukasz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC 0/5] bind filters and multicast list to subif
2012-06-19 14:32 ` Lukasz Kucharczyk
@ 2012-06-19 14:38 ` Johannes Berg
0 siblings, 0 replies; 9+ messages in thread
From: Johannes Berg @ 2012-06-19 14:38 UTC (permalink / raw)
To: Lukasz Kucharczyk; +Cc: linux-wireless
On Tue, 2012-06-19 at 16:32 +0200, Lukasz Kucharczyk wrote:
> On 06/18/2012 01:45 PM, Johannes Berg wrote:
> > On Mon, 2012-06-18 at 12:57 +0200, Lukasz Kucharczyk wrote:
> >> Hi,
> >>
> >> Following patches enables configuring filters and multicast list for
> >> specific interface. That probably might be useful in implementation
> >> of multi-channel operation.
> >
> > "Might be useful"?
> >
> > I guess I can see that, but we need
> > a) driver updates
> > b) to keep a global filter setting for drivers that don't have
> > per-interface settings
> >
>
> Ok, so I will need indication from driver what it supports.
> Do you think adding single flag to ieee80211_hw_flags (like
> IEEE80211_HW_SUPPORTS_IFCE_FILTERS) would be sufficient for that purpose?
I'm not sure that's needed? We'll have to maintain both a global and a
per-interface list anyway, so you could just add new per-interface
callbacks or so instead of changing the existing ones, and then the
driver can pick which ones it wants?
johannes
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-06-19 14:38 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-18 10:57 [RFC 0/5] bind filters and multicast list to subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 1/5] mac80211: make filter configuration work per subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 2/5] mac80211: bind FIF_* parameters to interface Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 3/5] mac80211: bind driver's filter callback to subif Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 4/5] mac80211: move multicast list " Lukasz Kucharczyk
2012-06-18 10:57 ` [RFC 5/5] mac80211: bind prepare_multicast callback " Lukasz Kucharczyk
2012-06-18 11:45 ` [RFC 0/5] bind filters and multicast list " Johannes Berg
2012-06-19 14:32 ` Lukasz Kucharczyk
2012-06-19 14:38 ` Johannes Berg
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.