aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-12 16:19:48 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-13 10:16:11 -0400
commit4290cb4bf212112e3d6f860e25f000ca8a1ca6a4 (patch)
treeb6dda8955a4e199c318860ffa01dc9b2ea417905 /net/wireless
parent5b7ccaf3fc7446e42b83a77fd7aa7ad92850acdd (diff)
cfg80211: reduce monitor interface tracking
Revert commit b78e8ceac23655e1e06b30aa95ab11742d1ac7c0 ("cfg80211: track monitor channel") and remove the set_monitor_enabled() callback. Due to the tracking happening in NETDEV_PRE_UP, it had introduced bugs because the monitor interface callback would be called before the device was started. It looks like there's no way to fix this, and using NETDEV_PRE_UP is broken anyway (since there's no NETDEV_UP_FAIL), so remove all that code, track interfaces in NETDEV_UP and also stop tracking the monitor channel in cfg80211. This mostly reverts to before the tracking, except that we keep the interface count tracking so that setting the monitor channel can be rejected properly. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c9
-rw-r--r--net/wireless/core.c48
-rw-r--r--net/wireless/core.h3
3 files changed, 2 insertions, 58 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index a16cdffb24a9..d355f67d0cdd 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -82,7 +82,6 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
82 int freq, enum nl80211_channel_type chantype) 82 int freq, enum nl80211_channel_type chantype)
83{ 83{
84 struct ieee80211_channel *chan; 84 struct ieee80211_channel *chan;
85 int err;
86 85
87 if (!rdev->ops->set_monitor_channel) 86 if (!rdev->ops->set_monitor_channel)
88 return -EOPNOTSUPP; 87 return -EOPNOTSUPP;
@@ -93,13 +92,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
93 if (!chan) 92 if (!chan)
94 return -EINVAL; 93 return -EINVAL;
95 94
96 err = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); 95 return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype);
97 if (!err) {
98 rdev->monitor_channel = chan;
99 rdev->monitor_channel_type = chantype;
100 }
101
102 return err;
103} 96}
104 97
105void 98void
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 0557bb159025..71b684b5a675 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -736,60 +736,14 @@ static struct device_type wiphy_type = {
736 .name = "wlan", 736 .name = "wlan",
737}; 737};
738 738
739static struct ieee80211_channel *
740cfg80211_get_any_chan(struct cfg80211_registered_device *rdev)
741{
742 struct ieee80211_supported_band *sband;
743 int i;
744
745 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
746 sband = rdev->wiphy.bands[i];
747 if (sband && sband->n_channels > 0)
748 return &sband->channels[0];
749 }
750
751 return NULL;
752}
753
754static void cfg80211_init_mon_chan(struct cfg80211_registered_device *rdev)
755{
756 struct ieee80211_channel *chan;
757
758 chan = cfg80211_get_any_chan(rdev);
759 if (WARN_ON(!chan))
760 return;
761
762 mutex_lock(&rdev->devlist_mtx);
763 WARN_ON(cfg80211_set_monitor_channel(rdev, chan->center_freq,
764 NL80211_CHAN_NO_HT));
765 mutex_unlock(&rdev->devlist_mtx);
766}
767
768void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 739void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
769 enum nl80211_iftype iftype, int num) 740 enum nl80211_iftype iftype, int num)
770{ 741{
771 bool has_monitors_only_old = cfg80211_has_monitors_only(rdev);
772 bool has_monitors_only_new;
773
774 ASSERT_RTNL(); 742 ASSERT_RTNL();
775 743
776 rdev->num_running_ifaces += num; 744 rdev->num_running_ifaces += num;
777 if (iftype == NL80211_IFTYPE_MONITOR) 745 if (iftype == NL80211_IFTYPE_MONITOR)
778 rdev->num_running_monitor_ifaces += num; 746 rdev->num_running_monitor_ifaces += num;
779
780 has_monitors_only_new = cfg80211_has_monitors_only(rdev);
781 if (has_monitors_only_new != has_monitors_only_old) {
782 if (rdev->ops->set_monitor_enabled)
783 rdev->ops->set_monitor_enabled(&rdev->wiphy,
784 has_monitors_only_new);
785
786 if (!has_monitors_only_new) {
787 rdev->monitor_channel = NULL;
788 rdev->monitor_channel_type = NL80211_CHAN_NO_HT;
789 } else {
790 cfg80211_init_mon_chan(rdev);
791 }
792 }
793} 747}
794 748
795static int cfg80211_netdev_notifier_call(struct notifier_block *nb, 749static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
@@ -912,6 +866,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
912 mutex_unlock(&rdev->devlist_mtx); 866 mutex_unlock(&rdev->devlist_mtx);
913 dev_put(dev); 867 dev_put(dev);
914 } 868 }
869 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
915 cfg80211_lock_rdev(rdev); 870 cfg80211_lock_rdev(rdev);
916 mutex_lock(&rdev->devlist_mtx); 871 mutex_lock(&rdev->devlist_mtx);
917 wdev_lock(wdev); 872 wdev_lock(wdev);
@@ -1006,7 +961,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1006 mutex_unlock(&rdev->devlist_mtx); 961 mutex_unlock(&rdev->devlist_mtx);
1007 if (ret) 962 if (ret)
1008 return notifier_from_errno(ret); 963 return notifier_from_errno(ret);
1009 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
1010 break; 964 break;
1011 } 965 }
1012 966
diff --git a/net/wireless/core.h b/net/wireless/core.h
index bac97da751df..5206c6844fd7 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -61,9 +61,6 @@ struct cfg80211_registered_device {
61 int num_running_ifaces; 61 int num_running_ifaces;
62 int num_running_monitor_ifaces; 62 int num_running_monitor_ifaces;
63 63
64 struct ieee80211_channel *monitor_channel;
65 enum nl80211_channel_type monitor_channel_type;
66
67 /* BSSes/scanning */ 64 /* BSSes/scanning */
68 spinlock_t bss_lock; 65 spinlock_t bss_lock;
69 struct list_head bss_list; 66 struct list_head bss_list;