diff mbox series

[v2,3/4] nl80211: validate RU puncturing bitmap

Message ID 20220323191640.31230-3-quic_alokad@quicinc.com
State New
Headers show
Series [v2,1/4] nl80211: advertise RU puncturing support to userspace | expand

Commit Message

Aloka Dixit March 23, 2022, 7:16 p.m. UTC
Add new attributes NL80211_ATTR_RU_PUNCT_BITMAP and
NL80211_ATTR_RU_PUNCT_SUPP_HE to receive RU puncturing information
from the userspace.
- Bitmap consists of 16 bits, each bit corresponding to a 20 MHz
channel in the operating bandwidth. Lowest bit corresponds to
the lowest frequency. Validate the bitmap against the minimum
bandwidth support advertised by the driver.
- HE support flag indicates whether OFDMA puncturing patterns
should be considered during validation.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
---
 include/uapi/linux/nl80211.h | 20 +++++++++++++++
 net/wireless/nl80211.c       | 49 ++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
diff mbox series

Patch

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index bdd2cb22b5a0..e8b9f07cdd38 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1469,6 +1469,8 @@  enum nl80211_commands {
 
 	NL80211_CMD_SET_SAR_SPECS,
 
+	NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS,
+
 	NL80211_CMD_OBSS_COLOR_COLLISION,
 
 	NL80211_CMD_COLOR_CHANGE_REQUEST,
@@ -1477,6 +1479,8 @@  enum nl80211_commands {
 	NL80211_CMD_COLOR_CHANGE_ABORTED,
 	NL80211_CMD_COLOR_CHANGE_COMPLETED,
 
+	NL80211_CMD_AWGN_DETECT,
+
 	NL80211_CMD_SET_FILS_AAD,
 
 	NL80211_CMD_ASSOC_COMEBACK,
@@ -2667,6 +2671,14 @@  enum nl80211_commands {
  *	the driver supports preamble puncturing, value should be of type
  *	&enum nl80211_ru_punct_supp_bw
  *
+ * @NL80211_ATTR_RU_PUNCT_SUPP_HE: flag attribute, used to indicate that RU
+ *	puncturing bitmap validation should include OFDMA bitmaps.
+ *
+ * @NL80211_ATTR_RU_PUNCT_BITMAP: (u16) RU puncturing bitmap where the lowest
+ *	bit corresponds to the lowest 20 MHz channel. Each bit set to 1
+ *	indicates that the sub-channel is punctured, set 0 indicates that the
+ *	channel is active.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3164,6 +3176,8 @@  enum nl80211_attrs {
 
 	NL80211_ATTR_DISABLE_HE,
 
+	NL80211_ATTR_HE_MUEDCA_PARAMS,
+
 	NL80211_ATTR_OBSS_COLOR_BITMAP,
 
 	NL80211_ATTR_COLOR_CHANGE_COUNT,
@@ -3180,6 +3194,8 @@  enum nl80211_attrs {
 	NL80211_ATTR_EHT_CAPABILITY,
 
 	NL80211_ATTR_RU_PUNCT_SUPP_BW,
+	NL80211_ATTR_RU_PUNCT_SUPP_HE,
+	NL80211_ATTR_RU_PUNCT_BITMAP,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -4170,6 +4186,10 @@  enum nl80211_reg_rule_attr {
 
 	NL80211_ATTR_DFS_CAC_TIME,
 
+	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 1fbfda2b3b14..e3a7a94d89ca 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -792,6 +792,8 @@  static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 				 NL80211_EHT_MAX_CAPABILITY_LEN),
 	[NL80211_ATTR_RU_PUNCT_SUPP_BW] =
 		NLA_POLICY_MAX(NLA_U8, NL80211_RU_PUNCT_SUPP_BW_320),
+	[NL80211_ATTR_RU_PUNCT_SUPP_HE] = { .type = NLA_FLAG },
+	[NL80211_ATTR_RU_PUNCT_BITMAP] = { .type = NLA_U16 },
 };
 
 /* policy for the key attributes */
@@ -3122,6 +3124,46 @@  static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
 		wdev->iftype == NL80211_IFTYPE_P2P_GO;
 }
 
+static int nl80211_parse_ru_punct_bitmap(struct cfg80211_registered_device *rdev,
+					 struct genl_info *info,
+					 struct cfg80211_chan_def *chandef)
+{
+	chandef->ru_punct_bitmap_supp_he =
+		nla_get_flag(info->attrs[NL80211_ATTR_RU_PUNCT_SUPP_HE]);
+
+	chandef->ru_punct_bitmap =
+		nla_get_u16(info->attrs[NL80211_ATTR_RU_PUNCT_BITMAP]);
+
+	if (!chandef->ru_punct_bitmap)
+		return 0;
+
+	if (!rdev->wiphy.ru_punct_supp_bw &&
+	    (chandef->ru_punct_bitmap || chandef->ru_punct_bitmap_supp_he))
+		return -EOPNOTSUPP;
+
+	switch (chandef->width) {
+	case NL80211_CHAN_WIDTH_80:
+		if (rdev->wiphy.ru_punct_supp_bw >=
+		    NL80211_RU_PUNCT_SUPP_BW_160)
+			return -EOPNOTSUPP;
+		break;
+
+	case NL80211_CHAN_WIDTH_160:
+		if (rdev->wiphy.ru_punct_supp_bw >=
+		    NL80211_RU_PUNCT_SUPP_BW_320)
+			return -EOPNOTSUPP;
+		break;
+
+	case NL80211_CHAN_WIDTH_320:
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 			  struct genl_info *info,
 			  struct cfg80211_chan_def *chandef)
@@ -3129,6 +3171,7 @@  int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 	struct netlink_ext_ack *extack = info->extack;
 	struct nlattr **attrs = info->attrs;
 	u32 control_freq;
+	int err;
 
 	if (!attrs[NL80211_ATTR_WIPHY_FREQ])
 		return -EINVAL;
@@ -3205,6 +3248,12 @@  int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 				nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
 	}
 
+	if (info->attrs[NL80211_ATTR_RU_PUNCT_BITMAP]) {
+		err = nl80211_parse_ru_punct_bitmap(rdev, info, chandef);
+		if (err)
+			return err;
+	}
+
 	if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
 		chandef->edmg.channels =
 		      nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);