Search Linux Wireless

[RFC 3/4] wifi: nl80211: validate RU puncturing bitmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Aloka Dixit <quic_alokad@xxxxxxxxxxx>

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@xxxxxxxxxxx>
Co-developed-by: Muna Sinada <quic_msinada@xxxxxxxxxxx>
Signed-off-by: Muna Sinada <quic_msinada@xxxxxxxxxxx>
---
 include/uapi/linux/nl80211.h | 10 ++++++++++
 net/wireless/nl80211.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e5218fd7b37b..286579d56809 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2756,6 +2756,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
@@ -3287,6 +3295,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_TD_BITMAP,
 
 	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 */
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4b4cb3c64f62..fd7d83c533a8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -807,6 +807,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
 	[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 */
@@ -3192,6 +3194,38 @@ 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 net_device *dev,
+					 struct genl_info *info,
+					 struct vif_params *params)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	bool change = false;
+
+	if (info->attrs[NL80211_ATTR_RU_PUNCT_BITMAP]) {
+		params->ru_punct_bitmap =
+			 nla_get_u16(info->attrs[NL80211_ATTR_RU_PUNCT_BITMAP]);
+
+	if (!params->ru_punct_bitmap)
+		return change;
+
+	params->ru_punct_bitmap_supp_he =
+		nla_get_flag(info->attrs[NL80211_ATTR_RU_PUNCT_SUPP_HE]);
+
+	if (!rdev->wiphy.ru_punct_supp_bw &&
+	    (params->ru_punct_bitmap || params->ru_punct_bitmap_supp_he))
+		return -EOPNOTSUPP;
+
+	changed = true;
+
+	wdev_lock(wdev);
+	wdev->ru_punct_bitmap_supp_he = params->ru_punct_bitmap_supp_he;
+	wdev->ru_punct_bitmap = params->ru_punct_bitmap;
+	wdev_unlock(wdev);
+
+	return change ? 1 : 0;
+}
+
 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 			  struct genl_info *info,
 			  struct cfg80211_chan_def *chandef)
@@ -4175,6 +4209,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 		params.use_4addr = -1;
 	}
 
+	err = nl80211_parse_ru_punct_bitmap(rdev, dev, info, &params);
+	if (err < 0)
+		return err;
+	else if (err > 0)
+		change = true;
+
 	err = nl80211_parse_mon_options(rdev, ntype, info, &params);
 	if (err < 0)
 		return err;
-- 
2.7.4




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux