[PATCH v3 03/36] PR: Update channels that are supported to perform ranging

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

This includes channels where Enhanced Distributed channel Access
(EDCA-802.11mc) is supported as well channels where Non-Trigger Based
(NTB-802.11az) ranging is supported based on the corresponding format
and bandwidth.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla@xxxxxxxxxxxxxxxx>
---
 src/common/proximity_ranging.h |  73 +++++++++++
 wpa_supplicant/pr_supplicant.c | 224 +++++++++++++++++++++++++++++++++
 2 files changed, 297 insertions(+)

diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index affabc19c..7b63c35dc 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -14,11 +14,80 @@
 #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;
+};
+
+/**
+ * Format and Bandwidth values for EDCA based ranging with range of 10-16
+ * specified in (Proximity Ranging Implementation Considerations for P2P
+ * Operation July 2025 Draft 1.8 Table-8)
+ */
+enum edca_fomat_and_bw_value {
+	EDCA_FORMAT_AND_BW_VHT20 = 10,
+	EDCA_FORMAT_AND_BW_HT40 = 11,
+	EDCA_FORMAT_AND_BW_VHT40 = 12,
+	EDCA_FORMAT_AND_BW_VHT80 = 13,
+	EDCA_FORMAT_AND_BW_VHT80P80 = 14,
+	EDCA_FORMAT_AND_BW_VHT160_SINGLE_LO = 15,
+	EDCA_FORMAT_AND_BW_VHT160_DUAL_LO = 16
+};
+
+/**
+ * Format and Bandwidth values for NTB based ranging as
+ * specified in (Proximity Ranging Implementation Considerations for P2P
+ * Operation July 2025 Draft 1.8 Table-9)
+ */
+enum ntb_fomat_and_bw_value {
+	NTB_FORMAT_AND_BW_HE20 = 0,
+	NTB_FORMAT_AND_BW_HE40 = 1,
+	NTB_FORMAT_AND_BW_HE80 = 2,
+	NTB_FORMAT_AND_BW_HE80P80 = 3,
+	NTB_FORMAT_AND_BW_HE160_SINGLE_LO = 4,
+	NTB_FORMAT_AND_BW_HE160_DUAL_LO = 5
+};
+
 /**
  * struct pr_device_info - Proximity ranging peer information
  */
