[RFC 2/4] hostapd: DFS: allow skipping radar channels

Janusz Dziedzic janusz.dziedzic at tieto.com
Sat Nov 23 02:12:27 EST 2013


From: Michal Kazior <michal.kazior at tieto.com>

This is needed for AP CSA. Since CSA must happen
immediately after radar is detected there's no
time to perform CAC. Thus radar channels must be
disabled when looking for a new channel to escape
to after radar is detected.

Signed-hostap: Michal Kazior <michal.kazior at tieto.com>
---
 src/ap/dfs.c |   32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 0a909f4..b331c81 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -44,8 +44,15 @@ static int dfs_get_used_n_chans(struct hostapd_iface *iface)
 }
 
 
-static int dfs_channel_available(struct hostapd_channel_data *chan)
+static int dfs_channel_available(struct hostapd_channel_data *chan,
+				 int skip_radar)
 {
+	/* When radar detection happens CSA is performed. However there's no
+	 * time for CAC so radar channels must be skipped when finding a new
+	 * channel for CSA. */
+	if (skip_radar && chan->flag & HOSTAPD_CHAN_RADAR)
+		return 0;
+
 	if (chan->flag & HOSTAPD_CHAN_DISABLED)
 		return 0;
 	if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
@@ -96,7 +103,8 @@ static int dfs_is_chan_allowed(struct hostapd_channel_data *chan, int n_chans)
 
 
 static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
-				    int first_chan_idx, int num_chans)
+				    int first_chan_idx, int num_chans,
+				    int skip_radar)
 {
 	struct hostapd_channel_data *first_chan, *chan;
 	int i;
@@ -112,7 +120,7 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
 		if (first_chan->freq + i * 20 != chan->freq)
 			return 0;
 
-		if (!dfs_channel_available(chan))
+		if (!dfs_channel_available(chan, skip_radar))
 			return 0;
 	}
 
@@ -129,7 +137,7 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
  */
 static int dfs_find_channel(struct hostapd_iface *iface,
 			    struct hostapd_channel_data **ret_chan,
-			    int idx)
+			    int idx, int skip_radar)
 {
 	struct hostapd_hw_modes *mode;
 	struct hostapd_channel_data *chan;
@@ -149,7 +157,7 @@ static int dfs_find_channel(struct hostapd_iface *iface,
 			continue;
 
 		/* Skip incompatible chandefs */
-		if (!dfs_chan_range_available(mode, i, n_chans))
+		if (!dfs_chan_range_available(mode, i, n_chans, skip_radar))
 			continue;
 
 		if (ret_chan && idx == channel_idx) {
@@ -322,7 +330,8 @@ static struct hostapd_channel_data *
 dfs_get_valid_channel(struct hostapd_iface *iface,
 		      int *secondary_channel,
 		      u8 *vht_oper_centr_freq_seg0_idx,
-		      u8 *vht_oper_centr_freq_seg1_idx)
+		      u8 *vht_oper_centr_freq_seg1_idx,
+		      int skip_radar)
 {
 	struct hostapd_hw_modes *mode;
 	struct hostapd_channel_data *chan = NULL;
@@ -340,13 +349,13 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
 		return NULL;
 
 	/* Get the count first */
-	num_available_chandefs = dfs_find_channel(iface, NULL, 0);
+	num_available_chandefs = dfs_find_channel(iface, NULL, 0, skip_radar);
 	if (num_available_chandefs == 0)
 		return NULL;
 
 	os_get_random((u8 *) &_rand, sizeof(_rand));
 	chan_idx = _rand % num_available_chandefs;
-	dfs_find_channel(iface, &chan, chan_idx);
+	dfs_find_channel(iface, &chan, chan_idx, skip_radar);
 
 	/* dfs_find_channel() calculations assume HT40+ */
 	if (iface->conf->secondary_channel)
@@ -518,6 +527,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
 {
 	struct hostapd_channel_data *channel;
 	int res, n_chans, start_chan_idx;
+	int skip_radar = 0;
 
 	iface->cac_started = 0;
 
@@ -555,7 +565,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
 			int sec;
 			u8 cf1, cf2;
 
-			channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2);
+			channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, skip_radar);
 			if (!channel) {
 				wpa_printf(MSG_ERROR, "could not get valid channel");
 				return -1;
@@ -621,11 +631,13 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 	int secondary_channel;
 	u8 vht_oper_centr_freq_seg0_idx;
 	u8 vht_oper_centr_freq_seg1_idx;
+	int skip_radar = 1;
 
 	wpa_printf(MSG_DEBUG, "%s called", __func__);
 	channel = dfs_get_valid_channel(iface, &secondary_channel,
 					&vht_oper_centr_freq_seg0_idx,
-					&vht_oper_centr_freq_seg1_idx);
+					&vht_oper_centr_freq_seg1_idx,
+					skip_radar);
 	if (channel) {
 		wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
 			   channel->chan);
-- 
1.7.9.5



More information about the HostAP mailing list