aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);