iwmon: parse ATTR_REG_RULES

This parses out the regulatory rules and prints them.
This commit is contained in:
James Prestwood 2022-02-25 09:58:09 -08:00 committed by Denis Kenzior
parent 999879c9b8
commit 3348f20696
1 changed files with 89 additions and 1 deletions

View File

@ -5455,6 +5455,93 @@ static void print_wiphy_bands(unsigned int level, const char *label,
}
}
static void print_reg_rule_flags(unsigned int level, const char *label,
const void *data, uint16_t size)
{
uint32_t flag;
flag = l_get_u32(data);
if (!flag)
return;
print_attr(level, "%s: len %u", label, size);
if (flag & NL80211_RRF_NO_OFDM)
print_attr(level + 1, "No ODFM");
if (flag & NL80211_RRF_NO_CCK)
print_attr(level + 1, "No CCK");
if (flag & NL80211_RRF_NO_INDOOR)
print_attr(level + 1, "No Indoor");
if (flag & NL80211_RRF_NO_OUTDOOR)
print_attr(level + 1, "No Outdoor");
if (flag & NL80211_RRF_DFS)
print_attr(level + 1, "DFS");
if (flag & NL80211_RRF_PTP_ONLY)
print_attr(level + 1, "PTP Only");
if (flag & NL80211_RRF_PTMP_ONLY)
print_attr(level + 1, "PTMP Only");
if (flag & NL80211_RRF_NO_IR)
print_attr(level + 1, "No IR");
if (flag & __NL80211_RRF_NO_IBSS)
print_attr(level + 1, "No IBSS");
if (flag & NL80211_RRF_AUTO_BW)
print_attr(level + 1, "Auto BW");
if (flag & NL80211_RRF_IR_CONCURRENT)
print_attr(level + 1, "IR Concurrent");
if (flag & NL80211_RRF_NO_HT40MINUS)
print_attr(level + 1, "No HT40-");
if (flag & NL80211_RRF_NO_HT40PLUS)
print_attr(level + 1, "No HT40+");
if (flag & NL80211_RRF_NO_80MHZ)
print_attr(level + 1, "No 80MHz");
if (flag & NL80211_RRF_NO_160MHZ)
print_attr(level + 1, "No 160MHz");
if (flag & NL80211_RRF_NO_HE)
print_attr(level + 1, "No HE");
}
static void print_u32_div_1000(unsigned int level, const char *label,
const void *data, uint16_t size)
{
uint32_t val = l_get_u32(data) / 1000;
print_attr(level, "%s: %u MHz", label, val);
}
static const struct attr_entry reg_rule_table[] = {
{ NL80211_ATTR_REG_RULE_FLAGS, "Flags", ATTR_CUSTOM,
{ .function = print_reg_rule_flags } },
{ NL80211_ATTR_FREQ_RANGE_START, "Frequency Start", ATTR_CUSTOM,
{ .function = print_u32_div_1000 } },
{ NL80211_ATTR_FREQ_RANGE_END, "Frequency End", ATTR_CUSTOM,
{ .function = print_u32_div_1000 } },
{ NL80211_ATTR_FREQ_RANGE_MAX_BW, "Frequency Range Max BW", ATTR_CUSTOM,
{ .function = print_u32_div_1000 } },
{ NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, "Max Antenna Gain", ATTR_U32 },
{ NL80211_ATTR_POWER_RULE_MAX_EIRP, "Max EIRP", ATTR_U32 },
{ NL80211_ATTR_DFS_CAC_TIME, "DFS CAC Time", ATTR_U32 },
{ }
};
static void print_reg_rules(unsigned int level, const char *label,
const void *data, uint16_t size)
{
const struct nlattr *nla;
uint16_t nla_type;
print_attr(level, "%s: len %u", label, size);
for (nla = data; NLA_OK(nla, size); nla = NLA_NEXT(nla, size)) {
nla_type = nla->nla_type & NLA_TYPE_MASK;
print_attr(level + 1, "Rule %u: len %u", nla_type,
NLA_PAYLOAD(nla));
print_attributes(level + 2, reg_rule_table,
NLA_DATA(nla), NLA_PAYLOAD(nla));
}
}
static void print_eapol_key(unsigned int level, const void *data, uint32_t size)
{
const struct eapol_key *ek = (struct eapol_key *)data;
@ -6004,7 +6091,8 @@ static const struct attr_entry attr_table[] = {
{ NL80211_ATTR_REG_ALPHA2,
"Regulatory Alpha2", ATTR_STRING },
{ NL80211_ATTR_REG_RULES,
"Regulatory Rules" },
"Regulatory Rules", ATTR_CUSTOM,
{ .function = print_reg_rules } },
{ NL80211_ATTR_MESH_CONFIG,
"Mesh Configuration" },
{ NL80211_ATTR_BSS_BASIC_RATES,