@ -425,9 +425,9 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
}
static bool cfg80211_secondary_chans_ok ( struct wiphy * wiphy ,
u32 center_freq , u32 bandwidth ,
u32 prohibited_flags )
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 ;
@ -435,18 +435,75 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
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 ;
/* check for radar flags */
if ( ( prohibited_flags & c - > flags & IEEE80211_CHAN_RADAR ) & &
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 )
{
struct ieee80211_channel * c ;
u32 freq , start_freq , end_freq ;
/* check for the other flags */
if ( c - > flags & prohibited_flags & ~ IEEE80211_CHAN_RADAR )
start_freq = cfg80211_get_start_freq ( center_freq , bandwidth ) ;
end_freq = cfg80211_get_end_freq ( center_freq , bandwidth ) ;
for ( freq = start_freq ; freq < = end_freq ; freq + = 20 ) {
c = ieee80211_get_channel ( wiphy , freq ) ;
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 ;