提交 f976376d 编写于 作者: L Luis R. Rodriguez 提交者: John W. Linville

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: NLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 716f9392
...@@ -186,6 +186,15 @@ struct ieee80211_supported_band { ...@@ -186,6 +186,15 @@ struct ieee80211_supported_band {
* ISO / IEC 3166 alpha2 it belongs to. When this is enabled * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
* we will disregard the first regulatory hint (when the * we will disregard the first regulatory hint (when the
* initiator is %REGDOM_SET_BY_CORE). * initiator is %REGDOM_SET_BY_CORE).
* @strict_regulatory: tells us the driver for this device will ignore
* regulatory domain settings until it gets its own regulatory domain
* via its regulatory_hint(). After its gets its own regulatory domain
* it will only allow further regulatory domain settings to further
* enhance compliance. For example if channel 13 and 14 are disabled
* by this regulatory domain no user regulatory domain can enable these
* channels at a later time. This can be used for devices which do not
* have calibration information gauranteed for frequencies or settings
* outside of its regulatory domain.
* @reg_notifier: the driver's regulatory notification callback * @reg_notifier: the driver's regulatory notification callback
* @regd: the driver's regulatory domain, if one was requested via * @regd: the driver's regulatory domain, if one was requested via
* the regulatory_hint() API. This can be used by the driver * the regulatory_hint() API. This can be used by the driver
...@@ -202,6 +211,7 @@ struct wiphy { ...@@ -202,6 +211,7 @@ struct wiphy {
u16 interface_modes; u16 interface_modes;
bool custom_regulatory; bool custom_regulatory;
bool strict_regulatory;
/* If multiple wiphys are registered and you're handed e.g. /* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't * a regular netdev with assigned ieee80211_ptr, you won't
......
...@@ -867,6 +867,22 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, ...@@ -867,6 +867,22 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
power_rule = &reg_rule->power_rule; power_rule = &reg_rule->power_rule;
if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
last_request->wiphy && last_request->wiphy == wiphy &&
last_request->wiphy->strict_regulatory) {
/* This gaurantees the driver's requested regulatory domain
* will always be used as a base for further regulatory
* settings */
chan->flags = chan->orig_flags =
map_regdom_flags(reg_rule->flags);
chan->max_antenna_gain = chan->orig_mag =
(int) MBI_TO_DBI(power_rule->max_antenna_gain);
chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
chan->max_power = chan->orig_mpwr =
(int) MBM_TO_DBM(power_rule->max_eirp);
return;
}
chan->flags = flags | map_regdom_flags(reg_rule->flags); chan->flags = flags | map_regdom_flags(reg_rule->flags);
chan->max_antenna_gain = min(chan->orig_mag, chan->max_antenna_gain = min(chan->orig_mag,
(int) MBI_TO_DBI(power_rule->max_antenna_gain)); (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,6 +913,11 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
if (setby == REGDOM_SET_BY_CORE && if (setby == REGDOM_SET_BY_CORE &&
wiphy->custom_regulatory) wiphy->custom_regulatory)
return true; return true;
/* wiphy->regd will be set once the device has its own
* desired regulatory domain set */
if (wiphy->strict_regulatory && !wiphy->regd &&
!is_world_regdom(last_request->alpha2))
return true;
return false; return false;
} }
...@@ -1155,10 +1176,15 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, ...@@ -1155,10 +1176,15 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
void regulatory_hint(struct wiphy *wiphy, const char *alpha2) void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
{ {
int r;
BUG_ON(!alpha2); BUG_ON(!alpha2);
mutex_lock(&cfg80211_drv_mutex); mutex_lock(&cfg80211_drv_mutex);
__regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, 0, ENVIRON_ANY); r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER,
alpha2, 0, ENVIRON_ANY);
/* This is required so that the orig_* parameters are saved */
if (r == -EALREADY && wiphy->strict_regulatory)
wiphy_update_regulatory(wiphy, REGDOM_SET_BY_DRIVER);
mutex_unlock(&cfg80211_drv_mutex); mutex_unlock(&cfg80211_drv_mutex);
} }
EXPORT_SYMBOL(regulatory_hint); EXPORT_SYMBOL(regulatory_hint);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册