diff options
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 16 |
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 | ||
2993 | static 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 |
2994 | static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) | 3004 | static 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, | |||
1485 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | 1485 | int 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 */ | ||
1489 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local); | ||
1490 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local); | ||
1491 | |||
1488 | /* channel management */ | 1492 | /* channel management */ |
1489 | enum ieee80211_chan_mode { | 1493 | enum 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 | ||
333 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 333 | int 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 | ||
374 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 374 | void 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 | ||
825 | static int ieee80211_stop(struct net_device *dev) | 813 | static int ieee80211_stop(struct net_device *dev) |