summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>2015-08-15 15:39:50 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-09-22 09:21:22 -0400
commit1b09b5568e5f46c6dfb781d7c1dfad431a6d8ec1 (patch)
tree1e437f5a6693228d1d5d4f122d0ef0ad99edc734
parent7bdbe400d1b2aac116513f90b75969ad2365fba6 (diff)
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>
-rw-r--r--include/net/mac80211.h16
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/driver-ops.h16
-rw-r--r--net/mac80211/trace.h30
4 files changed, 80 insertions, 4 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e3314e516681..167864503138 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5,6 +5,7 @@
5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright (C) 2015 Intel Deutschland GmbH
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -1358,6 +1359,8 @@ enum ieee80211_vif_flags {
1358 * @debugfs_dir: debugfs dentry, can be used by drivers to create own per 1359 * @debugfs_dir: debugfs dentry, can be used by drivers to create own per
1359 * interface debug files. Note that it will be NULL for the virtual 1360 * interface debug files. Note that it will be NULL for the virtual
1360 * monitor interface (if that is requested.) 1361 * monitor interface (if that is requested.)
1362 * @probe_req_reg: probe requests should be reported to mac80211 for this
1363 * interface.
1361 * @drv_priv: data area for driver use, will always be aligned to 1364 * @drv_priv: data area for driver use, will always be aligned to
1362 * sizeof(void *). 1365 * sizeof(void *).
1363 * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) 1366 * @txq: the multicast data TX queue (if driver uses the TXQ abstraction)
@@ -1382,6 +1385,8 @@ struct ieee80211_vif {
1382 struct dentry *debugfs_dir; 1385 struct dentry *debugfs_dir;
1383#endif 1386#endif
1384 1387
1388 unsigned int probe_req_reg;
1389
1385 /* must be last */ 1390 /* must be last */
1386 u8 drv_priv[0] __aligned(sizeof(void *)); 1391 u8 drv_priv[0] __aligned(sizeof(void *));
1387}; 1392};
@@ -2825,6 +2830,13 @@ enum ieee80211_reconfig_type {
2825 * See the section "Frame filtering" for more information. 2830 * See the section "Frame filtering" for more information.
2826 * This callback must be implemented and can sleep. 2831 * This callback must be implemented and can sleep.
2827 * 2832 *
2833 * @config_iface_filter: Configure the interface's RX filter.
2834 * This callback is optional and is used to configure which frames
2835 * should be passed to mac80211. The filter_flags is the combination
2836 * of FIF_* flags. The changed_flags is a bit mask that indicates
2837 * which flags are changed.
2838 * This callback can sleep.
2839 *
2828 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit 2840 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
2829 * must be set or cleared for a given STA. Must be atomic. 2841 * must be set or cleared for a given STA. Must be atomic.
2830 * 2842 *
@@ -3264,6 +3276,10 @@ struct ieee80211_ops {
3264 unsigned int changed_flags, 3276 unsigned int changed_flags,
3265 unsigned int *total_flags, 3277 unsigned int *total_flags,
3266 u64 multicast); 3278 u64 multicast);
3279 void (*config_iface_filter)(struct ieee80211_hw *hw,
3280 struct ieee80211_vif *vif,
3281 unsigned int filter_flags,
3282 unsigned int changed_flags);
3267 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 3283 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
3268 bool set); 3284 bool set);
3269 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3285 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1ca972e5418b..9eab783701aa 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3516,18 +3516,32 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
3516 u16 frame_type, bool reg) 3516 u16 frame_type, bool reg)
3517{ 3517{
3518 struct ieee80211_local *local = wiphy_priv(wiphy); 3518 struct ieee80211_local *local = wiphy_priv(wiphy);
3519 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3519 3520
3520 switch (frame_type) { 3521 switch (frame_type) {
3521 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 3522 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
3522 if (reg) 3523 if (reg) {
3523 local->probe_req_reg++; 3524 local->probe_req_reg++;
3524 else 3525 sdata->vif.probe_req_reg++;
3525 local->probe_req_reg--; 3526 } else {
3527 if (local->probe_req_reg)
3528 local->probe_req_reg--;
3529
3530 if (sdata->vif.probe_req_reg)
3531 sdata->vif.probe_req_reg--;
3532 }
3526 3533
3527 if (!local->open_count) 3534 if (!local->open_count)
3528 break; 3535 break;
3529 3536
3530 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 3537 if (sdata->vif.probe_req_reg == 1)
3538 drv_config_iface_filter(local, sdata, FIF_PROBE_REQ,
3539 FIF_PROBE_REQ);
3540 else if (sdata->vif.probe_req_reg == 0)
3541 drv_config_iface_filter(local, sdata, 0,
3542 FIF_PROBE_REQ);
3543
3544 ieee80211_configure_filter(local);
3531 break; 3545 break;
3532 default: 3546 default:
3533 break; 3547 break;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 02d91332d7dd..157b20baf752 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,
260 trace_drv_return_void(local); 260 trace_drv_return_void(local);
261} 261}
262 262
263static inline void drv_config_iface_filter(struct ieee80211_local *local,
264 struct ieee80211_sub_if_data *sdata,
265 unsigned int filter_flags,
266 unsigned int changed_flags)
267{
268 might_sleep();
269
270 trace_drv_config_iface_filter(local, sdata, filter_flags,
271 changed_flags);
272 if (local->ops->config_iface_filter)
273 local->ops->config_iface_filter(&local->hw, &sdata->vif,
274 filter_flags,
275 changed_flags);
276 trace_drv_return_void(local);
277}
278
263static inline int drv_set_tim(struct ieee80211_local *local, 279static inline int drv_set_tim(struct ieee80211_local *local,
264 struct ieee80211_sta *sta, bool set) 280 struct ieee80211_sta *sta, bool set)
265{ 281{
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 6f14591d8ca9..b5960b948f60 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -497,6 +497,36 @@ TRACE_EVENT(drv_configure_filter,
497 ) 497 )
498); 498);
499 499
500TRACE_EVENT(drv_config_iface_filter,
501 TP_PROTO(struct ieee80211_local *local,
502 struct ieee80211_sub_if_data *sdata,
503 unsigned int filter_flags,
504 unsigned int changed_flags),
505
506 TP_ARGS(local, sdata, filter_flags, changed_flags),
507
508 TP_STRUCT__entry(
509 LOCAL_ENTRY
510 VIF_ENTRY
511 __field(unsigned int, filter_flags)
512 __field(unsigned int, changed_flags)
513 ),
514
515 TP_fast_assign(
516 LOCAL_ASSIGN;
517 VIF_ASSIGN;
518 __entry->filter_flags = filter_flags;
519 __entry->changed_flags = changed_flags;
520 ),
521
522 TP_printk(
523 LOCAL_PR_FMT VIF_PR_FMT
524 " filter_flags: %#x changed_flags: %#x",
525 LOCAL_PR_ARG, VIF_PR_ARG, __entry->filter_flags,
526 __entry->changed_flags
527 )
528);
529
500TRACE_EVENT(drv_set_tim, 530TRACE_EVENT(drv_set_tim,
501 TP_PROTO(struct ieee80211_local *local, 531 TP_PROTO(struct ieee80211_local *local,
502 struct ieee80211_sta *sta, bool set), 532 struct ieee80211_sta *sta, bool set),