mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
cfg80211: allow beaconing after DFS CAC
Allow beconing after we pass Channel Availability Check (CAC). Allow non-DFS and DFS channels mix. All DFS channels have to be in NL80211_DFS_AVAILABLE state (pass CAC). Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
d2859df5e7
commit
6bc54fbcee
@ -425,6 +425,72 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
|
||||
static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
|
||||
u32 center_freq,
|
||||
u32 bandwidth)
|
||||
{
|
||||
struct ieee80211_channel *c;
|
||||
u32 freq, start_freq, end_freq;
|
||||
|
||||
start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
|
||||
end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
|
||||
|
||||
/*
|
||||
* Check entire range of channels for the bandwidth.
|
||||
* If any channel in between is disabled or has not
|
||||
* had gone through CAC return false
|
||||
*/
|
||||
for (freq = start_freq; freq <= end_freq; freq += 20) {
|
||||
c = ieee80211_get_channel(wiphy, freq);
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
if (c->flags & IEEE80211_CHAN_DISABLED)
|
||||
return false;
|
||||
|
||||
if ((c->flags & IEEE80211_CHAN_RADAR) &&
|
||||
(c->dfs_state != NL80211_DFS_AVAILABLE))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
int width;
|
||||
int r;
|
||||
|
||||
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
|
||||
return false;
|
||||
|
||||
width = cfg80211_chandef_get_width(chandef);
|
||||
if (width < 0)
|
||||
return false;
|
||||
|
||||
r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1,
|
||||
width);
|
||||
|
||||
/* If any of channels unavailable for cf1 just return */
|
||||
if (!r)
|
||||
return r;
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
WARN_ON(!chandef->center_freq2);
|
||||
r = cfg80211_get_chans_dfs_available(wiphy,
|
||||
chandef->center_freq2,
|
||||
width);
|
||||
default:
|
||||
WARN_ON(chandef->center_freq2);
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
|
||||
u32 center_freq, u32 bandwidth,
|
||||
u32 prohibited_flags)
|
||||
@ -437,16 +503,7 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
|
||||
|
||||
for (freq = start_freq; freq <= end_freq; freq += 20) {
|
||||
c = ieee80211_get_channel(wiphy, freq);
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
/* check for radar flags */
|
||||
if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) &&
|
||||
(c->dfs_state != NL80211_DFS_AVAILABLE))
|
||||
return false;
|
||||
|
||||
/* check for the other flags */
|
||||
if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR)
|
||||
if (!c || c->flags & prohibited_flags)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -552,13 +609,19 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
bool res;
|
||||
u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_RADAR;
|
||||
|
||||
trace_cfg80211_reg_can_beacon(wiphy, chandef);
|
||||
|
||||
res = cfg80211_chandef_usable(wiphy, chandef,
|
||||
IEEE80211_CHAN_DISABLED |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_RADAR);
|
||||
if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
|
||||
cfg80211_chandef_dfs_available(wiphy, chandef)) {
|
||||
/* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
|
||||
prohibited_flags = IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
|
||||
res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
|
||||
|
||||
trace_cfg80211_return_bool(res);
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user