aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch398
1 files changed, 0 insertions, 398 deletions
diff --git a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch
deleted file mode 100644
index a47e29794c..0000000000
--- a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch
+++ /dev/null
@@ -1,398 +0,0 @@
-From: Carl Huang <cjhuang@codeaurora.org>
-Date: Thu, 3 Dec 2020 05:37:26 -0500
-Subject: [PATCH] nl80211: add common API to configure SAR power limitations
-
-NL80211_CMD_SET_SAR_SPECS is added to configure SAR from
-user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR
-power specification when used with NL80211_CMD_SET_SAR_SPECS.
-
-Wireless driver needs to register SAR type, supported frequency
-ranges to wiphy, so user space can query it. The index in
-frequency range is used to specify which sub band the power
-limitation applies to. The SAR type is for compatibility, so later
-other SAR mechanism can be implemented without breaking the user
-space SAR applications.
-
-Normal process is user space queries the SAR capability, and
-gets the index of supported frequency ranges and associates the
-power limitation with this index and sends to kernel.
-
-Here is an example of message send to kernel:
-8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81
-08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80
-08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00
-14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00
-48 00 00 00
-
-NL80211_CMD_SET_SAR_SPECS: 0x8c
-NL80211_ATTR_WIPHY: 0x01(phy idx is 0)
-NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED)
-NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER)
-NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED)
-freq range 0 power: 0x38 in 0.25dbm unit (14dbm)
-freq range 1 power: 0x48 in 0.25dbm unit (18dbm)
-
-Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
-Reviewed-by: Brian Norris <briannorris@chromium.org>
-Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
-Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org
-[minor edits, NLA parse cleanups]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1737,6 +1737,54 @@ struct station_info {
- u8 connected_to_as;
- };
-
-+/**
-+ * struct cfg80211_sar_sub_specs - sub specs limit
-+ * @power: power limitation in 0.25dbm
-+ * @freq_range_index: index the power limitation applies to
-+ */
-+struct cfg80211_sar_sub_specs {
-+ s32 power;
-+ u32 freq_range_index;
-+};
-+
-+/**
-+ * struct cfg80211_sar_specs - sar limit specs
-+ * @type: it's set with power in 0.25dbm or other types
-+ * @num_sub_specs: number of sar sub specs
-+ * @sub_specs: memory to hold the sar sub specs
-+ */
-+struct cfg80211_sar_specs {
-+ enum nl80211_sar_type type;
-+ u32 num_sub_specs;
-+ struct cfg80211_sar_sub_specs sub_specs[];
-+};
-+
-+
-+/**
-+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges
-+ * @start_freq: start range edge frequency
-+ * @end_freq: end range edge frequency
-+ */
-+struct cfg80211_sar_freq_ranges {
-+ u32 start_freq;
-+ u32 end_freq;
-+};
-+
-+/**
-+ * struct cfg80211_sar_capa - sar limit capability
-+ * @type: it's set via power in 0.25dbm or other types
-+ * @num_freq_ranges: number of frequency ranges
-+ * @freq_ranges: memory to hold the freq ranges.
-+ *
-+ * Note: WLAN driver may append new ranges or split an existing
-+ * range to small ones and then append them.
-+ */
-+struct cfg80211_sar_capa {
-+ enum nl80211_sar_type type;
-+ u32 num_freq_ranges;
-+ const struct cfg80211_sar_freq_ranges *freq_ranges;
-+};
-+
- #if IS_ENABLED(CPTCFG_CFG80211)
- /**
- * cfg80211_get_station - retrieve information about a given station
-@@ -4259,6 +4307,8 @@ struct cfg80211_ops {
- struct cfg80211_tid_config *tid_conf);
- int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
- const u8 *peer, u8 tids);
-+ int (*set_sar_specs)(struct wiphy *wiphy,
-+ struct cfg80211_sar_specs *sar);
- };
-
- /*
-@@ -5030,6 +5080,8 @@ struct wiphy {
-
- u8 max_data_retry_count;
-
-+ const struct cfg80211_sar_capa *sar_capa;
-+
- char priv[] __aligned(NETDEV_ALIGN);
- };
-
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL
- .len = IEEE80211_MAX_DATA_LEN }
- };
-
-+static const struct nla_policy
-+sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
-+ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
-+ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
-+};
-+
-+static const struct nla_policy
-+sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
-+ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
-+ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
-+};
-+
- static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
- [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
- [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
-@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p
- [NL80211_ATTR_SAE_PWE] =
- NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
- NL80211_SAE_PWE_BOTH),
-+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
- [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
- };
-
-@@ -2117,6 +2130,56 @@ fail:
- return -ENOBUFS;
- }
-
-+static int
-+nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
-+ struct sk_buff *msg)
-+{
-+ struct nlattr *sar_capa, *specs, *sub_freq_range;
-+ u8 num_freq_ranges;
-+ int i;
-+
-+ if (!rdev->wiphy.sar_capa)
-+ return 0;
-+
-+ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
-+
-+ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
-+ if (!sar_capa)
-+ return -ENOSPC;
-+
-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
-+ goto fail;
-+
-+ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
-+ if (!specs)
-+ goto fail;
-+
-+ /* report supported freq_ranges */
-+ for (i = 0; i < num_freq_ranges; i++) {
-+ sub_freq_range = nla_nest_start(msg, i + 1);
-+ if (!sub_freq_range)
-+ goto fail;
-+
-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
-+ rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
-+ goto fail;
-+
-+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
-+ rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
-+ goto fail;
-+
-+ nla_nest_end(msg, sub_freq_range);
-+ }
-+
-+ nla_nest_end(msg, specs);
-+ nla_nest_end(msg, sar_capa);
-+
-+ return 0;
-+fail:
-+ nla_nest_cancel(msg, sar_capa);
-+ return -ENOBUFS;
-+}
-+
- struct nl80211_dump_wiphy_state {
- s64 filter_wiphy;
- long start;
-@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg
- CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
- CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
- CMD(update_ft_ies, UPDATE_FT_IES);
-+ if (rdev->wiphy.sar_capa)
-+ CMD(set_sar_specs, SET_SAR_SPECS);
- }
- #undef CMD
-
-@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg
-
- if (nl80211_put_tid_config_support(rdev, msg))
- goto nla_put_failure;
-+ state->split_start++;
-+ break;
-+ case 16:
-+ if (nl80211_put_sar_specs(rdev, msg))
-+ goto nla_put_failure;
-
- /* done */
- state->split_start = 0;
-@@ -14712,6 +14782,111 @@ static void nl80211_post_doit(__genl_con
- }
- }
-
-+static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
-+ struct cfg80211_sar_specs *sar_specs,
-+ struct nlattr *spec[], int index)
-+{
-+ u32 range_index, i;
-+
-+ if (!sar_specs || !spec)
-+ return -EINVAL;
-+
-+ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
-+ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
-+ return -EINVAL;
-+
-+ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
-+
-+ /* check if range_index exceeds num_freq_ranges */
-+ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
-+ return -EINVAL;
-+
-+ /* check if range_index duplicates */
-+ for (i = 0; i < index; i++) {
-+ if (sar_specs->sub_specs[i].freq_range_index == range_index)
-+ return -EINVAL;
-+ }
-+
-+ sar_specs->sub_specs[index].power =
-+ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
-+
-+ sar_specs->sub_specs[index].freq_range_index = range_index;
-+
-+ return 0;
-+}
-+
-+static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
-+{
-+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
-+ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
-+ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
-+ struct cfg80211_sar_specs *sar_spec;
-+ enum nl80211_sar_type type;
-+ struct nlattr *spec_list;
-+ u32 specs;
-+ int rem, err;
-+
-+ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
-+ return -EOPNOTSUPP;
-+
-+ if (!info->attrs[NL80211_ATTR_SAR_SPEC])
-+ return -EINVAL;
-+
-+ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
-+ info->attrs[NL80211_ATTR_SAR_SPEC],
-+ NULL, NULL);
-+
-+ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
-+ return -EINVAL;
-+
-+ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
-+ if (type != rdev->wiphy.sar_capa->type)
-+ return -EINVAL;
-+
-+ specs = 0;
-+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
-+ specs++;
-+
-+ if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
-+ return -EINVAL;
-+
-+ sar_spec = kzalloc(sizeof(*sar_spec) +
-+ specs * sizeof(struct cfg80211_sar_sub_specs),
-+ GFP_KERNEL);
-+ if (!sar_spec)
-+ return -ENOMEM;
-+
-+ sar_spec->type = type;
-+ specs = 0;
-+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
-+ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
-+ spec_list, NULL, NULL);
-+
-+ switch (type) {
-+ case NL80211_SAR_TYPE_POWER:
-+ if (nl80211_set_sar_sub_specs(rdev, sar_spec,
-+ spec, specs)) {
-+ err = -EINVAL;
-+ goto error;
-+ }
-+ break;
-+ default:
-+ err = -EINVAL;
-+ goto error;
-+ }
-+ specs++;
-+ }
-+
-+ sar_spec->num_sub_specs = specs;
-+
-+ rdev->cur_cmd_info = info;
-+ err = rdev_set_sar_specs(rdev, sar_spec);
-+ rdev->cur_cmd_info = NULL;
-+error:
-+ kfree(sar_spec);
-+ return err;
-+}
-+
- static __genl_const struct genl_ops nl80211_ops[] = {
- {
- .cmd = NL80211_CMD_GET_WIPHY,
-@@ -15575,6 +15750,14 @@ static const struct genl_small_ops nl802
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
- NL80211_FLAG_NEED_RTNL,
- },
-+ {
-+ .cmd = NL80211_CMD_SET_SAR_SPECS,
-+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
-+ .doit = nl80211_set_sar_specs,
-+ .flags = GENL_UNS_ADMIN_PERM,
-+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
-+ NL80211_FLAG_NEED_RTNL,
-+ },
- };
-
- static struct genl_family nl80211_fam __genl_ro_after_init = {
---- a/net/wireless/rdev-ops.h
-+++ b/net/wireless/rdev-ops.h
-@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config(
- return ret;
- }
-
-+static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev,
-+ struct cfg80211_sar_specs *sar)
-+{
-+ int ret;
-+
-+ trace_rdev_set_sar_specs(&rdev->wiphy, sar);
-+ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar);
-+ trace_rdev_return_int(&rdev->wiphy, ret);
-+
-+ return ret;
-+}
-+
- #endif /* __CFG80211_RDEV_OPS */
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config,
- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x",
- WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids)
- );
-+
-+TRACE_EVENT(rdev_set_sar_specs,
-+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar),
-+ TP_ARGS(wiphy, sar),
-+ TP_STRUCT__entry(
-+ WIPHY_ENTRY
-+ __field(u16, type)
-+ __field(u16, num)
-+ ),
-+ TP_fast_assign(
-+ WIPHY_ASSIGN;
-+ __entry->type = sar->type;
-+ __entry->num = sar->num_sub_specs;
-+
-+ ),
-+ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d",
-+ WIPHY_PR_ARG, __entry->type, __entry->num)
-+);
-+
- #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
-
- #undef TRACE_INCLUDE_PATH