aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
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 /net/wireless/nl80211.c
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>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c81
1 files changed, 81 insertions, 0 deletions
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,