diff mbox series

[7/7] cfg80211: save 6 GHz power mode of the regulatory rules

Message ID 20220704102341.5692-8-quic_adisi@quicinc.com
State Superseded
Headers show
Series [1/7] cfg80211: save Power Spectral Density (PSD) of the regulatory rule | expand

Commit Message

Aditya Kumar Singh July 4, 2022, 10:23 a.m. UTC
Currently when user space demands the reg rules via NL80211_CMD_GET_REG
command, along with Power Spectral Denity (PSD) values, power mode
needs to be advertised since in 6 GHz AP beacon, Tx power envelope
should have PSD info as well which can be opted based on the power
mode. Similarly, via NL80211_CMD_SET_REG command, user space can try
to set regulatory rules and cfg80211 needs to store the incoming power
mode for the rule.

Add support for 6 GHz power mode advertisement in
NL80211_CMD_GET_REG command and saving 6 GHz power mode for reg rules
via NL80211_CMD_SET_REG command.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 include/uapi/linux/nl80211.h |  4 ++++
 net/wireless/nl80211.c       | 20 ++++++++++++++++++++
 2 files changed, 24 insertions(+)
diff mbox series

Patch

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e62838887802..f2a32023a3f4 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4258,6 +4258,8 @@  enum nl80211_reg_type {
  *	If not present or 0 default CAC time will be used.
  * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
  *	This could be negative.
+ * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6 GHz rules.
+ *	Referenced from &enum nl80211_regulatory_power_modes
  * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
  *	currently defined
  * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
@@ -4277,6 +4279,8 @@  enum nl80211_reg_rule_attr {
 
 	NL80211_ATTR_POWER_RULE_PSD,
 
+	NL80211_ATTR_REG_POWER_MODE,
+
 	/* keep last */
 	__NL80211_REG_RULE_ATTR_AFTER_LAST,
 	NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 915516bd4d93..5c0ac12c26b7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8200,6 +8200,13 @@  static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
 				reg_rule->dfs_cac_ms))
 			goto nla_put_failure;
 
+		/* Put power mode as well if its a 6 GHz reg rule */
+		if (freq_range->start_freq_khz >= MHZ_TO_KHZ(5925) &&
+		    freq_range->end_freq_khz <= MHZ_TO_KHZ(7125) &&
+		    nla_put_u8(msg, NL80211_ATTR_REG_POWER_MODE,
+			       reg_rule->power_mode))
+			goto nla_put_failure;
+
 		if ((reg_rule->flags & NL80211_RRF_PSD) &&
 		    nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD,
 			       reg_rule->psd))
@@ -8379,6 +8386,10 @@  static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] =
 	[NL80211_ATTR_POWER_RULE_MAX_EIRP]	= { .type = NLA_U32 },
 	[NL80211_ATTR_DFS_CAC_TIME]		= { .type = NLA_U32 },
 	[NL80211_ATTR_POWER_RULE_PSD]		= { .type = NLA_S8 },
+	[NL80211_ATTR_REG_POWER_MODE]		=
+			  NLA_POLICY_RANGE(NLA_U8,
+					   NL80211_REG_AP_LPI,
+					   NL80211_REG_MAX_POWER_MODES),
 };
 
 static int parse_reg_rule(struct nlattr *tb[],
@@ -8426,6 +8437,15 @@  static int parse_reg_rule(struct nlattr *tb[],
 		reg_rule->dfs_cac_ms =
 			nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
 
+	if (freq_range->start_freq_khz >= MHZ_TO_KHZ(5925) &&
+	    freq_range->end_freq_khz <= MHZ_TO_KHZ(7125)) {
+		if (!tb[NL80211_ATTR_REG_POWER_MODE])
+			return -EINVAL;
+
+		reg_rule->power_mode =
+			nla_get_u8(tb[NL80211_ATTR_REG_POWER_MODE]);
+	}
+
 	return 0;
 }