summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>2015-08-15 22:39:50 +0300
committerJohannes Berg <johannes.berg@intel.com>2015-09-22 15:21:22 +0200
commit1b09b5568e5f46c6dfb781d7c1dfad431a6d8ec1 (patch)
tree1e437f5a6693228d1d5d4f122d0ef0ad99edc734 /net
parent7bdbe400d1b2aac116513f90b75969ad2365fba6 (diff)
downloadop-kernel-dev-1b09b5568e5f46c6dfb781d7c1dfad431a6d8ec1.zip
op-kernel-dev-1b09b5568e5f46c6dfb781d7c1dfad431a6d8ec1.tar.gz
mac80211: introduce per vif frame registration API
Currently the cfg80211's frame registration api receives wdev, however mac80211 assumes per device filter configuration and ignores wdev. Per device filtering is too wasteful, especially for multi-channel devices. Introduce new per vif frame registration API and use it for probe request registrations in ieee80211_mgmt_frame_register() Also call directly to ieee80211_configure_filter instead of using a work since it is now allowed to sleep in ieee80211_mgmt_frame_register. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/driver-ops.h16
-rw-r--r--net/mac80211/trace.h30
3 files changed, 64 insertions, 4 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1ca972e..9eab783 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3516,18 +3516,32 @@ 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_WDEV_TO_SUB_IF(wdev);
switch (frame_type) {
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
- if (reg)
+ if (reg) {
local->probe_req_reg++;
- else
- local->probe_req_reg--;
+ sdata->vif.probe_req_reg++;
+ } else {
+ if (local->probe_req_reg)
+ local->probe_req_reg--;
+
+ if (sdata->vif.probe_req_reg)
+ sdata->vif.probe_req_reg--;
+ }
if (!local->open_count)
break;
- ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+ if (sdata->vif.probe_req_reg == 1)
+ drv_config_iface_filter(local, sdata, FIF_PROBE_REQ,
+ FIF_PROBE_REQ);
+ else if (sdata->vif.probe_req_reg == 0)
+ drv_config_iface_filter(local, sdata, 0,
+ FIF_PROBE_REQ);
+
+ ieee80211_configure_filter(local);
break;
default:
break;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 02d9133..157b20b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -260,6 +260,22 @@ static inline void drv_configure_filter(struct ieee80211_local *local,
trace_drv_return_void(local);
}
+static inline void drv_config_iface_filter(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ unsigned int filter_flags,
+ unsigned int changed_flags)
+{
+ might_sleep();
+
+ trace_drv_config_iface_filter(local, sdata, filter_flags,
+ changed_flags);
+ if (local->ops->config_iface_filter)
+ local->ops->config_iface_filter(&local->hw, &sdata->vif,
+ filter_flags,
+ changed_flags);
+ trace_drv_return_void(local);
+}
+
static inline int drv_set_tim(struct ieee80211_local *local,
struct ieee80211_sta *sta, bool set)
{
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 6f14591..b5960b9 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -497,6 +497,36 @@ TRACE_EVENT(drv_configure_filter,
)
);
+TRACE_EVENT(drv_config_iface_filter,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ unsigned int filter_flags,
+ unsigned int changed_flags),
+
+ TP_ARGS(local, sdata, filter_flags, changed_flags),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ __field(unsigned int, filter_flags)
+ __field(unsigned int, changed_flags)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ __entry->filter_flags = filter_flags;
+ __entry->changed_flags = changed_flags;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT
+ " filter_flags: %#x changed_flags: %#x",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->filter_flags,
+ __entry->changed_flags
+ )
+);
+
TRACE_EVENT(drv_set_tim,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sta *sta, bool set),
OpenPOWER on IntegriCloud