[PATCH 02/34] PR: Update PR device configs and capabilities from driver

Peddolla Harshavardhan Reddy peddolla at qti.qualcomm.com
Thu Jun 19 08:36:55 PDT 2025


Add changes to fetch device configurations, capabilities, and
supported channels for ranging and store them in Proximity Ranging
global context.

This includes propagation of Enhanced Distributed channel Access
(EDCA-802.11mc) based ranging capabilities and channels as well
as Non-Trigger Based (NTB-802.11az) ranging capabilities and channels.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
 src/common/proximity_ranging.h    | 86 ++++++++++++++++++++++++++++
 src/drivers/driver.h              | 23 ++++++++
 wpa_supplicant/config.c           |  2 +
 wpa_supplicant/config.h           |  9 +++
 wpa_supplicant/config_file.c      |  4 ++
 wpa_supplicant/pr_supplicant.c    | 93 +++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.c   | 15 +++++
 wpa_supplicant/wpa_supplicant_i.h | 16 ++++++
 8 files changed, 248 insertions(+)

diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 0e597f85e..dce2d0870 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -13,12 +13,51 @@
 #include "utils/list.h"
 #include "drivers/driver.h"
 
+/**
+ * PR_MAX_OP_CLASSES - Maximum number of operating classes
+ */
+#define PR_MAX_OP_CLASSES 15
+
+/**
+ * PR_MAX_OP_CLASS_CHANNELS - Maximum number of channels per operating class
+ */
+#define PR_MAX_OP_CLASS_CHANNELS 60
 
 /**
  * PR_MAX_PEER - Maximum number of Proximity Ranging peers that device can store
  */
 #define PR_MAX_PEER 100
 
+/**
+ * struct pr_channels - List of supported channels
+ */
+struct pr_channels {
+	/**
+	 * struct pr_op_class - Supported operating class
+	 */
+	struct pr_op_class {
+		/**
+		 * op_class - Regulatory class (IEEE 802.11-2020)
+		 */
+		u8 op_class;
+
+		/**
+		 * channel - Supported channels
+		 */
+		u8 channel[PR_MAX_OP_CLASS_CHANNELS];
+
+		/**
+		 * channels - Number of channel entries in use
+		 */
+		size_t channels;
+	} op_class[PR_MAX_OP_CLASSES];
+
+	/**
+	 * op_classes - Number of op_class entries in use
+	 */
+	size_t op_classes;
+};
+
 /**
  * struct pr_device_info - Proximity ranging peer information
  */
