diff mbox

[v3,3/3] cfg80211: Allow usermode to query wiphy specific regd info

Message ID 1416754941-4439-3-git-send-email-arik@wizery.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Arik Nemtsov Nov. 23, 2014, 3:02 p.m. UTC
From: Jonathan Doron <jond@wizery.com>

Allow usermode to query wiphy-specific regd info, for drivers that use
wiphy-specific regulatory management.

Use the existing API for sending regdomain info to usermode, but return
the wiphy-specific regd in case wiphy index is provided and the driver
employs wiphy-specific management. This implies user and kernel-mode
support for the feature and is backward compatible.

Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
---
 include/uapi/linux/nl80211.h | 18 ++++++++++-
 net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
 net/wireless/reg.c           |  2 +-
 net/wireless/reg.h           |  1 +
 4 files changed, 78 insertions(+), 14 deletions(-)

Comments

Luis Chamberlain Nov. 25, 2014, 8:28 p.m. UTC | #1
On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
> From: Jonathan Doron <jond@wizery.com>
> 
> Allow usermode to query wiphy-specific regd info, for drivers that use
> wiphy-specific regulatory management.
> 
> Use the existing API for sending regdomain info to usermode, but return
> the wiphy-specific regd in case wiphy index is provided and the driver
> employs wiphy-specific management. This implies user and kernel-mode
> support for the feature and is backward compatible.
> 
> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
> ---
>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>  net/wireless/reg.c           |  2 +-
>  net/wireless/reg.h           |  1 +
>  4 files changed, 78 insertions(+), 14 deletions(-)
> 
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index 3771e7d..b222e5c 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -252,7 +252,12 @@
>   *	%NL80211_ATTR_IFINDEX.
>   *
>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
> - * 	regulatory domain.
> + *	regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
> + *	self-manages its regulatory settings, its private regulatory domain
> + *	will be returned.
> + *	If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
> + *	%NL80211_ATTR_WIPHY, a device's private regulatory domain will be
> + *	returned, even if it's regulatory is not self-managed.
>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>   *	after being queried by the kernel. CRDA replies by sending a regulatory
>   *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>   *
>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>   *
> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
> + *	regulatory information was obtained from the private regdomain
> + *	of a device with self-managed regulatory.
> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
> + *	information should be obtained from a device's private regdomain,
> + *	if it exists. This will happen even if the device is not self-managing
> + *	its regulatory.

As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
Then this can be used by cfg80211 to send to userspace regdomains for wiphys
that have used this API. Below you enable userspace to only query for these
explictly but we want to be able to let userspace get all information, ie
through 'iw reg get'. This should go in as a separate patch along with
NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
plate code for getting that reg first, getting self managed regd's can then
go in as a clear secondary evolutionary step.

The documentation for NL80211_ATTR_WIPHY_GET_PRIV_REG can refer to the new
%REGULATORY_WIPHY_REG_HINT flag. NL80211_ATTR_WIPHY_SELF_MANAGED_REG should
refer to %REGULATORY_WIPHY_SELF_MANAGED

> @@ -5346,13 +5345,54 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
>  	if (!hdr)
>  		goto put_failure;
>  
> -	if (reg_last_request_cell_base() &&
> -	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
> -			NL80211_USER_REG_HINT_CELL_BASE))
> -		goto nla_put_failure;
> +	if (info->attrs[NL80211_ATTR_WIPHY]) {
> +		u32 reg_flags;
> +		struct wiphy *wiphy;
> +		struct cfg80211_registered_device *rdev =
> +			cfg80211_get_dev_from_info(genl_info_net(info), info);
> +
> +		if (IS_ERR(rdev)) {
> +			nlmsg_free(msg);
> +			return PTR_ERR(rdev);
> +		}
> +
> +		wiphy = &rdev->wiphy;
> +		reg_flags = wiphy->regulatory_flags;
> +		if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED ||
> +		    info->attrs[NL80211_ATTR_WIPHY_GET_PRIV_REG]) {
> +			regdom = get_wiphy_regdom(wiphy);
> +			if (!regdom) {
> +				nlmsg_free(msg);
> +				return -EINVAL;
> +			}
> +
> +			if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
> +					rdev->wiphy_idx))
> +				goto nla_put_failure;
> +
> +			if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED &&
> +			    nla_put_flag(msg,
> +					 NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
> +				goto nla_put_failure;
> +		}
> +	}

