From 2203251da7bdd2c55ddf7e233c57e80aac0aca16 Mon Sep 17 00:00:00 2001 From: Luis R. Rodriguez Date: Mon, 14 Jul 2008 00:29:56 -0700 Subject: [PATCH] Add a helper to get regulatory information for a specific frequency and desired bandwidth. This lets other subsystems make use of our regulatory information. To: johannes@sipsolutions.net, linville@tuxdriver.com Cc: linux-wireless@vger.kernel.org Signed-off-by: Luis R. Rodriguez --- net/wireless/reg.c | 54 ++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 44 insertions(+), 10 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4ec2008..646edf2 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -262,14 +262,30 @@ static u32 map_regdom_flags(u32 rd_flags) { return channel_flags; } -static void handle_channel(struct ieee80211_channel *chan, - const struct ieee80211_regdomain *rd) +/** + * freq_reg_info - get regulatory information for the given frequency + * @center_freq: Frequency in KHz for which we want regulatory information for + * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one + * you can set this to 0. If this frequency is allowed we then set + * this value to the maximum allowed bandwidth. + * @rd: the regulatory domain we want to get information from + * @reg_rule: the regulatory rule which we have for this frequency + * + * Use this function to get the regulatory rule for a specific frequency. Caller + * must hold cfg80211_reg_mutex but note that if you are using this within a + * callback registered with register_regulatory_notifier() no locking is + * necessary as reg_notify() is always called with the lock held for you. + * + * This should be useful for the different subsystems which want to make + * use of regulatory information. + */ +int freq_reg_info(u32 center_freq, + u32 *bandwidth, + const struct ieee80211_regdomain *rd, + const struct ieee80211_reg_rule *reg_rule) { int i; - u32 flags = chan->orig_flags; u32 max_bandwidth = 0; - const struct ieee80211_reg_rule *reg_rule = NULL; - const struct ieee80211_power_rule *power_rule = NULL; for (i = 0; i < rd->n_reg_rules; i++) { const struct ieee80211_reg_rule *rr; @@ -278,21 +294,39 @@ static void handle_channel(struct ieee80211_channel *chan, rr = &rd->reg_rules[i]; fr = &rr->freq_range; pr = &rr->power_rule; - max_bandwidth = freq_max_bandwidth(fr, - MHZ_TO_KHZ(chan->center_freq)); - if (max_bandwidth) { + max_bandwidth = freq_max_bandwidth(fr, center_freq); + if (max_bandwidth && *bandwidth <= max_bandwidth) { reg_rule = rr; - power_rule = &rr->power_rule; + *bandwidth = max_bandwidth; break; } } - if (!max_bandwidth) { + return !max_bandwidth; +} +EXPORT_SYMBOL(freq_reg_info); + + +static void handle_channel(struct ieee80211_channel *chan, + const struct ieee80211_regdomain *rd) +{ + int r; + u32 flags = chan->orig_flags; + u32 max_bandwidth = 0; + const struct ieee80211_reg_rule *reg_rule = NULL; + const struct ieee80211_power_rule *power_rule = NULL; + + r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq), + &max_bandwidth, rd, reg_rule); + + if (r) { flags |= IEEE80211_CHAN_DISABLED; chan->flags = flags; return; } + power_rule = ®_rule->power_rule; + chan->flags = map_regdom_flags(reg_rule->flags); chan->max_antenna_gain = min(chan->orig_mag, (int) MBI_TO_DBI(power_rule->max_antenna_gain)); -- 1.5.4.3