wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/592-nl80211-validate-RU-puncturing-bitmap.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

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;
}