aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
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);