aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--net/wireless/chan.c9
-rw-r--r--net/wireless/core.c48
-rw-r--r--net/wireless/core.h3
4 files changed, 2 insertions, 62 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8115d68eb60..0245208c297 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1504,8 +1504,6 @@ struct cfg80211_gtk_rekey_data {
1504 * interfaces are active this callback should reject the configuration. 1504 * interfaces are active this callback should reject the configuration.
1505 * If no interfaces are active or the device is down, the channel should 1505 * If no interfaces are active or the device is down, the channel should
1506 * be stored for when a monitor interface becomes active. 1506 * be stored for when a monitor interface becomes active.
1507 * @set_monitor_enabled: Notify driver that there are only monitor
1508 * interfaces running.
1509 * 1507 *
1510 * @scan: Request to do a scan. If returning zero, the scan request is given 1508 * @scan: Request to do a scan. If returning zero, the scan request is given
1511 * the driver, and will be valid until passed to cfg80211_scan_done(). 1509 * the driver, and will be valid until passed to cfg80211_scan_done().
@@ -1824,8 +1822,6 @@ struct cfg80211_ops {
1824 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, 1822 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
1825 u32 sset, u8 *data); 1823 u32 sset, u8 *data);
1826 1824
1827 void (*set_monitor_enabled)(struct wiphy *wiphy, bool enabled);
1828
1829 struct ieee80211_channel * 1825 struct ieee80211_channel *
1830 (*get_channel)(struct wiphy *wiphy, 1826 (*get_channel)(struct wiphy *wiphy,
1831 struct wireless_dev *wdev, 1827 struct wireless_dev *wdev,
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index a16cdffb24a..d355f67d0cd 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 0557bb15902..71b684b5a67 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 bac97da751d..5206c6844fd 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;