diff mbox

[v3,3/6] cfg80211: Enable GO operation on additional channels

Message ID 1390818118-27261-4-git-send-email-ilan.peer@intel.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Peer, Ilan Jan. 27, 2014, 10:21 a.m. UTC
Allow GO operation on a channel marked with IEEE80211_CHAN_GO_CONCURRENT
iff there is an active station interface that is associated to
an AP operating on the same channel in 2.4 or the same UNII band in 5.2
(assuming that the AP is an authorized master)

Note that this is a permissive approach to the FCC definitions,
that require a clear assessment that the device operating the AP is
an authorized master, i.e., with radar detection and DFS capabilities.

It is assumed that such restrictions are enforced by user space.
Furthermore, it is assumed, that if the conditions that allowed for
the operation of the GO on such a channel change, i.e., the station
interface disconnected from the AP, it is the responsibility of user
space to evacuate the GO from the channel.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 include/net/cfg80211.h   |    4 ++-
 include/net/regulatory.h |    4 +++
 net/mac80211/ibss.c      |    9 ++++--
 net/wireless/Kconfig     |   14 ++++++++++
 net/wireless/chan.c      |   68 ++++++++++++++++++++++++++++++++++++++++++++--
 net/wireless/mesh.c      |    3 +-
 net/wireless/nl80211.c   |   11 +++++---
 net/wireless/reg.c       |   26 ++++++++++++++++++
 net/wireless/reg.h       |   12 ++++++++
 net/wireless/trace.h     |   11 +++++---
 10 files changed, 146 insertions(+), 16 deletions(-)

Comments

Johannes Berg Jan. 31, 2014, 2:11 p.m. UTC | #1
On Mon, 2014-01-27 at 12:21 +0200, Ilan Peer wrote:

> It is assumed that such restrictions are enforced by user space.
> Furthermore, it is assumed, that if the conditions that allowed for
> the operation of the GO on such a channel change, i.e., the station
> interface disconnected from the AP, it is the responsibility of user
> space to evacuate the GO from the channel.

For the latter here, don't we need some sort of flag with userspace
saying "trust me, I know what I'm doing"? Or put another way - how does
this not make us break compliance when running with old versions of
wpa_supplicant?

johannes

--
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
Peer, Ilan Feb. 2, 2014, 7:20 p.m. UTC | #2
Hi Johannes, 

> > It is assumed that such restrictions are enforced by user space.

> > Furthermore, it is assumed, that if the conditions that allowed for

> > the operation of the GO on such a channel change, i.e., the station

> > interface disconnected from the AP, it is the responsibility of user

> > space to evacuate the GO from the channel.

> 

> For the latter here, don't we need some sort of flag with userspace saying

> "trust me, I know what I'm doing"? Or put another way - how does this not

> make us break compliance when running with old versions of

> wpa_supplicant?

> 


I do not think that this will be needed, as current wpa_supplicant logic is not aware of the GO_CONCURRENT and INDOOR_ONLY flags (leaving them ignored) and does not allow instantiating an AP/GO on channels marked with NO_IR. In addition as this feature must be enabled under CONFIG_ONUS, I expect that whoever uses it uses know what's is doing.

Such logic might be needed if kernel enforces regulatory compliance after the GO_CONCURRENT relaxation conditions are no longer met (station interface leaves the channel), where if such a case is true, it would be appropriate to add an indication to the kernel telling it that user space knows what it's doing, so the kernel will not do any quiescing logic (similar to what Luis suggested).

Regards,

Ilan.
Johannes Berg Feb. 3, 2014, 12:46 p.m. UTC | #3
On Sun, 2014-02-02 at 19:20 +0000, Peer, Ilan wrote:

> I do not think that this will be needed, as current wpa_supplicant
> logic is not aware of the GO_CONCURRENT and INDOOR_ONLY flags (leaving
> them ignored) and does not allow instantiating an AP/GO on channels
> marked with NO_IR. In addition as this feature must be enabled under
> CONFIG_ONUS, I expect that whoever uses it uses know what's is doing.

Ok, thanks for the clarification. I wasn't sure how existing wpa_s
versions would treat this.

> Such logic might be needed if kernel enforces regulatory compliance
> after the GO_CONCURRENT relaxation conditions are no longer met
> (station interface leaves the channel), where if such a case is true,
> it would be appropriate to add an indication to the kernel telling it
> that user space knows what it's doing, so the kernel will not do any
> quiescing logic (similar to what Luis suggested).

I'm not convinced that is necessary - the "quiescing" would be good I
suppose, but there should be plenty of time before it for userspace to
request an appropriate CSA so I don't think any additional flag is
needed.

Assuming we're talking about the same scenario? I guess it should be
like this:

 - STA connected to AP on an "additional" channel
 - GO operating on the same channel
 - AP starts to advertise CSA
 - wpa_s will request CSA for GO as well
 - all will be fine

If wpa_s is broken, then at the time that the CSA actually kicks in the
GO would be stopped, since it didn't switch channel, but I don't think
there's a need for any additional flags.

johannes

--
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
Peer, Ilan Feb. 3, 2014, 1:24 p.m. UTC | #4
> > Such logic might be needed if kernel enforces regulatory compliance

> > after the GO_CONCURRENT relaxation conditions are no longer met

> > (station interface leaves the channel), where if such a case is true,

> > it would be appropriate to add an indication to the kernel telling it

