diff mbox series

[6/9] DFS: introduce hostapd_dfs_request_channel_switch routine

Message ID c1bf7dc195281330e7108c533da5770adf479d84.1640014128.git.lorenzo@kernel.org
State New
Headers show
Series introduce background radar detection support | expand

Commit Message

Lorenzo Bianconi Dec. 20, 2021, 3:48 p.m. UTC
This is a preliminary patch to add Channel Switch Announcement for
background radar detection.

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

Comments

Jouni Malinen March 3, 2022, 10:54 p.m. UTC | #1
On Mon, Dec 20, 2021 at 04:48:21PM +0100, Lorenzo Bianconi wrote:
> This is a preliminary patch to add Channel Switch Announcement for
> background radar detection.

> diff --git a/src/ap/dfs.c b/src/ap/dfs.c
> @@ -940,6 +940,85 @@ int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
>  
> +static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,

> +	struct hostapd_hw_modes *cmode = iface->current_mode;
> +	int ieee80211_mode = IEEE80211_MODE_AP, err, i;

That i needs to be unsigned int (like it was in the function from which
it was moved to here) to avoid a compiler warning.

> +	u8 new_vht_oper_chwidth;

> +	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
> +	hostapd_set_oper_chwidth(iface->conf,
> +				 hostapd_get_oper_chwidth(iface->conf));

This looks quite strange.. hostapd_dfs_start_channel_switch() used
current_vht_oper_chwidth to store the current value from beginning of
the function and restored it at this location. The new version in this
helper function seems to something strange, or well, nothing. That does
not feel correct.

>  static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
>  {
> -	unsigned int i;

That's where i was unsigned..

> -	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);

And that's where the current value is picked at the beginning of
hostapd_dfs_start_channel_switch().

> -	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
> -	hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);

And this looks quite different compared to what was in the new helper
function.
Lorenzo Bianconi March 4, 2022, 11:52 a.m. UTC | #2
> On Mon, Dec 20, 2021 at 04:48:21PM +0100, Lorenzo Bianconi wrote:
> > This is a preliminary patch to add Channel Switch Announcement for
> > background radar detection.
> 
> > diff --git a/src/ap/dfs.c b/src/ap/dfs.c
> > @@ -940,6 +940,85 @@ int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
> >  
> > +static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
> 
> > +	struct hostapd_hw_modes *cmode = iface->current_mode;
> > +	int ieee80211_mode = IEEE80211_MODE_AP, err, i;
> 
> That i needs to be unsigned int (like it was in the function from which
> it was moved to here) to avoid a compiler warning.

ack, I will fix it

> 
> > +	u8 new_vht_oper_chwidth;
> 
> > +	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
> > +	hostapd_set_oper_chwidth(iface->conf,
> > +				 hostapd_get_oper_chwidth(iface->conf));
> 
> This looks quite strange.. hostapd_dfs_start_channel_switch() used
> current_vht_oper_chwidth to store the current value from beginning of
> the function and restored it at this location. The new version in this
> helper function seems to something strange, or well, nothing. That does
> not feel correct.
> 
> >  static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
> >  {
> > -	unsigned int i;
> 
> That's where i was unsigned..
> 
> > -	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
> 
> And that's where the current value is picked at the beginning of
> hostapd_dfs_start_channel_switch().
> 
> > -	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
> > -	hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
> 
> And this looks quite different compared to what was in the new helper
> function.

ack, I will fix it.

Regards,
Lorenzo

> 
> -- 
> Jouni Malinen                                            PGP id EFC895FA
>
diff mbox series

Patch

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 94ef87d87..bd8a2484d 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -940,6 +940,85 @@  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 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, i;
+	struct csa_settings csa_settings;
+	u8 new_vht_oper_chwidth;
+
+	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,
+				 hostapd_get_oper_chwidth(iface->conf));
+
+	/* 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 +1258,13 @@  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)
 {
 	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 skip_radar = 1;
-	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 +1327,11 @@  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,
+						  oper_centr_freq_seg0_idx,
+						  oper_centr_freq_seg1_idx);
 }