[PATCH v2 3/5] DFS: introduce hostapd_dfs_request_channel_switch routine

Lorenzo Bianconi lorenzo at kernel.org
Sun Mar 6 11:34:12 PST 2022


This is a preliminary patch to add Channel Switch Announcement for
background radar detection.

Tested-by: Owen Peng <owen.peng at mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 src/ap/dfs.c | 162 +++++++++++++++++++++++++++------------------------
 1 file changed, 87 insertions(+), 75 deletions(-)

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 29c3bb4b3..049ab3525 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -930,6 +930,86 @@ int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
 	return dfs_check_chans_available(iface, start_chan_idx, n_chans);
 }
 
+static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
+					      int channel, int freq,
+					      int secondary_channel,
+					      u8 current_vht_oper_chwidth,
+					      u8 oper_centr_freq_seg0_idx,
+					      u8 oper_centr_freq_seg1_idx)
+{
+	struct hostapd_hw_modes *cmode = iface->current_mode;
+	int ieee80211_mode = IEEE80211_MODE_AP, err;
+	struct csa_settings csa_settings;
+	u8 new_vht_oper_chwidth;
+	unsigned int i;
+
+	wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel);
+	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
+		"freq=%d chan=%d sec_chan=%d", freq, channel,
+		secondary_channel);
+
+	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+	hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
+
+	/* Setup CSA request */
+	os_memset(&csa_settings, 0, sizeof(csa_settings));
+	csa_settings.cs_count = 5;
+	csa_settings.block_tx = 1;
+#ifdef CONFIG_MESH
+	if (iface->mconf)
+		ieee80211_mode = IEEE80211_MODE_MESH;
+#endif /* CONFIG_MESH */
+	err = hostapd_set_freq_params(&csa_settings.freq_params,
+				      iface->conf->hw_mode,
+				      freq, channel,
+				      iface->conf->enable_edmg,
+				      iface->conf->edmg_channel,
+				      iface->conf->ieee80211n,
+				      iface->conf->ieee80211ac,
+				      iface->conf->ieee80211ax,
+				      secondary_channel,
+				      new_vht_oper_chwidth,
+				      oper_centr_freq_seg0_idx,
+				      oper_centr_freq_seg1_idx,
+				      cmode->vht_capab,
+				      &cmode->he_capab[ieee80211_mode]);
+
+	if (err) {
+		wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
+		hostapd_disable_iface(iface);
+		return err;
+	}
+
+	for (i = 0; i < iface->num_bss; i++) {
+		err = hostapd_switch_channel(iface->bss[i], &csa_settings);
+		if (err)
+			break;
+	}
+
+	if (err) {
+		wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback",
+			   err);
+		iface->freq = freq;
+		iface->conf->channel = channel;
+		iface->conf->secondary_channel = secondary_channel;
+		hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
+		hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
+						     oper_centr_freq_seg0_idx);
+		hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
+						     oper_centr_freq_seg1_idx);
+
+		hostapd_disable_iface(iface);
+		hostapd_enable_iface(iface);
+
+		return 0;
+	}
+
+	/* Channel configuration will be updated once CSA completes and
+	 * ch_switch_notify event is received */
+	wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
+
+	return 0;
+}
 
 static struct hostapd_channel_data *
 dfs_downgrade_bandwidth(struct hostapd_iface *iface, int *secondary_channel,
@@ -1179,21 +1259,14 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
 	return err;
 }
 
-
 static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 {
+	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
 	struct hostapd_channel_data *channel;
 	int secondary_channel;
 	u8 oper_centr_freq_seg0_idx;
 	u8 oper_centr_freq_seg1_idx;
-	u8 new_vht_oper_chwidth;
 	int channel_type = DFS_AVAILABLE;
-	struct csa_settings csa_settings;
-	unsigned int i;
-	int err = 1;
-	struct hostapd_hw_modes *cmode = iface->current_mode;
-	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
-	int ieee80211_mode = IEEE80211_MODE_AP;
 
 	wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
 		   __func__, iface->cac_started ? "yes" : "no",
@@ -1256,73 +1329,12 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
 		}
 	}
 
-	wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
-		   channel->chan);
-	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-		"freq=%d chan=%d sec_chan=%d", channel->freq,
-		channel->chan, secondary_channel);
-
-	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
-	hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
-
-	/* Setup CSA request */
-	os_memset(&csa_settings, 0, sizeof(csa_settings));
-	csa_settings.cs_count = 5;
-	csa_settings.block_tx = 1;
-#ifdef CONFIG_MESH
-	if (iface->mconf)
-		ieee80211_mode = IEEE80211_MODE_MESH;
-#endif /* CONFIG_MESH */
-	err = hostapd_set_freq_params(&csa_settings.freq_params,
-				      iface->conf->hw_mode,
-				      channel->freq,
-				      channel->chan,
-				      iface->conf->enable_edmg,
-				      iface->conf->edmg_channel,
-				      iface->conf->ieee80211n,
-				      iface->conf->ieee80211ac,
-				      iface->conf->ieee80211ax,
-				      secondary_channel,
-				      new_vht_oper_chwidth,
-				      oper_centr_freq_seg0_idx,
-				      oper_centr_freq_seg1_idx,
-				      cmode->vht_capab,
-				      &cmode->he_capab[ieee80211_mode]);
-
-	if (err) {
-		wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
-		hostapd_disable_iface(iface);
-		return err;
-	}
-
-	for (i = 0; i < iface->num_bss; i++) {
-		err = hostapd_switch_channel(iface->bss[i], &csa_settings);
-		if (err)
-			break;
-	}
-
-	if (err) {
-		wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback",
-			   err);
-		iface->freq = channel->freq;
-		iface->conf->channel = channel->chan;
-		iface->conf->secondary_channel = secondary_channel;
-		hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
-		hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
-						     oper_centr_freq_seg0_idx);
-		hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
-						     oper_centr_freq_seg1_idx);
-
-		hostapd_disable_iface(iface);
-		hostapd_enable_iface(iface);
-		return 0;
-	}
-
-	/* Channel configuration will be updated once CSA completes and
-	 * ch_switch_notify event is received */
-
-	wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
-	return 0;
+	return hostapd_dfs_request_channel_switch(iface, channel->chan,
+						  channel->freq,
+						  secondary_channel,
+						  current_vht_oper_chwidth,
+						  oper_centr_freq_seg0_idx,
+						  oper_centr_freq_seg1_idx);
 }
 
 
-- 
2.35.1




More information about the Hostap mailing list