> > that user space knows what it's doing, so the kernel will not do any

> > quiescing logic (similar to what Luis suggested).

> 

> I'm not convinced that is necessary - the "quiescing" would be good I

> suppose, but there should be plenty of time before it for userspace to

> request an appropriate CSA so I don't think any additional flag is needed.

> 

> Assuming we're talking about the same scenario? I guess it should be like

> this:

> 

>  - STA connected to AP on an "additional" channel

>  - GO operating on the same channel

>  - AP starts to advertise CSA

>  - wpa_s will request CSA for GO as well


This also requires a fix, as currently the wpa_supplicant is not aware of the station switching channel due to AP's CSA.

>  - all will be fine


Yes. The wpa_supplicant should be aware of the current usage of the channels and act accordingly, i.e., if the GO is established on a channel due to GO_CONCURRENT relaxation, it should evacuate the channel once there is no station on that channel (or on that UNII band). I'm currently enabling this logic in the wpa_supplicant.

Regards,

Ilan.
Luis R. Rodriguez Feb. 18, 2014, 11:38 p.m. UTC | #5
On Mon, Jan 27, 2014 at 12:21:55PM +0200, Ilan Peer wrote:
> Allow GO operation on a channel marked with IEEE80211_CHAN_GO_CONCURRENT
> iff there is an active station interface that is associated to
> an AP operating on the same channel in 2.4 or the same UNII band in 5.2
> (assuming that the AP is an authorized master)
> 
> Note that this is a permissive approach to the FCC definitions,
> that require a clear assessment that the device operating the AP is
> an authorized master, i.e., with radar detection and DFS capabilities.

OK It seems here you are clarifying that the feature is only when
you can verify the AP is DFS-capable. How can you verify that?

> It is assumed that such restrictions are enforced by user space.
> Furthermore, it is assumed, that if the conditions that allowed for
> the operation of the GO on such a channel change, i.e., the station
> interface disconnected from the AP, it is the responsibility of user
> space to evacuate the GO from the channel.

This is a pretty important piece of information as well. Once
these patches go in I really want to make it clear that we should
update the documentation the wiki as noted before.

> Signed-off-by: Ilan Peer <ilan.peer@intel.com>
> ---
>  include/net/cfg80211.h   |    4 ++-
>  include/net/regulatory.h |    4 +++
>  net/mac80211/ibss.c      |    9 ++++--
>  net/wireless/Kconfig     |   14 ++++++++++
>  net/wireless/chan.c      |   68 ++++++++++++++++++++++++++++++++++++++++++++--
>  net/wireless/mesh.c      |    3 +-
>  net/wireless/nl80211.c   |   11 +++++---
>  net/wireless/reg.c       |   26 ++++++++++++++++++
>  net/wireless/reg.h       |   12 ++++++++
>  net/wireless/trace.h     |   11 +++++---
>  10 files changed, 146 insertions(+), 16 deletions(-)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index dbc5490..317bd06 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -4520,12 +4520,14 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
>   * cfg80211_reg_can_beacon - check if beaconing is allowed
>   * @wiphy: the wiphy
>   * @chandef: the channel definition
> + * @iftype: interface type
>   *
>   * Return: %true if there is no secondary channel or the secondary channel(s)
>   * can be used for beaconing (i.e. is not a radar channel etc.)
>   */
>  bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
> -			     struct cfg80211_chan_def *chandef);
> +			     struct cfg80211_chan_def *chandef,
> +			     enum nl80211_iftype iftype);
>  
>  /*
>   * cfg80211_ch_switch_notify - update wdev channel and notify userspace
> diff --git a/include/net/regulatory.h b/include/net/regulatory.h
> index b07cdc9..fab0c37 100644
> --- a/include/net/regulatory.h
> +++ b/include/net/regulatory.h
> @@ -131,6 +131,9 @@ struct regulatory_request {
>   * 	all country IE information processed by the regulatory core. This will
>   * 	override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will
>   * 	be ignored.
> + * @REGULATORY_DISABLE_RELAX_NO_IR: for devices that do not wish to allow the
> + *      NO_IR relaxation, which enables transmissions on channels on which
> + *      otherwise initiating radiation is not allowed.

Please provide an example. A read of this documentation likely
cannot guess the available relaxations available, and this is
only obvious to the reader of this patch series. If you are
adding a Kconfig entry you can refer to it, or you can refer
to the channel flags as pointers to further documentation.

> diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
> index 81c05e4..6335590 100644
> --- a/net/wireless/Kconfig
> +++ b/net/wireless/Kconfig
> @@ -102,6 +102,20 @@ config CFG80211_REG_CELLULAR_HINTS
>  	  This option adds support for drivers that can receive regulatory
>  	  hints from cellular base stations
>  
> +config CFG80211_REG_RELAX_NO_IR
> +	bool "cfg80211 support for NO_IR relaxation"
> +	depends on CFG80211_CERTIFICATION_ONUS
> +	---help---
> +	  This option enables relaxation of the NO_IR flag. The relaxation
> +	  allows initiating radiation on channels that are marked with the
> +	  NO_IR flag which forbids transmissions on the channel.
> +
> +	  For example, enabling this option allows the operation of a P2P
> +	  group owner on channels marked with NO_IR if there is an additional
> +	  BSS interface which is connected to an AP which is assumed to be
> +	  an authorized master, i.e., with radar detection support and DFS
> +	  capabilities

Please use:

This option enables support for relaxation of the NO_IR flag
for situations that certain regulatory bodies have provided
clarifications on how relaxation can occur. This feature
has an inherent dependency on userspace features which must
have been properly tested and as such is not enabled by
default.

A relaxation feature example is allowing the operation of a P2P
group owner (GO) on channels marked with NO_IR if there is an
additional BSS interface which associated to an AP which
userspace assumes or confirems to be an authorized master,
i.e., with radar detection support and DFS capabilities.


Ilan, also extend the above with language similar to the one
I provided on the cellular base station hints if you ended
up adding a device feature capability.

> diff --git a/net/wireless/chan.c b/net/wireless/chan.c
> index 78559b5..87a9d0e 100644
> --- a/net/wireless/chan.c
> +++ b/net/wireless/chan.c
> @@ -605,15 +605,77 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
>  }
>  EXPORT_SYMBOL(cfg80211_chandef_usable);
>  
> +/*
> + * For GO only, check if the channel can be used under permissive conditions
> + * mandated by the some regulatory bodies, i.e., the channel is marked with
> + * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station interface
> + * associated to an AP on the same channel or on the same UNII band
> + * (assuming that the AP is an authorized master).
> + */
> +static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev,
> +					struct ieee80211_channel *chan)
> +{
> +	struct wireless_dev *wdev_iter;
> +
> +	ASSERT_RTNL();

You can simplify the check that calls this by having the
config_enabled() check here. You can also add the check
for REGULATORY_DISABLE_RELAX_NO_IR here.

> +
> +	if (!(chan->flags & IEEE80211_CHAN_GO_CONCURRENT))
> +		return false;
> +
> +	list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
> +		struct ieee80211_channel *other_chan = NULL;
> +		int r1, r2;
> +
> +		if (wdev_iter->iftype != NL80211_IFTYPE_STATION ||
> +		    !netif_running(wdev_iter->netdev))
> +				continue;
> +
> +		wdev_lock(wdev_iter);
> +		if (wdev_iter->current_bss)
> +			other_chan = wdev_iter->current_bss->pub.channel;
> +		wdev_unlock(wdev_iter);

Please wrap this up into a helper either for this series or after.
Just a friendly reminder :)