If no NL80211_ATTR_WIPHY was requested specifically it would still
be good to send the central regulatory domain followed by each
wiphy's own regulatory domain whether priv or managed. Can you add
that as well? With the split above the first patch would send
all regds for all wiphys that used regulatory_hint(), the second
patch would extend this to add the self managed list too.

I think we really need then only two interfaces:

iw reg get
iw reg get dev wlan0

I don't think we need to be letting userspace asking for
NL80211_ATTR_WIPHY_SELF_MANAGED_REG regds or priv ones.

 Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arik Nemtsov Nov. 26, 2014, 11:48 a.m. UTC | #2
On Tue, Nov 25, 2014 at 10:28 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
>> From: Jonathan Doron <jond@wizery.com>
>>
>> Allow usermode to query wiphy-specific regd info, for drivers that use
>> wiphy-specific regulatory management.
>>
>> Use the existing API for sending regdomain info to usermode, but return
>> the wiphy-specific regd in case wiphy index is provided and the driver
>> employs wiphy-specific management. This implies user and kernel-mode
>> support for the feature and is backward compatible.
>>
>> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
>> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
>> ---
>>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>>  net/wireless/reg.c           |  2 +-
>>  net/wireless/reg.h           |  1 +
>>  4 files changed, 78 insertions(+), 14 deletions(-)
>>
>> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
>> index 3771e7d..b222e5c 100644
>> --- a/include/uapi/linux/nl80211.h
>> +++ b/include/uapi/linux/nl80211.h
>> @@ -252,7 +252,12 @@
>>   *   %NL80211_ATTR_IFINDEX.
>>   *
>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>> - *   regulatory domain.
>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>> + *   self-manages its regulatory settings, its private regulatory domain
>> + *   will be returned.
>> + *   If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
>> + *   %NL80211_ATTR_WIPHY, a device's private regulatory domain will be
>> + *   returned, even if it's regulatory is not self-managed.
>>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>>   *   after being queried by the kernel. CRDA replies by sending a regulatory
>>   *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
>> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>>   *
>>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>>   *
>> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
>> + *   regulatory information was obtained from the private regdomain
>> + *   of a device with self-managed regulatory.
>> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
>> + *   information should be obtained from a device's private regdomain,
>> + *   if it exists. This will happen even if the device is not self-managing
>> + *   its regulatory.
>
> As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
> drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
> Then this can be used by cfg80211 to send to userspace regdomains for wiphys
> that have used this API. Below you enable userspace to only query for these
> explictly but we want to be able to let userspace get all information, ie
> through 'iw reg get'. This should go in as a separate patch along with
> NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
> NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
> plate code for getting that reg first, getting self managed regd's can then
> go in as a clear secondary evolutionary step.
>
> The documentation for NL80211_ATTR_WIPHY_GET_PRIV_REG can refer to the new
> %REGULATORY_WIPHY_REG_HINT flag. NL80211_ATTR_WIPHY_SELF_MANAGED_REG should
> refer to %REGULATORY_WIPHY_SELF_MANAGED
>
>> @@ -5346,13 +5345,54 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
>>       if (!hdr)
>>               goto put_failure;
>>
>> -     if (reg_last_request_cell_base() &&
>> -         nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
>> -                     NL80211_USER_REG_HINT_CELL_BASE))
>> -             goto nla_put_failure;
>> +     if (info->attrs[NL80211_ATTR_WIPHY]) {
>> +             u32 reg_flags;
>> +             struct wiphy *wiphy;
>> +             struct cfg80211_registered_device *rdev =
>> +                     cfg80211_get_dev_from_info(genl_info_net(info), info);
>> +
>> +             if (IS_ERR(rdev)) {
>> +                     nlmsg_free(msg);
>> +                     return PTR_ERR(rdev);
>> +             }
>> +
>> +             wiphy = &rdev->wiphy;
>> +             reg_flags = wiphy->regulatory_flags;
>> +             if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED ||
>> +                 info->attrs[NL80211_ATTR_WIPHY_GET_PRIV_REG]) {
>> +                     regdom = get_wiphy_regdom(wiphy);
>> +                     if (!regdom) {
>> +                             nlmsg_free(msg);
>> +                             return -EINVAL;
>> +                     }
>> +
>> +                     if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
>> +                                     rdev->wiphy_idx))
>> +                             goto nla_put_failure;
>> +
>> +                     if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED &&
>> +                         nla_put_flag(msg,
>> +                                      NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
>> +                             goto nla_put_failure;
>> +             }
>> +     }
>
> If no NL80211_ATTR_WIPHY was requested specifically it would still
> be good to send the central regulatory domain followed by each
> wiphy's own regulatory domain whether priv or managed. Can you add
> that as well? With the split above the first patch would send
> all regds for all wiphys that used regulatory_hint(), the second
> patch would extend this to add the self managed list too.

