nl80211: Process 6 GHz regulatory rules to accurate channel flags

This is needed to be able to indicate all supported operating classes.

Signed-off-by: Ainy Kumari <quic_ainykuma@quicinc.com>
This commit is contained in:
Ainy Kumari 2024-02-22 09:32:04 +05:30 committed by Jouni Malinen
parent 59951ebf09
commit e74d95e0aa
2 changed files with 59 additions and 0 deletions

View file

@ -43,6 +43,7 @@
#define HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL 0x00000800 #define HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL 0x00000800
#define HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL 0x00001000 #define HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL 0x00001000
#define HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL 0x00002000
#define HOSTAPD_CHAN_INDOOR_ONLY 0x00010000 #define HOSTAPD_CHAN_INDOOR_ONLY 0x00010000
#define HOSTAPD_CHAN_GO_CONCURRENT 0x00020000 #define HOSTAPD_CHAN_GO_CONCURRENT 0x00020000

View file

@ -2405,6 +2405,57 @@ static void nl80211_reg_rule_vht(struct nlattr *tb[],
} }
static void nl80211_set_6ghz_mode(struct hostapd_hw_modes *mode, int start,
int end, int max_bw)
{
int c;
for (c = 0; c < mode->num_channels; c++) {
struct hostapd_channel_data *chan = &mode->channels[c];
if (chan->freq - 10 < start || chan->freq + 10 > end)
continue;
if (max_bw >= 80)
chan->flag |= HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL;
if (max_bw >= 160)
chan->flag |= HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL;
if (max_bw >= 320)
chan->flag |= HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL;
}
}
static void nl80211_reg_rule_6ghz(struct nlattr *tb[],
struct phy_info_arg *results)
{
u32 start, end, max_bw;
u16 m;
if (!tb[NL80211_ATTR_FREQ_RANGE_START] ||
!tb[NL80211_ATTR_FREQ_RANGE_END] ||
!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
return;
start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
if (max_bw < 80)
return;
for (m = 0; m < *results->num_modes; m++) {
if (results->modes[m].num_channels == 0 ||
!is_6ghz_freq(results->modes[m].channels[0].freq))
continue;
nl80211_set_6ghz_mode(&results->modes[m], start, end, max_bw);
}
}
static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region, static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region,
u8 *dfs_domain) u8 *dfs_domain)
{ {
@ -2523,6 +2574,13 @@ static int nl80211_get_reg(struct nl_msg *msg, void *arg)
nl80211_reg_rule_vht(tb_rule, results); nl80211_reg_rule_vht(tb_rule, results);
} }
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
nl80211_reg_rule_6ghz(tb_rule, results);
}
return NL_SKIP; return NL_SKIP;
} }