diff options
author | Luciano Coelho <luciano.coelho@intel.com> | 2014-02-27 04:07:21 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-04-09 04:55:47 -0400 |
commit | b6a550156bc08a472c9d2515631649e229fcfcef (patch) | |
tree | e47650bdbadff71e05f76c7b8e3a490347efffcd | |
parent | 71965c1d04b2b48ab7c56395bd1f996a56aaa592 (diff) |
cfg80211/mac80211: move more combination checks to mac80211
Get rid of the cfg80211_can_add_interface() and
cfg80211_can_change_interface() functions by moving that functionality
to mac80211. With this patch all interface combination checks are now
out of cfg80211 (except for the channel switch case which will be
addressed in a future commit).
Additionally, modify the ieee80211_check_combinations() function so
that an undefined chandef can be passed, in order to use it before a
channel is defined.
Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/cfg.c | 9 | ||||
-rw-r--r-- | net/mac80211/iface.c | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 10 | ||||
-rw-r--r-- | net/wireless/core.c | 11 | ||||
-rw-r--r-- | net/wireless/core.h | 22 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 5 | ||||
-rw-r--r-- | net/wireless/util.c | 5 |
7 files changed, 26 insertions, 42 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8bf94eaa0456..23d60110aebd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -109,6 +109,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
109 | static int ieee80211_start_p2p_device(struct wiphy *wiphy, | 109 | static int ieee80211_start_p2p_device(struct wiphy *wiphy, |
110 | struct wireless_dev *wdev) | 110 | struct wireless_dev *wdev) |
111 | { | 111 | { |
112 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
113 | int ret; | ||
114 | |||
115 | mutex_lock(&sdata->local->chanctx_mtx); | ||
116 | ret = ieee80211_check_combinations(sdata, NULL, 0, 0); | ||
117 | mutex_unlock(&sdata->local->chanctx_mtx); | ||
118 | if (ret < 0) | ||
119 | return ret; | ||
120 | |||
112 | return ieee80211_do_open(wdev, true); | 121 | return ieee80211_do_open(wdev, true); |
113 | } | 122 | } |
114 | 123 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4826c8f5d0b2..ad5badd783d8 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -250,6 +250,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, | |||
250 | { | 250 | { |
251 | struct ieee80211_local *local = sdata->local; | 251 | struct ieee80211_local *local = sdata->local; |
252 | struct ieee80211_sub_if_data *nsdata; | 252 | struct ieee80211_sub_if_data *nsdata; |
253 | int ret; | ||
253 | 254 | ||
254 | ASSERT_RTNL(); | 255 | ASSERT_RTNL(); |
255 | 256 | ||
@@ -300,7 +301,10 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, | |||
300 | } | 301 | } |
301 | } | 302 | } |
302 | 303 | ||
303 | return 0; | 304 | mutex_lock(&local->chanctx_mtx); |
305 | ret = ieee80211_check_combinations(sdata, NULL, 0, 0); | ||
306 | mutex_unlock(&local->chanctx_mtx); | ||
307 | return ret; | ||
304 | } | 308 | } |
305 | 309 | ||
306 | static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, | 310 | static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 436f98870066..5a6cc3382ae9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2808,7 +2808,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, | |||
2808 | enum nl80211_iftype iftype = sdata->wdev.iftype; | 2808 | enum nl80211_iftype iftype = sdata->wdev.iftype; |
2809 | int num[NUM_NL80211_IFTYPES]; | 2809 | int num[NUM_NL80211_IFTYPES]; |
2810 | struct ieee80211_chanctx *ctx; | 2810 | struct ieee80211_chanctx *ctx; |
2811 | int num_different_channels = 1; | 2811 | int num_different_channels = 0; |
2812 | int total = 1; | 2812 | int total = 1; |
2813 | 2813 | ||
2814 | lockdep_assert_held(&local->chanctx_mtx); | 2814 | lockdep_assert_held(&local->chanctx_mtx); |
@@ -2816,9 +2816,13 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, | |||
2816 | if (WARN_ON(hweight32(radar_detect) > 1)) | 2816 | if (WARN_ON(hweight32(radar_detect) > 1)) |
2817 | return -EINVAL; | 2817 | return -EINVAL; |
2818 | 2818 | ||
2819 | if (WARN_ON(chanmode == IEEE80211_CHANCTX_SHARED && !chandef->chan)) | 2819 | if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED && |
2820 | !chandef->chan)) | ||
2820 | return -EINVAL; | 2821 | return -EINVAL; |
2821 | 2822 | ||
2823 | if (chandef) | ||
2824 | num_different_channels = 1; | ||
2825 | |||
2822 | if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) | 2826 | if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) |
2823 | return -EINVAL; | 2827 | return -EINVAL; |
2824 | 2828 | ||
@@ -2841,7 +2845,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, | |||
2841 | num_different_channels++; | 2845 | num_different_channels++; |
2842 | continue; | 2846 | continue; |
2843 | } | 2847 | } |
2844 | if ((chanmode == IEEE80211_CHANCTX_SHARED) && | 2848 | if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && |
2845 | cfg80211_chandef_compatible(chandef, | 2849 | cfg80211_chandef_compatible(chandef, |
2846 | &ctx->conf.def)) | 2850 | &ctx->conf.def)) |
2847 | continue; | 2851 | continue; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 5a63c3cbda2e..33d12e23771c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -439,10 +439,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) | |||
439 | for (j = 0; j < c->n_limits; j++) { | 439 | for (j = 0; j < c->n_limits; j++) { |
440 | u16 types = c->limits[j].types; | 440 | u16 types = c->limits[j].types; |
441 | 441 | ||
442 | /* | 442 | /* interface types shouldn't overlap */ |
443 | * interface types shouldn't overlap, this is | ||
444 | * used in cfg80211_can_change_interface() | ||
445 | */ | ||
446 | if (WARN_ON(types & all_iftypes)) | 443 | if (WARN_ON(types & all_iftypes)) |
447 | return -EINVAL; | 444 | return -EINVAL; |
448 | all_iftypes |= types; | 445 | all_iftypes |= types; |
@@ -840,7 +837,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
840 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 837 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
841 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 838 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
842 | struct cfg80211_registered_device *rdev; | 839 | struct cfg80211_registered_device *rdev; |
843 | int ret; | ||
844 | 840 | ||
845 | if (!wdev) | 841 | if (!wdev) |
846 | return NOTIFY_DONE; | 842 | return NOTIFY_DONE; |
@@ -1003,9 +999,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
1003 | case NETDEV_PRE_UP: | 999 | case NETDEV_PRE_UP: |
1004 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 1000 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
1005 | return notifier_from_errno(-EOPNOTSUPP); | 1001 | return notifier_from_errno(-EOPNOTSUPP); |
1006 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); | 1002 | if (rfkill_blocked(rdev->rfkill)) |
1007 | if (ret) | 1003 | return notifier_from_errno(-ERFKILL); |
1008 | return notifier_from_errno(ret); | ||
1009 | break; | 1004 | break; |
1010 | } | 1005 | } |
1011 | 1006 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index 6684c5d965d8..5bee6cc94b21 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -412,28 +412,6 @@ unsigned int | |||
412 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, | 412 | cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, |
413 | const struct cfg80211_chan_def *chandef); | 413 | const struct cfg80211_chan_def *chandef); |
414 | 414 | ||
415 | static inline int | ||
416 | cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | ||
417 | struct wireless_dev *wdev, | ||
418 | enum nl80211_iftype iftype) | ||
419 | { | ||
420 | /* TODO: For this function, we'll probably need to keep some | ||
421 | * kind of interface combination check in cfg80211... | ||
422 | */ | ||
423 | return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL, | ||
424 | CHAN_MODE_UNDEFINED, 0); | ||
425 | } | ||
426 | |||
427 | static inline int | ||
428 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, | ||
429 | enum nl80211_iftype iftype) | ||
430 | { | ||
431 | if (rfkill_blocked(rdev->rfkill)) | ||
432 | return -ERFKILL; | ||
433 | |||
434 | return cfg80211_can_change_interface(rdev, NULL, iftype); | ||
435 | } | ||
436 | |||
437 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start) | 415 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start) |
438 | { | 416 | { |
439 | unsigned long end = jiffies; | 417 | unsigned long end = jiffies; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2b99aad33ae0..232d15c0ac6e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -8969,9 +8969,8 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) | |||
8969 | if (wdev->p2p_started) | 8969 | if (wdev->p2p_started) |
8970 | return 0; | 8970 | return 0; |
8971 | 8971 | ||
8972 | err = cfg80211_can_add_interface(rdev, wdev->iftype); | 8972 | if (rfkill_blocked(rdev->rfkill)) |
8973 | if (err) | 8973 | return -ERFKILL; |
8974 | return err; | ||
8975 | 8974 | ||
8976 | err = rdev_start_p2p_device(rdev, wdev); | 8975 | err = rdev_start_p2p_device(rdev, wdev); |
8977 | if (err) | 8976 | if (err) |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 9bfc4c621509..5433659a08ee 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -888,11 +888,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
888 | return -EBUSY; | 888 | return -EBUSY; |
889 | 889 | ||
890 | if (ntype != otype && netif_running(dev)) { | 890 | if (ntype != otype && netif_running(dev)) { |
891 | err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, | ||
892 | ntype); | ||
893 | if (err) | ||
894 | return err; | ||
895 | |||
896 | dev->ieee80211_ptr->use_4addr = false; | 891 | dev->ieee80211_ptr->use_4addr = false; |
897 | dev->ieee80211_ptr->mesh_id_up_len = 0; | 892 | dev->ieee80211_ptr->mesh_id_up_len = 0; |
898 | wdev_lock(dev->ieee80211_ptr); | 893 | wdev_lock(dev->ieee80211_ptr); |