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/chan.c | |
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/chan.c')
-rw-r--r-- | net/wireless/chan.c | 74 |
1 files changed, 56 insertions, 18 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; |