Search Linux Wireless

Re: [PROPOSAL RFC] S1G Primary Channel Implementation Proposal

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

 



On Tue, Aug 26, 2025 at 08:56:21PM +0200, Johannes Berg wrote:
> > The channelisation of an S1G PHY consists of two components, a center
> > frequency and a primary center frequency as per IEEE80211-2024 23.3.14.
> > The center frequency is equivalent to other PHY types, being the center
> > operating frequency for the operating channel and the primary center
> > frequency being the center frequency for the primary channel.
> >
> > When an S1G PHY changes channel, it requires both the operating channel
> > and the primary channel parameters. The implementation of this will be
> > briefly mentioned at the end of this email.
>
> How is the primary channel in S1G different from the primary channel in
> 2.4/5/6 GHz bands? The widths are multiples of 20 MHz rather than
> multiples of 1 MHz, but it seems pretty similar otherwise?

Ok so reading below, I think the only difference is that the S1G primary
can be 1MHz or 2MHz. That shouldn't matter though, see below

> > and must exist as a primary subchannel within the operating channels band.
> > Using the sample above, operating channel 44 can have a 1MHz primary of
> > 37, 39, 41, 43, 45, 47, 49 or 51 and same goes for the 2MHz channels. Whereas
> > an operating channel of 40 may only have primary 1MHz channels of 37, 39,
> > 41 and 43.
>
> Again, very similar to HT etc., which is all captured well by the
> chandef today.

Correct, there is only 1 new field required, that being the primary
channel location. Ill describe below.

> > Proposed Solution
> > -----------------
> >
> > We propose a new flag within struct ieee80211_channel_flags called
> > IEEE80211_CHAN_S1G_NO_PRIMARY or something similar that tells the
> > wireless subsystem that this channel cannot be used as a primary channel,
> > but is not disabled. This is an important distinction as during subchannel
> > validation, if a single subchannel is disabled that operating channel cannot
> > be used (similar to VHT and other PHY types) but an operating channel can
> > be used if an edgeband 1MHz channel has the NO_PRIMARY flag but is _not_
> > disabled.
> >
> > NB: While the existing for_each_subchan macro doesn't work for S1G channels
> >     given its fixed step size of 20MHz, this will be updated during
> >     the implementation.
> >
> > It's also important to note that this can only apply to edgeband primary
> > channels for the current regdom. This validation will be performed upon
> > advertisement by the driver of the available channels for the S1G band.
> > Additionally, puncturing is not supported for S1G.
> >
> > This will be an implementation detail, as this is not explicitly described
> > by the standard, but rather used by vendors to ensure FCC compliance.
>
> Hmm. So first I wanted to say that this totally makes sense to me. But
> actually I'm not so sure. I mean, get the restriction and why it's
> needed and all that, however, we have to consider interplay of various
> factors here.
>
> Consider the difference between AU and US in the regdb (the only
> countries currently listed with S1G support):
>
> country AU: DFS-ETSI
>         (915 - 920 @ 4), (1000 mW)
>         (920 - 928 @ 8), (1000 mW)
>
> country US: DFS-FCC
>         (902 - 904 @ 2), (30)
>         (904 - 920 @ 16), (30)
>         (920 - 928 @ 8), (30)
>
> I'm not sure which operating class you're applying to get those channel
> numbers in your figure above, so I'm going to have to handwave a bit.
> But assuming such a restriction also applies on the lower band edge
> (OFDM is symmetric, so it probably should) then you'd have to disable
> different channels in AU and US regdomains, since one starts at 902 MHz
> and the other only at 915 MHz. So for a channel that's between 915/916
> MHz (which according to your figure I guess would be channel 27?) you'd
> probably have to disable it in AU but not disable it in the US?

Correct.

> So I'm not sure statically disabling the channels from the driver works
> unless you assume there's no regulatory domain involved or anything?

