mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
146 lines
4.6 KiB
Diff
146 lines
4.6 KiB
Diff
From 726f01686254ab45b8bdbe1403e52460254201f3 Mon Sep 17 00:00:00 2001
|
|
From: Aloka Dixit <quic_alokad@quicinc.com>
|
|
Date: Mon, 14 Feb 2022 14:30:51 -0800
|
|
Subject: [PATCH 3/7] nl80211: validate RU puncturing bitmap
|
|
|
|
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 | 10 ++++++++
|
|
net/wireless/nl80211.c | 49 ++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 59 insertions(+)
|
|
|
|
--- a/include/uapi/linux/nl80211.h
|
|
+++ b/include/uapi/linux/nl80211.h
|
|
@@ -2776,6 +2776,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
|
|
@@ -3320,6 +3328,10 @@ enum nl80211_attrs {
|
|
|
|
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 */
|
|
|
|
__NL80211_ATTR_AFTER_LAST,
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -854,6 +854,8 @@ static const struct nla_policy nl80211_p
|
|
[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
|
|
[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 */
|
|
@@ -3239,6 +3241,46 @@ static bool nl80211_can_set_dev_channel(
|
|
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)
|
|
@@ -3247,6 +3289,7 @@ int nl80211_parse_chandef(struct cfg8021
|
|
struct nlattr **attrs = info->attrs;
|
|
enum nl80211_regulatory_power_modes mode = NL80211_REG_AP_LPI;
|
|
u32 control_freq;
|
|
+ int err;
|
|
|
|
if (!attrs[NL80211_ATTR_WIPHY_FREQ])
|
|
return -EINVAL;
|
|
@@ -3343,6 +3386,12 @@ int nl80211_parse_chandef(struct cfg8021
|
|
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]);
|
|
@@ -3835,6 +3884,16 @@ static int nl80211_send_chandef(struct s
|
|
if (chandef->center_freq2 &&
|
|
nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
|
|
return -ENOBUFS;
|
|
+
|
|
+ if (chandef->ru_punct_bitmap) {
|
|
+ if (chandef->ru_punct_bitmap_supp_he &&
|
|
+ nla_put_flag(msg, NL80211_ATTR_RU_PUNCT_SUPP_HE))
|
|
+ return -ENOBUFS;
|
|
+ if (nla_put_u16(msg, NL80211_ATTR_RU_PUNCT_BITMAP,
|
|
+ chandef->ru_punct_bitmap))
|
|
+ return -ENOBUFS;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|