aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c11
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c16
3 files changed, 17 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 0f02c8b77e1c..ea4b1ea9105a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2990,6 +2990,16 @@ ieee80211_wiphy_get_channel(struct wiphy *wiphy,
2990 return local->oper_channel; 2990 return local->oper_channel;
2991} 2991}
2992 2992
2993static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled)
2994{
2995 struct ieee80211_local *local = wiphy_priv(wiphy);
2996
2997 if (enabled)
2998 WARN_ON(ieee80211_add_virtual_monitor(local));
2999 else
3000 ieee80211_del_virtual_monitor(local);
3001}
3002
2993#ifdef CONFIG_PM 3003#ifdef CONFIG_PM
2994static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) 3004static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled)
2995{ 3005{
@@ -3065,6 +3075,7 @@ struct cfg80211_ops mac80211_config_ops = {
3065 .probe_client = ieee80211_probe_client, 3075 .probe_client = ieee80211_probe_client,
3066 .get_channel = ieee80211_wiphy_get_channel, 3076 .get_channel = ieee80211_wiphy_get_channel,
3067 .set_noack_map = ieee80211_set_noack_map, 3077 .set_noack_map = ieee80211_set_noack_map,
3078 .set_monitor_enabled = ieee80211_set_monitor_enabled,
3068#ifdef CONFIG_PM 3079#ifdef CONFIG_PM
3069 .set_wakeup = ieee80211_set_wakeup, 3080 .set_wakeup = ieee80211_set_wakeup,
3070#endif 3081#endif
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6b7157d20507..b88bdfd248ff 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1485,6 +1485,10 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1485int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, 1485int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1486 struct sk_buff *skb, bool need_basic); 1486 struct sk_buff *skb, bool need_basic);
1487 1487
1488/* virtual monitor */
1489int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
1490void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
1491
1488/* channel management */ 1492/* channel management */
1489enum ieee80211_chan_mode { 1493enum ieee80211_chan_mode {
1490 CHAN_MODE_UNDEFINED, 1494 CHAN_MODE_UNDEFINED,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0a6b4e1043cb..fbef7a1ada7a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -330,7 +330,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
330 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 330 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
331} 331}
332 332
333static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 333int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
334{ 334{
335 struct ieee80211_sub_if_data *sdata; 335 struct ieee80211_sub_if_data *sdata;
336 int ret; 336 int ret;
@@ -371,7 +371,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
371 return 0; 371 return 0;
372} 372}
373 373
374static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 374void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
375{ 375{
376 struct ieee80211_sub_if_data *sdata; 376 struct ieee80211_sub_if_data *sdata;
377 377
@@ -487,12 +487,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
487 break; 487 break;
488 } 488 }
489 489
490 if (local->monitors == 0 && local->open_count == 0) {
491 res = ieee80211_add_virtual_monitor(local);
492 if (res)
493 goto err_stop;
494 }
495
496 /* must be before the call to ieee80211_configure_filter */ 490 /* must be before the call to ieee80211_configure_filter */
497 local->monitors++; 491 local->monitors++;
498 if (local->monitors == 1) { 492 if (local->monitors == 1) {
@@ -507,8 +501,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
507 break; 501 break;
508 default: 502 default:
509 if (coming_up) { 503 if (coming_up) {
510 ieee80211_del_virtual_monitor(local);
511
512 res = drv_add_interface(local, sdata); 504 res = drv_add_interface(local, sdata);
513 if (res) 505 if (res)
514 goto err_stop; 506 goto err_stop;
@@ -743,7 +735,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
743 if (local->monitors == 0) { 735 if (local->monitors == 0) {
744 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; 736 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
745 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 737 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
746 ieee80211_del_virtual_monitor(local);
747 } 738 }
748 739
749 ieee80211_adjust_monitor_flags(sdata, -1); 740 ieee80211_adjust_monitor_flags(sdata, -1);
@@ -817,9 +808,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
817 } 808 }
818 } 809 }
819 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 810 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
820
821 if (local->monitors == local->open_count && local->monitors > 0)
822 ieee80211_add_virtual_monitor(local);
823} 811}
824 812
825static int ieee80211_stop(struct net_device *dev) 813static int ieee80211_stop(struct net_device *dev)