aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-01-22 18:05:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:01:18 -0500
commitf976376de0d6a9697fb635369f12ae00251f4566 (patch)
tree11e94926ba6da6ed420bce7c82276e705838dca5
parent716f9392e2b84cacc18cc11f7427cb98adeb1c3d (diff)
cfg80211: Allow for strict regulatory settings
This allows drivers to request strict regulatory settings to be applied to its devices. This is desirable for devices where proper calibration and compliance can only be gauranteed for for the device's programmed regulatory domain. Regulatory domain settings will be ignored until the device's own regulatory domain is properly configured. If no regulatory domain is received only the world regulatory domain will be applied -- if OLD_REG (default to "US") is not enabled. If OLD_REG behaviour is not acceptable to drivers they must update their wiphy with a custom reuglatory prior to wiphy registration. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/wireless.h10
-rw-r--r--net/wireless/reg.c28
2 files changed, 37 insertions, 1 deletions
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 9c19764a4849..a42c1562d52b 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -186,6 +186,15 @@ struct ieee80211_supported_band {
186 * ISO / IEC 3166 alpha2 it belongs to. When this is enabled 186 * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
187 * we will disregard the first regulatory hint (when the 187 * we will disregard the first regulatory hint (when the
188 * initiator is %REGDOM_SET_BY_CORE). 188 * initiator is %REGDOM_SET_BY_CORE).
189 * @strict_regulatory: tells us the driver for this device will ignore
190 * regulatory domain settings until it gets its own regulatory domain
191 * via its regulatory_hint(). After its gets its own regulatory domain
192 * it will only allow further regulatory domain settings to further
193 * enhance compliance. For example if channel 13 and 14 are disabled
194 * by this regulatory domain no user regulatory domain can enable these
195 * channels at a later time. This can be used for devices which do not
196 * have calibration information gauranteed for frequencies or settings
197 * outside of its regulatory domain.
189 * @reg_notifier: the driver's regulatory notification callback 198 * @reg_notifier: the driver's regulatory notification callback
190 * @regd: the driver's regulatory domain, if one was requested via 199 * @regd: the driver's regulatory domain, if one was requested via
191 * the regulatory_hint() API. This can be used by the driver 200 * the regulatory_hint() API. This can be used by the driver
@@ -202,6 +211,7 @@ struct wiphy {
202 u16 interface_modes; 211 u16 interface_modes;
203 212
204 bool custom_regulatory; 213 bool custom_regulatory;
214 bool strict_regulatory;
205 215
206 /* If multiple wiphys are registered and you're handed e.g. 216 /* If multiple wiphys are registered and you're handed e.g.
207 * a regular netdev with assigned ieee80211_ptr, you won't 217 * a regular netdev with assigned ieee80211_ptr, you won't
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cad4daadba0d..89e0d8b3cf1e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -867,6 +867,22 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
867 867
868 power_rule = &reg_rule->power_rule; 868 power_rule = &reg_rule->power_rule;
869 869
870 if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
871 last_request->wiphy && last_request->wiphy == wiphy &&
872 last_request->wiphy->strict_regulatory) {
873 /* This gaurantees the driver's requested regulatory domain
874 * will always be used as a base for further regulatory
875 * settings */
876 chan->flags = chan->orig_flags =
877 map_regdom_flags(reg_rule->flags);
878 chan->max_antenna_gain = chan->orig_mag =
879 (int) MBI_TO_DBI(power_rule->max_antenna_gain);
880 chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
881 chan->max_power = chan->orig_mpwr =
882 (int) MBM_TO_DBM(power_rule->max_eirp);
883 return;
884 }
885
870 chan->flags = flags | map_regdom_flags(reg_rule->flags); 886 chan->flags = flags | map_regdom_flags(reg_rule->flags);
871 chan->max_antenna_gain = min(chan->orig_mag, 887 chan->max_antenna_gain = min(chan->orig_mag,
872 (int) MBI_TO_DBI(power_rule->max_antenna_gain)); 888 (int) MBI_TO_DBI(power_rule->max_antenna_gain));
@@ -897,6 +913,11 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
897 if (setby == REGDOM_SET_BY_CORE && 913 if (setby == REGDOM_SET_BY_CORE &&
898 wiphy->custom_regulatory) 914 wiphy->custom_regulatory)
899 return true; 915 return true;
916 /* wiphy->regd will be set once the device has its own
917 * desired regulatory domain set */
918 if (wiphy->strict_regulatory && !wiphy->regd &&
919 !is_world_regdom(last_request->alpha2))
920 return true;
900 return false; 921 return false;
901} 922}
902 923
@@ -1155,10 +1176,15 @@ new_request:
1155 1176
1156void regulatory_hint(struct wiphy *wiphy, const char *alpha2) 1177void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1157{ 1178{
1179 int r;
1158 BUG_ON(!alpha2); 1180 BUG_ON(!alpha2);
1159 1181
1160 mutex_lock(&cfg80211_drv_mutex); 1182 mutex_lock(&cfg80211_drv_mutex);
1161 __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, 0, ENVIRON_ANY); 1183 r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER,
1184 alpha2, 0, ENVIRON_ANY);
1185 /* This is required so that the orig_* parameters are saved */
1186 if (r == -EALREADY && wiphy->strict_regulatory)
1187 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_DRIVER);
1162 mutex_unlock(&cfg80211_drv_mutex); 1188 mutex_unlock(&cfg80211_drv_mutex);
1163} 1189}
1164EXPORT_SYMBOL(regulatory_hint); 1190EXPORT_SYMBOL(regulatory_hint);