aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-03-09 22:07:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-16 18:09:40 -0400
commit73d54c9e74c4d8ee8a41bc516f481f0f754eca32 (patch)
treece190210e3a0cd00008b7aa88af6c1ebccee2193 /net/wireless/nl80211.c
parent7db90f4a25bd4184f3d36dfa4f512f53b0448da7 (diff)
cfg80211: add regulatory netlink multicast group
This allows us to send to userspace "regulatory" events. For now we just send an event when we change regulatory domains. We also notify userspace when devices are using their own custom world roaming regulatory domains. 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.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 531bb67cf502..8ac3d26014a8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2739,6 +2739,9 @@ static struct genl_multicast_group nl80211_config_mcgrp = {
2739static struct genl_multicast_group nl80211_scan_mcgrp = { 2739static struct genl_multicast_group nl80211_scan_mcgrp = {
2740 .name = "scan", 2740 .name = "scan",
2741}; 2741};
2742static struct genl_multicast_group nl80211_regulatory_mcgrp = {
2743 .name = "regulatory",
2744};
2742 2745
2743/* notification functions */ 2746/* notification functions */
2744 2747
@@ -2818,6 +2821,61 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
2818 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 2821 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2819} 2822}
2820 2823
2824/*
2825 * This can happen on global regulatory changes or device specific settings
2826 * based on custom world regulatory domains.
2827 */
2828void nl80211_send_reg_change_event(struct regulatory_request *request)
2829{
2830 struct sk_buff *msg;
2831 void *hdr;
2832
2833 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2834 if (!msg)
2835 return;
2836
2837 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
2838 if (!hdr) {
2839 nlmsg_free(msg);
2840 return;
2841 }
2842
2843 /* Userspace can always count this one always being set */
2844 NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
2845
2846 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
2847 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2848 NL80211_REGDOM_TYPE_WORLD);
2849 else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
2850 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2851 NL80211_REGDOM_TYPE_CUSTOM_WORLD);
2852 else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
2853 request->intersect)
2854 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2855 NL80211_REGDOM_TYPE_INTERSECTION);
2856 else {
2857 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
2858 NL80211_REGDOM_TYPE_COUNTRY);
2859 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
2860 }
2861
2862 if (wiphy_idx_valid(request->wiphy_idx))
2863 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
2864
2865 if (genlmsg_end(msg, hdr) < 0) {
2866 nlmsg_free(msg);
2867 return;
2868 }
2869
2870 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);
2871
2872 return;
2873
2874nla_put_failure:
2875 genlmsg_cancel(msg, hdr);
2876 nlmsg_free(msg);
2877}
2878
2821/* initialisation/exit functions */ 2879/* initialisation/exit functions */
2822 2880
2823int nl80211_init(void) 2881int nl80211_init(void)
@@ -2842,6 +2900,10 @@ int nl80211_init(void)
2842 if (err) 2900 if (err)
2843 goto err_out; 2901 goto err_out;
2844 2902
2903 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
2904 if (err)
2905 goto err_out;
2906
2845 return 0; 2907 return 0;
2846 err_out: 2908 err_out:
2847 genl_unregister_family(&nl80211_fam); 2909 genl_unregister_family(&nl80211_fam);