[RFC 1/2] nl80211: add common API to configure SAR power limitations.
cjhuang at codeaurora.org
cjhuang at codeaurora.org
Tue Sep 22 01:47:24 EDT 2020
Sorry, send to wrong ath11k list.
Let me resend to ath10k list for these 2 patches.
Thanks,
Carl
On 2020-09-22 13:36, Carl Huang wrote:
> 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 quries 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 03 00 15 00 00 00 38 00 26 81
> 08 00 01 00 00 00 00 00 2c 00 02 80 14 00 01 80
> 05 00 02 00 00 00 00 00 05 00 01 00 38 00 00 00
> 14 00 02 80 05 00 02 00 01 00 00 00 05 00 01 00
> 48 00 00 00
>
> NL80211_CMD_SET_SAR_SPECS: 0x8c
> NL80211_ATTR_SAR_SPEC: 0x8126 (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 at codeaurora.org>
> ---
> include/net/cfg80211.h | 52 +++++++++++++
> include/net/mac80211.h | 2 +
> include/uapi/linux/nl80211.h | 86 +++++++++++++++++++++
> net/mac80211/cfg.c | 12 +++
> net/wireless/nl80211.c | 173
> +++++++++++++++++++++++++++++++++++++++++++
> net/wireless/rdev-ops.h | 12 +++
> net/wireless/trace.h | 19 +++++
> 7 files changed, 356 insertions(+)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index c9bce9b..94f09dd 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1663,6 +1663,55 @@ struct station_info {
> u8 connected_to_as;
> };
>
> +/**
> + * struct cfg80211_sar_sub_specs - sub specs limit
> + * @power: value in 0.25dbm
> + * @freq_range_index: index the power limitation applies to
> + */
> +struct cfg80211_sar_sub_specs {
> + u8 power;
> + u8 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;
> + u16 num_sub_specs;
> + struct cfg80211_sar_sub_specs *sub_specs;
> +};
> +
> +
> +/**
> + * @struct cfg80211_sar_chan_ranges - sar frequency ranges
> + * @index: the index of this range. It's used to specify
> + * the frequency range when setting SAR power limitation
> + * @start_freq: start channel frequency in kHZ. For example,
> + * 2.4G channel 1 is represented as 2412000
> + * @end_freq: end channel frequency in kHZ
> + */
> +struct cfg80211_sar_freq_ranges {
> + u8 index;
> + 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
> + * @chan_ranges: memory to hold the channel ranges.
> + */
> +struct cfg80211_sar_capa {
> + enum nl80211_sar_type type;
> + u8 num_freq_ranges;
> + const struct cfg80211_sar_freq_ranges *freq_ranges;
> +};
> +
> #if IS_ENABLED(CONFIG_CFG80211)
> /**
> * cfg80211_get_station - retrieve information about a given station
> @@ -4153,6 +4202,7 @@ 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);
> };
>
> /*
> @@ -4919,6 +4969,8 @@ struct wiphy {
>
> u8 max_data_retry_count;
>
> + const struct cfg80211_sar_capa *sar_capa;
> +
> char priv[] __aligned(NETDEV_ALIGN);
> };
>
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index ec148b3..df758ee 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -4125,6 +4125,8 @@ struct ieee80211_ops {
> int (*reset_tid_config)(struct ieee80211_hw *hw,
> struct ieee80211_vif *vif,
> struct ieee80211_sta *sta, u8 tids);
> + int (*set_sar_specs)(struct ieee80211_hw *hw,
> + const struct cfg80211_sar_specs *sar);
> };
>
> /**
> diff --git a/include/uapi/linux/nl80211.h
> b/include/uapi/linux/nl80211.h
> index 0584e0d..2dcfed4 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -1177,6 +1177,9 @@
> * includes the contents of the frame. %NL80211_ATTR_ACK flag is
> included
> * if the recipient acknowledged the frame.
> *
> + * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
> + * passed using %NL80211_ATTR_SAR_SPEC.
> + *
> * @NL80211_CMD_MAX: highest used command number
> * @__NL80211_CMD_AFTER_LAST: internal use
> */
> @@ -1407,6 +1410,8 @@ enum nl80211_commands {
>
> NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
>
> + NL80211_CMD_SET_SAR_SPECS,
> +
> /* add new commands above here */
>
> /* used to define NL80211_CMD_MAX below */
> @@ -2513,6 +2518,10 @@ enum nl80211_commands {
> * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element
> (from
> * association request when used with NL80211_CMD_NEW_STATION).
> *
> + * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
> + * used with %NL80211_CMD_SET_SAR_SPECS. It contains array of
> + * %nl80211_sar_specs_attrs.
> + *
> * @NUM_NL80211_ATTR: total number of nl80211_attrs available
> * @NL80211_ATTR_MAX: highest attribute number currently defined
> * @__NL80211_ATTR_AFTER_LAST: internal use
> @@ -2995,6 +3004,8 @@ enum nl80211_attrs {
>
> NL80211_ATTR_HE_6GHZ_CAPABILITY,
>
> + NL80211_ATTR_SAR_SPEC,
> +
> /* add attributes here, update the policy in nl80211.c */
>
> __NL80211_ATTR_AFTER_LAST,
> @@ -7004,4 +7015,79 @@ enum nl80211_iftype_akm_attributes {
> NL80211_IFTYPE_AKM_ATTR_MAX = __NL80211_IFTYPE_AKM_ATTR_LAST - 1,
> };
>
> +/**
> + * enum nl80211_sar_type - type of SAR specs
> + *
> + * @NL80211_SAR_TYPE_POWER: the value is specified in 0.25 dbm
> + *
> + */
> +enum nl80211_sar_type {
> + NL80211_SAR_TYPE_POWER,
> +
> + /* add new type here */
> +
> + /* Keep last */
> + NUM_NL80211_SAR_TYPE,
> +};
> +
> +/**
> + * nl80211_sar_attrs - Attributes for SAR spec
> + *
> + * @NL80211_SAR_ATTR_TYPE: Type of SAR: power or index
> + *
> + * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
> + * limit specifications. Each specification contains a set
> + * of %nl80211_sar_specs_attrs
> + *
> + * @__NL80211_SAR_ATTR_LAST: Internal
> + * @NL80211_SAR_ATTR_MAX: highest sar attribute
> + *
> + * These attributes are used with %NL80211_CMD_SET_SAR_SPEC
> + */
> +enum nl80211_sar_attrs {
> + __NL80211_SAR_ATTR_INVALID,
> +
> + NL80211_SAR_ATTR_TYPE,
> + NL80211_SAR_ATTR_SPECS,
> +
> + __NL80211_SAR_ATTR_LAST,
> + NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1,
> +};
> +
> +#define NL80211_SAR_ALL_FREQ_RNAGES 0xff
> +#define NUM_MAX_NL80211_SAR_FREQ_RANGES 0xfe
> +
> +/**
> + * nl80211_sar_specs_attrs - Attributes for SAR power limit specs
> + *
> + * @NL80211_SAR_ATTR_SPECS_POWER: Required (u32)value to specify the
> actual
> + * power limit value in units of 0.25 dBm if type is
> + * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm)
> + *
> + * @NL80211_SAR_ATTR_SPECS_FREQ_RANGES_INDEX: optional (u32) value to
> specify the
> + * index of exported freq ranges table. If this attribute is not
> present, then
> + * the power is applied to all freq ranges, i.e, all bands
> + *
> + * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to
> specify the start
> + * frequency of this range to register SAR capability to wihpy and the
> unit
> + * is kHZ
> + *
> + * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify
> the end frequency
> + * of this range to register SAR capability to wiphy and the unit is
> kHZ
> + *
> + * @__NL80211_SAR_ATTR_SPECS_LAST: Internal
> + * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute
> + */
> +enum nl80211_sar_specs_attrs {
> + __NL80211_SAR_ATTR_SPECS_INVALID,
> +
> + NL80211_SAR_ATTR_SPECS_POWER,
> + NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX,
> + NL80211_SAR_ATTR_SPECS_START_FREQ,
> + NL80211_SAR_ATTR_SPECS_END_FREQ,
> +
> + __NL80211_SAR_ATTR_SPECS_LAST,
> + NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
> +};
> +
> #endif /* __LINUX_NL80211_H */
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index b4e39e3..cc74322 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -3993,6 +3993,17 @@ static int ieee80211_reset_tid_config(struct
> wiphy *wiphy,
> return ret;
> }
>
> +static int ieee80211_set_sar_specs(struct wiphy *wiphy,
> + struct cfg80211_sar_specs *sar)
> +{
> + struct ieee80211_local *local = wiphy_priv(wiphy);
> +
> + if (!local->ops->set_sar_specs)
> + return -EOPNOTSUPP;
> +
> + return local->ops->set_sar_specs(&local->hw, sar);
> +}
> +
> const struct cfg80211_ops mac80211_config_ops = {
> .add_virtual_intf = ieee80211_add_iface,
> .del_virtual_intf = ieee80211_del_iface,
> @@ -4096,4 +4107,5 @@ const struct cfg80211_ops mac80211_config_ops = {
> .probe_mesh_link = ieee80211_probe_mesh_link,
> .set_tid_config = ieee80211_set_tid_config,
> .reset_tid_config = ieee80211_reset_tid_config,
> + .set_sar_specs = ieee80211_set_sar_specs,
> };
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 52a35e7..9318b3a 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -367,6 +367,19 @@
> nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
> NLA_POLICY_NESTED(nl80211_txattr_policy),
> };
>
> +static const struct nla_policy
> +sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
> + [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_U8 },
> + [NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX] =
> + NLA_POLICY_MAX(NLA_U8, NUM_MAX_NL80211_SAR_FREQ_RANGES),
> +};
> +
> +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 },
> @@ -675,6 +688,7 @@ static const struct nla_policy
> nl80211_policy[NUM_NL80211_ATTR] = {
> [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
> [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
> NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
> + [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
> };
>
> /* policy for the key attributes */
> @@ -1856,6 +1870,8 @@ static int nl80211_add_commands_unsplit(struct
> cfg80211_registered_device *rdev,
> goto nla_put_failure;
> }
>
> + CMD(set_sar_specs, SET_SAR_SPECS);
> +
> return i;
> nla_put_failure:
> return -ENOBUFS;
> @@ -2034,6 +2050,55 @@ nl80211_put_tid_config_support(struct
> cfg80211_registered_device *rdev,
> 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_u16(msg, NL80211_SAR_ATTR_TYPE,
> rdev->wiphy.sar_capa->type))
> + goto fail;
> +
> + specs = nla_nest_start_noflag(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_noflag(msg, i + 1);
> +
> + nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
> + rdev->wiphy.sar_capa->freq_ranges[i].start_freq);
> +
> + nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
> + rdev->wiphy.sar_capa->freq_ranges[i].end_freq);
> +
> + nla_put_u8(msg, NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX,
> + rdev->wiphy.sar_capa->freq_ranges[i].index);
> +
> + 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;
> @@ -2598,6 +2663,9 @@ static int nl80211_send_wiphy(struct
> cfg80211_registered_device *rdev,
> if (nl80211_put_tid_config_support(rdev, msg))
> goto nla_put_failure;
>
> + if (nl80211_put_sar_specs(rdev, msg))
> + goto nla_put_failure;
> +
> /* done */
> state->split_start = 0;
> break;
> @@ -14473,6 +14541,103 @@ static void nl80211_post_doit(const struct
> genl_ops *ops, struct sk_buff *skb,
> }
> }
>
> +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;
> + u8 type, power, index, specs;
> + struct nlattr *spec_list;
> + int rem, err;
> +
> + if (!rdev->wiphy.sar_capa)
> + 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],
> + sar_policy, info->extack);
> +
> + if (!tb[NL80211_SAR_ATTR_TYPE])
> + return -EINVAL;
> +
> + type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
> +
> + if (!tb[NL80211_SAR_ATTR_SPECS])
> + return -EINVAL;
> +
> + specs = 0;
> + nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
> + specs++;
> +
> + sar_spec = kzalloc(sizeof(*sar_spec) +
> + specs * sizeof(struct cfg80211_sar_sub_specs),
> + GFP_KERNEL);
> + if (!sar_spec)
> + return -ENOMEM;
> +
> + sar_spec->sub_specs = (struct cfg80211_sar_sub_specs *)
> + ((char *)sar_spec + sizeof(*sar_spec));
> + specs = 0;
> + sar_spec->type = type;
> +
> + nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
> + if (nla_parse(spec,
> + NL80211_SAR_ATTR_SPECS_MAX,
> + nla_data(spec_list),
> + nla_len(spec_list),
> + sar_specs_policy,
> + NULL)) {
> + err = -EINVAL;
> + goto error;
> + }
> +
> + /* for power type, power value must be presented */
> + if (!spec[NL80211_SAR_ATTR_SPECS_POWER] &&
> + type == NL80211_SAR_TYPE_POWER) {
> + err = -EINVAL;
> + goto error;
> + }
> +
> + power = nla_get_u8(spec[NL80211_SAR_ATTR_SPECS_POWER]);
> + sar_spec->sub_specs[specs].power = power;
> +
> + /* if NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX isn't present,
> + * then the power applies to all bands. But it's only valid
> + * for the first entry.
> + */
> + if (!spec[NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX]) {
> + if (specs) {
> + err = -EINVAL;
> + goto error;
> + } else {
> + sar_spec->sub_specs[specs].freq_range_index =
> + NL80211_SAR_ALL_FREQ_RNAGES;
> + specs++;
> + break;
> + }
> + }
> +
> + index = nla_get_u8(spec[NL80211_SAR_ATTR_SPECS_FREQ_RANGE_INDEX]);
> + sar_spec->sub_specs[specs].freq_range_index = index;
> + specs++;
> + }
> +
> + sar_spec->num_sub_specs = specs;
> +
> + rdev->cur_cmd_info = info;
> + if (rdev->ops->set_sar_specs)
> + err = rdev_set_sar_specs(rdev, sar_spec);
> + else
> + err = -EOPNOTSUPP;
> + rdev->cur_cmd_info = NULL;
> +error:
> + kfree(sar_spec);
> + return err;
> +}
> +
> static const struct genl_ops nl80211_ops[] = {
> {
> .cmd = NL80211_CMD_GET_WIPHY,
> @@ -15331,6 +15496,14 @@ static const struct genl_ops nl80211_ops[] = {
> .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_NETDEV_UP |
> + NL80211_FLAG_NEED_RTNL,
> + },
> };
>
> static struct genl_family nl80211_fam __ro_after_init = {
> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
> index 950d574..d9931c5 100644
> --- a/net/wireless/rdev-ops.h
> +++ b/net/wireless/rdev-ops.h
> @@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config(struct
> cfg80211_registered_device *rdev,
> 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 */
> diff --git a/net/wireless/trace.h b/net/wireless/trace.h
> index 6e218a0..116be64 100644
> --- a/net/wireless/trace.h
> +++ b/net/wireless/trace.h
> @@ -3547,6 +3547,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
> --
> 2.7.4
More information about the ath11k
mailing list