> +
> +		if (!other_chan)
> +			continue;
> +
> +		if (chan == other_chan)
> +			return true;

This seems to me to indicate that we have allowed here
daisy chaining / trust on another GO who also trusted
its AP. That is, we are leaving it up to the kernel for
the above few lines of code to check if the STA was
associated to an AP that had DFS support. How do we
know the AP the STA was associated to was not another
GO that ran through this permissive check? Is the FCC
happy with that?

Also to be clear, you check for IEEE80211_CHAN_GO_CONCURRENT
only on the caller's channel, not the STA's device, is that
OK ? Lets consider the case case of two different types of
interfaces on the same system. I am aware of at least one
802.11 AP company selling devices with one 802.11 vendor as
the AP and another as the STA. I don't consider this rare
anymore now, as such please think about this case as well.

> +
> +		if (chan->band != IEEE80211_BAND_5GHZ)
> +			continue;
> +
> +		r1 = cfg80211_get_unii(chan->center_freq);
> +		r2 = cfg80211_get_unii(other_chan->center_freq);
> +
> +		if (r1 != -EINVAL && r1 == r2)
> +			return true;

Looks good, the same concern about IEEE80211_CHAN_GO_CONCURRENT
on the other_chan applies here.

> +	}
> +
> +	return false;
> +}
> +
>  bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
> -			     struct cfg80211_chan_def *chandef)
> +			     struct cfg80211_chan_def *chandef,
> +			     enum nl80211_iftype iftype)
>  {
> +	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
>  	bool res;
>  	u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
> -			       IEEE80211_CHAN_NO_IR |
>  			       IEEE80211_CHAN_RADAR;
>  
> -	trace_cfg80211_reg_can_beacon(wiphy, chandef);
> +	trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype);
> +
> +	/*
> +	 * Under certain conditions suggested by the some regulatory bodies
> +	 * a GO can operate on channels marked with IEEE80211_NO_IR
> +	 * so set this flag only if such relaxations are not enabled and
> +	 * the conditions are not met.
> +	 */
> +	if (iftype != NL80211_IFTYPE_P2P_GO ||
> +	    !config_enabled(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
> +	    (wiphy->regulatory_flags & REGULATORY_DISABLE_RELAX_NO_IR) ||
> +	    !cfg80211_go_permissive_chan(rdev, chandef->chan))

This is the check I was saying you could simplify by tossing the
config checks and wiphy->regulatory_flags check there.

> +		prohibited_flags |= IEEE80211_CHAN_NO_IR;
>  
>  	if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
>  	    cfg80211_chandef_dfs_available(wiphy, chandef)) {
> diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
> index 8858624..93c4d42 100644
> --- a/net/wireless/mesh.c
> +++ b/net/wireless/mesh.c
> @@ -175,7 +175,8 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
>  							       scan_width);
>  	}
>  
> -	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
> +	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef,
> +				     NL80211_IFTYPE_MESH_POINT))
>  		return -EINVAL;
>  
>  	err = cfg80211_chandef_dfs_required(wdev->wiphy, &setup->chandef);
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 3c1587f..b37b36e 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -1914,7 +1914,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
>  			result = -EBUSY;
>  			break;
>  		}
> -		if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
> +		if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, iftype)) {
>  			result = -EINVAL;
>  			break;
>  		}
> @@ -3263,7 +3263,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
>  	} else if (!nl80211_get_ap_channel(rdev, &params))
>  		return -EINVAL;
>  
> -	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
> +	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
> +				     wdev->iftype))
>  		return -EINVAL;
>  
>  	err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef);
> @@ -5852,7 +5853,8 @@ skip_beacons:
>  	if (err)
>  		return err;
>  
> -	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
> +	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
> +				     wdev->iftype))
>  		return -EINVAL;
>  
>  	if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
> @@ -6623,7 +6625,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
>  	if (err)
>  		return err;
>  
> -	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
> +	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
> +				     NL80211_IFTYPE_ADHOC))
>  		return -EINVAL;
>  
>  	switch (ibss.chandef.width) {
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 8a81913..ec38f5d 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -2489,6 +2489,32 @@ static void reg_timeout_work(struct work_struct *work)
>  	rtnl_unlock();
>  }
>  
>
> +int cfg80211_get_unii(int freq)

