[PATCH 1/6] tests: add S1G channel helpers
James Ewing
james at teledatics.com
Tue Sep 30 12:11:38 PDT 2025
Extend the hwsim utilities with `list_s1g_capable_channels()` and
`s1g_supported()` so tests can detect IEEE 802.11ah capability directly
from `iw phy` output. The parser copes with output variants where S1G
channels omit the `[idx]` token and normalises the reported MHz into a
structured dictionary.
This is required by the upcoming S1G smoke and association scenarios to
choose an operable channel without hardcoding numbers.
Tested: python3 - <<'PY'
from utils import list_s1g_capable_channels
list_s1g_capable_channels()
PY
Signed-off-by: James Ewing <james at teledatics.com>
---
tests/hwsim/utils.py | 55 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/tests/hwsim/utils.py b/tests/hwsim/utils.py
index 5c2af5635..26db40b8d 100644
--- a/tests/hwsim/utils.py
+++ b/tests/hwsim/utils.py
@@ -185,6 +185,61 @@ def he_6ghz_supported(freq=5975):
return False
+
+def _list_phys():
+ base = "/sys/class/ieee80211"
+ try:
+ return sorted(os.listdir(base))
+ except FileNotFoundError:
+ return []
+
+
+def list_s1g_capable_channels():
+ """Return S1G channel metadata exposed by available phys.
+
+ Each entry contains ``phy`` (string), ``freq_mhz`` (float), and
+ ``channel`` (int). The list is empty if the running kernel/mac80211
+ stack does not advertise any S1G channels.
+ """
+
+ channels = []
+ phys = _list_phys()
+ for phy in phys:
+ try:
+ out = subprocess.check_output(["iw", "phy", phy, "info"],
+ stderr=subprocess.DEVNULL,
+ universal_newlines=True)
+ except Exception:
+ continue
+
+ for line in out.splitlines():
+ stripped = line.strip()
+ if not stripped.startswith('* '):
+ continue
+
+ match =
re.match(r"\*\s+([0-9]+(?:\.[0-9]+)?)\s+MHz(?:\s+\[(\d+)\])?",
+ stripped)
+ if not match:
+ continue
+
+ freq_mhz = float(match.group(1))
+ if freq_mhz < 700 or freq_mhz > 1000:
+ continue
+
+ channels.append({
+ "phy": phy,
+ "freq_mhz": freq_mhz,
+ "channel": int(match.group(2)) if match.group(2) else None,
+ })
+
+ return channels
+
+
+def s1g_supported():
+ """Check whether any local mac80211 wiphy advertises S1G channels."""
+
+ return len(list_s1g_capable_channels()) > 0
+
# This function checks whether the provided dev, which may be either
# WpaSupplicant or Hostapd supports CSA.
def csa_supported(dev):
--
2.43.0
More information about the Hostap
mailing list