aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-02-18 04:40:36 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-04-09 04:55:41 -0400
commit2beb6dab2d799ee8934cb0801845e551ad8c70f2 (patch)
tree58261561098a2bc3aaf747041382324119b00128 /net/wireless
parentcb2d956dd329caa11b5ece454dc52253aa038e73 (diff)
cfg80211/mac80211: refactor cfg80211_chandef_dfs_required()
Some interface types don't require DFS (such as STATION, P2P_CLIENT etc). In order to centralize these decisions, make cfg80211_chandef_dfs_required() take the iftype into consideration. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c74
-rw-r--r--net/wireless/mesh.c7
-rw-r--r--net/wireless/nl80211.c37
3 files changed, 78 insertions, 40 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index c3180dc03a33..c61bcdd3dfbc 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -326,28 +326,57 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
326 326
327 327
328int cfg80211_chandef_dfs_required(struct wiphy *wiphy, 328int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
329 const struct cfg80211_chan_def *chandef) 329 const struct cfg80211_chan_def *chandef,
330 enum nl80211_iftype iftype)
330{ 331{
331 int width; 332 int width;
332 int r; 333 int ret;
333 334
334 if (WARN_ON(!cfg80211_chandef_valid(chandef))) 335 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
335 return -EINVAL; 336 return -EINVAL;
336 337
337 width = cfg80211_chandef_get_width(chandef); 338 switch (iftype) {
338 if (width < 0) 339 case NL80211_IFTYPE_ADHOC:
339 return -EINVAL; 340 case NL80211_IFTYPE_AP:
341 case NL80211_IFTYPE_P2P_GO:
342 case NL80211_IFTYPE_MESH_POINT:
343 width = cfg80211_chandef_get_width(chandef);
344 if (width < 0)
345 return -EINVAL;
340 346
341 r = cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq1, 347 ret = cfg80211_get_chans_dfs_required(wiphy,
342 width); 348 chandef->center_freq1,
343 if (r) 349 width);
344 return r; 350 if (ret < 0)
351 return ret;
352 else if (ret > 0)
353 return BIT(chandef->width);
345 354
346 if (!chandef->center_freq2) 355 if (!chandef->center_freq2)
347 return 0; 356 return 0;
357
358 ret = cfg80211_get_chans_dfs_required(wiphy,
359 chandef->center_freq2,
360 width);
361 if (ret < 0)
362 return ret;
363 else if (ret > 0)
364 return BIT(chandef->width);
348 365
349 return cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq2, 366 break;
350 width); 367 case NL80211_IFTYPE_STATION:
368 case NL80211_IFTYPE_P2P_CLIENT:
369 case NL80211_IFTYPE_MONITOR:
370 case NL80211_IFTYPE_AP_VLAN:
371 case NL80211_IFTYPE_WDS:
372 case NL80211_IFTYPE_P2P_DEVICE:
373 case NL80211_IFTYPE_UNSPECIFIED:
374 break;
375 case NUM_NL80211_IFTYPES:
376 WARN_ON(1);
377 }
378
379 return 0;
351} 380}
352EXPORT_SYMBOL(cfg80211_chandef_dfs_required); 381EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
353 382
@@ -749,7 +778,8 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
749 !cfg80211_go_permissive_chan(rdev, chandef->chan)) 778 !cfg80211_go_permissive_chan(rdev, chandef->chan))
750 prohibited_flags |= IEEE80211_CHAN_NO_IR; 779 prohibited_flags |= IEEE80211_CHAN_NO_IR;
751 780
752 if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 && 781 if (cfg80211_chandef_dfs_required(wiphy, chandef,
782 NL80211_IFTYPE_UNSPECIFIED) > 0 &&
753 cfg80211_chandef_dfs_available(wiphy, chandef)) { 783 cfg80211_chandef_dfs_available(wiphy, chandef)) {
754 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ 784 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
755 prohibited_flags = IEEE80211_CHAN_DISABLED; 785 prohibited_flags = IEEE80211_CHAN_DISABLED;
@@ -779,6 +809,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
779 enum cfg80211_chan_mode *chanmode, 809 enum cfg80211_chan_mode *chanmode,
780 u8 *radar_detect) 810 u8 *radar_detect)
781{ 811{
812 int ret;
813
782 *chan = NULL; 814 *chan = NULL;
783 *chanmode = CHAN_MODE_UNDEFINED; 815 *chanmode = CHAN_MODE_UNDEFINED;
784 816
@@ -821,8 +853,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
821 *chan = wdev->chandef.chan; 853 *chan = wdev->chandef.chan;
822 *chanmode = CHAN_MODE_SHARED; 854 *chanmode = CHAN_MODE_SHARED;
823 855
824 if (cfg80211_chandef_dfs_required(wdev->wiphy, 856 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
825 &wdev->chandef)) 857 &wdev->chandef,
858 wdev->iftype);
859 WARN_ON(ret < 0);
860 if (ret > 0)
826 *radar_detect |= BIT(wdev->chandef.width); 861 *radar_detect |= BIT(wdev->chandef.width);
827 } 862 }
828 return; 863 return;
@@ -831,8 +866,11 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
831 *chan = wdev->chandef.chan; 866 *chan = wdev->chandef.chan;
832 *chanmode = CHAN_MODE_SHARED; 867 *chanmode = CHAN_MODE_SHARED;
833 868
834 if (cfg80211_chandef_dfs_required(wdev->wiphy, 869 ret = cfg80211_chandef_dfs_required(wdev->wiphy,
835 &wdev->chandef)) 870 &wdev->chandef,
871 wdev->iftype);
872 WARN_ON(ret < 0);
873 if (ret > 0)
836 *radar_detect |= BIT(wdev->chandef.width); 874 *radar_detect |= BIT(wdev->chandef.width);
837 } 875 }
838 return; 876 return;
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 7031ee0afad8..6ebe883653a4 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -179,10 +179,13 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
179 NL80211_IFTYPE_MESH_POINT)) 179 NL80211_IFTYPE_MESH_POINT))
180 return -EINVAL; 180 return -EINVAL;
181 181
182 err = cfg80211_chandef_dfs_required(wdev->wiphy, &setup->chandef); 182 err = cfg80211_chandef_dfs_required(wdev->wiphy,
183 &setup->chandef,
184 NL80211_IFTYPE_MESH_POINT);
183 if (err < 0) 185 if (err < 0)
184 return err; 186 return err;
185 if (err) 187
188 if (err > 0)
186 radar_detect_width = BIT(setup->chandef.width); 189 radar_detect_width = BIT(setup->chandef.width);
187 190
188 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 191 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 85bc830fd7e3..4f82b9b71db1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3275,12 +3275,15 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3275 wdev->iftype)) 3275 wdev->iftype))
3276 return -EINVAL; 3276 return -EINVAL;
3277 3277
3278 err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef); 3278 err = cfg80211_chandef_dfs_required(wdev->wiphy,
3279 &params.chandef,
3280 NL80211_IFTYPE_AP);
3279 if (err < 0) 3281 if (err < 0)
3280 return err; 3282 return err;
3281 if (err) { 3283
3282 radar_detect_width = BIT(params.chandef.width); 3284 if (err > 0) {
3283 params.radar_required = true; 3285 params.radar_required = true;
3286 radar_detect_width = BIT(params.chandef.width);
3284 } 3287 }
3285 3288
3286 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 3289 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
@@ -5806,7 +5809,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5806 if (wdev->cac_started) 5809 if (wdev->cac_started)
5807 return -EBUSY; 5810 return -EBUSY;
5808 5811
5809 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef); 5812 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
5813 NL80211_IFTYPE_UNSPECIFIED);
5810 if (err < 0) 5814 if (err < 0)
5811 return err; 5815 return err;
5812 5816
@@ -5942,22 +5946,15 @@ skip_beacons:
5942 wdev->iftype)) 5946 wdev->iftype))
5943 return -EINVAL; 5947 return -EINVAL;
5944 5948
5945 switch (dev->ieee80211_ptr->iftype) { 5949 err = cfg80211_chandef_dfs_required(wdev->wiphy,
5946 case NL80211_IFTYPE_AP: 5950 &params.chandef,
5947 case NL80211_IFTYPE_P2P_GO: 5951 wdev->iftype);
5948 case NL80211_IFTYPE_ADHOC: 5952 if (err < 0)
5949 case NL80211_IFTYPE_MESH_POINT: 5953 return err;
5950 err = cfg80211_chandef_dfs_required(wdev->wiphy, 5954
5951 &params.chandef); 5955 if (err > 0) {
5952 if (err < 0) 5956 radar_detect_width = BIT(params.chandef.width);
5953 return err; 5957 params.radar_required = true;
5954 if (err) {
5955 radar_detect_width = BIT(params.chandef.width);
5956 params.radar_required = true;
5957 }
5958 break;
5959 default:
5960 break;
5961 } 5958 }
5962 5959
5963 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5960 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,