A reference to where this is documented would be good.

> +{
> +	/* UNII-1 */
> +	if (freq >= 5150 && freq <= 5250)
> +		return 0;
> +
> +	/* UNII-2A */
> +	if (freq > 5250 && freq <= 5350)
> +		return 1;
> +
> +	/* UNII-2B */
> +	if (freq > 5350 && freq <= 5470)
> +		return 2;
> +
> +	/* UNII-2C */
> +	if (freq > 5470 && freq <= 5725)
> +		return 3;
> +
> +	/* UNII-3 */
> +	if (freq > 5725 && freq <= 5825)
> +		return 4;
> +
> +	WARN_ON(1);

probably best to avoid that warning -- there are some
4 GHz channels used out there, and pretty sure we'll hit
this fast.

  Luis
Peer, Ilan Feb. 19, 2014, 2:52 p.m. UTC | #6
> > Note that this is a permissive approach to the FCC definitions, that
> > require a clear assessment that the device operating the AP is an
> > authorized master, i.e., with radar detection and DFS capabilities.
> 
> OK It seems here you are clarifying that the feature is only when you can
> verify the AP is DFS-capable. How can you verify that?

The assumption here is that if the AP is operating under the known regulatory restrictions, and radar detection capabilities are ONLY given as an example.
As you pointed in the previous patch, regardless of the AP regulatory constraints, if the local device thinks that the current operating channel of the AP is a radar channel this relaxation is not allowed. Will clarify this in the commit message.

> 
> > It is assumed that such restrictions are enforced by user space.
> > Furthermore, it is assumed, that if the conditions that allowed for
> > the operation of the GO on such a channel change, i.e., the station
> > interface disconnected from the AP, it is the responsibility of user
> > space to evacuate the GO from the channel.
> 
> This is a pretty important piece of information as well. Once these patches go
> in I really want to make it clear that we should update the documentation the
> wiki as noted before.
> 

Sure. 

[...]

> > + * @REGULATORY_DISABLE_RELAX_NO_IR: for devices that do not wish
> to allow the
> > + *      NO_IR relaxation, which enables transmissions on channels on which
> > + *      otherwise initiating radiation is not allowed.
> 
> Please provide an example. A read of this documentation likely cannot guess
> the available relaxations available, and this is only obvious to the reader of
> this patch series. If you are adding a Kconfig entry you can refer to it, or you
> can refer to the channel flags as pointers to further documentation.
> 

I will add a reference to the Kconfig option.

> > +config CFG80211_REG_RELAX_NO_IR
> > +	bool "cfg80211 support for NO_IR relaxation"
> > +	depends on CFG80211_CERTIFICATION_ONUS
> > +	---help---
> > +	  This option enables relaxation of the NO_IR flag. The relaxation
> > +	  allows initiating radiation on channels that are marked with the
> > +	  NO_IR flag which forbids transmissions on the channel.
> > +
> > +	  For example, enabling this option allows the operation of a P2P
> > +	  group owner on channels marked with NO_IR if there is an
> additional
> > +	  BSS interface which is connected to an AP which is assumed to be
> > +	  an authorized master, i.e., with radar detection support and DFS
> > +	  capabilities
> 
> Please use:
> 
> This option enables support for relaxation of the NO_IR flag for situations
> that certain regulatory bodies have provided clarifications on how relaxation
> can occur. This feature has an inherent dependency on userspace features
> which must have been properly tested and as such is not enabled by default.
> 
> A relaxation feature example is allowing the operation of a P2P group owner
> (GO) on channels marked with NO_IR if there is an additional BSS interface
> which associated to an AP which userspace assumes or confirems to be an
> authorized master, i.e., with radar detection support and DFS capabilities.
> 
> 

Done.

> Ilan, also extend the above with language similar to the one I provided on the
> cellular base station hints if you ended up adding a device feature capability.
> 

You mean specify that this option is enabled, drivers can still use the device specific flags to disable this?

> > diff --git a/net/wireless/chan.c b/net/wireless/chan.c index
> > 78559b5..87a9d0e 100644
> > --- a/net/wireless/chan.c
> > +++ b/net/wireless/chan.c
> > @@ -605,15 +605,77 @@ bool cfg80211_chandef_usable(struct wiphy
> > *wiphy,  }  EXPORT_SYMBOL(cfg80211_chandef_usable);
> >
> > +/*
> > + * For GO only, check if the channel can be used under permissive
> > +conditions
> > + * mandated by the some regulatory bodies, i.e., the channel is
> > +marked with
> > + * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station
> > +interface
> > + * associated to an AP on the same channel or on the same UNII band
> > + * (assuming that the AP is an authorized master).
> > + */
> > +static bool cfg80211_go_permissive_chan(struct
> cfg80211_registered_device *rdev,
> > +					struct ieee80211_channel *chan)
> > +{
> > +	struct wireless_dev *wdev_iter;
> > +
> > +	ASSERT_RTNL();
> 
> You can simplify the check that calls this by having the
> config_enabled() check here. You can also add the check for
> REGULATORY_DISABLE_RELAX_NO_IR here.

Done.

> 
> > +
> > +	if (!(chan->flags & IEEE80211_CHAN_GO_CONCURRENT))
> > +		return false;
> > +
> > +	list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
> > +		struct ieee80211_channel *other_chan = NULL;
> > +		int r1, r2;
> > +
> > +		if (wdev_iter->iftype != NL80211_IFTYPE_STATION ||
> > +		    !netif_running(wdev_iter->netdev))
> > +				continue;
> > +
> > +		wdev_lock(wdev_iter);
> > +		if (wdev_iter->current_bss)
> > +			other_chan = wdev_iter->current_bss-
> >pub.channel;
> > +		wdev_unlock(wdev_iter);
> 
> Please wrap this up into a helper either for this series or after.
> Just a friendly reminder :)

Ok.

> > +
> > +		if (!other_chan)
> > +			continue;
> > +
> > +		if (chan == other_chan)
> > +			return true;
> 
> This seems to me to indicate that we have allowed here daisy chaining / trust
> on another GO who also trusted its AP. That is, we are leaving it up to the
> kernel for the above few lines of code to check if the STA was associated to
> an AP that had DFS support. How do we know the AP the STA was associated
> to was not another GO that ran through this permissive check? Is the FCC
> happy with that?
> 

This verification should be done by user space, i.e., if the station is a legacy client associated to a GO, then wpa_supplicant should not allow the GO_CONCURRENT relaxation. In addition, a GO instantiated on channel based on this relaxation should not allow connection from legacy clients ... again this should be enforced by user space. System wise this should adhere to the FCC expectations and prevent daisy chaining.

> Also to be clear, you check for IEEE80211_CHAN_GO_CONCURRENT only on
> the caller's channel, not the STA's device, is that OK ? Lets consider the case
> case of two different types of interfaces on the same system. I am aware of
> at least one
> 802.11 AP company selling devices with one 802.11 vendor as the AP and
> another as the STA. I don't consider this rare anymore now, as such please
> think about this case as well.

The property is of the channel so this should suffice. Overall, I think that the FCC definition rules are centered on the UNII bands, so the rules mandated for a given channel in a specific channel should also hold to other channels in the same UNII band. Ultimately, I would expect all channels in the same UNII band to share the same settings.

The iteration in this case is over all the interfaces of the same registered device
 
> > +
> > +		if (chan->band != IEEE80211_BAND_5GHZ)
> > +			continue;
> > +
> > +		r1 = cfg80211_get_unii(chan->center_freq);
> > +		r2 = cfg80211_get_unii(other_chan->center_freq);
> > +
> > +		if (r1 != -EINVAL && r1 == r2)
> > +			return true;
> 
> Looks good, the same concern about IEEE80211_CHAN_GO_CONCURRENT
> on the other_chan applies here.
> 

Same as above.

> > +	}
> > +
> > +	return false;
> > +}
> > +	/*
> > +	 * Under certain conditions suggested by the some regulatory bodies
> > +	 * a GO can operate on channels marked with IEEE80211_NO_IR
> > +	 * so set this flag only if such relaxations are not enabled and
> > +	 * the conditions are not met.
> > +	 */
> > +	if (iftype != NL80211_IFTYPE_P2P_GO ||
> > +	    !config_enabled(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
> > +	    (wiphy->regulatory_flags & REGULATORY_DISABLE_RELAX_NO_IR)
> ||
> > +	    !cfg80211_go_permissive_chan(rdev, chandef->chan))
> 
> This is the check I was saying you could simplify by tossing the config checks
> and wiphy->regulatory_flags check there.
> 

Ok :)

