[PATCH 1/3] nl80211: add common API to configure SAR power limitations.

Johannes Berg johannes at sipsolutions.net
Fri Nov 6 05:25:02 EST 2020


Hi,

Looks pretty good. Some comments, mostly nits, below.


> +/**
> + * nl80211_sar_attrs - Attributes for SAR spec

missing enum

> + *
> + * @NL80211_SAR_ATTR_TYPE: the SAR type and it's defined in %nl80211_sar_type.

better use &enum nl80211_sar_type for a link in docs

> + *
> + * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
> + *	limit specifications. Each specification contains a set
> + *      of %nl80211_sar_specs_attrs.
> + *
> + *      For SET operation, it contains array of NL80211_SAR_ATTR_SPECS_POWER

some odd indent?

Usually we just use a single tab.

> +/**
> + * nl80211_sar_specs_attrs - Attributes for SAR power limit specs

again, enum missing

> + *
> + * @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).
> + *	0 means userspace doesn't have SAR limitation on this associated range.
> + *
> + * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the
> + *	index of exported freq range table and the associated power limitation
> + *	is applied to this range.
> + *
> + *	Userspace isn't required to set all the ranges advertised by WLAN driver,
> + *	and userspace can skip some certain ranges. These skipped ranges don't
> + *	have SAR limitations, and these are same as setting the
> + *	%NL80211_SAR_ATTR_SPECS_POWER to 0. But it's required to set at least one range,
> + *	no matter the power limiation is 0 or not.

(typo - limitation)

Should "0" really be the magic value? Theoretically, 0 and even negative
values are valid. Perhaps we should just use something big (0xffffffff)
to indicate no limit, or just not have such a "no limitation" value
because userspace can always set it to something very big that means no
practical limitation anyway?

OK actually you have a U8 now so the high limit is 63.75dBm, but there's
not really a good reason for that, since U32 takes the same space in
netlink anyway.

And wait, I thought we agreed to remove the index? Now I'm confused.

And even if we do need the index, then perhaps we should use the
(otherwise anyway ignored) nla_type() of the container, instead of an
explicit inner attribute?

> + *
> + *	Every SET operation overwrites previous SET operation.
> + *
> + * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start
> + *	frequency of this range edge when registering SAR capability to wiphy. It's
> + *	not a channel center frequency. The unit is KHz.

"kHz" not "KHz", in a few places other than this too

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

extra space?

> +	for (i = 0; i < num_freq_ranges; i++) {
> +		sub_freq_range = nla_nest_start(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);


Need to check the return values of these three calls.


And an aside, unrelated to this particular code: Should we do some kind
of validation that the ranges reported actually overlap all supported
channels (taking 20 MHz bandwidth into account)?

> +	nla_parse_nested(tb, NL80211_SAR_ATTR_MAX, info->attrs[NL80211_ATTR_SAR_SPEC],
> +			 sar_policy, info->extack);

If you're not checking the return value then no point in passing a
policy or extack :-)

And yes, it's already validated, so you don't have to do it again.

> +	sar_spec->type = type;
> +	specs = 0;
> +	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)) {

Similar here, don't really need to validate it since it's done by the
policy.

> +			err = -EINVAL;
> +			goto error;
> +		}
> +
> +		/* for power type, power value and index must be presented */
> +		if ((!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
> +		     !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]) &&
> +		    type == NL80211_SAR_TYPE_POWER) {

maybe "switch (type) {...}" or something and return -EINVAL also if it's
a type not supported in the code yet, i.e. default case?

Otherwise we might add a type, and forget this pretty easily.

> +			err = -EINVAL;
> +			goto error;
> +		}
> +
> +		power = nla_get_u8(spec[NL80211_SAR_ATTR_SPECS_POWER]);
> +		sar_spec->sub_specs[specs].power = power;

and that probably should then be in a sub function or something also
inside the particular type.

or maybe just all in a separate function? dunno. not really _necessary_,
but the lines are getting kinda long already, and one more indentation
level with the switch won't help ...

johannes




More information about the ath10k mailing list