diff mbox series

ACS, DFS: Support min_tx_power configuration

Message ID 77e8410a-4831-3101-cee4-a0a3dc94ed97@gmail.com
State Accepted
Headers show
Series ACS, DFS: Support min_tx_power configuration | expand

Commit Message

Alan Young Nov. 11, 2021, 4:41 p.m. UTC

Comments

Jouni Malinen Dec. 12, 2021, 9:34 p.m. UTC | #1
On Thu, Nov 11, 2021 at 04:41:45PM +0000, Alan Young wrote:
> If min_tx_power is specified (default 0 dBm) then ACS and DFS will not
> consider channels whose available max_tx_power is less than the
> configured value.
> 
> This may be useful to exclude SRD (Short Range Device) channels which
> may be limited to 13.9 dBm (25 mW) in some regulatory domains.

Thanks, applied.
diff mbox series

Patch

From cf2cd3c648a19143a4754bd7c25b8a317b319023 Mon Sep 17 00:00:00 2001
From: Alan Young <consult.awy@gmail.com>
Date: Thu, 11 Nov 2021 16:40:05 +0000
Subject: [PATCH] ACS, DFS: Support min_tx_power configuration

If min_tx_power is specified (default 0 dBm) then ACS and DFS will not
consider channels whose available max_tx_power is less than the
configured value.

This may be useful to exclude SRD (Short Range Device) channels which
may be limited to 13.9 dBm (25 mW) in some regulatory domains.

Signed-off-by: Alan Young <consult.awy@gmail.com>
---
 hostapd/config_file.c | 9 +++++++++
 hostapd/hostapd.conf  | 4 ++++
 src/ap/acs.c          | 9 +++++++++
 src/ap/ap_config.c    | 1 +
 src/ap/ap_config.h    | 1 +
 src/ap/ap_drv_ops.c   | 3 ++-
 src/ap/dfs.c          | 3 +++
 7 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index daf3f37ad..754eb199a 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3193,6 +3193,15 @@  static int hostapd_config_fill(struct hostapd_config *conf,
 		conf->acs_freq_list_present = 1;
 	} else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
 		conf->acs_exclude_6ghz_non_psc = atoi(pos);
+	} else if (os_strcmp(buf, "min_tx_power") == 0) {
+		int val = atoi(pos);
+		if (val < 0 || val > 255) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: invalid min_tx_power %d (expected 0..255)",
+				   line, val);
+			return 1;
+		}
+		conf->min_tx_power = val;
 	} else if (os_strcmp(buf, "beacon_int") == 0) {
 		int val = atoi(pos);
 		/* MIB defines range as 1..65535, but very small values
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 67d4cefb9..1d3325263 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -225,6 +225,10 @@  channel=1
 # Default behavior is to include all PSC and non-PSC channels.
 #acs_exclude_6ghz_non_psc=1
 
+# Set minimum permitted max TX power (in dBm) for ACS & DFS channel selection.
+# (default 0)
+# min_tx_power=20
+
 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
 beacon_int=100
 
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 46429f265..0030edc2a 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -546,6 +546,9 @@  static void acs_survey_mode_interference_factor(
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)",
 			   chan->chan, chan->freq);
 
@@ -673,6 +676,9 @@  acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		if (!chan_bw_allowed(chan, bw, 1, 1)) {
 			wpa_printf(MSG_DEBUG,
 				   "ACS: Channel %d: BW %u is not supported",
@@ -1047,6 +1053,9 @@  static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		*freq++ = chan->freq;
 	}
 
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 86b6e097c..9ca1f7391 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -262,6 +262,7 @@  struct hostapd_config * hostapd_config_defaults(void)
 
 	conf->acs = 0;
 	conf->acs_ch_list.num = 0;
+	conf->min_tx_power = 0;
 #ifdef CONFIG_ACS
 	conf->acs_num_scans = 5;
 #endif /* CONFIG_ACS */
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index b8f791e56..20e2afe24 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -953,6 +953,7 @@  struct hostapd_config {
 	struct wpa_freq_range_list acs_freq_list;
 	u8 acs_freq_list_present;
 	int acs_exclude_dfs;
+	u8 min_tx_power;
 	enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
 	int acs_exclude_6ghz_non_psc;
 	enum {
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index d1642d7df..e91773666 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -888,7 +888,8 @@  static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
 			continue;
 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
 		    !(hapd->iface->conf->acs_exclude_dfs &&
-		      (chan->flag & HOSTAPD_CHAN_RADAR)))
+		      (chan->flag & HOSTAPD_CHAN_RADAR)) &&
+		    !(chan->max_tx_power < hapd->iface->conf->min_tx_power))
 			int_array_add_unique(freq_list, chan->freq);
 	}
 }
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 03c99b175..5c99ecfd0 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -246,6 +246,9 @@  static int dfs_find_channel(struct hostapd_iface *iface,
 			continue;
 		}
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		if (ret_chan && idx == channel_idx) {
 			wpa_printf(MSG_DEBUG, "Selected channel %d (%d)",
 				   chan->freq, chan->chan);
-- 
2.25.1