> >
> >
> > +int cfg80211_get_unii(int freq)
> 
> A reference to where this is documented would be good.
> 

Done.

> > +{
> > +	/* UNII-1 */
> > +	if (freq >= 5150 && freq <= 5250)
> > +		return 0;
> > +
> > +	/* UNII-2A */
> > +	if (freq > 5250 && freq <= 5350)
> > +		return 1;
> > +
> > +	/* UNII-2B */
> > +	if (freq > 5350 && freq <= 5470)
> > +		return 2;
> > +
> > +	/* UNII-2C */
> > +	if (freq > 5470 && freq <= 5725)
> > +		return 3;
> > +
> > +	/* UNII-3 */
> > +	if (freq > 5725 && freq <= 5825)
> > +		return 4;
> > +
> > +	WARN_ON(1);
> 
> probably best to avoid that warning -- there are some
> 4 GHz channels used out there, and pretty sure we'll hit this fast.
> 

Done.

Thanks,

Ilan.
--
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 R. Rodriguez Feb. 19, 2014, 3:47 p.m. UTC | #7
On Wed, Feb 19, 2014 at 02:52:13PM +0000, Peer, Ilan wrote:
> > Ilan, also extend the above with language similar to the one I provided on the
> > cellular base station hints if you ended up adding a device feature capability.
> > 
> 
> You mean specify that this option is enabled, drivers can still use
> the device specific flags to disable this?

Yeap! In particular its important to make it clear that
enabling this option isn't enough to get enable this feature,
this option will only be usable on device drivers that have
support for this feature.

> > > +
> > > +		if (!other_chan)
> > > +			continue;
> > > +
> > > +		if (chan == other_chan)
> > > +			return true;
> > 
> > This seems to me to indicate that we have allowed here daisy chaining / trust
> > on another GO who also trusted its AP. That is, we are leaving it up to the
> > kernel for the above few lines of code to check if the STA was associated to
> > an AP that had DFS support. How do we know the AP the STA was associated
> > to was not another GO that ran through this permissive check? Is the FCC
> > happy with that?
> > 
> 
> This verification should be done by user space, i.e., if the station
> is a legacy client associated to a GO, then wpa_supplicant should not
> allow the GO_CONCURRENT relaxation. In addition, a GO instantiated on
> channel based on this relaxation should not allow connection from
> legacy clients ... again this should be enforced by user space. System
> wise this should adhere to the FCC expectations and prevent daisy
> chaining.

Wow this is a hugely important piece of information, please toss it into
the documentation both kconfig and wiki (once accepted upstream). As for
references to userspace you can mention supplicant (wpa_supplicant).

> > Also to be clear, you check for IEEE80211_CHAN_GO_CONCURRENT only on
> > the caller's channel, not the STA's device, is that OK ? Lets
> > consider the case case of two different types of interfaces on the
> > same system. I am aware of at least one 802.11 AP company selling
> > devices with one 802.11 vendor as the AP and another as the STA. I
> > don't consider this rare anymore now, as such please think about
> > this case as well.
> 
> The property is of the channel so this should suffice. Overall, I
> think that the FCC definition rules are centered on the UNII bands, so
> the rules mandated for a given channel in a specific channel should
> also hold to other channels in the same UNII band. Ultimately, I would
> expect all channels in the same UNII band to share the same settings.

OK.

> The iteration in this case is over all the interfaces of the same
> registered device

This feature seems limited then. Can this be extended to relay on the
information from any other registered device? I suspect folks may soon
enter bug reports for this otherwise. That carefulness here seems to
be an implementation preference, but is it a hard requirement? If not
then please considering revising all registered devices.

  Luis
Peer, Ilan Feb. 20, 2014, 7:31 a.m. UTC | #8
> 
> On Wed, Feb 19, 2014 at 02:52:13PM +0000, Peer, Ilan wrote:
> > > Ilan, also extend the above with language similar to the one I
> > > provided on the cellular base station hints if you ended up adding a
> device feature capability.
> > >
> >
> > You mean specify that this option is enabled, drivers can still use
> > the device specific flags to disable this?
> 
> Yeap! In particular its important to make it clear that enabling this option isn't
> enough to get enable this feature, this option will only be usable on device
> drivers that have support for this feature.
> 

Great :) already added it in the previous patch set. 

> > > > +
> > > > +		if (!other_chan)
> > > > +			continue;
> > > > +
> > > > +		if (chan == other_chan)
> > > > +			return true;
> > >
> > > This seems to me to indicate that we have allowed here daisy
> > > chaining / trust on another GO who also trusted its AP. That is, we
> > > are leaving it up to the kernel for the above few lines of code to
> > > check if the STA was associated to an AP that had DFS support. How
> > > do we know the AP the STA was associated to was not another GO that
> > > ran through this permissive check? Is the FCC happy with that?
> > >
> >
> > This verification should be done by user space, i.e., if the station
> > is a legacy client associated to a GO, then wpa_supplicant should not
> > allow the GO_CONCURRENT relaxation. In addition, a GO instantiated on
> > channel based on this relaxation should not allow connection from
> > legacy clients ... again this should be enforced by user space. System
> > wise this should adhere to the FCC expectations and prevent daisy
> > chaining.
> 
> Wow this is a hugely important piece of information, please toss it into the
> documentation both kconfig and wiki (once accepted upstream). As for
> references to userspace you can mention supplicant (wpa_supplicant).
> 

Sure.

> > > Also to be clear, you check for IEEE80211_CHAN_GO_CONCURRENT only
> on
> > > the caller's channel, not the STA's device, is that OK ? Lets
> > > consider the case case of two different types of interfaces on the
> > > same system. I am aware of at least one 802.11 AP company selling
> > > devices with one 802.11 vendor as the AP and another as the STA. I
> > > don't consider this rare anymore now, as such please think about
> > > this case as well.
> >
> > The property is of the channel so this should suffice. Overall, I
> > think that the FCC definition rules are centered on the UNII bands, so
> > the rules mandated for a given channel in a specific channel should
> > also hold to other channels in the same UNII band. Ultimately, I would
> > expect all channels in the same UNII band to share the same settings.
> 
> OK.
> 
> > The iteration in this case is over all the interfaces of the same
> > registered device
> 
> This feature seems limited then. Can this be extended to relay on the
> information from any other registered device? I suspect folks may soon
> enter bug reports for this otherwise. That carefulness here seems to be an
> implementation preference, but is it a hard requirement? If not then please
> considering revising all registered devices.
> 

