linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] wireless: add regulatory_struct_hint
@ 2008-10-21 10:31 Johannes Berg
  2008-10-22 12:21 ` Luis R. Rodriguez
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Johannes Berg @ 2008-10-21 10:31 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, Zhu Yi, Marcel Holtmann, Luis R. Rodriguez

This adds a new function, regulatory_struct_hint, which acts
as a hint to the wireless core which regdomain a card thinks
the system is operating in, but given in terms of the actual
regdomain definition. Multiple hints are permitted when the
specified bands do not overlap.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Entirely untested. Anyone want to give it a go in the dual-band scenario?

 include/net/wireless.h |   14 +++
 net/wireless/reg.c     |  225 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 161 insertions(+), 78 deletions(-)

--- everything.orig/include/net/wireless.h	2008-10-21 11:50:01.000000000 +0200
+++ everything/include/net/wireless.h	2008-10-21 11:50:16.000000000 +0200
@@ -355,4 +355,18 @@ ieee80211_get_channel(struct wiphy *wiph
  * for a regulatory domain structure for the respective country.
  */
 extern void regulatory_hint(const char *alpha2);
+
+/**
+ * regulatory_struct_hint - hint wireless core about regdomain
+ *
+ * @rd: regdomain structure containing the frequency ranges that are
+ *	permitted for use.
+ * @bands: bitmask of bands this contains, use BIT(IEEE80211_BAND_...)
+ *
+ * This function informs the wireless core that the driver believes
+ * that the bands indicated are defined by the given structure in the
+ * regulatory domain the system is operating in.
+ */
+extern void regulatory_struct_hint(struct ieee80211_regdomain *rd,
+				   u32 bands);
 #endif /* __NET_WIRELESS_H */
--- everything.orig/net/wireless/reg.c	2008-10-21 11:50:14.000000000 +0200
+++ everything/net/wireless/reg.c	2008-10-21 12:26:08.000000000 +0200
@@ -45,9 +45,9 @@
 /* wiphy is set if this request's initiator is REGDOM_SET_BY_COUNTRY_IE */
 struct regulatory_request {
 	struct wiphy *wiphy;
-	int granted;
 	enum reg_set_by initiator;
 	char alpha2[2];
+	u32 bands;
 };
 
 static struct regulatory_request *last_request;
@@ -296,82 +296,6 @@ static int call_crda(const char *alpha2)
 	return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
 }
 
-/* This has the logic which determines when a new request
- * should be ignored. */
-static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
-			  const char *alpha2)
-{
-	/* All initial requests are respected */
-	if (!last_request)
-		return 0;
-
-	switch (set_by) {
-	case REGDOM_SET_BY_INIT:
-		return -EINVAL;
-	case REGDOM_SET_BY_CORE:
-		/* Always respect new wireless core hints, should only
-		 * come in for updating the world regulatory domain at init
-		 * anyway */
-		return 0;
-	case REGDOM_SET_BY_COUNTRY_IE:
-		if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
-			if (last_request->wiphy != wiphy) {
-				/* Two cards with two APs claiming different
-				 * different Country IE alpha2s!
-				 * You're special!! */
-				if (!alpha2_equal(last_request->alpha2,
-						cfg80211_regdomain->alpha2)) {
-					/* XXX: Deal with conflict, consider
-					 * building a new one out of the
-					 * intersection */
-					WARN_ON(1);
-					return -EOPNOTSUPP;
-				}
-				return -EALREADY;
-			}
-			/* Two consecutive Country IE hints on the same wiphy */
-			if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
-				return 0;
-			return -EALREADY;
-		}
-		if (WARN_ON(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2)),
-				"Invalid Country IE regulatory hint passed "
-				"to the wireless core\n")
-			return -EINVAL;
-		/* We ignore Country IE hints for now, as we haven't yet
-		 * added the dot11MultiDomainCapabilityEnabled flag
-		 * for wiphys */
-		return 1;
-	case REGDOM_SET_BY_DRIVER:
-		BUG_ON(!wiphy);
-		if (last_request->initiator == REGDOM_SET_BY_DRIVER)
-			return -EALREADY;
-		if (last_request->initiator == REGDOM_SET_BY_CORE)
-			return 0;
-		/* XXX: Handle intersection, and add the
-		 * dot11MultiDomainCapabilityEnabled flag to wiphy. For now
-		 * we assume the driver has this set to false, following the
-		 * 802.11d dot11MultiDomainCapabilityEnabled documentation */
-		if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
-			return 0;
-		return 0;
-	case REGDOM_SET_BY_USER:
-		if (last_request->initiator == REGDOM_SET_BY_USER ||
-		    last_request->initiator == REGDOM_SET_BY_CORE)
-			return 0;
-		/* Drivers can use their wiphy's reg_notifier()
-		 * to override any information */
-		if (last_request->initiator == REGDOM_SET_BY_DRIVER)
-			return 0;
-		/* XXX: Handle intersection */
-		if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
-			return -EOPNOTSUPP;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
 bool reg_is_valid_request(const char *alpha2)
 {
@@ -542,6 +466,83 @@ void wiphy_update_regulatory(struct wiph
 	}
 }
 
+/* This has the logic which determines when a new request
+ * should be ignored. */
+static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
+			  const char *alpha2)
+{
+	/* All initial requests are respected */
+	if (!last_request)
+		return 0;
+
+	switch (set_by) {
+	case REGDOM_SET_BY_INIT:
+		return -EINVAL;
+	case REGDOM_SET_BY_CORE:
+		/* Always respect new wireless core hints, should only
+		 * come in for updating the world regulatory domain at init
+		 * anyway */
+		return 0;
+	case REGDOM_SET_BY_COUNTRY_IE:
+		if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
+			if (last_request->wiphy != wiphy) {
+				/* Two cards with two APs claiming different
+				 * different Country IE alpha2s!
+				 * You're special!! */
+				if (!alpha2_equal(last_request->alpha2,
+						cfg80211_regdomain->alpha2)) {
+					/* XXX: Deal with conflict, consider
+					 * building a new one out of the
+					 * intersection */
+					WARN_ON(1);
+					return -EOPNOTSUPP;
+				}
+				return -EALREADY;
+			}
+			/* Two consecutive Country IE hints on the same wiphy */
+			if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
+				return 0;
+			return -EALREADY;
+		}
+		if (WARN_ON(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2)),
+				"Invalid Country IE regulatory hint passed "
+				"to the wireless core\n")
+			return -EINVAL;
+		/* We ignore Country IE hints for now, as we haven't yet
+		 * added the dot11MultiDomainCapabilityEnabled flag
+		 * for wiphys */
+		return 1;
+	case REGDOM_SET_BY_DRIVER:
+		BUG_ON(!wiphy);
+		switch (last_request->initiator) {
+		case REGDOM_SET_BY_DRIVER:
+			return -EALREADY;
+		case REGDOM_SET_BY_INIT:
+		case REGDOM_SET_BY_CORE:
+		case REGDOM_SET_BY_USER:
+		case REGDOM_SET_BY_COUNTRY_IE:
+			return 0;
+		default:
+			break;
+		}
+		return 0;
+	case REGDOM_SET_BY_USER:
+		if (last_request->initiator == REGDOM_SET_BY_USER ||
+		    last_request->initiator == REGDOM_SET_BY_CORE)
+			return 0;
+		/* Drivers can use their wiphy's reg_notifier()
+		 * to override any information */
+		if (last_request->initiator == REGDOM_SET_BY_DRIVER)
+			return 0;
+		/* XXX: Handle intersection */
+		if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
+			return -EOPNOTSUPP;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 /* Caller must hold &cfg80211_drv_mutex */
 int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
 		      const char *alpha2)
@@ -567,6 +568,7 @@ int __regulatory_hint(struct wiphy *wiph
 		request->alpha2[1] = alpha2[1];
 		request->initiator = set_by;
 		request->wiphy = wiphy;
+		request->bands = ~0;
 
 		kfree(last_request);
 		last_request = request;
@@ -594,6 +596,74 @@ void regulatory_hint(const char *alpha2)
 }
 EXPORT_SYMBOL(regulatory_hint);
 
+void regulatory_struct_hint(struct ieee80211_regdomain *rd, u32 bands)
+{
+	const struct ieee80211_regdomain *orig = NULL;
+	struct ieee80211_regdomain *new = NULL;
+	int origrules;
+
+	BUG_ON(!rd);
+	BUG_ON(!bands);
+
+	mutex_lock(&cfg80211_drv_mutex);
+
+	/*
+	 * ignore hint if anything else set it or if the given
+	 * bands overlap already defined bands
+	 */
+	if (last_request) {
+		switch (last_request->initiator) {
+		case REGDOM_SET_BY_DRIVER:
+			if (last_request->bands & bands)
+				goto out;
+			break;
+		case REGDOM_SET_BY_CORE:
+			break;
+		default:
+			goto out;
+		}
+
+		/* modify the currently set regdom */
+		orig = cfg80211_regdomain;
+		origrules = orig->n_reg_rules;
+	} else {
+		last_request = kzalloc(sizeof(struct regulatory_request),
+				       GFP_KERNEL);
+		if (!last_request)
+			goto out;
+
+		last_request->alpha2[0] = '9';
+		last_request->alpha2[1] = '9';
+		last_request->initiator = REGDOM_SET_BY_DRIVER;
+
+		origrules = 0;
+	}
+
+	last_request->bands |= bands;
+
+	new = krealloc(orig,
+		       sizeof(struct ieee80211_regdomain) +
+		       sizeof(struct ieee80211_reg_rule) * origrules +
+		       sizeof(struct ieee80211_reg_rule) * rd->n_reg_rules,
+		       GFP_KERNEL);
+	if (!new)
+		goto out;
+
+	new->alpha2[0] = '9';
+	new->alpha2[1] = '9';
+	new->n_reg_rules = origrules + rd->n_reg_rules;
+	/* original rules still intact */
+	memcpy(&new->reg_rules[origrules],
+	       rd->reg_rules,
+	       sizeof(struct ieee80211_reg_rule) * rd->n_reg_rules);
+
+	set_regdom(new);
+	kfree(rd);
+
+ out:
+	mutex_unlock(&cfg80211_drv_mutex);
+}
+
 
 static void print_rd_rules(const struct ieee80211_regdomain *rd)
 {
@@ -710,7 +780,6 @@ static int __set_regdom(const struct iee
 
 	/* Tada! */
 	cfg80211_regdomain = rd;
-	last_request->granted = 1;
 
 	return 0;
 }



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-21 10:31 [PATCH] wireless: add regulatory_struct_hint Johannes Berg
@ 2008-10-22 12:21 ` Luis R. Rodriguez
  2008-10-22 19:30   ` Johannes Berg
  2008-10-23 19:40   ` Perez-Gonzalez, Inaky
  2008-10-22 12:27 ` Luis R. Rodriguez
  2008-10-24  2:43 ` Zhu Yi
  2 siblings, 2 replies; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-22 12:21 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless, Zhu Yi, Marcel Holtmann,
	Luis R. Rodriguez, Perez-Gonzalez, Inaky