Ok I'll make the change.

Arik
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arik Nemtsov Nov. 26, 2014, 4:43 p.m. UTC | #3
On Tue, Nov 25, 2014 at 10:28 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
>> From: Jonathan Doron <jond@wizery.com>
>>
>> Allow usermode to query wiphy-specific regd info, for drivers that use
>> wiphy-specific regulatory management.
>>
>> Use the existing API for sending regdomain info to usermode, but return
>> the wiphy-specific regd in case wiphy index is provided and the driver
>> employs wiphy-specific management. This implies user and kernel-mode
>> support for the feature and is backward compatible.
>>
>> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
>> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
>> ---
>>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>>  net/wireless/reg.c           |  2 +-
>>  net/wireless/reg.h           |  1 +
>>  4 files changed, 78 insertions(+), 14 deletions(-)
>>
>> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
>> index 3771e7d..b222e5c 100644
>> --- a/include/uapi/linux/nl80211.h
>> +++ b/include/uapi/linux/nl80211.h
>> @@ -252,7 +252,12 @@
>>   *   %NL80211_ATTR_IFINDEX.
>>   *
>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>> - *   regulatory domain.
>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>> + *   self-manages its regulatory settings, its private regulatory domain
>> + *   will be returned.
>> + *   If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
>> + *   %NL80211_ATTR_WIPHY, a device's private regulatory domain will be
>> + *   returned, even if it's regulatory is not self-managed.
>>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>>   *   after being queried by the kernel. CRDA replies by sending a regulatory
>>   *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
>> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>>   *
>>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>>   *
>> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
>> + *   regulatory information was obtained from the private regdomain
>> + *   of a device with self-managed regulatory.
>> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
>> + *   information should be obtained from a device's private regdomain,
>> + *   if it exists. This will happen even if the device is not self-managing
>> + *   its regulatory.
>
> As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
> drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
> Then this can be used by cfg80211 to send to userspace regdomains for wiphys
> that have used this API. Below you enable userspace to only query for these
> explictly but we want to be able to let userspace get all information, ie
> through 'iw reg get'. This should go in as a separate patch along with
> NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
> NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
> plate code for getting that reg first, getting self managed regd's can then
> go in as a clear secondary evolutionary step.

Note that we don't really need the new REGULATORY_WIPHY_REG_HINT.. If
a wiphy is not self-managed, we can just put
NL80211_ATTR_WIPHY_PRIV_REG, since it's obvious the regulatory_hint
API was used.