I think that this might be problematic in cases where the HW/FW has additional enforcement for GO concurrent cases, and thus will not allow to instantiate a GO although there is a station connection on another device. Eventually, it really comes to the question of can one device rely on another device for regulatory compliance?

Need to think about this option and take it with our regulatory people. For now I would prefer to stay with this limitation. 

Thanks,

Ilan.

--
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/net/cfg80211.h b/include/net/cfg80211.h
index dbc5490..317bd06 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4520,12 +4520,14 @@  void cfg80211_report_obss_beacon(struct wiphy *wiphy,
  * cfg80211_reg_can_beacon - check if beaconing is allowed
  * @wiphy: the wiphy
  * @chandef: the channel definition
+ * @iftype: interface type
  *
  * Return: %true if there is no secondary channel or the secondary channel(s)
  * can be used for beaconing (i.e. is not a radar channel etc.)
  */
 bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
-			     struct cfg80211_chan_def *chandef);
+			     struct cfg80211_chan_def *chandef,
+			     enum nl80211_iftype iftype);
 
 /*
  * cfg80211_ch_switch_notify - update wdev channel and notify userspace
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index b07cdc9..fab0c37 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -131,6 +131,9 @@  struct regulatory_request {
  * 	all country IE information processed by the regulatory core. This will
  * 	override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will
  * 	be ignored.
+ * @REGULATORY_DISABLE_RELAX_NO_IR: for devices that do not wish to allow the
+ *      NO_IR relaxation, which enables transmissions on channels on which
+ *      otherwise initiating radiation is not allowed.
  */
 enum ieee80211_regulatory_flags {
 	REGULATORY_CUSTOM_REG			= BIT(0),
@@ -138,6 +141,7 @@  enum ieee80211_regulatory_flags {
 	REGULATORY_DISABLE_BEACON_HINTS		= BIT(2),
 	REGULATORY_COUNTRY_IE_FOLLOW_POWER	= BIT(3),
 	REGULATORY_COUNTRY_IE_IGNORE		= BIT(4),
+	REGULATORY_DISABLE_RELAX_NO_IR          = BIT(5),
 };
 
 struct ieee80211_freq_range {
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 771080e..3503ddb 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -263,7 +263,8 @@  static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	/* make a copy of the chandef, it could be modified below. */
 	chandef = *req_chandef;
 	chan = chandef.chan;
-	if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+	if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef,
+				     NL80211_IFTYPE_ADHOC)) {
 		if (chandef.width == NL80211_CHAN_WIDTH_5 ||
 		    chandef.width == NL80211_CHAN_WIDTH_10 ||
 		    chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
@@ -275,7 +276,8 @@  static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		chandef.width = NL80211_CHAN_WIDTH_20;
 		chandef.center_freq1 = chan->center_freq;
 		/* check again for downgraded chandef */
-		if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+		if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef,
+					     NL80211_IFTYPE_ADHOC)) {
 			sdata_info(sdata,
 				   "Failed to join IBSS, beacons forbidden\n");
 			return;
@@ -868,7 +870,8 @@  ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		goto disconnect;
 	}
 
-	if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, &params.chandef)) {
+	if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, &params.chandef,
+				     NL80211_IFTYPE_ADHOC)) {
 		sdata_info(sdata,
 			   "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
 			   ifibss->bssid,
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 81c05e4..6335590 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -102,6 +102,20 @@  config CFG80211_REG_CELLULAR_HINTS
 	  This option adds support for drivers that can receive regulatory
 	  hints from cellular base stations
 
+config CFG80211_REG_RELAX_NO_IR
+	bool "cfg80211 support for NO_IR relaxation"
+	depends on CFG80211_CERTIFICATION_ONUS
+	---help---
+	  This option enables relaxation of the NO_IR flag. The relaxation
+	  allows initiating radiation on channels that are marked with the
+	  NO_IR flag which forbids transmissions on the channel.
+
+	  For example, enabling this option allows the operation of a P2P
+	  group owner on channels marked with NO_IR if there is an additional
+	  BSS interface which is connected to an AP which is assumed to be
+	  an authorized master, i.e., with radar detection support and DFS
+	  capabilities
+
 config CFG80211_DEFAULT_PS
 	bool "enable powersave by default"
 	depends on CFG80211
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 78559b5..87a9d0e 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -605,15 +605,77 @@  bool cfg80211_chandef_usable(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(cfg80211_chandef_usable);
 
+/*
+ * For GO only, check if the channel can be used under permissive conditions
+ * mandated by the some regulatory bodies, i.e., the channel is marked with
+ * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station interface
+ * associated to an AP on the same channel or on the same UNII band
+ * (assuming that the AP is an authorized master).
+ */
+static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev,
+					struct ieee80211_channel *chan)
+{
+	struct wireless_dev *wdev_iter;
+
+	ASSERT_RTNL();
+
+	if (!(chan->flags & IEEE80211_CHAN_GO_CONCURRENT))
+		return false;
+
+	list_for_each_entry(wdev_iter, &rdev->wdev_list, list) {
+		struct ieee80211_channel *other_chan = NULL;
+		int r1, r2;
+
+		if (wdev_iter->iftype != NL80211_IFTYPE_STATION ||
+		    !netif_running(wdev_iter->netdev))
+				continue;
+
+		wdev_lock(wdev_iter);
+		if (wdev_iter->current_bss)
+			other_chan = wdev_iter->current_bss->pub.channel;
+		wdev_unlock(wdev_iter);
+
+		if (!other_chan)
+			continue;
+
+		if (chan == other_chan)
+			return true;
+
+		if (chan->band != IEEE80211_BAND_5GHZ)
+			continue;
+
+		r1 = cfg80211_get_unii(chan->center_freq);
+		r2 = cfg80211_get_unii(other_chan->center_freq);
+
+		if (r1 != -EINVAL && r1 == r2)
+			return true;
+	}
+
+	return false;
+}
+
 bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
-			     struct cfg80211_chan_def *chandef)
+			     struct cfg80211_chan_def *chandef,
+			     enum nl80211_iftype iftype)
 {
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	bool res;
 	u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
-			       IEEE80211_CHAN_NO_IR |
 			       IEEE80211_CHAN_RADAR;
 
-	trace_cfg80211_reg_can_beacon(wiphy, chandef);
+	trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype);
+
+	/*
+	 * Under certain conditions suggested by the some regulatory bodies
+	 * a GO can operate on channels marked with IEEE80211_NO_IR
+	 * so set this flag only if such relaxations are not enabled and
+	 * the conditions are not met.
+	 */
+	if (iftype != NL80211_IFTYPE_P2P_GO ||
+	    !config_enabled(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
+	    (wiphy->regulatory_flags & REGULATORY_DISABLE_RELAX_NO_IR) ||
+	    !cfg80211_go_permissive_chan(rdev, chandef->chan))
+		prohibited_flags |= IEEE80211_CHAN_NO_IR;
 
 	if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
 	    cfg80211_chandef_dfs_available(wiphy, chandef)) {
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 8858624..93c4d42 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -175,7 +175,8 @@  int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 							       scan_width);
 	}
 
-	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
+	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef,
+				     NL80211_IFTYPE_MESH_POINT))
 		return -EINVAL;
 
 	err = cfg80211_chandef_dfs_required(wdev->wiphy, &setup->chandef);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3c1587f..b37b36e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1914,7 +1914,7 @@  static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
 			result = -EBUSY;
 			break;
 		}
-		if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
+		if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, iftype)) {
 			result = -EINVAL;
 			break;
 		}
@@ -3263,7 +3263,8 @@  static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 	} else if (!nl80211_get_ap_channel(rdev, &params))
 		return -EINVAL;
 
-	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
+	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
+				     wdev->iftype))
 		return -EINVAL;
 
 	err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef);
@@ -5852,7 +5853,8 @@  skip_beacons:
 	if (err)
 		return err;
 
-	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
+	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
+				     wdev->iftype))
 		return -EINVAL;
 
 	if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
@@ -6623,7 +6625,8 @@  static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 	if (err)
 		return err;
 
-	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
+	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
+				     NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
 	switch (ibss.chandef.width) {
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 8a81913..ec38f5d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2489,6 +2489,32 @@  static void reg_timeout_work(struct work_struct *work)
 	rtnl_unlock();
 }
 
+int cfg80211_get_unii(int freq)
+{
+	/* UNII-1 */
+	if (freq >= 5150 && freq <= 5250)
+		return 0;
+
+	/* UNII-2A */
+	if (freq > 5250 && freq <= 5350)
+		return 1;
+
+	/* UNII-2B */
+	if (freq > 5350 && freq <= 5470)
+		return 2;
+
+	/* UNII-2C */
+	if (freq > 5470 && freq <= 5725)
+		return 3;
+
+	/* UNII-3 */
+	if (freq > 5725 && freq <= 5825)
+		return 4;
+
+	WARN_ON(1);
+	return -EINVAL;
+}
+
 int __init regulatory_init(void)
 {
 	int err = 0;
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 02bd8f4..4d44cd4 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -103,4 +103,16 @@  void regulatory_hint_country_ie(struct wiphy *wiphy,
  */
 void regulatory_hint_disconnect(void);
 
+/**
+ * cfg80211_get_unii - get the U-NII band for the frequency
+ * @freq: the frequency for which we want to get the UNII band.
+
+ * Get a value specifying the U-NII band frequency belongs to.
+ * U-NII bands are defined by the FCC in C.F.R 47 part 15.
+ *
+ * Returns -EINVAL if freq is invalid, 0 for UNII-1, 1 for UNII-2A,
+ * 2 for UNII-2B, 3 for UNII-2C and 4 for UNII-3.
+ */
+int cfg80211_get_unii(int freq);
+
 #endif  /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index fbcc23e..3ba80c1 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2189,18 +2189,21 @@  TRACE_EVENT(cfg80211_cqm_rssi_notify,
 );
 
 TRACE_EVENT(cfg80211_reg_can_beacon,
-	TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
-	TP_ARGS(wiphy, chandef),
+	TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
+		 enum nl80211_iftype iftype),
+	TP_ARGS(wiphy, chandef, iftype),
 	TP_STRUCT__entry(
 		WIPHY_ENTRY
 		CHAN_DEF_ENTRY
+		__field(enum nl80211_iftype, iftype)
 	),
 	TP_fast_assign(
 		WIPHY_ASSIGN;
 		CHAN_DEF_ASSIGN(chandef);
+		__entry->iftype = iftype;
 	),
-	TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
-		  WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
+	TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", iftype=%d",
+		  WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->iftype)
 );
 
 TRACE_EVENT(cfg80211_chandef_dfs_required,