Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135268
b: refs/heads/master
c: 73d54c9
h: refs/heads/master
v: v3
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed Mar 16, 2009
1 parent 02da970 commit 9786d4e
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7db90f4a25bd4184f3d36dfa4f512f53b0448da7
refs/heads/master: 73d54c9e74c4d8ee8a41bc516f481f0f754eca32
48 changes: 48 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@
* @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
* partial scan results may be available
*
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
* has been changed and provides details of the request information
* that caused the change such as who initiated the regulatory request
* (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
* (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
* the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
* %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
* set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
* %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
* to (%NL80211_ATTR_REG_ALPHA2).
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -204,6 +215,8 @@ enum nl80211_commands {
NL80211_CMD_NEW_SCAN_RESULTS,
NL80211_CMD_SCAN_ABORTED,

NL80211_CMD_REG_CHANGE,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand All @@ -218,6 +231,8 @@ enum nl80211_commands {
#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE

#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE

/**
* enum nl80211_attrs - nl80211 netlink attributes
*
Expand Down Expand Up @@ -329,6 +344,11 @@ enum nl80211_commands {
* messages carried the same generation number)
* @NL80211_ATTR_BSS: scan result BSS
*
* @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
* currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
* @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
* set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -403,6 +423,9 @@ enum nl80211_attrs {
NL80211_ATTR_SCAN_GENERATION,
NL80211_ATTR_BSS,

NL80211_ATTR_REG_INITIATOR,
NL80211_ATTR_REG_TYPE,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand All @@ -420,6 +443,8 @@ enum nl80211_attrs {
#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
#define NL80211_ATTR_IE NL80211_ATTR_IE
#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE

#define NL80211_MAX_SUPP_RATES 32
#define NL80211_MAX_SUPP_REG_RULES 32
Expand Down Expand Up @@ -691,6 +716,29 @@ enum nl80211_reg_initiator {
NL80211_REGDOM_SET_BY_COUNTRY_IE,
};

/**
* enum nl80211_reg_type - specifies the type of regulatory domain
* @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
* to a specific country. When this is set you can count on the
* ISO / IEC 3166 alpha2 country code being valid.
* @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
* domain.
* @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
* driver specific world regulatory domain. These do not apply system-wide
* and are only applicable to the individual devices which have requested
* them to be applied.
* @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
* of an intersection between two regulatory domains -- the previously
* set regulatory domain on the system and the last accepted regulatory
* domain request to be processed.
*/
enum nl80211_reg_type {
NL80211_REGDOM_TYPE_COUNTRY,
NL80211_REGDOM_TYPE_WORLD,
NL80211_REGDOM_TYPE_CUSTOM_WORLD,
NL80211_REGDOM_TYPE_INTERSECTION,
};

/**
* enum nl80211_reg_rule_attr - regulatory rule attributes
* @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
Expand Down
11 changes: 11 additions & 0 deletions trunk/net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,17 @@ int wiphy_register(struct wiphy *wiphy)
if (IS_ERR(drv->wiphy.debugfsdir))
drv->wiphy.debugfsdir = NULL;

if (wiphy->custom_regulatory) {
struct regulatory_request request;

request.wiphy_idx = get_wiphy_idx(wiphy);
request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
request.alpha2[0] = '9';
request.alpha2[1] = '9';

nl80211_send_reg_change_event(&request);
}

res = 0;
out_unlock:
mutex_unlock(&cfg80211_mutex);
Expand Down
62 changes: 62 additions & 0 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,9 @@ static struct genl_multicast_group nl80211_config_mcgrp = {
static struct genl_multicast_group nl80211_scan_mcgrp = {
.name = "scan",
};
static struct genl_multicast_group nl80211_regulatory_mcgrp = {
.name = "regulatory",
};

/* notification functions */

Expand Down Expand Up @@ -2818,6 +2821,61 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
}

/*
* This can happen on global regulatory changes or device specific settings
* based on custom world regulatory domains.
*/
void nl80211_send_reg_change_event(struct regulatory_request *request)
{
struct sk_buff *msg;
void *hdr;

msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg)
return;

hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
if (!hdr) {
nlmsg_free(msg);
return;
}

/* Userspace can always count this one always being set */
NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);

if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_WORLD);
else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_CUSTOM_WORLD);
else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
request->intersect)
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_INTERSECTION);
else {
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_COUNTRY);
NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
}

if (wiphy_idx_valid(request->wiphy_idx))
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);

if (genlmsg_end(msg, hdr) < 0) {
nlmsg_free(msg);
return;
}

genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);

return;

nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}

/* initialisation/exit functions */

int nl80211_init(void)
Expand All @@ -2842,6 +2900,10 @@ int nl80211_init(void)
if (err)
goto err_out;

err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
if (err)
goto err_out;

return 0;
err_out:
genl_unregister_family(&nl80211_fam);
Expand Down
5 changes: 5 additions & 0 deletions trunk/net/wireless/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
extern void nl80211_send_reg_change_event(struct regulatory_request *request);
#else
static inline int nl80211_init(void)
{
Expand All @@ -31,6 +32,10 @@ static inline void nl80211_send_scan_aborted(
struct cfg80211_registered_device *rdev,
struct net_device *netdev)
{}
static inline void
nl80211_send_reg_change_event(struct regulatory_request *request)
{
}
#endif /* CONFIG_NL80211 */

#endif /* __NET_WIRELESS_NL80211_H */
13 changes: 12 additions & 1 deletion trunk/net/wireless/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <net/cfg80211.h>
#include "core.h"
#include "reg.h"
#include "nl80211.h"

/* Receipt of information from last regulatory request */
static struct regulatory_request *last_request;
Expand Down Expand Up @@ -1403,8 +1404,16 @@ static int __regulatory_hint(struct wiphy *wiphy,
pending_request = NULL;

/* When r == REG_INTERSECT we do need to call CRDA */
if (r < 0)
if (r < 0) {
/*
* Since CRDA will not be called in this case as we already
* have applied the requested regulatory domain before we just
* inform userspace we have processed the request
*/
if (r == -EALREADY)
nl80211_send_reg_change_event(last_request);
return r;
}

/*
* Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
Expand Down Expand Up @@ -2084,6 +2093,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)

print_regdomain(cfg80211_regdomain);

nl80211_send_reg_change_event(last_request);

return r;
}

Expand Down

0 comments on commit 9786d4e

Please sign in to comment.