On Tue, Oct 21, 2008 at 03:31:50AM -0700, Johannes Berg wrote:
> This adds a new function, regulatory_struct_hint, which acts
> as a hint to the wireless core which regdomain a card thinks
> the system is operating in, but given in terms of the actual
> regdomain definition. Multiple hints are permitted when the
> specified bands do not overlap.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> ---
> Entirely untested. Anyone want to give it a go in the dual-band scenario?
> 
>  include/net/wireless.h |   14 +++
>  net/wireless/reg.c     |  225 ++++++++++++++++++++++++++++++++-----------------
>  2 files changed, 161 insertions(+), 78 deletions(-)
> 
> --- everything.orig/include/net/wireless.h      2008-10-21 11:50:01.000000000 +0200
> +++ everything/include/net/wireless.h   2008-10-21 11:50:16.000000000 +0200
> @@ -355,4 +355,18 @@ ieee80211_get_channel(struct wiphy *wiph
>   * for a regulatory domain structure for the respective country.
>   */
>  extern void regulatory_hint(const char *alpha2);
> +
> +/**
> + * regulatory_struct_hint - hint wireless core about regdomain
> + *
> + * @rd: regdomain structure containing the frequency ranges that are
> + *     permitted for use.
> + * @bands: bitmask of bands this contains, use BIT(IEEE80211_BAND_...)

Since this is only for wiphys this seems reasonable. I just keep in the
back of my mind leaving open the possibility for other wireless
subsystems to be able to make use of the currently set regulatory domain
and its regulatory rules, but this is in keeping with that as our
current requests are not changing the regulatory definitions, and just
as we have a wiphy for last_request we can add later struct
foo_new_wireless_type there too. I am curious if band definitions
should be shared between Bluetooth and 802.11 though. I don't think
BT devices have any notion of regulatory though nor are they capable of
exporting it though. Marcel is this correct? Inaky -- how about uwb, or
WiMax?

For our purposes though this is OK though, just wanted to make that
note, so we keep in mind this *can* potentially be used by other
wireless foo.

> + *
> + * This function informs the wireless core that the driver believes
> + * that the bands indicated are defined by the given structure in the
> + * regulatory domain the system is operating in.
> + */
> +extern void regulatory_struct_hint(struct ieee80211_regdomain *rd,
> +                                  u32 bands);
>  #endif /* __NET_WIRELESS_H */
> --- everything.orig/net/wireless/reg.c  2008-10-21 11:50:14.000000000 +0200
> +++ everything/net/wireless/reg.c       2008-10-21 12:26:08.000000000 +0200
> @@ -45,9 +45,9 @@
>  /* wiphy is set if this request's initiator is REGDOM_SET_BY_COUNTRY_IE */
>  struct regulatory_request {
>         struct wiphy *wiphy;
> -       int granted;
>         enum reg_set_by initiator;
>         char alpha2[2];
> +       u32 bands;
>  };
> 
>  static struct regulatory_request *last_request;
> @@ -296,82 +296,6 @@ static int call_crda(const char *alpha2)
>         return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
>  }
> 
> -/* This has the logic which determines when a new request
> - * should be ignored. */
> -static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
> -                         const char *alpha2)
> -{

<-- snip -->

> -}
> -
>  /* Used by nl80211 before kmalloc'ing our regulatory domain */
>  bool reg_is_valid_request(const char *alpha2)
>  {

<-- snip -->

>         }
>  }
> 
> +/* This has the logic which determines when a new request
> + * should be ignored. */
> +static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
> +                         const char *alpha2)
> +{
> +}

I take it reg_is_valid_request() was just shifted, no changes were made to it
here?

