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>
This commit is contained in:
Родитель
716f9392e2
Коммит
f976376de0
|
@ -186,6 +186,15 @@ struct ieee80211_supported_band {
|
|||
* ISO / IEC 3166 alpha2 it belongs to. When this is enabled
|
||||
* we will disregard the first regulatory hint (when the
|
||||
* 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
|
||||
* @regd: the driver's regulatory domain, if one was requested via
|
||||
* the regulatory_hint() API. This can be used by the driver
|
||||
|
@ -202,6 +211,7 @@ struct wiphy {
|
|||
u16 interface_modes;
|
||||
|
||||
bool custom_regulatory;
|
||||
bool strict_regulatory;
|
||||
|
||||
/* If multiple wiphys are registered and you're handed e.g.
|
||||
* 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,
|
|||
|
||||
power_rule = ®_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->max_antenna_gain = min(chan->orig_mag,
|
||||
(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)
|
|||
if (setby == REGDOM_SET_BY_CORE &&
|
||||
wiphy->custom_regulatory)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1155,10 +1176,15 @@ new_request:
|
|||
|
||||
void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
|
||||
{
|
||||
int r;
|
||||
BUG_ON(!alpha2);
|
||||
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL(regulatory_hint);
|
||||
|
|
Загрузка…
Ссылка в новой задаче