cfg80211: VHT regulatory
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
@@ -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
Johannes Berg
maintainerQuoted 10 lines · Mahesh Palivela
/**
+ * structieee80211_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
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
Johannes Berg
maintainerQuoted 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 * dot11CurrentChannelCenterFrequencyIndexPrimary 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
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
Johannes Berg
maintainerQuoted 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 returnreg_rule. I think currentfreq_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
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_HT40PLUSetc. 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
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
Johannes Berg
maintainerQuoted 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
Johannes Berg
maintainerQuoted 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 "u8primary_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
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 "u8primary_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_freqtoprim_chan_offsetand 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
Johannes Berg
maintainerQuoted 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 "u8primary_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_freqtoprim_chan_offsetand 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
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.
Johannes Berg
maintainerQuoted 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