@@ -57,6 +126,8 @@ struct pr_config {
 
 	u8 max_rx_antenna;
 
+	struct pr_channels edca_channels;
+
 	bool ntb_ista_support;
 
 	bool ntb_rsta_support;
@@ -81,6 +152,8 @@ struct pr_config {
 
 	u8 ntb_format_and_bw;
 
+	struct pr_channels ntb_channels;
+
 	bool support_6ghz;
 
 
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index a69385980..98dafaa56 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -19,6 +19,223 @@
 #include "pr_supplicant.h"
 
 
+int wpas_pr_edca_get_bw(int format_and_bw)
+{
+	switch (format_and_bw) {
+	case EDCA_FORMAT_AND_BW_VHT20:
+		return 20;
+	case EDCA_FORMAT_AND_BW_HT40:
+	case EDCA_FORMAT_AND_BW_VHT40:
+		return 40;
+	case EDCA_FORMAT_AND_BW_VHT80:
+		return 80;
+	case EDCA_FORMAT_AND_BW_VHT80P80:
+	case EDCA_FORMAT_AND_BW_VHT160_SINGLE_LO:
+	case EDCA_FORMAT_AND_BW_VHT160_DUAL_LO:
+		return 160;
+	default:
+		return 0;
+	}
+}
+
+
+int wpas_pr_ntb_get_bw(int format_and_bw)
+{
+	switch (format_and_bw) {
+	case NTB_FORMAT_AND_BW_HE20:
+		return 20;
+	case NTB_FORMAT_AND_BW_HE40:
+		return 40;
+	case NTB_FORMAT_AND_BW_HE80:
+		return 80;
+	case NTB_FORMAT_AND_BW_HE80P80:
+	case NTB_FORMAT_AND_BW_HE160_SINGLE_LO:
+	case NTB_FORMAT_AND_BW_HE160_DUAL_LO:
+		return 160;
+	default:
+		return 0;
+	}
+}
+
+
+int wpas_pr_edca_is_valid_op_class(int format_and_bw,
+				   const struct oper_class_map *op_class_map)
+{
+	int bw = 0, op_class_bw = 0;
+
+	if (!op_class_map)
+		return -1;
+
+	op_class_bw = oper_class_bw_to_int(op_class_map);
+	bw = wpas_pr_edca_get_bw(format_and_bw);
+
+	if (!op_class_bw || !bw)
+		return -1;
+
+	if (format_and_bw <= EDCA_FORMAT_AND_BW_VHT80 &&
+	    format_and_bw >= EDCA_FORMAT_AND_BW_VHT20 &&
+	    op_class_bw <= bw) {
+		return 0;
+	} else if (format_and_bw == EDCA_FORMAT_AND_BW_VHT80P80 &&
+		   (op_class_bw < bw || op_class_map->bw == BW80P80)) {
+		return 0;
+	} else if ((format_and_bw == EDCA_FORMAT_AND_BW_VHT160_DUAL_LO ||
+		    format_and_bw == EDCA_FORMAT_AND_BW_VHT160_SINGLE_LO) &&
+		   (op_class_bw < bw || op_class_map->bw == BW160)) {
+		return 0;
+	}
+
+	return -1;
+}
+
+
+int wpas_pr_ntb_is_valid_op_class(int format_and_bw,
+				  const struct oper_class_map *op_class_map)
+{
+	int bw = 0, op_class_bw = 0;
+
+	if (!op_class_map)
+		return -1;
+
+	op_class_bw = oper_class_bw_to_int(op_class_map);
+	bw = wpas_pr_ntb_get_bw(format_and_bw);
+
+	if (!op_class_bw || !bw)
+		return -1;
+
+	if (format_and_bw <= NTB_FORMAT_AND_BW_HE80 &&
+	    format_and_bw >= NTB_FORMAT_AND_BW_HE20 &&
+	    op_class_bw <= bw) {
+		return 0;
+	} else if (format_and_bw == NTB_FORMAT_AND_BW_HE80P80 &&
+		   (op_class_bw < bw || op_class_map->bw == BW80P80)) {
+		return 0;
+	} else if ((format_and_bw == NTB_FORMAT_AND_BW_HE160_DUAL_LO ||
+		    format_and_bw == NTB_FORMAT_AND_BW_HE160_SINGLE_LO) &&
+		   (op_class_bw < bw || op_class_map->bw == BW160)) {
+		return 0;
+	}
+
+	return -1;
+}
+
+
+static int wpas_pr_setup_edca_channels(struct wpa_supplicant *wpa_s,
+				       struct pr_channels *chan,
+				       int format_and_bw)
+{
+	int cla = 0, i;
+	struct hostapd_hw_modes *mode;
+
+	for (i = 0; global_op_class[i].op_class; i++) {
+		unsigned int ch;
+		struct pr_op_class *op = NULL;
+		const struct oper_class_map *o = &global_op_class[i];
+
+		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
+				is_6ghz_op_class(o->op_class));
+		if (!mode || is_6ghz_op_class(o->op_class) ||
+		    wpas_pr_edca_is_valid_op_class(format_and_bw, o))
+			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;
+}
+
+
+static int wpas_pr_setup_ntb_channels(struct wpa_supplicant *wpa_s,
+				      struct pr_channels *chan,
+				      int format_and_bw, bool allow_6ghz)
+{
+	int cla = 0, i;
+	struct hostapd_hw_modes *mode;
+
+	for (i = 0; global_op_class[i].op_class; i++) {
+		unsigned int ch;
+		struct pr_op_class *op = NULL;
+		const struct oper_class_map *o = &global_op_class[i];
+
+		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)) ||
+		    wpas_pr_ntb_is_valid_op_class(format_and_bw, o))
+			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;
@@ -42,6 +259,9 @@ int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 	pr.max_rx_antenna = wpa_s->max_rx_antenna;
 	pr.max_tx_antenna = wpa_s->max_tx_antenna;
 
+	wpas_pr_setup_edca_channels(wpa_s, &pr.edca_channels,
+				    pr.edca_format_and_bw);
+
 	pr.ntb_ista_support = (wpa_s->drv_flags2
 			       & WPA_DRIVER_FLAGS2_NON_TRIGGER_BASED_INITIATOR);
 	pr.ntb_rsta_support = (wpa_s->drv_flags2 &
@@ -60,6 +280,10 @@ int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 
 	pr.secure_he_ltf = wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA;
 
+	wpas_pr_setup_ntb_channels(wpa_s, &pr.ntb_channels,
+				   pr.ntb_format_and_bw,
+				   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;
-- 
2.34.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux