Skip to content

Commit

Permalink
cfg80211: add flags to define country IE processing rules
Browse files Browse the repository at this point in the history
802.11 cards may have different country IE parsing behavioural
preferences and vendors may want to support these. These preferences
were managed by the WIPHY_FLAG_CUSTOM_REGULATORY and the
WIPHY_FLAG_STRICT_REGULATORY flags and their combination.
Instead of using this existing notation, split out the country IE
behavioural preferences to a new flag. This will allow us to add more
customizations easily and make the code more maintainable. Also add
a new flag to disable country IE hints issued by the CORE as the
first customization.

Change-Id: I66ba4a92ac0f029a115eea0a274b02db11279787
CRs-Fixed: 542802
Signed-off-by: Mihir Shete <smihir@codeaurora.org>

Conflicts:
	net/wireless/reg.c
  • Loading branch information
smihir authored and adrian-bl committed May 7, 2014
1 parent 65dcddd commit 97beb95
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/regd.c
Expand Up @@ -520,6 +520,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
*/
regd = ath_world_regdomain(reg);
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
wiphy->country_ie_pref = NL80211_COUNTRY_IE_FOLLOW_POWER;
} else {
/*
* This gets applied in the case of the absence of CRDA,
Expand Down
70 changes: 54 additions & 16 deletions include/net/cfg80211.h
Expand Up @@ -1797,22 +1797,28 @@ struct cfg80211_ops {
* enum wiphy_flags - wiphy capability flags
*
* @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device
* has its own custom regulatory domain and cannot identify the
* 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).
* @WIPHY_FLAG_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() unless the regulatory hint is
* from a country IE. 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 guaranteed for frequencies or settings
* outside of its regulatory domain. If used in combination with
* WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings
* will be followed.
* has its own custom regulatory domain and cannot identify the
* 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). wiphys can set the custom
* regulatory domain using wiphy_apply_custom_regulatory()
* prior to wiphy registration.
* @WIPHY_FLAG_STRICT_REGULATORY: tells us that the wiphy for this device
* has regulatory domain that it wishes to be considered as the
* superset for regulatory rules. After this device gets its regulatory
* domain programmed further regulatory hints shall only be considered
* for this device to enhance regulatory compliance, forcing the
* device to only possibly use subsets of the original regulatory
* rules. For example if channel 13 and 14 are disabled by this
* device's regulatory domain no user specified regulatory hint which
* has these channels enabled would enable them for this wiphy,
* the device's original regulatory domain will be trusted as the
* base. You can program the superset of regulatory rules for this
* wiphy with regulatory_hint() for cards programmed with an
* ISO3166-alpha2 country code. wiphys that use regulatory_hint()
* will have their wiphy->regd programmed once the regulatory
* domain is set, and all other regulatory hints will be ignored
* until their own regulatory domain gets programmed.
* @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
* that passive scan flags and beaconing flags may not be lifted by
* cfg80211 due to regulatory beacon hints. For more information on beacon
Expand Down Expand Up @@ -1879,6 +1885,34 @@ enum wiphy_flags {
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
};

/**
* enum nl80211_country_ie_pref - country IE processing preferences
*
* enumerates the different preferences a 802.11 card can advertize
* for parsing the country IEs. As per the current implementation
* country IEs are only used derive the apha2, the information
* for power settings that comes with the country IE is ignored
* and we use the power settings from regdb.
*
* @NL80211_COUNTRY_IE_FOLLOW_CORE - This is the default behaviour.
* It allows the core to update channel flags according to the
* ISO3166-alpha2 in the country IE. The applied power is -
* MIN(power specified by custom domain, power obtained from regdb)
* @NL80211_COUNTRY_IE_FOLLOW_POWER - for devices that have a
* preference that even though they may have programmed their own
* custom power setting prior to wiphy registration, they want
* to ensure their channel power settings are updated for this
* connection with the power settings derived from alpha2 of the
* country IE.
* @NL80211_COUNTRY_IE_IGNORE_CORE - for devices that have a preference to
* to ignore all country IE information processed by the core.
*/
enum nl80211_country_ie_pref {
NL80211_COUNTRY_IE_FOLLOW_CORE,
NL80211_COUNTRY_IE_FOLLOW_POWER,
NL80211_COUNTRY_IE_IGNORE_CORE,
};

/**
* struct ieee80211_iface_limit - limit on certain interface types
* @max: maximum number of interfaces of these types
Expand Down Expand Up @@ -2096,6 +2130,8 @@ struct wiphy_wowlan_support {
*
* @max_acl_mac_addrs: Maximum number of MAC addresses that the device
* supports for ACL.
* @country_ie_pref: country IE processing preferences specified
* by enum nl80211_country_ie_pref
*/
struct wiphy {
/* assign these fields before you register the wiphy */
Expand Down Expand Up @@ -2160,6 +2196,8 @@ struct wiphy {
*/
u32 probe_resp_offload;

u8 country_ie_pref;

/* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered
Expand Down
10 changes: 5 additions & 5 deletions net/wireless/reg.c
Expand Up @@ -898,13 +898,11 @@ static void handle_channel(struct wiphy *wiphy,
chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
if (chan->orig_mpwr) {
/*
* Devices that have their own custom regulatory domain
* but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
* passed country IE power settings.
* Devices that use NL80211_COUNTRY_IE_FOLLOW_POWER will always
* follow the passed country IE power settings.
*/
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
wiphy->country_ie_pref & NL80211_COUNTRY_IE_FOLLOW_POWER)
chan->max_power = chan->max_reg_power;
else
chan->max_power = min(chan->orig_mpwr,
Expand Down Expand Up @@ -1322,6 +1320,8 @@ static int ignore_request(struct wiphy *wiphy,
case NL80211_REGDOM_SET_BY_CORE:
return 0;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
if (wiphy->country_ie_pref & NL80211_COUNTRY_IE_IGNORE_CORE)
return -EALREADY;

last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);

Expand Down

0 comments on commit 97beb95

Please sign in to comment.