Right now (as since I sent this eamil I've written the patchset) the firmware
notifies us of disabled primaries, so then driver would add the flag to the
selected channels before registering the wiphy.

> If I'm right about this, then perhaps it should be expressed as a
> (wiphy-specific) "primary channel band edge distance"?

This sounds like a reasonable idea, looking at handle_channel() we can
move the flag setting to reg.c (where it should be). This is a region specific
value as you correctly pointed out - the channels that will be flagged are
different in the US vs AU and so forth. Rather then commenting too much now,
we will explore the idea and explain what we end up doing in the initial RFC.
The main idea behind this email in the first place was just making sure the
flag is OK to be added, we can work out the implementation during the review
process.

> > Primary Channel Representation
> > ------------------------------
> >
> > One potential challenge with actually implementing primary channel support
> > is how and where the primary channel is described. Initially it was thought
> > that a channel definition could contain a separate struct ieee80211_channel
> > like such:
> >
> > struct cfg80211_chan_def {
> >         struct ieee80211_channel *chan;
> >         [...]
> >         struct ieee80211_channel *s1g_pri_chan;
> > };
>
> Just off-hand, that seems awkward.
>
> > The obvious problem with this is that now a channel definition describes two
> > channels, though you could argue that to correctly describe an S1G channel
> > you require both components - which in some regards makes sense to put them
> > both in the channel definition. It does, however, require various API changes,
> > with the biggest one being cfg80211_chandef_create() to accept the new primary
> > channel parameter. An alternative is to create an S1G specific chandef creation
> > function which can then call the generic form.
>
> Yeah, but not even just technically awkward.
>
> It's also a complete deviation from how anything else works, and you'd
> actually have to have different channel structs for all those
> 'aggregate' channels like 44, which we certainly don't do for EHT. If
> this is the wrong way to think about it in EHT, why would it be the
> right way to do it in S1G? Even in EHT the whole channel is "44" (to
> stay in your numbering scheme), but the full channel is expressed as the
> overall width/center_freq1, and the control/primary channel is the
> pointer to the channel struct, and channel structs only exist for the 20
> MHz channels.
>
> > Additionally, we can reuse cfg80211_chandef_valid() to perform validation as
> > both the operating channel and primary channel exist within the same
> > channel definition. By extension, many of the function that operate on a
> > chandef have access to both the primary channel and operating channel.
> > Definitely something to consider.
> >
> > The second option is to treat them as two separate channel definitions. This
> > is probably more "correct" as after all a primary channel is a separate channel.
> > While this approach doesn't require many major API changes like the previous
> > method, it still has some negatives. Firstly, the need to carry a separate
> > channel definition in various places. Taking struct ieee80211_chanctx_conf as
> > an example:
> >
> > struct ieee80211_chanctx_conf {
> >         struct cfg80211_chan_def def;
> >         [...]
> >         struct cfg80211_chan_def s1g_pri_def;
> > };
> >
> > When building this new channel definition, we probably don't want to be using
> > _nl80211_parse_chandef() as it relies on the NL80211_ATTR_WIPHY_FREQ to find
> > the channel, where the primary channel center frequency will rely on a separate
> > attribute. Now we could, of course, add in another branch to handle this case,
> > but the function seems fairly overloaded as is and would be good to keep the
> > S1G specific case separate.
>
> I'm not really sure this is all that much better?
>
> Why not do it similar to what HT/VHT/HE/EHT does, and have:
>
>  * ->chan points to the primary 1 MHz channel
>  * ->width is 1, 2, 4 or 8 - which already exist
>  * ->center_freq1/->freq1_offset is the center frequency of the entire
>    channel (e.g. 924 for channel 44 8MHz, or 921.5 for channel 39 1MHz)
>
> This doesn't capture the fact that the primary channel could be 2 MHz
> wide, either we add that as a separate channel struct (not sure?) or we
> just add a flag or something? TBH with how this was done I always
> assumed the primary channel was _always_ 1 MHz wide.

So you are right, I re-read the VHT channelisation and also the chandef
and everything is there except for the primary channel location (will get to
that shortly). Fleshing out your example:

* ->chan points to the primary 1MHz or 2MHz channel

S1G channels contain the width flag (IEEE80211_CHAN_1MHZ/2MHZ) so that
can completely represent the primary channel. This channel would then
be required to exist as a subchannel within the operating channels
frequency range. (I assume this to be the same case for VHT / EHT etc.)

* -> width 1/2/4/8

This would be the operating channel width, channel 44 would be 8MHz.

* ->center_freq1/->freq1_offset

This would be the operating channel center frequency. So for example,
channel 44 would be 924MHz.

As mentioned, the one difference is that S1G primary channels can be 2MHz.
The standard (and by extension, the S1G Operation element) uses the notion of
primary channel location. When we have a 2MHz primary channel, the AP must
specify which 1MHz subchannel _within_ this 2MHz primary channel is used.
Now Im inclined to place this in the chandef, as it's a value used to
"configure" a channel... :). Anyway, that is an implementation specific
thing - we can clarify that during the review process.

lachlan.




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux