--- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -139,26 +139,34 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1, } EXPORT_SYMBOL(cfg80211_chandef_compatible); -static bool cfg80211_check_beacon_chans(struct wiphy *wiphy, - u32 center_freq, u32 bw) +bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, + u32 center_freq, u32 bandwidth, + u32 prohibited_flags) { struct ieee80211_channel *c; u32 freq; - for (freq = center_freq - bw/2 + 10; - freq <= center_freq + bw/2 - 10; + for (freq = center_freq - bandwidth/2 + 10; + freq <= center_freq + bandwidth/2 - 10; freq += 20) { c = ieee80211_get_channel(wiphy, freq); - if (!c || c->flags & (IEEE80211_CHAN_DISABLED | - IEEE80211_CHAN_PASSIVE_SCAN | - IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR)) + if (!c || c->flags & prohibited_flags) return false; } return true; } +static bool cfg80211_check_beacon_chans(struct wiphy *wiphy, + u32 center_freq, u32 bw) +{ + return cfg80211_secondary_chans_ok(wiphy, center_freq, bw, + IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_PASSIVE_SCAN | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_RADAR); +} + bool cfg80211_reg_can_beacon(struct wiphy *wiphy, struct cfg80211_chan_def *chandef) { --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -485,6 +485,10 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef); +bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, + u32 center_freq, u32 bandwidth, + u32 prohibited_flags); + #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1365,23 +1365,6 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) wdev->iftype == NL80211_IFTYPE_P2P_GO; } -static int nl80211_check_sec_chans(struct cfg80211_registered_device *rdev, - u32 center_freq, u32 bw) -{ - struct ieee80211_channel *c; - u32 freq; - - for (freq = center_freq - bw/2 + 10; - freq <= center_freq + bw/2 - 10; - freq += 20) { - c = ieee80211_get_channel(&rdev->wiphy, freq); - if (!c || c->flags & IEEE80211_CHAN_DISABLED) - return -EINVAL; - } - - return 0; -} - static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, struct genl_info *info, struct cfg80211_chan_def *chandef) @@ -1485,10 +1468,12 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, return -EINVAL; } - if (nl80211_check_sec_chans(rdev, chandef->center_freq1, width)) + if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1, + width, IEEE80211_CHAN_DISABLED)) return -EINVAL; if (chandef->center_freq2 && - nl80211_check_sec_chans(rdev, chandef->center_freq2, width)) + !cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2, + width, IEEE80211_CHAN_DISABLED)) return -EINVAL; /* TODO: missing regulatory check on bandwidth */