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? diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 626dbb6..703382a 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,9 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth, rr = &cfg80211_regdomain->reg_rules[i]; fr = &rr->freq_range; pr = &rr->power_rule; + + 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 +552,9 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth, } } + if (!band_rule_found) + return -ERANGE; + return !max_bandwidth; } @@ -533,8 +570,15 @@ static void handle_channel(struct ieee80211_channel *chan) &max_bandwidth, ®_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