Search Linux Wireless

Re: New Regulatory Domain Api.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 15, 2008 at 08:00:30PM -0700, Zhu Yi wrote:
> On Wed, 2008-10-15 at 12:56 -0600, Luis R. Rodriguez wrote:
> > On Wed, Oct 15, 2008 at 05:57:20PM -0700, Tomas Winkler wrote:
> > > On Wed, Oct 15, 2008 at 7:44 PM, Luis R. Rodriguez
> > > <lrodriguez@xxxxxxxxxxx> wrote:
> > > > Anyway since you only have 3 this should be very simple to resolve...
> > > > Just add the 5 GHz frequency ranges you always support. Obviously the BG
> > > > card will not be able to make use of them :)
> > >
> > > It's ugly but possible w/a but we still have 3945 and 4965 where it is
> > > not so simple.
> >
> > Ah. I see. Ok then please try this patch. What do you guys think?
> 
> With this patch, the second card own A band reg_rules are not enforced
> for itself. (Still use the first card BG, second card ABG example.)
> Think about the second card is not Intel like card which enforces the
> regulatory in the firmware. The second card uses alpha2 hint. But the
> regdomain allows ALL A band channels.

So.. you didn't look at the code to check where it may have failed...

Anyway try this one. This changes two lines, it checks if the band check
was already true, if so it doesn't overwrite it. If I get a chance I'll
test it.

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 626dbb6..25b6f19 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -469,6 +469,31 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
 	return 0;
 }
 
+/**
+ * freq_in_rule_band - tells us if a frequency rule is in freqs band
+ * @freq_range: frequency rule we want to query
+ * @freq_khz: frequency we are inquiring about
+ *
+ * This lets us know if a specific frequency rule is or is not relevant to
+ * a specific frequency's band. Bands are device specific and artificial
+ * definitions (the "2.4 GHz band" and the "5 GHz band"), however it is
+ * safe for now to assume that a frequency rule should not be part of a
+ * frequency's band if the start freq or end freq are off by more than 2 GHz.
+ * This resolution can be lowered and should be considered as we add
+ * regulatory rule support for other "bands".
+ **/
+static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
+	u32 freq_khz)
+{
+#define ONE_GHZ_IN_HZ	1000000000
+	if (abs(freq_khz - freq_range->start_freq_khz) <= (2 * ONE_GHZ_IN_HZ))
+		return true;
+	if (abs(freq_khz - freq_range->end_freq_khz) <= (2 * ONE_GHZ_IN_HZ))
+		return true;
+	return false;
+#undef ONE_GHZ_IN_HZ
+}
+
 /* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
  * want to just have the channel structure use these */
 static u32 map_regdom_flags(u32 rd_flags)
@@ -492,11 +517,17 @@ static u32 map_regdom_flags(u32 rd_flags)
  * @reg_rule: the regulatory rule which we have for this frequency
  *
  * Use this function to get the regulatory rule for a specific frequency.
+ * It returns 0 if it was able to find a valid regulatory rule which does
+ * apply to the given center_freq otherwise it returns non-zero. It will
+ * also -ERANGE if we determine the given center_freq does not even have
+ * a regulatory rule for a frequency range in the center_freq's band. See
+ * freq_in_rule_band() for our current definition of a band.
  */
 static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 			 const struct ieee80211_reg_rule **reg_rule)
 {
 	int i;
+	bool band_rule_found = false;
 	u32 max_bandwidth = 0;
 
 	if (!cfg80211_regdomain)
@@ -510,6 +541,13 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 		rr = &cfg80211_regdomain->reg_rules[i];
 		fr = &rr->freq_range;
 		pr = &rr->power_rule;
+
+		/* We only need to know if one frequency rule was
+		 * was in center_freq's band, that's enough, so lets
+		 * not overwrite it once found */
+		if (!band_rule_found)
+			band_rule_found = freq_in_rule_band(fr, center_freq);
+
 		max_bandwidth = freq_max_bandwidth(fr, center_freq);
 		if (max_bandwidth && *bandwidth <= max_bandwidth) {
 			*reg_rule = rr;
@@ -518,6 +556,9 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
 		}
 	}
 
+	if (!band_rule_found)
+		return -ERANGE;
+
 	return !max_bandwidth;
 }
 
@@ -533,8 +574,15 @@ static void handle_channel(struct ieee80211_channel *chan)
 		&max_bandwidth, &reg_rule);
 
 	if (r) {
-		flags |= IEEE80211_CHAN_DISABLED;
-		chan->flags = flags;
+		/* This means a regulatory rule was found with a frequency
+		 * range in center_freq's band. In this case we know the
+		 * regulatory rule has at least *one* regulatory rule for
+		 * the band so we must respect its band definitions. Otherwise
+		 * we assume it may not even know anything about our band */
+		if (r != -ERANGE) {
+			flags |= IEEE80211_CHAN_DISABLED;
+			chan->flags = flags;
+		}
 		return;
 	}
 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux