[RFC 14/56] common: Add some helper functions

Andrei Otcheretianski andrei.otcheretianski at intel.com
Sun Dec 7 03:18:23 PST 2025


From: Ilan Peer <ilan.peer at intel.com>

Add helper function for the following:

 1. Get the channel index within an operating class.
 2. Get the channel number by its index within an operating class.
 3. Get the center frequency corresponding to a control frequency
    based on the operating class bandwidth.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/common/ieee802_11_common.c | 146 +++++++++++++++++++++++++++++++++
 src/common/ieee802_11_common.h |   5 ++
 2 files changed, 151 insertions(+)

diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index a0b51c014f..c621ce91c6 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -3642,3 +3642,149 @@ int get_basic_mle_link_id(const u8 *buf, size_t len)
 
 	return buf[link_id_pos] & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
 }
+
+
+const u8 channels_80mhz[] = { 42, 58, 106, 122, 138, 155 };
+const u8 channels_160mhz[] = { 50, 114 };
+
+
+static u8 op_class_idx_to_chan_vht(u8 op_class, u8 idx)
+{
+	const u8 *chans_array;
+	u8 size;
+
+	if (op_class == 128 || op_class == 130) {
+		chans_array = channels_80mhz;
+		size = ARRAY_SIZE(channels_80mhz);
+	} else if (op_class == 129) {
+		chans_array = channels_160mhz;
+		size = ARRAY_SIZE(channels_160mhz);
+	} else {
+		return 0;
+	}
+
+	if (idx >= size)
+		return 0;
+
+	return chans_array[idx];
+}
+
+
+/**
+ * op_class_idx_to_chan - channel index in the operating class to channel number
+ * @op: A pointer to the operating class object
+ * @idx: The channel index within the operating class. The channels are ordered
+ *	from lowest number to highest, index starting from 0.
+ */
+u8 op_class_idx_to_chan(const struct oper_class_map *op, u8 idx)
+{
+	u8 chan;
+
+	if (op->bw == BW80 || op->bw == BW80P80 ||
+	    op->bw == BW160)
+		return op_class_idx_to_chan_vht(op->op_class, idx);
+
+	chan = op->min_chan + idx * op->inc;
+	if (chan > op->max_chan)
+		return 0;
+
+	return chan;
+}
+
+
+static int op_class_chan_to_idx_vht(u8 op_class, u8 chan)
+{
+	const u8 *chans_array;
+	u8 i, size;
+
+	if (op_class == 128 || op_class == 130) {
+		chans_array = channels_80mhz;
+		size = ARRAY_SIZE(channels_80mhz);
+	} else if (op_class == 129) {
+		chans_array = channels_80mhz;
+		size = ARRAY_SIZE(channels_160mhz);
+	} else {
+		return -1;
+	}
+
+	for (i = 0; i < size; i++)
+		if (chan == chans_array[i])
+			return i;
+
+	return -1;
+}
+
+/**
+ * op_class_chan_to_idx - channel number to channel index in the operating class
+ * @op: A pointer to the operating class object
+ * @chan: The channel number.
+ */
+int op_class_chan_to_idx(const struct oper_class_map *op, u8 chan)
+{
+	if (op->bw == BW80 || op->bw == BW80P80 ||
+	    op->bw == BW160)
+		return op_class_chan_to_idx_vht(op->op_class, chan);
+
+	if (chan < op->min_chan || chan > op->max_chan ||
+	    (chan - op->min_chan) % op->inc)
+		return -1;
+
+	return (chan - op->min_chan) / op->inc;
+}
+
+
+static int get_center_freq_80mhz(int ctrl_freq)
+{
+	int center_freqs[] = { 5210, 5290, 5530, 5610, 5690, 5775 };
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(center_freqs); i++) {
+		if (ctrl_freq >= center_freqs[i] - 30 &&
+		    ctrl_freq <= center_freqs[i] + 30)
+			return center_freqs[i];
+	}
+
+	return 0;
+}
+
+
+static int get_center_freq_160mhz(int ctrl_freq)
+{
+	int center_freqs[] = { 5250, 5570 };
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(center_freqs); i++) {
+		if (ctrl_freq >= center_freqs[i] - 70 &&
+		    ctrl_freq <= center_freqs[i] + 70)
+			return center_freqs[i];
+	}
+
+	return 0;
+}
+
+
+/**
+ * ieee80211_get_center_freq - return center frequency based on control
+ *     frequency and operating class information.
+ *
+ * @param: ctrl_freq: control frequency
+ * @bw: the bandwidth as defined in 'struct oper_class_map'
+ */
+int ieee80211_get_center_freq(int ctrl_freq, u32 bw)
+{
+	switch (bw) {
+	case BW20:
+		return ctrl_freq;
+	case BW40PLUS:
+		return ctrl_freq + 10;
+	case BW40MINUS:
+		return ctrl_freq - 10;
+	case BW80:
+	case BW80P80:
+		return get_center_freq_80mhz(ctrl_freq);
+	case BW160:
+		return get_center_freq_160mhz(ctrl_freq);
+	default:
+		return -1;
+	}
+}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index af011a3571..6b995fa10c 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -389,5 +389,10 @@ const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type);
 const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len);
 const u8 * get_basic_mle_eml_capa(const u8 *buf, size_t len);
 int get_basic_mle_link_id(const u8 *buf, size_t len);
+u8 op_class_idx_to_chan(const struct oper_class_map *op, u8 idx);
+
+int op_class_chan_to_idx(const struct oper_class_map *op, u8 chan);
+
+int ieee80211_get_center_freq(int ctrl_freq, u32 bw);
 
 #endif /* IEEE802_11_COMMON_H */
-- 
2.49.0




More information about the Hostap mailing list