[RFC v2 14/99] common: Add some helper functions
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Dec 23 03:51:18 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 | 147 +++++++++++++++++++++++++++++++++
src/common/ieee802_11_common.h | 5 ++
2 files changed, 152 insertions(+)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 5d1e02f81e..6946cdf11a 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -4019,3 +4019,150 @@ enum chan_width get_sta_operation_chan_width(
return ap_operation_chan_width;
}
+
+
+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_160mhz;
+ 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 09bd0675a1..8fa3d2c821 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -389,6 +389,11 @@ 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);
unsigned int get_max_nss_capability(struct ieee802_11_elems *elems,
bool parse_for_rx);
--
2.49.0
More information about the Hostap
mailing list