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