Arik
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luis Chamberlain Nov. 26, 2014, 4:47 p.m. UTC | #4
On Wed, Nov 26, 2014 at 11:43 AM, Arik Nemtsov <arik@wizery.com> wrote:
> On Tue, Nov 25, 2014 at 10:28 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
>> On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
>>> From: Jonathan Doron <jond@wizery.com>
>>>
>>> Allow usermode to query wiphy-specific regd info, for drivers that use
>>> wiphy-specific regulatory management.
>>>
>>> Use the existing API for sending regdomain info to usermode, but return
>>> the wiphy-specific regd in case wiphy index is provided and the driver
>>> employs wiphy-specific management. This implies user and kernel-mode
>>> support for the feature and is backward compatible.
>>>
>>> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
>>> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
>>> ---
>>>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>>>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>>>  net/wireless/reg.c           |  2 +-
>>>  net/wireless/reg.h           |  1 +
>>>  4 files changed, 78 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
>>> index 3771e7d..b222e5c 100644
>>> --- a/include/uapi/linux/nl80211.h
>>> +++ b/include/uapi/linux/nl80211.h
>>> @@ -252,7 +252,12 @@
>>>   *   %NL80211_ATTR_IFINDEX.
>>>   *
>>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>>> - *   regulatory domain.
>>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>>> + *   self-manages its regulatory settings, its private regulatory domain
>>> + *   will be returned.
>>> + *   If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
>>> + *   %NL80211_ATTR_WIPHY, a device's private regulatory domain will be
>>> + *   returned, even if it's regulatory is not self-managed.
>>>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>>>   *   after being queried by the kernel. CRDA replies by sending a regulatory
>>>   *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
>>> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>>>   *
>>>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>>>   *
>>> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
>>> + *   regulatory information was obtained from the private regdomain
>>> + *   of a device with self-managed regulatory.
>>> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
>>> + *   information should be obtained from a device's private regdomain,
>>> + *   if it exists. This will happen even if the device is not self-managing
>>> + *   its regulatory.
>>
>> As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
>> drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
>> Then this can be used by cfg80211 to send to userspace regdomains for wiphys
>> that have used this API. Below you enable userspace to only query for these
>> explictly but we want to be able to let userspace get all information, ie
>> through 'iw reg get'. This should go in as a separate patch along with
>> NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
>> NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
>> plate code for getting that reg first, getting self managed regd's can then
>> go in as a clear secondary evolutionary step.
>
> Note that we don't really need the new REGULATORY_WIPHY_REG_HINT.. If
> a wiphy is not self-managed, we can just put
> NL80211_ATTR_WIPHY_PRIV_REG, since it's obvious the regulatory_hint
> API was used.

What if a driver sets the managed flag and then uses regulatory_hint()
? Either way if this is addressed and we can also infer what type of
wiphy->regd it is well that's OK with me, the flag idea was just in
case we needed it, so I think you might be right.

 Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arik Nemtsov Nov. 26, 2014, 4:49 p.m. UTC | #5
