[RFC 0/8] Introduce S1G Support

Lachlan Hodges lachlan.hodges at morsemicro.com
Wed May 27 23:38:49 PDT 2026


Hi Jouni,

Firstly, this has been rebased and tested on 4706c1d6d93e ("SME: Fix compilation
warnings about unused functions") with wireless-next 1a1f055318d8
("Merge tag 'wireless-next-2026-05-21' of
https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next").

--

Over the last ~1.5 years we have been improving / fixing the S1G support
within mac80211/cfg80211 to the point where you can bring up a native
S1G AP/STA. We also have a driver currently under review [1].

This first submission is quite large, even when scoping to the absolute
minimum (i.e basic AP and STA, no channel switching, DPP etc.). Conceptually
there are two parts to this series - freq_offset and wider S1G support. The
freq_offset subset passes the hwsim tests indepedently of the wider patchset.

Below is a high level overview of the notable changes made by this series.

--

1) freq_offset
==============

The biggest deviation from existing 802.11 standards when it comes to
802.11ah or S1G is the fact that the spectrum is < 1 GHz. Within cfg80211,
this is denoted via a frequency component in MHz, and a frequency offset
component in KHz. This is potentially most contentious part of this entire
series as it requires modifications to core functions that work on various
channel calculations.

Take hw_mode_get_channel() as an example, to compare channels we now
must apply the freq_offset component:

MHZ_TO_KHZ(ch->freq) + ch->freq_offset == MHZ_TO_KHZ(freq) + freq_offset)

For non-S1G the frequency offset component is always 0, but this method
has been chosen as it is similar to how the similar channel calculation
functions were refactored to internally use these components, while
still limiting the external facing APIs from changing too much.

Another example is converting internal channel <-> frequency calculators
to use KHz:

int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
{
        return KHZ_TO_MHZ(ieee80211_chan_to_freq_khz(country, op_class, chan);
}

Where any specific S1G locations can then call ieee80211_chan_to_freq_khz()
directly. Again, we are emulating how this is done within cfg80211.
Additionally, a freq_offset component is then introduced to the parameter
list of key functions to do with setting and/or retrieving channels.

2) Regdom Support
=================

Currently, the upstream regdom supports only a limited number of
countries, this being US and AU. However, this patchset will _only_
be supporting the US. The reason is that, in order to support the
2024 AU channelisation schemes, additional kernel work is required.
This will begin once the driver is accepted, in part, to reduce the
initial scope of these patchsets (both within the kernel/driver and
hostapd).

As a result, only specific US 2024 op_classes are introduced, and an attempt
to configure with an unsupported op_class will result in an error. Obviously,
as support is extended - so will support in hostapd since country support is
far more granular for S1G.

3) S1G Implementation
=====================

Since S1G is based on the VHT phy, much of the implementation follows
that of VHT, besides some S1G specific parts of course.

4) hw_mode=ah
=============

With the new band introduced comes a new hwmode to represent 900 MHz
PHY. For existing drivers that use hw_mode=any there is no affect as
none of those drivers expose S1G channels. However, hwsim does. For now,
we exclude all S1G channels when hw_mode=any. This enables
mac80211_hwsim to function properly and emulates real world behaviour
since there (as of now, maybe in the future....) no multi-band radios
that include both a S1G and non-S1G radio.

5) hwsim tests
==============

A basic test suite is also included that tests various channel permutations
as well as the NO_PRIMARY flag to ensure edgeband primaries with the
NO_PRIMARY flag cannot be used, which is typical of real hardware. See [2]
for more information on this.

In order for the S1G hwsim tests to function, 2 patches [3] must be
applied onto wireless-next.

The actual hwsim output in terms of radiotap headers and whatnot is
not really accurate at all for S1G, however this is on our TODO list
among other things like proper rate reporting and so on. However, as
mentioned previously, the goal is to keep the initial scope of this work
as small as possible and build it up from there :).

6) Sample Config
================

A sample hostapd configuration for 80211ah is as follows:

```
interface=wlan0
country_code=US
driver=nl80211
ssid=wifi_halow

channel=43
ieee80211ah=1
op_class=71
beacon_int=100
dtim_period=10
s1g_oper_centr_freq_idx=44
s1g_primary_2mhz=1

hw_mode=ah
wpa=2
wpa_key_mgmt=SAE
rsn_pairwise=CCMP
sae_password=12345678
ieee80211w=2
```

The supplicant side is no different from regular Wi-Fi:

```
update_config=1
country=US
pmf=2

network={
        ssid="wifi_halow"
        sae_password="12345678"
        key_mgmt=SAE
}
```

lachlan