> +
>  /* Caller must hold &cfg80211_drv_mutex */
>  int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
>                       const char *alpha2)
> @@ -567,6 +568,7 @@ int __regulatory_hint(struct wiphy *wiph
>                 request->alpha2[1] = alpha2[1];
>                 request->initiator = set_by;
>                 request->wiphy = wiphy;
> +               request->bands = ~0;
> 
>                 kfree(last_request);
>                 last_request = request;
> @@ -594,6 +596,74 @@ void regulatory_hint(const char *alpha2)
>  }
>  EXPORT_SYMBOL(regulatory_hint);
> 
> +void regulatory_struct_hint(struct ieee80211_regdomain *rd, u32 bands)

I see you changed the return value to void for both routines the driver
or a subsystem can use, can you elaborate on the kdoc why this is the
case?

> +{
> +       const struct ieee80211_regdomain *orig = NULL;
> +       struct ieee80211_regdomain *new = NULL;
> +       int origrules;
> +
> +       BUG_ON(!rd);
> +       BUG_ON(!bands);
> +
> +       mutex_lock(&cfg80211_drv_mutex);
> +
> +       /*
> +        * ignore hint if anything else set it or if the given
> +        * bands overlap already defined bands

Is the assumption all along here that this is for hardware which registers
only the channels its hardware is legally capable of? If so can the
documentation clarify that?

Otherwise it would seem to me if USER already set it we should get the
intersection. For example when a user plugs in a USB wireless
card it would not have gotten the chance to have regulatory_hint'd
first so the user may have already set it and if the driver
didn't have a reg_notifier() and simply registered all the channels
upon mac80211 register then the channels the user set will be
allowed. Also what about when the COUNTRY_IE had set it (remember the
result of such country IE request may be in an intersection with the
first driver too, but its ok, we always can trust the result of the
structure of the last set regdomain)? Again, disregard this comment
if the answer to the above paragraph is yes.

> +        */
> +       if (last_request) {
> +               switch (last_request->initiator) {
> +               case REGDOM_SET_BY_DRIVER:
> +                       if (last_request->bands & bands)
> +                               goto out;
> +                       break;
> +               case REGDOM_SET_BY_CORE:
> +                       break;
> +               default:
> +                       goto out;
> +               }
> +
> +               /* modify the currently set regdom */
> +               orig = cfg80211_regdomain;
> +               origrules = orig->n_reg_rules;
> +       } else {
> +               last_request = kzalloc(sizeof(struct regulatory_request),
> +                                      GFP_KERNEL);
> +               if (!last_request)
> +                       goto out;
> +
> +               last_request->alpha2[0] = '9';
> +               last_request->alpha2[1] = '9';
> +               last_request->initiator = REGDOM_SET_BY_DRIVER;
> +
> +               origrules = 0;
> +       }
> +
> +       last_request->bands |= bands;
> +
> +       new = krealloc(orig,
> +                      sizeof(struct ieee80211_regdomain) +
> +                      sizeof(struct ieee80211_reg_rule) * origrules +
> +                      sizeof(struct ieee80211_reg_rule) * rd->n_reg_rules,
> +                      GFP_KERNEL);

Very nice :)

> +       if (!new)
> +               goto out;
> +
> +       new->alpha2[0] = '9';
> +       new->alpha2[1] = '9';

What about cases where the alpha2 can be determined? I know we have no
such hardware yet and doubt we will though. Or are we just going to
point those to use the alpha2 call instead?

> +       new->n_reg_rules = origrules + rd->n_reg_rules;
> +       /* original rules still intact */
> +       memcpy(&new->reg_rules[origrules],
> +              rd->reg_rules,
> +              sizeof(struct ieee80211_reg_rule) * rd->n_reg_rules);

So did this work ? :) Zhu Yi, did you get to test?

> +
> +       set_regdom(new);
> +       kfree(rd);

Very nice indeed.

> +
> + out:
> +       mutex_unlock(&cfg80211_drv_mutex);
> +}
> +
> 
>  static void print_rd_rules(const struct ieee80211_regdomain *rd)
>  {
> @@ -710,7 +780,6 @@ static int __set_regdom(const struct iee
> 
>         /* Tada! */
>         cfg80211_regdomain = rd;
> -       last_request->granted = 1;

What's wrong with this?

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-21 10:31 [PATCH] wireless: add regulatory_struct_hint Johannes Berg
  2008-10-22 12:21 ` Luis R. Rodriguez
@ 2008-10-22 12:27 ` Luis R. Rodriguez
  2008-10-22 19:31   ` Johannes Berg
  2008-10-24  2:43 ` Zhu Yi
  2 siblings, 1 reply; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-22 12:27 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless, Zhu Yi, Marcel Holtmann,
	Luis R. Rodriguez

On Tue, Oct 21, 2008 at 03:31:50AM -0700, Johannes Berg wrote:
> +extern void regulatory_struct_hint(struct ieee80211_regdomain *rd,
> +                                  u32 bands);
>  #endif /* __NET_WIRELESS_H */
> --- everything.orig/net/wireless/reg.c  2008-10-21 11:50:14.000000000 +0200
> +++ everything/net/wireless/reg.c       2008-10-21 12:26:08.000000000 +0200
>  EXPORT_SYMBOL(regulatory_hint);
> 
> +void regulatory_struct_hint(struct ieee80211_regdomain *rd, u32 bands)
> +{

<-- snip -->

> +}
> +

Oh and forgot the EXPORT_SYMBOL(regulatory_struct_hint) though.

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-22 12:21 ` Luis R. Rodriguez
@ 2008-10-22 19:30   ` Johannes Berg
  2008-10-23 19:40   ` Perez-Gonzalez, Inaky
  1 sibling, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2008-10-22 19:30 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: John Linville, linux-wireless, Zhu Yi, Marcel Holtmann,
	Luis R. Rodriguez, Perez-Gonzalez, Inaky

[-- Attachment #1: Type: text/plain, Size: 3904 bytes --]


> For our purposes though this is OK though, just wanted to make that
> note, so we keep in mind this *can* potentially be used by other
> wireless foo.

True, but that hopefully won't even try to use this hint :)

> > +/* This has the logic which determines when a new request
> > + * should be ignored. */
> > +static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
> > +                         const char *alpha2)
> > +{
> > +}
> 
> I take it reg_is_valid_request() was just shifted, no changes were made to it
> here?

Actually, I think I made a small change within, replacing a sequence of
if (...) with a switch().

> > +void regulatory_struct_hint(struct ieee80211_regdomain *rd, u32 bands)
> 
> I see you changed the return value to void for both routines the driver
> or a subsystem can use, can you elaborate on the kdoc why this is the
> case?

Well, I don't think I should explain in kdoc why there is no return
value, but I think that the return value is pointless on a _hint_, as
we've seen in earlier discussions everybody seems to be confused by it.
Can you cite a use case? When would you ever care what the system did
with your hint?

> > +       /*
> > +        * ignore hint if anything else set it or if the given
> > +        * bands overlap already defined bands
> 
> Is the assumption all along here that this is for hardware which registers
> only the channels its hardware is legally capable of? If so can the
> documentation clarify that?
> 
> Otherwise it would seem to me if USER already set it we should get the
> intersection. For example when a user plugs in a USB wireless
> card it would not have gotten the chance to have regulatory_hint'd
> first so the user may have already set it and if the driver
> didn't have a reg_notifier() and simply registered all the channels
> upon mac80211 register then the channels the user set will be
> allowed. Also what about when the COUNTRY_IE had set it (remember the
> result of such country IE request may be in an intersection with the
> first driver too, but its ok, we always can trust the result of the
> structure of the last set regdomain)? Again, disregard this comment
> if the answer to the above paragraph is yes.

I'm not sure I understand your concern. The point here is to allow a
driver to tell the core what it thinks the current operating domain is.
How do you define "[what] hardware is legally capable of"? The
assumption is that a driver will use this hint function if it thinks it
knows what the current operating domain is, in terms of frequency ranges
etc. I don't think there's any other assumption here.

> > +       new->alpha2[0] = '9';
> > +       new->alpha2[1] = '9';
> 
> What about cases where the alpha2 can be determined? I know we have no
> such hardware yet and doubt we will though. Or are we just going to
> point those to use the alpha2 call instead?

Yeah, why would hardware tell us what the regdom is if it has alpha2?
This hypothetical hw could also do both, first hint the structs and then
the alpha2, and if crda is installed the alpha2 hint will call out and
update.

> > +       new->n_reg_rules = origrules + rd->n_reg_rules;
> > +       /* original rules still intact */
> > +       memcpy(&new->reg_rules[origrules],
> > +              rd->reg_rules,
> > +              sizeof(struct ieee80211_reg_rule) * rd->n_reg_rules);
> 
> So did this work ? :) Zhu Yi, did you get to test?

No idea :)

> >  static void print_rd_rules(const struct ieee80211_regdomain *rd)
> >  {
> > @@ -710,7 +780,6 @@ static int __set_regdom(const struct iee
> > 
> >         /* Tada! */
> >         cfg80211_regdomain = rd;
> > -       last_request->granted = 1;
> 
> What's wrong with this?

Uh, I just removed the whole granted flag since it wasn't ever tested.
Side cleanup.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-22 12:27 ` Luis R. Rodriguez
@ 2008-10-22 19:31   ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2008-10-22 19:31 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: John Linville, linux-wireless, Zhu Yi, Marcel Holtmann,
	Luis R. Rodriguez

[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

On Wed, 2008-10-22 at 05:27 -0700, Luis R. Rodriguez wrote:
> On Tue, Oct 21, 2008 at 03:31:50AM -0700, Johannes Berg wrote:
> > +extern void regulatory_struct_hint(struct ieee80211_regdomain *rd,
> > +                                  u32 bands);
> >  #endif /* __NET_WIRELESS_H */
> > --- everything.orig/net/wireless/reg.c  2008-10-21 11:50:14.000000000 +0200
> > +++ everything/net/wireless/reg.c       2008-10-21 12:26:08.000000000 +0200
> >  EXPORT_SYMBOL(regulatory_hint);
> > 
> > +void regulatory_struct_hint(struct ieee80211_regdomain *rd, u32 bands)
> > +{
> 
> <-- snip -->
> 
> > +}
> > +
> 
> Oh and forgot the EXPORT_SYMBOL(regulatory_struct_hint) though.

Oh, good point. Maybe I'll just let those who test this stuff add it
though :)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH] wireless: add regulatory_struct_hint
  2008-10-22 12:21 ` Luis R. Rodriguez
  2008-10-22 19:30   ` Johannes Berg
@ 2008-10-23 19:40   ` Perez-Gonzalez, Inaky
  2008-10-23 19:51     ` Luis R. Rodriguez
  2008-10-23 19:54     ` Marcel Holtmann
  1 sibling, 2 replies; 19+ messages in thread
From: Perez-Gonzalez, Inaky @ 2008-10-23 19:40 UTC (permalink / raw)
  To: Luis R. Rodriguez, Johannes Berg
  Cc: John Linville, linux-wireless, Zhu, Yi, Marcel Holtmann,
	Luis R. Rodriguez

>From: Luis R. Rodriguez [mailto:lrodriguez@atheros.com]
>
>Since this is only for wiphys this seems reasonable. I just keep in the
>back of my mind leaving open the possibility for other wireless
>subsystems to be able to make use of the currently set regulatory domain
>and its regulatory rules, but this is in keeping with that as our
>current requests are not changing the regulatory definitions, and just
>as we have a wiphy for last_request we can add later struct
>foo_new_wireless_type there too. I am curious if band definitions
>should be shared between Bluetooth and 802.11 though. I don't think
>BT devices have any notion of regulatory though nor are they capable of
>exporting it though. Marcel is this correct? Inaky -- how about uwb, or
>WiMax?

UWB swipes over all the bands (from 3.1 to 10.6G), but keeping emission below FCCp15 limits (-41dBm, if memory serves) so it looks as interference to others. All the channel assignments are fixed and known, so in theory,
it'd be possible to coordinate.

On WiMAX the bands are allocated per country and per operator, so if the
device can tell us what it supports or what the operator is telling it to
use, it should be possible for it to report it to some band controller for coordination, but I don't know if it'll make any sense to ask the device to use only bands so and so, because the knowledge of what's allowed is in the network side.

I might be missing the crux of the question though :)


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-23 19:40   ` Perez-Gonzalez, Inaky
@ 2008-10-23 19:51     ` Luis R. Rodriguez
  2008-10-23 19:53       ` Perez-Gonzalez, Inaky
  2008-10-23 19:54     ` Marcel Holtmann
  1 sibling, 1 reply; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-23 19:51 UTC (permalink / raw)
  To: Perez-Gonzalez, Inaky
  Cc: Johannes Berg, John Linville, linux-wireless, Zhu, Yi,
	Marcel Holtmann

On Thu, Oct 23, 2008 at 12:40 PM, Perez-Gonzalez, Inaky
<inaky.perez-gonzalez@intel.com> wrote:
>>From: Luis R. Rodriguez [mailto:lrodriguez@atheros.com]
>>
>>Since this is only for wiphys this seems reasonable. I just keep in the
>>back of my mind leaving open the possibility for other wireless
>>subsystems to be able to make use of the currently set regulatory domain
>>and its regulatory rules, but this is in keeping with that as our
>>current requests are not changing the regulatory definitions, and just
>>as we have a wiphy for last_request we can add later struct
>>foo_new_wireless_type there too. I am curious if band definitions
>>should be shared between Bluetooth and 802.11 though. I don't think
>>BT devices have any notion of regulatory though nor are they capable of
>>exporting it though. Marcel is this correct? Inaky -- how about uwb, or
>>WiMax?
>
> UWB swipes over all the bands (from 3.1 to 10.6G), but keeping emission below FCCp15 limits (-41dBm, if memory serves) so it looks as interference to others. All the channel assignments are fixed and known, so in theory,
> it'd be possible to coordinate.
>
> On WiMAX the bands are allocated per country and per operator, so if the
> device can tell us what it supports or what the operator is telling it to
> use, it should be possible for it to report it to some band controller for coordination, but I don't know if it'll make any sense to ask the device to use only bands so and so, because the knowledge of what's allowed is in the network side.
>
> I might be missing the crux of the question though :)

Actually that helps a lot. As you had mentioned before though we are
not sure if *all* WiMAX devices will operate in the same way but its
good to know what yours are doing. I was wondering specifically if
other wireless technology can contribute to the regulatory rules
collection we have in the future. It seems it *might* be more than
anything we need coexistence technology.

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH] wireless: add regulatory_struct_hint
  2008-10-23 19:51     ` Luis R. Rodriguez
@ 2008-10-23 19:53       ` Perez-Gonzalez, Inaky
  0 siblings, 0 replies; 19+ messages in thread
From: Perez-Gonzalez, Inaky @ 2008-10-23 19:53 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Johannes Berg, John Linville, linux-wireless, Zhu, Yi,
	Marcel Holtmann

>From: mcgrof@gmail.com [mailto:mcgrof@gmail.com] On Behalf Of Luis R.
>
>Actually that helps a lot. As you had mentioned before though we are
>not sure if *all* WiMAX devices will operate in the same way but its
>good to know what yours are doing. I was wondering specifically if
>other wireless technology can contribute to the regulatory rules
>collection we have in the future. It seems it *might* be more than
>anything we need coexistence technology.

You bet -- I just need the time to implement the proof of concept
we presented in the summit :)

Glad it helped,


^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH] wireless: add regulatory_struct_hint
  2008-10-23 19:40   ` Perez-Gonzalez, Inaky
  2008-10-23 19:51     ` Luis R. Rodriguez
@ 2008-10-23 19:54     ` Marcel Holtmann
  2008-10-23 21:21       ` Tomas Winkler
  1 sibling, 1 reply; 19+ messages in thread
From: Marcel Holtmann @ 2008-10-23 19:54 UTC (permalink / raw)
  To: Perez-Gonzalez, Inaky
  Cc: Luis R. Rodriguez, Johannes Berg, John Linville, linux-wireless,
	Zhu, Yi, Luis R. Rodriguez

Hi Luis,

> >Since this is only for wiphys this seems reasonable. I just keep in the
> >back of my mind leaving open the possibility for other wireless
> >subsystems to be able to make use of the currently set regulatory domain
> >and its regulatory rules, but this is in keeping with that as our
> >current requests are not changing the regulatory definitions, and just
> >as we have a wiphy for last_request we can add later struct
> >foo_new_wireless_type there too. I am curious if band definitions
> >should be shared between Bluetooth and 802.11 though. I don't think
> >BT devices have any notion of regulatory though nor are they capable of
> >exporting it though. Marcel is this correct? Inaky -- how about uwb, or
> >WiMax?
> 
> UWB swipes over all the bands (from 3.1 to 10.6G), but keeping emission below FCCp15 limits (-41dBm, if memory serves) so it looks as interference to others. All the channel assignments are fixed and known, so in theory,
> it'd be possible to coordinate.

and Bluetooth uses the full 2.4 GHz band (split into 79 channels) and it
uses the full band equally and is allowed to. The regulatory efforts of
the Bluetooth SIG made it possible to use this world-wide. No regulatory
stuff is needed here.

Bluetooth will also use UWB in the future in the range of 6 GHz and it
will get the same world-wide regulatory effort.

The only part I am not sure is Bluetooth over 802.11 since they have
some weird stuff in there and the specification is not final yet.

Regards

Marcel



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-23 19:54     ` Marcel Holtmann
@ 2008-10-23 21:21       ` Tomas Winkler
  0 siblings, 0 replies; 19+ messages in thread
From: Tomas Winkler @ 2008-10-23 21:21 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Perez-Gonzalez, Inaky, Luis R. Rodriguez, Johannes Berg,
	John Linville, linux-wireless, Zhu, Yi, Luis R. Rodriguez

On Thu, Oct 23, 2008 at 9:54 PM, Marcel Holtmann
<holtmann@linux.intel.com> wrote:
> Hi Luis,
>
>> >Since this is only for wiphys this seems reasonable. I just keep in the
>> >back of my mind leaving open the possibility for other wireless
>> >subsystems to be able to make use of the currently set regulatory domain
>> >and its regulatory rules, but this is in keeping with that as our
>> >current requests are not changing the regulatory definitions, and just
>> >as we have a wiphy for last_request we can add later struct
>> >foo_new_wireless_type there too. I am curious if band definitions
>> >should be shared between Bluetooth and 802.11 though. I don't think
>> >BT devices have any notion of regulatory though nor are they capable of
>> >exporting it though. Marcel is this correct? Inaky -- how about uwb, or
>> >WiMax?
>>
>> UWB swipes over all the bands (from 3.1 to 10.6G), but keeping emission below FCCp15 limits (-41dBm, if memory serves) so it looks as interference to others. All the channel assignments are fixed and known, so in theory,
>> it'd be possible to coordinate.
>
> and Bluetooth uses the full 2.4 GHz band (split into 79 channels) and it
> uses the full band equally and is allowed to. The regulatory efforts of
> the Bluetooth SIG made it possible to use this world-wide. No regulatory
> stuff is needed here.
>
> Bluetooth will also use UWB in the future in the range of 6 GHz and it
> will get the same world-wide regulatory effort.
>
> The only part I am not sure is Bluetooth over 802.11 since they have
> some weird stuff in there and the specification is not final yet.
>
> Regards
>
> Marcel
>
There is a similar effort going on in WiFi but it probably will take
some time, till this regulator nonsense is removed
Tomas

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-21 10:31 [PATCH] wireless: add regulatory_struct_hint Johannes Berg
  2008-10-22 12:21 ` Luis R. Rodriguez
  2008-10-22 12:27 ` Luis R. Rodriguez
@ 2008-10-24  2:43 ` Zhu Yi
  2008-10-24  9:39   ` Johannes Berg
  2 siblings, 1 reply; 19+ messages in thread
From: Zhu Yi @ 2008-10-24  2:43 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless, Marcel Holtmann, Luis R. Rodriguez

[-- Attachment #1: Type: text/plain, Size: 1655 bytes --]

On Tue, 2008-10-21 at 03:31 -0700, Johannes Berg wrote:
> This adds a new function, regulatory_struct_hint, which acts
> as a hint to the wireless core which regdomain a card thinks
> the system is operating in, but given in terms of the actual
> regdomain definition. Multiple hints are permitted when the
> specified bands do not overlap.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

Thanks for the patch. I think this implemnted what we called the
per-band regulatory hint as we discussed. I'll test it.

It should solve the *real* problem. But in theory, it is still not
correct. I couldn't find a real example here. Let me just suppose a
non-exist device D, which is known to be broken for its channel 6. The
device excludes channel 6 on its EEPROM, thus the driver
regulatory_struct_hint() without channel 6. Then user insert the second
card. The second card works also without channel 6 support!

The real problem here is the mess up of device capabiliy vs. regulatory
rules. The channles a CARDx in a system with n wifi cards can be used
is:

(CARD1_REG & CARD2_REG & ... & CARDn_REG) & CARDx_CAPA

Given a device with the information of (CARDx_REG & CARDx_CAPA) in the
EEPROM, use it as the regulatory rules for the whole system is wrong. It
ends out CARDy is constrained with the capability of CARDx!

(CARD1_REG & ... & CARDx_REG & CARDx_CAPA & ...) & CARDy_CAPA

Although I couldn't find a real example in reality. And the valid dual
bands example is solved by this patch. So I don't have strong argument
on solving something not existed. But the logic is wrong!

I've attached my implmentation to this problem.

Thanks,
-yi

[-- Attachment #2: reg.patch --]
[-- Type: message/rfc822, Size: 9824 bytes --]

From: "Zhu, Yi" <yi.zhu@intel.com>
To: "linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Cc: "Zhu, Yi" <yi.zhu@intel.com>
Subject: [RFC] wireless: add hardware supported regulatory domain enforcement
Date: Wed, 22 Oct 2008 03:11:09 -0600
Message-ID: <1224666669-4538-1-git-send-email-yi.zhu@intel.com>

The patch extends the current regulatory framework to support regulatory
enforcement by device hardware (firmware). If the regulatory check is
performed by hardware, the driver uses a special flag to indicate the
regulatory framework, so that the regulatory framework will bypass all
the regulatory checks for this device and delegate it to the hardware.

The implementation of this "bypass" introduces a virtual regulatory domain
which is a super set of all the existed regdomains. Note the virtual
regdomain allows to be overwritten by any other regdomains from user,
country IE, core, or other drivers.

The patch resolves the problem a wireless device doesn't export enough
information for the regulatory domain it uses. This information is
unnecessary if the regulatory check can be done by the hardware.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |    4 ++
 include/net/cfg80211.h                 |    4 ++
 include/net/wireless.h                 |    5 ++-
 net/wireless/reg.c                     |   52 ++++++++++++++++++++++++++++----
 4 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 9882c65..6c4fe96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4322,6 +4322,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        if (err)
                goto out_remove_sysfs;

+       err = regulatory_hint(priv->hw->wiphy, NULL, NULL, REGULATORY_HARDWARE);
+       if (err)
+               printk("regulatory_hint returns %d\n", err);
+
        err = iwl_dbgfs_register(priv, DRV_NAME);
        if (err)
                IWL_ERROR("failed to create debugfs files\n");
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0e85ec3..b829b17 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -299,6 +299,9 @@ struct bss_parameters {
  * @REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an 802.11 country
  *     information element with regulatory information it thinks we
  *     should consider.
+ * @REGDOM_SET_BY_HARDWARE: a wireless device has the ability to perform
+ *     regulatory enforcement. The wireless core should delegate the regulatory
+ *     rules checking to the hardware.
  */
 enum reg_set_by {
        REGDOM_SET_BY_INIT,
@@ -306,6 +309,7 @@ enum reg_set_by {
        REGDOM_SET_BY_USER,
        REGDOM_SET_BY_DRIVER,
        REGDOM_SET_BY_COUNTRY_IE,
+       REGDOM_SET_BY_HARDWARE,
 };

 struct ieee80211_freq_range {
diff --git a/include/net/wireless.h b/include/net/wireless.h
index c0aa0fb..08ff1e9 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -367,6 +367,8 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq)
  */
 extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
                const char *alpha2, struct ieee80211_regdomain *rd);
+
+#define        REGULATORY_HARDWARE     BIT(0)
 /**
  * regulatory_hint - driver hint to the wireless core a regulatory domain
  * @wiphy: the driver's very own &struct wiphy
@@ -376,6 +378,7 @@ extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
  *     alpha2.
  * @rd: a complete regulatory domain provided by the driver. If passed
  *     the driver does not need to worry about freeing it.
+ * @flags: regulatory flags passed by the driver
  *
  * Wireless drivers can use this function to hint to the wireless core
  * what it believes should be the current regulatory domain by
@@ -391,5 +394,5 @@ extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
  * See __regulatory_hint() documentation for possible return values.
  */
 extern int regulatory_hint(struct wiphy *wiphy,
-               const char *alpha2, struct ieee80211_regdomain *rd);
+               const char *alpha2, struct ieee80211_regdomain *rd, u32 flags);
 #endif /* __NET_WIRELESS_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 626dbb6..cb1df45 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -81,9 +81,30 @@ static const struct ieee80211_regdomain world_regdom = {
        }
 };

+/* A virtual regdomain which is the super set for all existed domains */
+static const struct ieee80211_regdomain virtual_regdom = {
+       .n_reg_rules = 4,
+       .alpha2 =  "01",
+       .reg_rules = {
+               /* IEEE 802.11b/g, channels 1..14 */
+               REG_RULE(2412-10, 2484+10, 40, 6, 27, 0),
+               /* IEEE 802.11a, channel 36..64 */
+               REG_RULE(5170-10, 5320+10, 40, 6, 23, 0),
+               /* IEEE 802.11a, channels 100..140 */
+               REG_RULE(5500-10, 5700+10, 40, 6, 30,
+                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_DFS),
+               /* IEEE 802.11a, channels 149..165, outdoor */
+               REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
+       }
+};
+
 static const struct ieee80211_regdomain *cfg80211_world_regdom =
        &world_regdom;

+static const struct ieee80211_regdomain *cfg80211_virtual_regdom =
+       &virtual_regdom;
+
 #ifdef CONFIG_WIRELESS_OLD_REGULATORY
 static char *ieee80211_regdom = "US";
 module_param(ieee80211_regdom, charp, 0444);
@@ -184,11 +205,14 @@ static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
 static void reset_regdomains(void)
 {
        /* avoid freeing static information or freeing something twice */
-       if (cfg80211_regdomain == cfg80211_world_regdom)
+       if ((cfg80211_regdomain == cfg80211_world_regdom) ||
+           (cfg80211_regdomain == cfg80211_virtual_regdom))
                cfg80211_regdomain = NULL;
-       if (cfg80211_world_regdom == &world_regdom)
+       if ((cfg80211_world_regdom == &world_regdom) ||
+           (cfg80211_world_regdom == &virtual_regdom))
                cfg80211_world_regdom = NULL;
-       if (cfg80211_regdomain == &world_regdom)
+       if ((cfg80211_regdomain == &world_regdom) ||
+           (cfg80211_regdomain == &virtual_regdom))
                cfg80211_regdomain = NULL;
        if (is_old_static_regdom(cfg80211_regdomain))
                cfg80211_regdomain = NULL;
@@ -314,6 +338,11 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
        last_request = list_first_entry(&regulatory_requests,
                struct regulatory_request, list);

+       /* Any request can overwrite the virtual regdomain set by hardware. */
+       if ((last_request->initiator == REGDOM_SET_BY_HARDWARE) &&
+           (set_by != REGDOM_SET_BY_HARDWARE))
+               return 0;
+
        switch (set_by) {
        case REGDOM_SET_BY_INIT:
                return -EINVAL;
@@ -390,6 +419,10 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
                if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
                        return -EOPNOTSUPP;
                return 0;
+       case REGDOM_SET_BY_HARDWARE:
+               if (last_request->initiator == REGDOM_SET_BY_CORE)
+                       return 0;
+               return -EALREADY;
        default:
                return -EINVAL;
        }
@@ -600,6 +633,7 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
        case REGDOM_SET_BY_COUNTRY_IE:
        case REGDOM_SET_BY_DRIVER:
        case REGDOM_SET_BY_USER:
+       case REGDOM_SET_BY_HARDWARE:
                request = kzalloc(sizeof(struct regulatory_request),
                        GFP_KERNEL);
                if (!request)
@@ -629,14 +663,19 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,

 /* If rd is not NULL and if this call fails the caller must free it */
 int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
-       struct ieee80211_regdomain *rd)
+       struct ieee80211_regdomain *rd, u32 flags)
 {
        int r;
-       BUG_ON(!rd && !alpha2);
+       enum reg_set_by setby = (flags & REGULATORY_HARDWARE) ?
+                               REGDOM_SET_BY_HARDWARE : REGDOM_SET_BY_DRIVER;
+
+       BUG_ON(!rd && !alpha2 && !flags);
+       if (flags & REGULATORY_HARDWARE)
+               rd = (struct ieee80211_regdomain *) cfg80211_virtual_regdom;

        mutex_lock(&cfg80211_drv_mutex);

-       r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd);
+       r = __regulatory_hint(wiphy, setby, alpha2, rd);
        if (r || !rd)
                goto unlock_and_exit;

@@ -752,6 +791,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
        case REGDOM_SET_BY_CORE:
        case REGDOM_SET_BY_DRIVER:
        case REGDOM_SET_BY_USER:
+       case REGDOM_SET_BY_HARDWARE:
                if (!is_valid_rd(rd)) {
                        printk(KERN_ERR "cfg80211: Invalid "
                                "regulatory domain detected:\n");
--
1.5.3.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24  2:43 ` Zhu Yi
@ 2008-10-24  9:39   ` Johannes Berg
  2008-10-24 10:15     ` Luis R. Rodriguez
                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Johannes Berg @ 2008-10-24  9:39 UTC (permalink / raw)
  To: Zhu Yi; +Cc: John Linville, linux-wireless, Marcel Holtmann, Luis R. Rodriguez

[-- Attachment #1: Type: text/plain, Size: 2162 bytes --]

On Fri, 2008-10-24 at 10:43 +0800, Zhu Yi wrote:
>         
>         The patch extends the current regulatory framework to support regulatory
>         enforcement by device hardware (firmware). If the regulatory check is
>         performed by hardware, the driver uses a special flag to indicate the
>         regulatory framework, so that the regulatory framework will bypass all
>         the regulatory checks for this device and delegate it to the hardware.

The way I'm reading this, it's incorrect because it doesn't allow the
user to override the hardware's idea of the regulatory domain. I think
it's just a wrong description though.

However, there is another major problem with this, if I use a USB device
that has no regulatory information on a laptop that has this virtual
regdomain configured because of a built-in Intel device, my USB device
will wrongly enable all channels.

But inspired by your patch, here's a different idea:

 * remove the struct regdomain hint thing
 * introduce a "hardware has regulatory check" flag, which means that
    - hardware will enforce regulatory compliance to whatever it thinks
      the regulatory domain is
    - the driver will, of course, still also enforce the information in
      wiphy->bands as it does now
 * if a wiphy has the "hw regulatory" flag set and the
   cfg80211_regdomain is the world regdomain (whether hard-coded or
   gotten from CRDA), then (and only then!) don't apply the
   cfg80211_regdomain to it

This would have the following consequences:
 + much less code since all the hint stuff goes away
 + still works for users who move around with a hw-regulatory based
   laptop if they set the regdomain to something other than world
   manually
 - secondary hardware cannot benefit of the, now no longer given, hint
   which regdomain the laptop is in and will be restricted to world
 - some degree of confusion possible when one device can use channel 13
   (say iwl-agn hardware configured for Europe) and another cannot (say
   a USB device without regulatory information, leading to the world
   regdomain being the used one)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24  9:39   ` Johannes Berg
@ 2008-10-24 10:15     ` Luis R. Rodriguez
  2008-10-24 18:26       ` Johannes Berg
  2008-10-24 18:18     ` Marcel Holtmann
  2008-10-27  3:08     ` Zhu Yi
  2 siblings, 1 reply; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-24 10:15 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Zhu Yi, John Linville, linux-wireless, Marcel Holtmann,
	Luis R. Rodriguez

On Fri, Oct 24, 2008 at 02:39:36AM -0700, Johannes Berg wrote:
> On Fri, 2008-10-24 at 10:43 +0800, Zhu Yi wrote:
> >         
> >         The patch extends the current regulatory framework to support regulatory
> >         enforcement by device hardware (firmware). If the regulatory check is
> >         performed by hardware, the driver uses a special flag to indicate the
> >         regulatory framework, so that the regulatory framework will bypass all
> >         the regulatory checks for this device and delegate it to the hardware.
> 
> The way I'm reading this, it's incorrect because it doesn't allow the
> user to override the hardware's idea of the regulatory domain. I think
> it's just a wrong description though.
> 
> However, there is another major problem with this, if I use a USB device
> that has no regulatory information on a laptop that has this virtual
> regdomain configured because of a built-in Intel device, my USB device
> will wrongly enable all channels.
> 
> But inspired by your patch, here's a different idea:
> 
>  * remove the struct regdomain hint thing
>  * introduce a "hardware has regulatory check" flag, which means that
>     - hardware will enforce regulatory compliance to whatever it thinks
>       the regulatory domain is
>     - the driver will, of course, still also enforce the information in
>       wiphy->bands as it does now
>  * if a wiphy has the "hw regulatory" flag set and the
>    cfg80211_regdomain is the world regdomain (whether hard-coded or
>    gotten from CRDA)

And if initiator == CORE

> , then (and only then!) don't apply the
>    cfg80211_regdomain to it

I like this approach.

> This would have the following consequences:
>  + much less code since all the hint stuff goes away
>  + still works for users who move around with a hw-regulatory based
>    laptop if they set the regdomain to something other than world
>    manually
>  - secondary hardware cannot benefit of the, now no longer given, hint
>    which regdomain the laptop is in and will be restricted to world
>  - some degree of confusion possible when one device can use channel 13
>    (say iwl-agn hardware configured for Europe) and another cannot (say
>    a USB device without regulatory information, leading to the world
>    regdomain being the used one)

This will not be a problem if distributions end up asking to
set regdomain for a country for the user, which I think they should.

like_this_approach++

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24  9:39   ` Johannes Berg
  2008-10-24 10:15     ` Luis R. Rodriguez
@ 2008-10-24 18:18     ` Marcel Holtmann
  2008-10-24 18:24       ` Luis R. Rodriguez
  2008-10-27  3:08     ` Zhu Yi
  2 siblings, 1 reply; 19+ messages in thread
From: Marcel Holtmann @ 2008-10-24 18:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Zhu Yi, John Linville, linux-wireless, Luis R. Rodriguez

Hi Johannes,

> However, there is another major problem with this, if I use a USB device
> that has no regulatory information on a laptop that has this virtual
> regdomain configured because of a built-in Intel device, my USB device
> will wrongly enable all channels.
> 
> But inspired by your patch, here's a different idea:
> 
>  * remove the struct regdomain hint thing
>  * introduce a "hardware has regulatory check" flag, which means that
>     - hardware will enforce regulatory compliance to whatever it thinks
>       the regulatory domain is
>     - the driver will, of course, still also enforce the information in
>       wiphy->bands as it does now
>  * if a wiphy has the "hw regulatory" flag set and the
>    cfg80211_regdomain is the world regdomain (whether hard-coded or
>    gotten from CRDA), then (and only then!) don't apply the
>    cfg80211_regdomain to it

we really only care about the case where we have no userspace capable of
setting the regulatory domain. So in only that case it makes sense to
fallback to the hardware regulatory support. So I would not make this
depend on world domain since that might not work good enough in the 5
GHz case. Can the mac80211 just track if userspace has set a regulatory
domain and then enforce it. Otherwise leave it to the hardware that
supports it or enforce the world domain to hardware that has no
regulatory support in hardware.

Can we also have a command that clears/resets the regulatory domain
setting so we get back to the initial state without rebooting. Would be
also good to have for testing.

> This would have the following consequences:
>  + much less code since all the hint stuff goes away
>  + still works for users who move around with a hw-regulatory based
>    laptop if they set the regdomain to something other than world
>    manually
>  - secondary hardware cannot benefit of the, now no longer given, hint
>    which regdomain the laptop is in and will be restricted to world
>  - some degree of confusion possible when one device can use channel 13
>    (say iwl-agn hardware configured for Europe) and another cannot (say
>    a USB device without regulatory information, leading to the world
>    regdomain being the used one)

This discussion started with having two adapters and disabling 5 GHz for
the second if the first one is BG only. This solution would make this
work when the second card sets the hardware regulatory flag. So it looks
good to me.

I don't see a big problem with restricting channels. Disabling a whole
band is an issue. However we could add printk's to tell the user when we
apply different regulatory domains to different devices, because one has
the hardware flag set.

Other than that, I think this idea makes a lot of sense. Having a much
more simpler logic is a good thing.

Regards

Marcel



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24 18:18     ` Marcel Holtmann
@ 2008-10-24 18:24       ` Luis R. Rodriguez
  0 siblings, 0 replies; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-24 18:24 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Johannes Berg, Zhu Yi, John Linville, linux-wireless

On Fri, Oct 24, 2008 at 11:18 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Can the mac80211 just track if userspace has set a regulatory
> domain and then enforce it.

yeap, when initiator == CORE

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24 10:15     ` Luis R. Rodriguez
@ 2008-10-24 18:26       ` Johannes Berg
  2008-10-24 18:33         ` Luis R. Rodriguez
  0 siblings, 1 reply; 19+ messages in thread
From: Johannes Berg @ 2008-10-24 18:26 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Zhu Yi, John Linville, linux-wireless, Marcel Holtmann,
	Luis R. Rodriguez

[-- Attachment #1: Type: text/plain, Size: 561 bytes --]

On Fri, 2008-10-24 at 03:15 -0700, Luis R. Rodriguez wrote:

> >  * if a wiphy has the "hw regulatory" flag set and the
> >    cfg80211_regdomain is the world regdomain (whether hard-coded or
> >    gotten from CRDA)
> 
> And if initiator == CORE

Makes sense, yeah.


> This will not be a problem if distributions end up asking to
> set regdomain for a country for the user, which I think they should.

Right.

I'll post the patches that rework the current stuff and remove the
struct hint, and then we can implement this on top.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24 18:26       ` Johannes Berg
@ 2008-10-24 18:33         ` Luis R. Rodriguez
  2008-10-24 18:35           ` Johannes Berg
  0 siblings, 1 reply; 19+ messages in thread
From: Luis R. Rodriguez @ 2008-10-24 18:33 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Zhu Yi, John Linville, linux-wireless, Marcel Holtmann

On Fri, Oct 24, 2008 at 11:26 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2008-10-24 at 03:15 -0700, Luis R. Rodriguez wrote:
>
>> >  * if a wiphy has the "hw regulatory" flag set and the
>> >    cfg80211_regdomain is the world regdomain (whether hard-coded or
>> >    gotten from CRDA)
>>
>> And if initiator == CORE
>
> Makes sense, yeah.

Now that i think about it, this would suffice for the check, no need
to check for world reg. Thoughts?

  Luis

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24 18:33         ` Luis R. Rodriguez
@ 2008-10-24 18:35           ` Johannes Berg
  0 siblings, 0 replies; 19+ messages in thread
From: Johannes Berg @ 2008-10-24 18:35 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Zhu Yi, John Linville, linux-wireless, Marcel Holtmann

[-- Attachment #1: Type: text/plain, Size: 636 bytes --]

On Fri, 2008-10-24 at 11:33 -0700, Luis R. Rodriguez wrote:
> On Fri, Oct 24, 2008 at 11:26 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Fri, 2008-10-24 at 03:15 -0700, Luis R. Rodriguez wrote:
> >
> >> >  * if a wiphy has the "hw regulatory" flag set and the
> >> >    cfg80211_regdomain is the world regdomain (whether hard-coded or
> >> >    gotten from CRDA)
> >>
> >> And if initiator == CORE
> >
> > Makes sense, yeah.
> 
> Now that i think about it, this would suffice for the check, no need
> to check for world reg. Thoughts?

Indeed, probably easier, CORE always only sets world.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] wireless: add regulatory_struct_hint
  2008-10-24  9:39   ` Johannes Berg
  2008-10-24 10:15     ` Luis R. Rodriguez
  2008-10-24 18:18     ` Marcel Holtmann
@ 2008-10-27  3:08     ` Zhu Yi
  2 siblings, 0 replies; 19+ messages in thread
From: Zhu Yi @ 2008-10-27  3:08 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless, Marcel Holtmann, Luis R. Rodriguez

On Fri, 2008-10-24 at 02:39 -0700, Johannes Berg wrote:
> On Fri, 2008-10-24 at 10:43 +0800, Zhu Yi wrote:
> >         
> >         The patch extends the current regulatory framework to support regulatory
> >         enforcement by device hardware (firmware). If the regulatory check is
> >         performed by hardware, the driver uses a special flag to indicate the
> >         regulatory framework, so that the regulatory framework will bypass all
> >         the regulatory checks for this device and delegate it to the hardware.
> 
> The way I'm reading this, it's incorrect because it doesn't allow the
> user to override the hardware's idea of the regulatory domain. I think
> it's just a wrong description though.
> 
> However, there is another major problem with this, if I use a USB device
> that has no regulatory information on a laptop that has this virtual
> regdomain configured because of a built-in Intel device, my USB device
> will wrongly enable all channels.
> 
> But inspired by your patch, here's a different idea:
> 
>  * remove the struct regdomain hint thing
>  * introduce a "hardware has regulatory check" flag, which means that
>     - hardware will enforce regulatory compliance to whatever it thinks
>       the regulatory domain is
>     - the driver will, of course, still also enforce the information in
>       wiphy->bands as it does now
>  * if a wiphy has the "hw regulatory" flag set and the
>    cfg80211_regdomain is the world regdomain (whether hard-coded or
>    gotten from CRDA), then (and only then!) don't apply the
>    cfg80211_regdomain to it
> 
> This would have the following consequences:
>  + much less code since all the hint stuff goes away
>  + still works for users who move around with a hw-regulatory based
>    laptop if they set the regdomain to something other than world
>    manually
>  - secondary hardware cannot benefit of the, now no longer given, hint
>    which regdomain the laptop is in and will be restricted to world
>  - some degree of confusion possible when one device can use channel 13
>    (say iwl-agn hardware configured for Europe) and another cannot (say
>    a USB device without regulatory information, leading to the world
>    regdomain being the used one)

I totally agree.

Thanks,
-yi


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2008-10-27  3:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-21 10:31 [PATCH] wireless: add regulatory_struct_hint Johannes Berg
2008-10-22 12:21 ` Luis R. Rodriguez
2008-10-22 19:30   ` Johannes Berg
2008-10-23 19:40   ` Perez-Gonzalez, Inaky
2008-10-23 19:51     ` Luis R. Rodriguez
2008-10-23 19:53       ` Perez-Gonzalez, Inaky
2008-10-23 19:54     ` Marcel Holtmann
2008-10-23 21:21       ` Tomas Winkler
2008-10-22 12:27 ` Luis R. Rodriguez
2008-10-22 19:31   ` Johannes Berg
2008-10-24  2:43 ` Zhu Yi
2008-10-24  9:39   ` Johannes Berg
2008-10-24 10:15     ` Luis R. Rodriguez
2008-10-24 18:26       ` Johannes Berg
2008-10-24 18:33         ` Luis R. Rodriguez
2008-10-24 18:35           ` Johannes Berg
2008-10-24 18:18     ` Marcel Holtmann
2008-10-24 18:24       ` Luis R. Rodriguez
2008-10-27  3:08     ` Zhu Yi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).