On Wed, Nov 26, 2014 at 6:47 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Wed, Nov 26, 2014 at 11:43 AM, Arik Nemtsov <arik@wizery.com> wrote:
>> On Tue, Nov 25, 2014 at 10:28 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
>>> On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
>>>> From: Jonathan Doron <jond@wizery.com>
>>>>
>>>> Allow usermode to query wiphy-specific regd info, for drivers that use
>>>> wiphy-specific regulatory management.
>>>>
>>>> Use the existing API for sending regdomain info to usermode, but return
>>>> the wiphy-specific regd in case wiphy index is provided and the driver
>>>> employs wiphy-specific management. This implies user and kernel-mode
>>>> support for the feature and is backward compatible.
>>>>
>>>> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
>>>> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
>>>> ---
>>>>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>>>>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>>>>  net/wireless/reg.c           |  2 +-
>>>>  net/wireless/reg.h           |  1 +
>>>>  4 files changed, 78 insertions(+), 14 deletions(-)
>>>>
>>>> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
>>>> index 3771e7d..b222e5c 100644
>>>> --- a/include/uapi/linux/nl80211.h
>>>> +++ b/include/uapi/linux/nl80211.h
>>>> @@ -252,7 +252,12 @@
>>>>   *   %NL80211_ATTR_IFINDEX.
>>>>   *
>>>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>>>> - *   regulatory domain.
>>>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>>>> + *   self-manages its regulatory settings, its private regulatory domain
>>>> + *   will be returned.
>>>> + *   If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
>>>> + *   %NL80211_ATTR_WIPHY, a device's private regulatory domain will be
>>>> + *   returned, even if it's regulatory is not self-managed.
>>>>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>>>>   *   after being queried by the kernel. CRDA replies by sending a regulatory
>>>>   *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
>>>> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>>>>   *
>>>>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>>>>   *
>>>> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
>>>> + *   regulatory information was obtained from the private regdomain
>>>> + *   of a device with self-managed regulatory.
>>>> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
>>>> + *   information should be obtained from a device's private regdomain,
>>>> + *   if it exists. This will happen even if the device is not self-managing
>>>> + *   its regulatory.
>>>
>>> As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
>>> drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
>>> Then this can be used by cfg80211 to send to userspace regdomains for wiphys
>>> that have used this API. Below you enable userspace to only query for these
>>> explictly but we want to be able to let userspace get all information, ie
>>> through 'iw reg get'. This should go in as a separate patch along with
>>> NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
>>> NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
>>> plate code for getting that reg first, getting self managed regd's can then
>>> go in as a clear secondary evolutionary step.
>>
>> Note that we don't really need the new REGULATORY_WIPHY_REG_HINT.. If
>> a wiphy is not self-managed, we can just put
>> NL80211_ATTR_WIPHY_PRIV_REG, since it's obvious the regulatory_hint
>> API was used.
>
> What if a driver sets the managed flag and then uses regulatory_hint()
> ? Either way if this is addressed and we can also infer what type of
> wiphy->regd it is well that's OK with me, the flag idea was just in
> case we needed it, so I think you might be right.

A self-managed device can't use regulatory_hint().. This is the
regular path which also updates the cfg80211 regdomain.
If a device tries to do that, the new regd from CRDA will never reach
it. So we're covered here.

