Skip to contentSkip to conversation

cfg80211: VHT regulatory

RFC Superseded Mahesh Palivela 2 participants 14 messages Sep 5, 2012 – Oct 19, 2012 802.11 (including cfg80211/NL80211)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

RFC v2 1/1 cfg80211: VHT regulatory

VHT (11ac) regulatory new design. VHT channel center freq, bandwidth and primary channel are used to decide if that channel config is permitted in current regulatory domain.

---
Implementation of review comments by Johannes.

include/net/cfg80211.h | 37 +++++++++++++++++
net/wireless/reg.c | 105 ++++++++++++++++++++++++++++++++++++++++++

 2 files changed, 142 insertions(+), 0 deletions(-)
include/net/cfg80211.h +37 -0
index 4c518f1..edc743f 100644
@@ -83,6 +83,25 @@ enum ieee80211_band {
 };
 
 /**
+ * enum ieee80211_chan_width - channel bandwidths
+ *
+ * @IEEE80211_CHAN_WIDTH_20MHZ_NOHT: 20 MHz chan bandwidth No HT
+ * @IEEE80211_CHAN_WIDTH_20MHZ: 20 MHz chan bandwidth
+ * @IEEE80211_CHAN_WIDTH_40MHZ: 40 MHz chan bandwidth
+ * @IEEE80211_CHAN_WIDTH_80MHZ: 80 MHz chan bandwidth
+ * @IEEE80211_CHAN_WIDTH_160MHZ: 160 MHz chan bandwidth
+ * @IEEE80211_CHAN_WIDTH_80P80MHZ: 80+80 MHz chan bandwidth
+ */
+enum ieee80211_chan_width {
+	IEEE80211_CHAN_WIDTH_20MHZ_NOHT,
+	IEEE80211_CHAN_WIDTH_20MHZ,
+	IEEE80211_CHAN_WIDTH_40MHZ,
+	IEEE80211_CHAN_WIDTH_80MHZ,
+	IEEE80211_CHAN_WIDTH_160MHZ,
+	IEEE80211_CHAN_WIDTH_80P80MHZ
+};
+
+/**
  * enum ieee80211_channel_flags - channel flags
  *
  * Channel flags set by the regulatory control code.
@@ -144,6 +163,24 @@ struct ieee80211_channel {
 };
 
 /**
+ * struct ieee80211_channel_config - channel config definition
+ *
+ * This structure describes channel configuration
+ *
+ * @chan_width1: channel bandwidth
+ * @center_freq1: center frequency of 1 st frequency segment
+ * @center_freq2: center frequency of 2 nd frequency segment
+ * 	Used only for 80+80 MHz combination
+ * @prim_chan_freq: primary channel frequency
+ */
+struct ieee80211_channel_config {
+	enum ieee80211_chan_width chan_width;
+	u16 center_freq1;
+	u16 center_freq2;
+	u16 prim_chan_freq;
+};
+
+/**
  * enum ieee80211_rate_flags - rate flags
  *
  * Hardware/specification flags for rates. These are structured
net/wireless/reg.c +105 -0

111 lines not on this page · raw message

maintainer
#1 lore raw
Quoted 10 lines · Mahesh Palivela

/**
+ * struct ieee80211_channel_config - channel config definition
+ *
+ * This structure describes channel configuration
+ *
+ * @chan_width1: channel bandwidth
+ * @center_freq1: center frequency of 1 st frequency segment
+ * @center_freq2: center frequency of 2 nd frequency segment
+ * Used only for 80+80 MHz combination
+ * @prim_chan_freq: primary channel frequency

I still don't like this as a frequency, I think it makes a lot more sense to stick to how the standard does it.

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1135

Quoted 9 lines
net/wireless/reg.c +9 -0
+static bool reg_sec_chans_permitted(struct wiphy *wiphy,
+				    u32 center_freq,
+				    u32 bw_khz)
+{
+	struct ieee80211_channel *chan;
+	u32 left_end_freq, right_end_freq;
+
+	if (center_freq == 0 || bw_khz == 0)
+		return false;

Can that actually happen?

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1174

Quoted 1 line
net/wireless/reg.c +1 -0
+	// get chan BW from config

Please don't use C99-style comments.

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1201

Quoted 3 lines
net/wireless/reg.c +3 -0
+	r = freq_reg_info_regd(wiphy,
+			       chan_config->prim_chan_freq,
+			       desired_bw_khz,

This is wrong, I think? We won't use 40/80/160 MHz around the primary channel frequency, we use it around the center_freq1/2.

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1220

Quoted 3 lines
net/wireless/reg.c +3 -0
+	ret = reg_sec_chans_permitted(wiphy,
+				      chan_config->center_freq1,
+				      desired_bw_khz);

This seems better, but is missing the bandwidth check?

johannes

#2 lore raw
Quoted 7 lines · Johannes Berg
Quoted 1 line · Mahesh Palivela

+ * @prim_chan_freq: primary channel frequency

I still don't like this as a frequency, I think it makes a lot more sense to stick to how the standard does it.

From spec:

Channel center frequency [MHz]
= Channel starting frequency + 5 * dot11CurrentChannelCenterFrequencyIndex

Primary 20 MHz channel center frequency [MHz]
= Channel starting frequency + 5 * dot11CurrentPrimaryChannel

The channel starting frequency is defined as dot11ChannelStartingFactor × 500 kHz. If a channel center frequency is 5.000 GHz, it shall be indicated by dot11ChannelStartingFactor = 8000 and dot11CurrentPrimaryChannel = 200

end spec:

So spec defined center freq index and prim channel numbers. From those we compute actual freq value. I though push arithmetic part to apps. If we move to represent as numbers then will change types from u16 to u8. Let me know.

Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if (center_freq == 0 || bw_khz == 0)
+		return false;

Can that actually happen?

just a defensive check. I can remove it, if redundant

Quoted 4 lines

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1174

Quoted 1 line
net/wireless/reg.c +1 -0
+	// get chan BW from config

Please don't use C99-style comments.

Sure. will change it.

Quoted 7 lines

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1201

Quoted 3 lines
net/wireless/reg.c +3 -0
+	r = freq_reg_info_regd(wiphy,
+			       chan_config->prim_chan_freq,
+			       desired_bw_khz,

This is wrong, I think? We won't use 40/80/160 MHz around the primary channel frequency, we use it around the center_freq1/2.

This is to find the regulatory rule only. Not checking desired BW around prim channel. center freq chan 42 of 36, 40, 44 and 48 for 80 MHz BW may not be in list of freq values in reg rule.

Quoted 5 lines

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1220

Quoted 3 lines
net/wireless/reg.c +3 -0
+	ret = reg_sec_chans_permitted(wiphy,
+				      chan_config->center_freq1,
+				      desired_bw_khz);

This seems better, but is missing the bandwidth check?

bandwidths are checked in reg_chan_use_permitted. reg rule decides it right?

Quoted 3 lines

johannes

maintainer
#3 lore raw
Quoted 17 lines · Mahesh Palivela
Quoted 7 lines · Johannes Berg
Quoted 1 line · Mahesh Palivela

+ * @prim_chan_freq: primary channel frequency

I still don't like this as a frequency, I think it makes a lot more sense to stick to how the standard does it.

From spec:

Channel center frequency [MHz]
= Channel starting frequency + 5 * dot11CurrentChannelCenterFrequencyIndex

Primary 20 MHz channel center frequency [MHz]
= Channel starting frequency + 5 * dot11CurrentPrimaryChannel

Quoted 8 lines

The channel starting frequency is defined as dot11ChannelStartingFactor × 500 kHz. If a channel center frequency is 5.000 GHz, it shall be indicated by dot11ChannelStartingFactor = 8000 and dot11CurrentPrimaryChannel = 200

end spec:

So spec defined center freq index and prim channel numbers.

No, it doesn't. It *derives* these. Check "Table 22-22—Fields to specify VHT channels" for how it actually *specifies* them.

Quoted 7 lines
Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if (center_freq == 0 || bw_khz == 0)
+		return false;

Can that actually happen?

just a defensive check. I can remove it, if redundant

I was thinking then it should have a WARN_ON_ONCE() maybe.

Quoted 11 lines
Quoted 7 lines

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1201

Quoted 3 lines
net/wireless/reg.c +3 -0
+	r = freq_reg_info_regd(wiphy,
+			       chan_config->prim_chan_freq,
+			       desired_bw_khz,

This is wrong, I think? We won't use 40/80/160 MHz around the primary channel frequency, we use it around the center_freq1/2.

This is to find the regulatory rule only. Not checking desired BW around prim channel. center freq chan 42 of 36, 40, 44 and 48 for 80 MHz BW may not be in list of freq values in reg rule.

Hmm? Don't think I understand this. Why do you pass in the right bandwidth if it's not used?

Quoted 7 lines
Quoted 5 lines

net/wireless/reg.c static void reg_process_beacons(struct wiphy *wiphy) · line 1220

Quoted 3 lines
net/wireless/reg.c +3 -0
+	ret = reg_sec_chans_permitted(wiphy,
+				      chan_config->center_freq1,
+				      desired_bw_khz);

This seems better, but is missing the bandwidth check?

bandwidths are checked in reg_chan_use_permitted. reg rule decides it right?

I guess I don't really understand this.

johannes

#4 lore raw
Quoted 6 lines · Johannes Berg
Quoted 1 line · Mahesh Palivela

On 09/05/2012 07:09 PM, Johannes Berg wrote:

No, it doesn't. It *derives* these. Check "Table 22-22—Fields to specify VHT channels" for how it actually *specifies* them.

hostapd.conf specifies using numbers only. hostapd converts to freq values, puts into NL attribs and cfg80211 directly gets freq values rather than channel numbers. we have to do these calculations either in app or cfg80211. user space vs krnl space. I am ok either way.

Quoted 6 lines
Quoted 2 lines

just a defensive check. I can remove it, if redundant

I was thinking then it should have a WARN_ON_ONCE() maybe.

ok. will put WARN_ON_ONCE()

Quoted 8 lines
Quoted 4 lines

This is to find the regulatory rule only. Not checking desired BW around prim channel. center freq chan 42 of 36, 40, 44 and 48 for 80 MHz BW may not be in list of freq values in reg rule.

Hmm? Don't think I understand this. Why do you pass in the right bandwidth if it's not used?

ok. I will define new freq_reg_info_regd() to take center freq and desired BW and return reg_rule. I think current freq_reg_info_regd() may fail if we give chan 42.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

This seems better, but is missing the bandwidth check?

bandwidths are checked in reg_chan_use_permitted. reg rule decides it right?

I guess I don't really understand this.

what should I do for bandwidth check in reg_sec_chans_permitted() ?

Quoted 2 lines

johannes

maintainer
#5 lore raw
Quoted 8 lines · Mahesh Palivela
Quoted 6 lines · Johannes Berg
Quoted 1 line · Mahesh Palivela

On 09/05/2012 07:09 PM, Johannes Berg wrote:

No, it doesn't. It *derives* these. Check "Table 22-22—Fields to specify VHT channels" for how it actually *specifies* them.

Quoted 5 lines

hostapd.conf specifies using numbers only. hostapd converts to freq values, puts into NL attribs and cfg80211 directly gets freq values rather than channel numbers.
we have to do these calculations either in app or cfg80211. user space vs krnl space. I am ok either way.

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

Quoted 11 lines
Quoted 7 lines
Quoted 3 lines

This is to find the regulatory rule only. Not checking desired BW around prim channel. center freq chan 42 of 36, 40, 44 and 48 for 80 MHz BW may not be in list of freq values in reg rule.

Hmm? Don't think I understand this. Why do you pass in the right bandwidth if it's not used?

ok. I will define new freq_reg_info_regd() to take center freq and desired BW and return reg_rule. I think current freq_reg_info_regd() may fail if we give chan 42.

I have no idea. I don't know the regulatory code very well, sorry.

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

This seems better, but is missing the bandwidth check?

bandwidths are checked in reg_chan_use_permitted. reg rule decides it right?

I guess I don't really understand this.

what should I do for bandwidth check in reg_sec_chans_permitted() ?

It seems to me that if we're going to specify things as an overall center frequency + bandwidth then we don't really care about primary/secondary channels? We'd rather just get the reg rule(s) from the center freq(s)/bandwidth, and then check all channels that happen to fall into this space, or something like that?

Even if we do that, there's still another issue though. Some drivers, like ours, don't support HT40 everywhere. Right now I believe we pretty much support HT40 everywhere that is allowed, but that might not be the case for all drivers.

So previously, the driver was able to set the IEEE80211_CHAN_NO_HT40PLUS etc. flags on a channel before registering. If we remove these flags we'll have to find a way to allow the driver to influence the decision about what is allowed in some way, I guess? Or maybe the driver would have to register a regulatory rule that encapsulates everything in the device's EEPROM?

johannes

#6 lore raw
Quoted 5 lines · Johannes Berg

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

If we don't have to do any calculation, what for the formulas in spec? converting chan number to frequency value. Just with channel number entire cfg,mac and drivers are fine?

Quoted 3 lines

I have no idea. I don't know the regulatory code very well, sorry.

Sorry I take it back. we can pass center freq to get reg rule. RFC v3 is on way ...

Quoted 12 lines

It seems to me that if we're going to specify things as an overall center frequency + bandwidth then we don't really care about primary/secondary channels? We'd rather just get the reg rule(s) from the center freq(s)/bandwidth, and then check all channels that happen to fall into this space, or something like that?

Even if we do that, there's still another issue though. Some drivers, like ours, don't support HT40 everywhere. Right now I believe we pretty much support HT40 everywhere that is allowed, but that might not be the case for all drivers.

Quoted 6 lines

So previously, the driver was able to set the IEEE80211_CHAN_NO_HT40PLUS etc. flags on a channel before registering. If we remove these flags we'll have to find a way to allow the driver to influence the decision about what is allowed in some way, I guess? Or maybe the driver would have to register a regulatory rule that encapsulates everything in the device's EEPROM?

Let me know if my RFC v3 is ok for this.

Quoted 3 lines

johannes

Signature · 2 lines
Thanks,
Mahesh
#7 lore raw
In reply to Johannes Berg
Quoted 6 lines · Johannes Berg

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

struct ieee80211_channel_config {
        enum ieee80211_chan_width chan_width;
        u16 center_freq1;
        u16 center_freq2;
        u16 prim_chan_freq;
};

If we stick to standard, all u16 become u8, as their values range is from 1-200. But these numbers have to be converted to freqKHz in reg_chan_use_permitted() to find fits in reg rule or not? Is that ok?

If so I have to use below formulas to get freqKHz.

Channel center frequency [MHz]
= Channel starting frequency + 5 x dot11CurrentChannelCenterFrequencyIndex

Primary 20 MHz channel center frequency [MHz]
= Channel starting frequency + 5  dot11CurrentPrimaryChannel

Thanks,
Mahesh

maintainer
#8 lore raw
Quoted 15 lines · Mahesh Palivela
Quoted 6 lines · Johannes Berg

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

struct ieee80211_channel_config {
         enum ieee80211_chan_width chan_width;
         u16 center_freq1;
         u16 center_freq2;
         u16 prim_chan_freq;
};
Quoted 4 lines

If we stick to standard, all u16 become u8, as their values range is from 1-200. But these numbers have to be converted to freqKHz in reg_chan_use_permitted() to find fits in reg rule or not? Is that ok?

I prefer MHz for center freqs, but offset for the primary channel, and this is exactly like table 22-22 in the 802.11ac draft, so only the "u16 primary_channel_freq" becomes "u8 primary_channel_offset", not all of them change, no?

johannes

maintainer
#9 lore raw
Quoted 21 lines · Johannes Berg
Quoted 15 lines · Mahesh Palivela
Quoted 6 lines · Johannes Berg

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

struct ieee80211_channel_config {
         enum ieee80211_chan_width chan_width;
         u16 center_freq1;
         u16 center_freq2;
         u16 prim_chan_freq;
};
Quoted 4 lines

If we stick to standard, all u16 become u8, as their values range is from 1-200. But these numbers have to be converted to freqKHz in reg_chan_use_permitted() to find fits in reg rule or not? Is that ok?

Quoted 4 lines

I prefer MHz for center freqs, but offset for the primary channel, and this is exactly like table 22-22 in the 802.11ac draft, so only the "u16 primary_channel_freq" becomes "u8 primary_channel_offset", not all of them change, no?

Ohh, wait, it's called frequency in table 22-22 but actually says the valid range is 1-200 ... wtf? Ok you're right, then it uses the equation 22-99, but ... hmm that's a bit stupid since it needs the (non-constant) "Channel starting frequency".

Ok so maybe that wasn't such a good idea. How about we just change prim_chan_freq to prim_chan_offset and leave the other two unchanged?

Sorry.

johannes

#10 lore raw
Quoted 27 lines · Johannes Berg
Quoted 21 lines · Johannes Berg
Quoted 15 lines · Mahesh Palivela
Quoted 6 lines · Johannes Berg

We don't have to do any calculation in kernel though as far as I can tell? Maybe we do need the channel, but I think in terms of *specifying*, in particular in the nl80211 and cfg80211 APIs, we should stick to the standard if we're going to change it now.

struct ieee80211_channel_config {
          enum ieee80211_chan_width chan_width;
          u16 center_freq1;
          u16 center_freq2;
          u16 prim_chan_freq;
};
Quoted 4 lines

If we stick to standard, all u16 become u8, as their values range is from 1-200. But these numbers have to be converted to freqKHz in reg_chan_use_permitted() to find fits in reg rule or not? Is that ok?

Quoted 4 lines

I prefer MHz for center freqs, but offset for the primary channel, and this is exactly like table 22-22 in the 802.11ac draft, so only the "u16 primary_channel_freq" becomes "u8 primary_channel_offset", not all of them change, no?

Quoted 7 lines

Ohh, wait, it's called frequency in table 22-22 but actually says the valid range is 1-200 ... wtf? Ok you're right, then it uses the equation 22-99, but ... hmm that's a bit stupid since it needs the (non-constant) "Channel starting frequency".

Ok so maybe that wasn't such a good idea. How about we just change prim_chan_freq to prim_chan_offset and leave the other two unchanged?

we need "channel starting frequency" anyways for calculating center freq. so we can use same constant for computing primary chan freq as well. why switch to prim_chan_offset?

Quoted 2 lines

Sorry.

Signature · 2 lines
Thanks,
Mahesh
maintainer
#11 lore raw
Quoted 10 lines · Mahesh Palivela
Quoted 10 lines
Quoted 4 lines

I prefer MHz for center freqs, but offset for the primary channel, and this is exactly like table 22-22 in the 802.11ac draft, so only the "u16 primary_channel_freq" becomes "u8 primary_channel_offset", not all of them change, no?

Ohh, wait, it's called frequency in table 22-22 but actually says the valid range is 1-200 ... wtf? Ok you're right, then it uses the equation 22-99, but ... hmm that's a bit stupid since it needs the (non-constant) "Channel starting frequency".

Quoted 6 lines
Quoted 2 lines

Ok so maybe that wasn't such a good idea. How about we just change prim_chan_freq to prim_chan_offset and leave the other two unchanged?

we need "channel starting frequency" anyways for calculating center freq. so we can use same constant for computing primary chan freq as well. why switch to prim_chan_offset?

I think it'd be easier for drivers, since they typically seem to use that to specify the control channel. If we give the frequency, they'll have to calculate back to offset. The offset is also used in IEs etc., so I think overall that would simplify things.

johannes

#12 lore raw
Quoted 9 lines · Johannes Berg
Quoted 4 lines

we need "channel starting frequency" anyways for calculating center freq. so we can use same constant for computing primary chan freq as well. why switch to prim_chan_offset?

I think it'd be easier for drivers, since they typically seem to use that to specify the control channel. If we give the frequency, they'll have to calculate back to offset. The offset is also used in IEs etc., so I think overall that would simplify things.

Offset means we specify one of -70, -50, -30, -10, +10, +30, +50, +70 for 80/160 MHz BW from center freq.
For ex. 80 MHz BW of channel 36, 40, 44 and 48 center freq is 42. If control chan 36, then we specify offset -30. Is that what we want?

VHT IEs doesn't use offset anywhere. I am not sure why/where drivers use offset values.

maintainer
#13 lore raw
Quoted 11 lines · Mahesh Palivela
Quoted 9 lines · Johannes Berg
Quoted 4 lines

we need "channel starting frequency" anyways for calculating center freq. so we can use same constant for computing primary chan freq as well. why switch to prim_chan_offset?

I think it'd be easier for drivers, since they typically seem to use that to specify the control channel. If we give the frequency, they'll have to calculate back to offset. The offset is also used in IEs etc., so I think overall that would simplify things.

Quoted 7 lines

Offset means we specify one of -70, -50, -30, -10, +10, +30, +50, +70 for 80/160 MHz BW from center freq.
For ex. 80 MHz BW of channel 36, 40, 44 and 48 center freq is 42. If control chan 36, then we specify offset -30. Is that what we want?

VHT IEs doesn't use offset anywhere. I am not sure why/where drivers use offset values.

Ok, d'oh, our device uses an offset but I just reviewed the spec and that just says the control channel is specified in the *HT* IE...

SO let's do what you suggested before and have all the three different frequencies.

johannes