diff options
author | Luciano Coelho <luciano.coelho@intel.com> | 2014-02-18 04:40:36 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-04-09 04:55:41 -0400 |
commit | 2beb6dab2d799ee8934cb0801845e551ad8c70f2 (patch) | |
tree | 58261561098a2bc3aaf747041382324119b00128 /net/wireless | |
parent | cb2d956dd329caa11b5ece454dc52253aa038e73 (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.c | 74 | ||||
-rw-r--r-- | net/wireless/mesh.c | 7 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 37 |
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 | ||
328 | int cfg80211_chandef_dfs_required(struct wiphy *wiphy, | 328 | int 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 | } |
352 | EXPORT_SYMBOL(cfg80211_chandef_dfs_required); | 381 | EXPORT_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, ¶ms.chandef); | 3278 | err = cfg80211_chandef_dfs_required(wdev->wiphy, |
3279 | ¶ms.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 | ¶ms.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 | ¶ms.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, |