@@ -34,6 +73,12 @@ struct pr_device {
 
 
 struct pr_config {
+	u8 pasn_type;
+
+	int preferred_ranging_role;
+
+	char country[3];
+
 	u8 dev_addr[ETH_ALEN];
 
 	/**
@@ -41,6 +86,47 @@ struct pr_config {
 	 */
 	char *dev_name;
 
+	bool edca_ista_support;
+
+	bool edca_rsta_support;
+
+	u8 edca_format_and_bw;
+
+	u8 max_tx_antenna;
+
+	u8 max_rx_antenna;
+
+	struct pr_channels edca_channels;
+
+	bool ntb_ista_support;
+
+	bool ntb_rsta_support;
+
+	bool secure_he_ltf;
+
+	u8 max_tx_ltf_repetations;
+
+	u8 max_rx_ltf_repetations;
+
+	u8 max_tx_ltf_total;
+
+	u8 max_rx_ltf_total;
+
+	u8 max_rx_sts_le_80;
+
+	u8 max_rx_sts_gt_80;
+
+	u8 max_tx_sts_le_80;
+
+	u8 max_tx_sts_gt_80;
+
+	u8 ntb_format_and_bw;
+
+	struct pr_channels ntb_channels;
+
+	bool support_6ghz;
+
+
 	/**
 	 * cb_ctx - Context to use with callback functions
 	 */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 54a3b694d..60f898317 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2417,6 +2417,12 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS2_P2P_FEATURE_V2	0x0000000002000000ULL
 /** Driver supports P2P PCC mode */
 #define WPA_DRIVER_FLAGS2_P2P_FEATURE_PCC_MODE	0x0000000004000000ULL
+/** Driver supports FTM initiator functionality */
+#define WPA_DRIVER_FLAGS2_FTM_INITIATOR		0x0000000008000000ULL
+/** Driver supports non-trigger based ranging responder functionality */
+#define WPA_DRIVER_FLAGS2_NON_TRIGGER_BASED_RESPONDER   0x0000000010000000ULL
+/** Driver supports non-trigger based ranging initiator functionality */
+#define WPA_DRIVER_FLAGS2_NON_TRIGGER_BASED_INITIATOR	0x0000000020000000ULL
 	u64 flags2;
 
 #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -2541,6 +2547,23 @@ struct wpa_driver_capa {
 	/* Maximum number of bytes of extra IE(s) that can be added to Probe
 	 * Request frames */
 	size_t max_probe_req_ie_len;
+
+	/* EDCA based ranging capabilities */
+	u8 edca_format_and_bw;
+	u8 max_tx_antenna;
+	u8 max_rx_antenna;
+
+	/* NTB based ranging capabilities */
+	u8 ntb_format_and_bw;
+	u8 max_tx_ltf_repetations;
+	u8 max_rx_ltf_repetations;
+	u8 max_tx_ltf_total;
+	u8 max_rx_ltf_total;
+	u8 max_rx_sts_le_80;
+	u8 max_rx_sts_gt_80;
+	u8 max_tx_sts_le_80;
+	u8 max_tx_sts_gt_80;
+
 };
 
 
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 77eb9bf68..120c6b36c 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -5707,6 +5707,8 @@ static const struct global_parse_data global_fields[] = {
 	{ INT_RANGE(wfa_gen_capa, 0, 2), 0},
 	{ BIN(wfa_gen_capa_supp), 0 },
 	{ BIN(wfa_gen_capa_cert), 0 },
+	{ INT(pr_pasn_type), 0 },
+	{ INT_RANGE(pr_preferred_role, 0, 1), 0},
 	/* NOTE: When adding new parameters here, add_interface() in
 	 * wpa_supplicant/dbus_new_introspect.c may need to be modified to
 	 * increase the size of the iface->xml buffer. */
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 69946076e..42fe67388 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1901,6 +1901,15 @@ struct wpa_config {
 	 * wfa_gen_capa_supp.
 	 */
 	struct wpabuf *wfa_gen_capa_cert;
+
+	/* Indicates the types of PASN supported for Proximity Ranging */
+	int pr_pasn_type;
+
+	/* Indicates the preferred Proximity Ranging Role
+	 * 0: Prefer ranging initiator role (default)
+	 * 1: Prefer ranging responder role
+	 */
+	int pr_preferred_role;
 };
 
 
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 26c7d44bc..a13365fd3 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1756,6 +1756,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
 		fprintf(f, "wfa_gen_capa=%d\n", config->wfa_gen_capa);
 	write_global_bin(f, "wfa_gen_capa_supp", config->wfa_gen_capa_supp);
 	write_global_bin(f, "wfa_gen_capa_cert", config->wfa_gen_capa_cert);
+	if (config->pr_pasn_type)
+		fprintf(f, "pr_pasn_type=%d\n", config->pr_pasn_type);
+	if (config->pr_preferred_role)
+		fprintf(f, "pr_preferred_role=%d\n", config->pr_preferred_role);
 }
 
 static void wpa_config_write_identity(FILE *f, struct wpa_dev_ik *dev_ik)
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index ba8746589..63cd4bc4d 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -18,6 +18,62 @@
 #include "common/proximity_ranging.h"
 #include "pr_supplicant.h"
 
+
+static int wpas_pr_setup_channels(struct wpa_supplicant *wpa_s,
+				  struct pr_channels *chan, bool allow_6ghz)
+{
+	int cla = 0, op;
+	struct hostapd_hw_modes *mode;
+
+	for (op = 0; global_op_class[op].op_class; op++) {
+		const struct oper_class_map *o = &global_op_class[op];
+		unsigned int ch;
+		struct pr_op_class *op = NULL;
+
+		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
+				is_6ghz_op_class(o->op_class));
+		if (!mode || (!allow_6ghz && is_6ghz_op_class(o->op_class)))
+			continue;
+
+		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
+			enum chan_allowed res;
+
+			/* Check for non-continuous jump in channel index
+			 * increment.
+			 */
+			if ((o->op_class >= 128 && o->op_class <= 130) &&
+			    ch < 149 && ch + o->inc > 149)
+				ch = 149;
+
+			res = verify_channel(mode, o->op_class, ch, o->bw);
+
+			if (res == ALLOWED) {
+				if (!op) {
+					if (cla == PR_MAX_OP_CLASSES)
+						continue;
+					wpa_printf(MSG_DEBUG, "PR: Add operating class: %u",
+						   o->op_class);
+					op = &chan->op_class[cla];
+					cla++;
+					op->op_class = o->op_class;
+				}
+				if (op->channels == PR_MAX_OP_CLASS_CHANNELS)
+					continue;
+				op->channel[op->channels] = ch;
+				op->channels++;
+			}
+		}
+		if (op) {
+			wpa_hexdump(MSG_DEBUG, "PR: Channels",
+				    op->channel, op->channels);
+		}
+	}
+
+	chan->op_classes = cla;
+
+	return 0;
+}
+
 int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 {
 	struct pr_config pr;
@@ -30,6 +86,43 @@ int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 	os_memcpy(pr.dev_addr, wpa_s->own_addr, ETH_ALEN);
 	pr.cb_ctx = wpa_s;
 	pr.dev_name = wpa_s->conf->device_name;
+	pr.pasn_type = wpa_s->conf->pr_pasn_type;
+	pr.preferred_ranging_role = wpa_s->conf->pr_preferred_role;
+
+	pr.edca_ista_support = wpa_s->drv_flags2 &
+				WPA_DRIVER_FLAGS2_FTM_INITIATOR;
+	pr.edca_rsta_support = wpa_s->drv_flags &
+				WPA_DRIVER_FLAGS_FTM_RESPONDER;
+	pr.edca_format_and_bw = wpa_s->edca_format_and_bw;
+	pr.max_rx_antenna = wpa_s->max_rx_antenna;
+	pr.max_tx_antenna = wpa_s->max_tx_antenna;
+
+	wpas_pr_setup_channels(wpa_s, &pr.edca_channels, false);
+
+	pr.ntb_ista_support = (wpa_s->drv_flags2
+			       & WPA_DRIVER_FLAGS2_NON_TRIGGER_BASED_INITIATOR);
+	pr.ntb_rsta_support = (wpa_s->drv_flags2 &
+				WPA_DRIVER_FLAGS2_NON_TRIGGER_BASED_RESPONDER);
+	pr.ntb_format_and_bw = wpa_s->ntb_format_and_bw;
+	pr.max_tx_ltf_repetations = wpa_s->max_tx_ltf_repetations;
+	pr.max_rx_ltf_repetations = wpa_s->max_rx_ltf_repetations;
+	pr.max_tx_ltf_total = wpa_s->max_tx_ltf_total;
+	pr.max_rx_ltf_total = wpa_s->max_rx_ltf_total;
+	pr.max_rx_sts_le_80 = wpa_s->max_rx_sts_le_80;
+	pr.max_rx_sts_gt_80 = wpa_s->max_rx_sts_gt_80;
+	pr.max_tx_sts_le_80 = wpa_s->max_tx_sts_le_80;
+	pr.max_tx_sts_gt_80 = wpa_s->max_tx_sts_gt_80;
+
+	pr.support_6ghz = wpas_is_6ghz_supported(wpa_s, true);
+
+	pr.secure_he_ltf = wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA;
+
+	wpas_pr_setup_channels(wpa_s, &pr.ntb_channels, pr.support_6ghz);
+	if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
+		os_memcpy(pr.country, wpa_s->conf->country, 2);
+		pr.country[2] = 0x04;
+	} else
+		os_memcpy(pr.country, "XX\x04", 3);
 
 	global->pr = pr_init(&pr);
 	if (!global->pr) {
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index fd2c41e60..1524794aa 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7791,6 +7791,21 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		wpa_s->extended_capa_len = capa.extended_capa_len;
 		wpa_s->num_multichan_concurrent =
 			capa.num_multichan_concurrent;
+
+		wpa_s->edca_format_and_bw = capa.edca_format_and_bw;
+		wpa_s->max_tx_antenna = capa.max_tx_antenna;
+		wpa_s->max_rx_antenna = capa.max_rx_antenna;
+
+		wpa_s->ntb_format_and_bw = capa.ntb_format_and_bw;
+		wpa_s->max_tx_ltf_repetations = capa.max_tx_ltf_repetations;
+		wpa_s->max_rx_ltf_repetations = capa.max_rx_ltf_repetations;
+		wpa_s->max_tx_ltf_total = capa.max_tx_ltf_total;
+		wpa_s->max_rx_ltf_total = capa.max_rx_ltf_total;
+		wpa_s->max_rx_sts_le_80 = capa.max_rx_sts_le_80;
+		wpa_s->max_rx_sts_gt_80 = capa.max_rx_sts_gt_80;
+		wpa_s->max_tx_sts_le_80 = capa.max_tx_sts_le_80;
+		wpa_s->max_tx_sts_gt_80 = capa.max_tx_sts_gt_80;
+
 #ifndef CONFIG_NO_WMM_AC
 		wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
 #endif /* CONFIG_NO_WMM_AC */
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b0e6a743d..f1b0f31ae 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -955,6 +955,22 @@ struct wpa_supplicant {
 	unsigned int max_stations;
 	unsigned int max_num_akms;
 
+	/* EDCA based ranging capabilities */
+	u8 edca_format_and_bw;
+	u8 max_tx_antenna;
+	u8 max_rx_antenna;
+
+	/* NTB based ranging capabilities */
+	u8 ntb_format_and_bw;
+	u8 max_tx_ltf_repetations;
+	u8 max_rx_ltf_repetations;
+	u8 max_tx_ltf_total;
+	u8 max_rx_ltf_total;
+	u8 max_rx_sts_le_80;
+	u8 max_rx_sts_gt_80;
+	u8 max_tx_sts_le_80;
+	u8 max_tx_sts_gt_80;
+
 	int pending_mic_error_report;
 	int pending_mic_error_pairwise;
 	int mic_errors_seen; /* Michael MIC errors with the current PTK */
-- 
2.34.1




More information about the Hostap mailing list