aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-01-22 18:05:44 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:01:14 -0500
commit1fa25e413659f943dfec65da2abe713d566c7fdf (patch)
tree7de278f35b33c2bf35f4964e0b5381a6f029dff5 /net/wireless
parent078e1e60dd6c6b0d4bc8d58ccb80c008e8efc9ff (diff)
cfg80211: add wiphy_apply_custom_regulatory()
This adds wiphy_apply_custom_regulatory() to be used by drivers prior to wiphy registration to apply a custom regulatory domain. This can be used by drivers that do not have a direct 1-1 mapping between a regulatory domain and a country. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/reg.c115
1 files changed, 91 insertions, 24 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index b34fd84b3e2f..0d6059502b40 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -782,36 +782,18 @@ static u32 map_regdom_flags(u32 rd_flags)
782 return channel_flags; 782 return channel_flags;
783} 783}
784 784
785/** 785static int freq_reg_info_regd(struct wiphy *wiphy,
786 * freq_reg_info - get regulatory information for the given frequency 786 u32 center_freq,
787 * @wiphy: the wiphy for which we want to process this rule for 787 u32 *bandwidth,
788 * @center_freq: Frequency in KHz for which we want regulatory information for 788 const struct ieee80211_reg_rule **reg_rule,
789 * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one 789 const struct ieee80211_regdomain *custom_regd)
790 * you can set this to 0. If this frequency is allowed we then set
791 * this value to the maximum allowed bandwidth.
792 * @reg_rule: the regulatory rule which we have for this frequency
793 *
794 * Use this function to get the regulatory rule for a specific frequency on
795 * a given wireless device. If the device has a specific regulatory domain
796 * it wants to follow we respect that unless a country IE has been received
797 * and processed already.
798 *
799 * Returns 0 if it was able to find a valid regulatory rule which does
800 * apply to the given center_freq otherwise it returns non-zero. It will
801 * also return -ERANGE if we determine the given center_freq does not even have
802 * a regulatory rule for a frequency range in the center_freq's band. See
803 * freq_in_rule_band() for our current definition of a band -- this is purely
804 * subjective and right now its 802.11 specific.
805 */
806static int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
807 const struct ieee80211_reg_rule **reg_rule)
808{ 790{
809 int i; 791 int i;
810 bool band_rule_found = false; 792 bool band_rule_found = false;
811 const struct ieee80211_regdomain *regd; 793 const struct ieee80211_regdomain *regd;
812 u32 max_bandwidth = 0; 794 u32 max_bandwidth = 0;
813 795
814 regd = cfg80211_regdomain; 796 regd = custom_regd ? custom_regd : cfg80211_regdomain;
815 797
816 /* Follow the driver's regulatory domain, if present, unless a country 798 /* Follow the driver's regulatory domain, if present, unless a country
817 * IE has been processed */ 799 * IE has been processed */
@@ -852,6 +834,34 @@ static int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
852 return !max_bandwidth; 834 return !max_bandwidth;
853} 835}
854 836
837/**
838 * freq_reg_info - get regulatory information for the given frequency
839 * @wiphy: the wiphy for which we want to process this rule for
840 * @center_freq: Frequency in KHz for which we want regulatory information for
841 * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
842 * you can set this to 0. If this frequency is allowed we then set
843 * this value to the maximum allowed bandwidth.
844 * @reg_rule: the regulatory rule which we have for this frequency
845 *
846 * Use this function to get the regulatory rule for a specific frequency on
847 * a given wireless device. If the device has a specific regulatory domain
848 * it wants to follow we respect that unless a country IE has been received
849 * and processed already.
850 *
851 * Returns 0 if it was able to find a valid regulatory rule which does
852 * apply to the given center_freq otherwise it returns non-zero. It will
853 * also return -ERANGE if we determine the given center_freq does not even have
854 * a regulatory rule for a frequency range in the center_freq's band. See
855 * freq_in_rule_band() for our current definition of a band -- this is purely
856 * subjective and right now its 802.11 specific.
857 */
858static int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
859 const struct ieee80211_reg_rule **reg_rule)
860{
861 return freq_reg_info_regd(wiphy, center_freq,
862 bandwidth, reg_rule, NULL);
863}
864
855static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, 865static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
856 unsigned int chan_idx) 866 unsigned int chan_idx)
857{ 867{
@@ -962,6 +972,63 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
962 wiphy->reg_notifier(wiphy, setby); 972 wiphy->reg_notifier(wiphy, setby);
963} 973}
964 974
975static void handle_channel_custom(struct wiphy *wiphy,
976 enum ieee80211_band band,
977 unsigned int chan_idx,
978 const struct ieee80211_regdomain *regd)
979{
980 int r;
981 u32 max_bandwidth = 0;
982 const struct ieee80211_reg_rule *reg_rule = NULL;
983 const struct ieee80211_power_rule *power_rule = NULL;
984 struct ieee80211_supported_band *sband;
985 struct ieee80211_channel *chan;
986
987 sband = wiphy->bands[band];
988 BUG_ON(chan_idx >= sband->n_channels);
989 chan = &sband->channels[chan_idx];
990
991 r = freq_reg_info_regd(wiphy, MHZ_TO_KHZ(chan->center_freq),
992 &max_bandwidth, &reg_rule, regd);
993
994 if (r) {
995 chan->flags = IEEE80211_CHAN_DISABLED;
996 return;
997 }
998
999 power_rule = &reg_rule->power_rule;
1000
1001 chan->flags |= map_regdom_flags(reg_rule->flags);
1002 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
1003 chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
1004 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
1005}
1006
1007static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band,
1008 const struct ieee80211_regdomain *regd)
1009{
1010 unsigned int i;
1011 struct ieee80211_supported_band *sband;
1012
1013 BUG_ON(!wiphy->bands[band]);
1014 sband = wiphy->bands[band];
1015
1016 for (i = 0; i < sband->n_channels; i++)
1017 handle_channel_custom(wiphy, band, i, regd);
1018}
1019
1020/* Used by drivers prior to wiphy registration */
1021void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1022 const struct ieee80211_regdomain *regd)
1023{
1024 enum ieee80211_band band;
1025 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1026 if (wiphy->bands[band])
1027 handle_band_custom(wiphy, band, regd);
1028 }
1029}
1030EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1031
965static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd, 1032static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
966 const struct ieee80211_regdomain *src_regd) 1033 const struct ieee80211_regdomain *src_regd)
967{ 1034{