aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-02-27 04:07:21 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-04-09 04:55:47 -0400
commitb6a550156bc08a472c9d2515631649e229fcfcef (patch)
treee47650bdbadff71e05f76c7b8e3a490347efffcd
parent71965c1d04b2b48ab7c56395bd1f996a56aaa592 (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.c9
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/util.c10
-rw-r--r--net/wireless/core.c11
-rw-r--r--net/wireless/core.h22
-rw-r--r--net/wireless/nl80211.c5
-rw-r--r--net/wireless/util.c5
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,
109static int ieee80211_start_p2p_device(struct wiphy *wiphy, 109static 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
306static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, 310static 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
412cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, 412cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
413 const struct cfg80211_chan_def *chandef); 413 const struct cfg80211_chan_def *chandef);
414 414
415static inline int
416cfg80211_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
427static inline int
428cfg80211_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
437static inline unsigned int elapsed_jiffies_msecs(unsigned long start) 415static 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);