aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-01-30 12:26:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-09 15:03:45 -0500
commitf130347c2dd8e7ce0757cd3cf80bedbc6ed63c4c (patch)
tree868f78203b5f529d80a014ed2169e7eab0a260ed
parent47f4d8872ffc57ad92d0fb344e677d12acc34acd (diff)
cfg80211: add get reg command
This lets userspace request to get the currently set regulatory domain. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h4
-rw-r--r--net/wireless/nl80211.c81
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/reg.h2
4 files changed, 88 insertions, 1 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 76aae3d8e97e..4bc27049f4e5 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -113,6 +113,8 @@
113 * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by 113 * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
114 * %NL80211_ATTR_IFINDEX. 114 * %NL80211_ATTR_IFINDEX.
115 * 115 *
116 * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
117 * regulatory domain.
116 * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command 118 * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
117 * after being queried by the kernel. CRDA replies by sending a regulatory 119 * after being queried by the kernel. CRDA replies by sending a regulatory
118 * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our 120 * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
@@ -188,6 +190,8 @@ enum nl80211_commands {
188 190
189 NL80211_CMD_SET_MGMT_EXTRA_IE, 191 NL80211_CMD_SET_MGMT_EXTRA_IE,
190 192
193 NL80211_CMD_GET_REG,
194
191 /* add new commands above here */ 195 /* add new commands above here */
192 196
193 /* used to define NL80211_CMD_MAX below */ 197 /* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e69da8d20474..d452396006ee 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2093,6 +2093,81 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2093 2093
2094#undef FILL_IN_MESH_PARAM_IF_SET 2094#undef FILL_IN_MESH_PARAM_IF_SET
2095 2095
2096static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2097{
2098 struct sk_buff *msg;
2099 void *hdr = NULL;
2100 struct nlattr *nl_reg_rules;
2101 unsigned int i;
2102 int err = -EINVAL;
2103
2104 mutex_lock(&cfg80211_drv_mutex);
2105
2106 if (!cfg80211_regdomain)
2107 goto out;
2108
2109 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2110 if (!msg) {
2111 err = -ENOBUFS;
2112 goto out;
2113 }
2114
2115 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2116 NL80211_CMD_GET_REG);
2117 if (!hdr)
2118 goto nla_put_failure;
2119
2120 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
2121 cfg80211_regdomain->alpha2);
2122
2123 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
2124 if (!nl_reg_rules)
2125 goto nla_put_failure;
2126
2127 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
2128 struct nlattr *nl_reg_rule;
2129 const struct ieee80211_reg_rule *reg_rule;
2130 const struct ieee80211_freq_range *freq_range;
2131 const struct ieee80211_power_rule *power_rule;
2132
2133 reg_rule = &cfg80211_regdomain->reg_rules[i];
2134 freq_range = &reg_rule->freq_range;
2135 power_rule = &reg_rule->power_rule;
2136
2137 nl_reg_rule = nla_nest_start(msg, i);
2138 if (!nl_reg_rule)
2139 goto nla_put_failure;
2140
2141 NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
2142 reg_rule->flags);
2143 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
2144 freq_range->start_freq_khz);
2145 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
2146 freq_range->end_freq_khz);
2147 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
2148 freq_range->max_bandwidth_khz);
2149 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
2150 power_rule->max_antenna_gain);
2151 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
2152 power_rule->max_eirp);
2153
2154 nla_nest_end(msg, nl_reg_rule);
2155 }
2156
2157 nla_nest_end(msg, nl_reg_rules);
2158
2159 genlmsg_end(msg, hdr);
2160 err = genlmsg_unicast(msg, info->snd_pid);
2161 goto out;
2162
2163nla_put_failure:
2164 genlmsg_cancel(msg, hdr);
2165 err = -EMSGSIZE;
2166out:
2167 mutex_unlock(&cfg80211_drv_mutex);
2168 return err;
2169}
2170
2096static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 2171static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2097{ 2172{
2098 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; 2173 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -2333,6 +2408,12 @@ static struct genl_ops nl80211_ops[] = {
2333 .flags = GENL_ADMIN_PERM, 2408 .flags = GENL_ADMIN_PERM,
2334 }, 2409 },
2335 { 2410 {
2411 .cmd = NL80211_CMD_GET_REG,
2412 .doit = nl80211_get_reg,
2413 .policy = nl80211_policy,
2414 /* can be retrieved by unprivileged users */
2415 },
2416 {
2336 .cmd = NL80211_CMD_SET_REG, 2417 .cmd = NL80211_CMD_SET_REG,
2337 .doit = nl80211_set_reg, 2418 .doit = nl80211_set_reg,
2338 .policy = nl80211_policy, 2419 .policy = nl80211_policy,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f643d3981102..2323644330cd 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -57,7 +57,7 @@ static u32 supported_bandwidths[] = {
57/* Central wireless core regulatory domains, we only need two, 57/* Central wireless core regulatory domains, we only need two,
58 * the current one and a world regulatory domain in case we have no 58 * the current one and a world regulatory domain in case we have no
59 * information to give us an alpha2 */ 59 * information to give us an alpha2 */
60static const struct ieee80211_regdomain *cfg80211_regdomain; 60const struct ieee80211_regdomain *cfg80211_regdomain;
61 61
62/* We use this as a place for the rd structure built from the 62/* We use this as a place for the rd structure built from the
63 * last parsed country IE to rest until CRDA gets back to us with 63 * last parsed country IE to rest until CRDA gets back to us with
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index eb1dd5bc9b27..fe8c83f34fb7 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -1,6 +1,8 @@
1#ifndef __NET_WIRELESS_REG_H 1#ifndef __NET_WIRELESS_REG_H
2#define __NET_WIRELESS_REG_H 2#define __NET_WIRELESS_REG_H
3 3
4extern const struct ieee80211_regdomain *cfg80211_regdomain;
5
4bool is_world_regdom(const char *alpha2); 6bool is_world_regdom(const char *alpha2);
5bool reg_is_valid_request(const char *alpha2); 7bool reg_is_valid_request(const char *alpha2);
6 8