Arik
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luis Chamberlain Nov. 26, 2014, 4:55 p.m. UTC | #6
On Wed, Nov 26, 2014 at 11:49 AM, Arik Nemtsov <arik@wizery.com> wrote:
> On Wed, Nov 26, 2014 at 6:47 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
>> On Wed, Nov 26, 2014 at 11:43 AM, Arik Nemtsov <arik@wizery.com> wrote:
>>> On Tue, Nov 25, 2014 at 10:28 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
>>>> On Sun, Nov 23, 2014 at 05:02:21PM +0200, Arik Nemtsov wrote:
>>>>> From: Jonathan Doron <jond@wizery.com>
>>>>>
>>>>> Allow usermode to query wiphy-specific regd info, for drivers that use
>>>>> wiphy-specific regulatory management.
>>>>>
>>>>> Use the existing API for sending regdomain info to usermode, but return
>>>>> the wiphy-specific regd in case wiphy index is provided and the driver
>>>>> employs wiphy-specific management. This implies user and kernel-mode
>>>>> support for the feature and is backward compatible.
>>>>>
>>>>> Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
>>>>> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
>>>>> ---
>>>>>  include/uapi/linux/nl80211.h | 18 ++++++++++-
>>>>>  net/wireless/nl80211.c       | 71 ++++++++++++++++++++++++++++++++++++--------
>>>>>  net/wireless/reg.c           |  2 +-
>>>>>  net/wireless/reg.h           |  1 +
>>>>>  4 files changed, 78 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
>>>>> index 3771e7d..b222e5c 100644
>>>>> --- a/include/uapi/linux/nl80211.h
>>>>> +++ b/include/uapi/linux/nl80211.h
>>>>> @@ -252,7 +252,12 @@
>>>>>   *   %NL80211_ATTR_IFINDEX.
>>>>>   *
>>>>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>>>>> - *   regulatory domain.
>>>>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>>>>> + *   self-manages its regulatory settings, its private regulatory domain
>>>>> + *   will be returned.
>>>>> + *   If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
>>>>> + *   %NL80211_ATTR_WIPHY, a device's private regulatory domain will be
>>>>> + *   returned, even if it's regulatory is not self-managed.
>>>>>   * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
>>>>>   *   after being queried by the kernel. CRDA replies by sending a regulatory
>>>>>   *   domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
>>>>> @@ -1693,6 +1698,14 @@ enum nl80211_commands {
>>>>>   *
>>>>>   * @NL80211_ATTR_MAC_MASK: MAC address mask
>>>>>   *
>>>>> + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
>>>>> + *   regulatory information was obtained from the private regdomain
>>>>> + *   of a device with self-managed regulatory.
>>>>> + * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
>>>>> + *   information should be obtained from a device's private regdomain,
>>>>> + *   if it exists. This will happen even if the device is not self-managing
>>>>> + *   its regulatory.
>>>>
>>>> As with REGULATORY_WIPHY_SELF_MANAGED we need a flag that cfg80211 sets for
>>>> drivers that use regulatory_hint() API, perhaps REGULATORY_WIPHY_REG_HINT.
>>>> Then this can be used by cfg80211 to send to userspace regdomains for wiphys
>>>> that have used this API. Below you enable userspace to only query for these
>>>> explictly but we want to be able to let userspace get all information, ie
>>>> through 'iw reg get'. This should go in as a separate patch along with
>>>> NL80211_ATTR_WIPHY_GET_PRIV_REG as its use predates
>>>> NL80211_ATTR_WIPHY_SELF_MANAGED_REG, this will also let you stuff in the boiler
>>>> plate code for getting that reg first, getting self managed regd's can then
>>>> go in as a clear secondary evolutionary step.
>>>
>>> Note that we don't really need the new REGULATORY_WIPHY_REG_HINT.. If
>>> a wiphy is not self-managed, we can just put
>>> NL80211_ATTR_WIPHY_PRIV_REG, since it's obvious the regulatory_hint
>>> API was used.
>>
>> What if a driver sets the managed flag and then uses regulatory_hint()
>> ? Either way if this is addressed and we can also infer what type of
>> wiphy->regd it is well that's OK with me, the flag idea was just in
>> case we needed it, so I think you might be right.
>
> A self-managed device can't use regulatory_hint().. This is the
> regular path which also updates the cfg80211 regdomain.
> If a device tries to do that, the new regd from CRDA will never reach
> it. So we're covered here.

OK cool.

 Luis
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 3771e7d..b222e5c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -252,7 +252,12 @@ 
  *	%NL80211_ATTR_IFINDEX.
  *
  * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
- * 	regulatory domain.
+ *	regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
+ *	self-manages its regulatory settings, its private regulatory domain
+ *	will be returned.
+ *	If %NL80211_ATTR_WIPHY_GET_PRIV_REG is specified in addition to
+ *	%NL80211_ATTR_WIPHY, a device's private regulatory domain will be
+ *	returned, even if it's regulatory is not self-managed.
  * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
  *	after being queried by the kernel. CRDA replies by sending a regulatory
  *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
@@ -1693,6 +1698,14 @@  enum nl80211_commands {
  *
  * @NL80211_ATTR_MAC_MASK: MAC address mask
  *
+ * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating the
+ *	regulatory information was obtained from the private regdomain
+ *	of a device with self-managed regulatory.
+ * @NL80211_ATTR_WIPHY_GET_PRIV_REG: flag attribute indicating the regulatory
+ *	information should be obtained from a device's private regdomain,
+ *	if it exists. This will happen even if the device is not self-managing
+ *	its regulatory.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2050,6 +2063,9 @@  enum nl80211_attrs {
 
 	NL80211_ATTR_MAC_MASK,
 
+	NL80211_ATTR_WIPHY_SELF_MANAGED_REG,
+	NL80211_ATTR_WIPHY_GET_PRIV_REG,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index de3a47a..42ccca7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -396,6 +396,8 @@  static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
 	[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
 	[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
+	[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
+	[NL80211_ATTR_WIPHY_GET_PRIV_REG] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -5328,15 +5330,12 @@  static int nl80211_update_mesh_config(struct sk_buff *skb,
 
 static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 {
-	const struct ieee80211_regdomain *regdom;
+	const struct ieee80211_regdomain *regdom = NULL;
 	struct sk_buff *msg;
 	void *hdr = NULL;
 	struct nlattr *nl_reg_rules;
 	unsigned int i;
 
-	if (!cfg80211_regdomain)
-		return -EINVAL;
-
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
 		return -ENOBUFS;
@@ -5346,13 +5345,54 @@  static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 	if (!hdr)
 		goto put_failure;
 
-	if (reg_last_request_cell_base() &&
-	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
-			NL80211_USER_REG_HINT_CELL_BASE))
-		goto nla_put_failure;
+	if (info->attrs[NL80211_ATTR_WIPHY]) {
+		u32 reg_flags;
+		struct wiphy *wiphy;
+		struct cfg80211_registered_device *rdev =
+			cfg80211_get_dev_from_info(genl_info_net(info), info);
+
+		if (IS_ERR(rdev)) {
+			nlmsg_free(msg);
+			return PTR_ERR(rdev);
+		}
+
+		wiphy = &rdev->wiphy;
+		reg_flags = wiphy->regulatory_flags;
+		if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED ||
+		    info->attrs[NL80211_ATTR_WIPHY_GET_PRIV_REG]) {
+			regdom = get_wiphy_regdom(wiphy);
+			if (!regdom) {
+				nlmsg_free(msg);
+				return -EINVAL;
+			}
+
+			if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
+					rdev->wiphy_idx))
+				goto nla_put_failure;
+
+			if (reg_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+			    nla_put_flag(msg,
+					 NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
+				goto nla_put_failure;
+		}
+	}
+
+	if (!regdom) {
+		if (!cfg80211_regdomain) {
+			nlmsg_free(msg);
+			return -EINVAL;
+		}
+
+		if (reg_last_request_cell_base() &&
+		    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
+				NL80211_USER_REG_HINT_CELL_BASE))
+			goto nla_put_failure;
+	}
 
 	rcu_read_lock();
-	regdom = rcu_dereference(cfg80211_regdomain);
+
+	if (!regdom)
+		regdom = rcu_dereference(cfg80211_regdomain);
 
 	if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
 	    (regdom->dfs_region &&
@@ -10970,9 +11010,16 @@  static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
 			goto nla_put_failure;
 	}
 
-	if (request->wiphy_idx != WIPHY_IDX_INVALID &&
-	    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
-		goto nla_put_failure;
+	if (request->wiphy_idx != WIPHY_IDX_INVALID) {
+		struct wiphy *wiphy;
+
+		wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
+		if (wiphy &&
+		    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx) &&
+		    wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+		    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
+			goto nla_put_failure;
+	}
 
 	return true;
 
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 18cf13b..662d947 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -142,7 +142,7 @@  static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
 	return rtnl_dereference(cfg80211_regdomain);
 }
 
-static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
+const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
 {
 	return rtnl_dereference(wiphy->regd);
 }
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 5e48031..4b45d6e 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -38,6 +38,7 @@  unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
 				   const struct ieee80211_reg_rule *rule);
 
 bool reg_last_request_cell_base(void);
+const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy);
 
 /**
  * regulatory_hint_found_beacon - hints a beacon was found on a channel