[1] https://lore.kernel.org/linux-wireless/20260430045615.334669-1-lachlan.hodges@morsemicro.com/
[2] https://lore.kernel.org/linux-wireless/20250918051913.500781-2-lachlan.hodges@morsemicro.com/
[3] https://lore.kernel.org/linux-wireless/20260527033828.183821-1-lachlan.hodges@morsemicro.com/T/#t

Lachlan Hodges (8):
  AP/STA: introduce support for freq_offset
  nl80211: introduce freq_offset support
  tests: expose scan_freq_offset
  config: enable configuration of S1G
  AP: add S1G support
  STA: add S1G support
  nl80211: add S1G support
  tests: add S1G channel tests

 hostapd/Makefile                          |   5 +
 hostapd/config_file.c                     |  10 +
 hostapd/defconfig                         |   3 +
 hostapd/hostapd.conf                      |  26 ++-
 src/ap/Makefile                           |   1 +
 src/ap/ap_config.c                        |  34 +++
 src/ap/ap_config.h                        |  23 ++
 src/ap/ap_drv_ops.c                       |  28 ++-
 src/ap/ap_drv_ops.h                       |   7 +-
 src/ap/beacon.c                           |  98 ++++++++-
 src/ap/ctrl_iface_ap.c                    |   8 +-
 src/ap/dfs.c                              |  12 +-
 src/ap/drv_callbacks.c                    |   6 +-
 src/ap/hostapd.c                          |  42 ++--
 src/ap/hostapd.h                          |   1 +
 src/ap/hw_features.c                      |  75 +++++--
 src/ap/hw_features.h                      |   2 +-
 src/ap/ieee802_11.c                       |  60 +++++-
 src/ap/ieee802_11.h                       |  10 +
 src/ap/ieee802_11_s1g.c                   | 196 +++++++++++++++++
 src/ap/ieee802_11_shared.c                |  14 ++
 src/ap/interference.c                     |   3 +-
 src/ap/sta_info.c                         |   5 +-
 src/ap/sta_info.h                         |   4 +-
 src/common/defs.h                         |  10 +
 src/common/hw_features_common.c           |  71 ++++++-
 src/common/hw_features_common.h           |  19 +-
 src/common/ieee802_11_common.c            | 183 +++++++++++-----
 src/common/ieee802_11_common.h            |   7 +-
 src/common/ieee802_11_defs.h              |  55 +++++
 src/common/privsep_commands.h             |   1 +
 src/common/proximity_ranging.h            |   3 +-
 src/drivers/driver.h                      |  67 +++++-
 src/drivers/driver_nl80211.c              | 157 ++++++++++----
 src/drivers/driver_nl80211.h              |   3 +
 src/drivers/driver_nl80211_capa.c         |  66 +++++-
 src/drivers/driver_nl80211_event.c        |  36 +++-
 src/drivers/driver_nl80211_scan.c         |  34 ++-
 src/drivers/driver_privsep.c              |   7 +-
 tests/hwsim/example-hostapd.config        |   1 +
 tests/hwsim/example-wpa_supplicant.config |   1 +
 tests/hwsim/test_s1g.py                   | 245 ++++++++++++++++++++++
 tests/hwsim/wpasupplicant.py              |   3 +-
 wlantest/bss.c                            |   2 +-
 wpa_supplicant/Makefile                   |   6 +
 wpa_supplicant/ap.c                       |   4 +-
 wpa_supplicant/bss.c                      |   5 +-
 wpa_supplicant/bss.h                      |   2 +
 wpa_supplicant/config.c                   |   1 +
 wpa_supplicant/config_ssid.h              |  12 ++
 wpa_supplicant/ctrl_iface.c               |   1 +
 wpa_supplicant/defconfig                  |   3 +
 wpa_supplicant/driver_i.h                 |   9 +-
 wpa_supplicant/events.c                   |  21 +-
 wpa_supplicant/ibss_rsn.c                 |   2 +-
 wpa_supplicant/mesh.c                     |   5 +-
 wpa_supplicant/nan_supplicant.c           |   2 +-
 wpa_supplicant/p2p_supplicant.c           |   4 +-
 wpa_supplicant/pasn_supplicant.c          |   4 +-
 wpa_supplicant/scan.c                     |  10 +-
 wpa_supplicant/sme.c                      |  20 +-
 wpa_supplicant/wpa_priv.c                 |   1 +
 wpa_supplicant/wpa_supplicant.c           |  26 ++-
 wpa_supplicant/wpa_supplicant_i.h         |   2 +
 64 files changed, 1518 insertions(+), 266 deletions(-)
 create mode 100644 src/ap/ieee802_11_s1g.c
 create mode 100644 tests/hwsim/test_s1g.py

-- 
2.43.0




More information about the Hostap mailing list