diff options
-rw-r--r-- | include/linux/nl80211.h | 32 | ||||
-rw-r--r-- | include/net/regulatory.h | 5 | ||||
-rw-r--r-- | net/wireless/core.c | 1 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 23 | ||||
-rw-r--r-- | net/wireless/reg.c | 113 | ||||
-rw-r--r-- | net/wireless/reg.h | 5 |
6 files changed, 171 insertions, 8 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index d6cfacc3ce4d..2f3878806403 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -1245,6 +1245,12 @@ enum nl80211_commands { | |||
1245 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds | 1245 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds |
1246 | * or 0 to disable background scan. | 1246 | * or 0 to disable background scan. |
1247 | * | 1247 | * |
1248 | * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from | ||
1249 | * userspace. If unset it is assumed the hint comes directly from | ||
1250 | * a user. If set code could specify exactly what type of source | ||
1251 | * was used to provide the hint. For the different types of | ||
1252 | * allowed user regulatory hints see nl80211_user_reg_hint_type. | ||
1253 | * | ||
1248 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1254 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1249 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1255 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1250 | */ | 1256 | */ |
@@ -1498,6 +1504,8 @@ enum nl80211_attrs { | |||
1498 | 1504 | ||
1499 | NL80211_ATTR_WDEV, | 1505 | NL80211_ATTR_WDEV, |
1500 | 1506 | ||
1507 | NL80211_ATTR_USER_REG_HINT_TYPE, | ||
1508 | |||
1501 | /* add attributes here, update the policy in nl80211.c */ | 1509 | /* add attributes here, update the policy in nl80211.c */ |
1502 | 1510 | ||
1503 | __NL80211_ATTR_AFTER_LAST, | 1511 | __NL80211_ATTR_AFTER_LAST, |
@@ -2061,6 +2069,26 @@ enum nl80211_dfs_regions { | |||
2061 | }; | 2069 | }; |
2062 | 2070 | ||
2063 | /** | 2071 | /** |
2072 | * enum nl80211_user_reg_hint_type - type of user regulatory hint | ||
2073 | * | ||
2074 | * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always | ||
2075 | * assumed if the attribute is not set. | ||
2076 | * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular | ||
2077 | * base station. Device drivers that have been tested to work | ||
2078 | * properly to support this type of hint can enable these hints | ||
2079 | * by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature | ||
2080 | * capability on the struct wiphy. The wireless core will | ||
2081 | * ignore all cell base station hints until at least one device | ||
2082 | * present has been registered with the wireless core that | ||
2083 | * has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a | ||
2084 | * supported feature. | ||
2085 | */ | ||
2086 | enum nl80211_user_reg_hint_type { | ||
2087 | NL80211_USER_REG_HINT_USER = 0, | ||
2088 | NL80211_USER_REG_HINT_CELL_BASE = 1, | ||
2089 | }; | ||
2090 | |||
2091 | /** | ||
2064 | * enum nl80211_survey_info - survey information | 2092 | * enum nl80211_survey_info - survey information |
2065 | * | 2093 | * |
2066 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO | 2094 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO |
@@ -2963,11 +2991,15 @@ enum nl80211_ap_sme_features { | |||
2963 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. | 2991 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. |
2964 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up | 2992 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up |
2965 | * the connected inactive stations in AP mode. | 2993 | * the connected inactive stations in AP mode. |
2994 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested | ||
2995 | * to work properly to suppport receiving regulatory hints from | ||
2996 | * cellular base stations. | ||
2966 | */ | 2997 | */ |
2967 | enum nl80211_feature_flags { | 2998 | enum nl80211_feature_flags { |
2968 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 2999 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
2969 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 3000 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
2970 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3001 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
3002 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | ||
2971 | }; | 3003 | }; |
2972 | 3004 | ||
2973 | /** | 3005 | /** |
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index a5f79933e211..7dcaa2794fde 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h | |||
@@ -52,6 +52,10 @@ enum environment_cap { | |||
52 | * DFS master operation on a known DFS region (NL80211_DFS_*), | 52 | * DFS master operation on a known DFS region (NL80211_DFS_*), |
53 | * dfs_region represents that region. Drivers can use this and the | 53 | * dfs_region represents that region. Drivers can use this and the |
54 | * @alpha2 to adjust their device's DFS parameters as required. | 54 | * @alpha2 to adjust their device's DFS parameters as required. |
55 | * @user_reg_hint_type: if the @initiator was of type | ||
56 | * %NL80211_REGDOM_SET_BY_USER, this classifies the type | ||
57 | * of hint passed. This could be any of the %NL80211_USER_REG_HINT_* | ||
58 | * types. | ||
55 | * @intersect: indicates whether the wireless core should intersect | 59 | * @intersect: indicates whether the wireless core should intersect |
56 | * the requested regulatory domain with the presently set regulatory | 60 | * the requested regulatory domain with the presently set regulatory |
57 | * domain. | 61 | * domain. |
@@ -70,6 +74,7 @@ enum environment_cap { | |||
70 | struct regulatory_request { | 74 | struct regulatory_request { |
71 | int wiphy_idx; | 75 | int wiphy_idx; |
72 | enum nl80211_reg_initiator initiator; | 76 | enum nl80211_reg_initiator initiator; |
77 | enum nl80211_user_reg_hint_type user_reg_hint_type; | ||
73 | char alpha2[2]; | 78 | char alpha2[2]; |
74 | u8 dfs_region; | 79 | u8 dfs_region; |
75 | bool intersect; | 80 | bool intersect; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 71b684b5a675..c0307b05986c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -542,6 +542,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
542 | } | 542 | } |
543 | 543 | ||
544 | /* set up regulatory info */ | 544 | /* set up regulatory info */ |
545 | wiphy_regulatory_register(wiphy); | ||
545 | regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); | 546 | regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); |
546 | 547 | ||
547 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); | 548 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9216e45e53a0..50b1a0e84f1a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -354,6 +354,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
354 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, | 354 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, |
355 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | 355 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, |
356 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, | 356 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, |
357 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, | ||
357 | }; | 358 | }; |
358 | 359 | ||
359 | /* policy for the key attributes */ | 360 | /* policy for the key attributes */ |
@@ -3582,6 +3583,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
3582 | { | 3583 | { |
3583 | int r; | 3584 | int r; |
3584 | char *data = NULL; | 3585 | char *data = NULL; |
3586 | enum nl80211_user_reg_hint_type user_reg_hint_type; | ||
3585 | 3587 | ||
3586 | /* | 3588 | /* |
3587 | * You should only get this when cfg80211 hasn't yet initialized | 3589 | * You should only get this when cfg80211 hasn't yet initialized |
@@ -3601,7 +3603,21 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
3601 | 3603 | ||
3602 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | 3604 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); |
3603 | 3605 | ||
3604 | r = regulatory_hint_user(data); | 3606 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) |
3607 | user_reg_hint_type = | ||
3608 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); | ||
3609 | else | ||
3610 | user_reg_hint_type = NL80211_USER_REG_HINT_USER; | ||
3611 | |||
3612 | switch (user_reg_hint_type) { | ||
3613 | case NL80211_USER_REG_HINT_USER: | ||
3614 | case NL80211_USER_REG_HINT_CELL_BASE: | ||
3615 | break; | ||
3616 | default: | ||
3617 | return -EINVAL; | ||
3618 | } | ||
3619 | |||
3620 | r = regulatory_hint_user(data, user_reg_hint_type); | ||
3605 | 3621 | ||
3606 | return r; | 3622 | return r; |
3607 | } | 3623 | } |
@@ -3971,6 +3987,11 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
3971 | cfg80211_regdomain->dfs_region))) | 3987 | cfg80211_regdomain->dfs_region))) |
3972 | goto nla_put_failure; | 3988 | goto nla_put_failure; |
3973 | 3989 | ||
3990 | if (reg_last_request_cell_base() && | ||
3991 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | ||
3992 | NL80211_USER_REG_HINT_CELL_BASE)) | ||
3993 | goto nla_put_failure; | ||
3994 | |||
3974 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); | 3995 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); |
3975 | if (!nl_reg_rules) | 3996 | if (!nl_reg_rules) |
3976 | goto nla_put_failure; | 3997 | goto nla_put_failure; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ad6f9029c564..83583a9c15d9 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -97,9 +97,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain; | |||
97 | * - cfg80211_world_regdom | 97 | * - cfg80211_world_regdom |
98 | * - cfg80211_regdom | 98 | * - cfg80211_regdom |
99 | * - last_request | 99 | * - last_request |
100 | * - reg_num_devs_support_basehint | ||
100 | */ | 101 | */ |
101 | static DEFINE_MUTEX(reg_mutex); | 102 | static DEFINE_MUTEX(reg_mutex); |
102 | 103 | ||
104 | /* | ||
105 | * Number of devices that registered to the core | ||
106 | * that support cellular base station regulatory hints | ||
107 | */ | ||
108 | static int reg_num_devs_support_basehint; | ||
109 | |||
103 | static inline void assert_reg_lock(void) | 110 | static inline void assert_reg_lock(void) |
104 | { | 111 | { |
105 | lockdep_assert_held(®_mutex); | 112 | lockdep_assert_held(®_mutex); |
@@ -911,6 +918,59 @@ static void handle_band(struct wiphy *wiphy, | |||
911 | handle_channel(wiphy, initiator, band, i); | 918 | handle_channel(wiphy, initiator, band, i); |
912 | } | 919 | } |
913 | 920 | ||
921 | static bool reg_request_cell_base(struct regulatory_request *request) | ||
922 | { | ||
923 | if (request->initiator != NL80211_REGDOM_SET_BY_USER) | ||
924 | return false; | ||
925 | if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) | ||
926 | return false; | ||
927 | return true; | ||
928 | } | ||
929 | |||
930 | bool reg_last_request_cell_base(void) | ||
931 | { | ||
932 | assert_cfg80211_lock(); | ||
933 | |||
934 | mutex_lock(®_mutex); | ||
935 | return reg_request_cell_base(last_request); | ||
936 | mutex_unlock(®_mutex); | ||
937 | } | ||
938 | |||
939 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS | ||
940 | |||
941 | /* Core specific check */ | ||
942 | static int reg_ignore_cell_hint(struct regulatory_request *pending_request) | ||
943 | { | ||
944 | if (!reg_num_devs_support_basehint) | ||
945 | return -EOPNOTSUPP; | ||
946 | |||
947 | if (reg_request_cell_base(last_request)) { | ||
948 | if (!regdom_changes(pending_request->alpha2)) | ||
949 | return -EALREADY; | ||
950 | return 0; | ||
951 | } | ||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | /* Device specific check */ | ||
956 | static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy) | ||
957 | { | ||
958 | if (!(wiphy->features & NL80211_FEATURE_CELL_BASE_REG_HINTS)) | ||
959 | return true; | ||
960 | return false; | ||
961 | } | ||
962 | #else | ||
963 | static int reg_ignore_cell_hint(struct regulatory_request *pending_request) | ||
964 | { | ||
965 | return -EOPNOTSUPP; | ||
966 | } | ||
967 | static int reg_dev_ignore_cell_hint(struct wiphy *wiphy) | ||
968 | { | ||
969 | return true; | ||
970 | } | ||
971 | #endif | ||
972 | |||
973 | |||
914 | static bool ignore_reg_update(struct wiphy *wiphy, | 974 | static bool ignore_reg_update(struct wiphy *wiphy, |
915 | enum nl80211_reg_initiator initiator) | 975 | enum nl80211_reg_initiator initiator) |
916 | { | 976 | { |
@@ -944,6 +1004,9 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
944 | return true; | 1004 | return true; |
945 | } | 1005 | } |
946 | 1006 | ||
1007 | if (reg_request_cell_base(last_request)) | ||
1008 | return reg_dev_ignore_cell_hint(wiphy); | ||
1009 | |||
947 | return false; | 1010 | return false; |
948 | } | 1011 | } |
949 | 1012 | ||
@@ -1307,6 +1370,13 @@ static int ignore_request(struct wiphy *wiphy, | |||
1307 | return 0; | 1370 | return 0; |
1308 | case NL80211_REGDOM_SET_BY_COUNTRY_IE: | 1371 | case NL80211_REGDOM_SET_BY_COUNTRY_IE: |
1309 | 1372 | ||
1373 | if (reg_request_cell_base(last_request)) { | ||
1374 | /* Trust a Cell base station over the AP's country IE */ | ||
1375 | if (regdom_changes(pending_request->alpha2)) | ||
1376 | return -EOPNOTSUPP; | ||
1377 | return -EALREADY; | ||
1378 | } | ||
1379 | |||
1310 | last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 1380 | last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); |
1311 | 1381 | ||
1312 | if (unlikely(!is_an_alpha2(pending_request->alpha2))) | 1382 | if (unlikely(!is_an_alpha2(pending_request->alpha2))) |
@@ -1351,6 +1421,12 @@ static int ignore_request(struct wiphy *wiphy, | |||
1351 | 1421 | ||
1352 | return REG_INTERSECT; | 1422 | return REG_INTERSECT; |
1353 | case NL80211_REGDOM_SET_BY_USER: | 1423 | case NL80211_REGDOM_SET_BY_USER: |
1424 | if (reg_request_cell_base(pending_request)) | ||
1425 | return reg_ignore_cell_hint(pending_request); | ||
1426 | |||
1427 | if (reg_request_cell_base(last_request)) | ||
1428 | return -EOPNOTSUPP; | ||
1429 | |||
1354 | if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) | 1430 | if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) |
1355 | return REG_INTERSECT; | 1431 | return REG_INTERSECT; |
1356 | /* | 1432 | /* |
@@ -1640,7 +1716,8 @@ static int regulatory_hint_core(const char *alpha2) | |||
1640 | } | 1716 | } |
1641 | 1717 | ||
1642 | /* User hints */ | 1718 | /* User hints */ |
1643 | int regulatory_hint_user(const char *alpha2) | 1719 | int regulatory_hint_user(const char *alpha2, |
1720 | enum nl80211_user_reg_hint_type user_reg_hint_type) | ||
1644 | { | 1721 | { |
1645 | struct regulatory_request *request; | 1722 | struct regulatory_request *request; |
1646 | 1723 | ||
@@ -1654,6 +1731,7 @@ int regulatory_hint_user(const char *alpha2) | |||
1654 | request->alpha2[0] = alpha2[0]; | 1731 | request->alpha2[0] = alpha2[0]; |
1655 | request->alpha2[1] = alpha2[1]; | 1732 | request->alpha2[1] = alpha2[1]; |
1656 | request->initiator = NL80211_REGDOM_SET_BY_USER; | 1733 | request->initiator = NL80211_REGDOM_SET_BY_USER; |
1734 | request->user_reg_hint_type = user_reg_hint_type; | ||
1657 | 1735 | ||
1658 | queue_regulatory_request(request); | 1736 | queue_regulatory_request(request); |
1659 | 1737 | ||
@@ -1906,7 +1984,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1906 | * settings, user regulatory settings takes precedence. | 1984 | * settings, user regulatory settings takes precedence. |
1907 | */ | 1985 | */ |
1908 | if (is_an_alpha2(alpha2)) | 1986 | if (is_an_alpha2(alpha2)) |
1909 | regulatory_hint_user(user_alpha2); | 1987 | regulatory_hint_user(user_alpha2, NL80211_USER_REG_HINT_USER); |
1910 | 1988 | ||
1911 | if (list_empty(&tmp_reg_req_list)) | 1989 | if (list_empty(&tmp_reg_req_list)) |
1912 | return; | 1990 | return; |
@@ -2081,9 +2159,16 @@ static void print_regdomain(const struct ieee80211_regdomain *rd) | |||
2081 | else { | 2159 | else { |
2082 | if (is_unknown_alpha2(rd->alpha2)) | 2160 | if (is_unknown_alpha2(rd->alpha2)) |
2083 | pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n"); | 2161 | pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n"); |
2084 | else | 2162 | else { |
2085 | pr_info("Regulatory domain changed to country: %c%c\n", | 2163 | if (reg_request_cell_base(last_request)) |
2086 | rd->alpha2[0], rd->alpha2[1]); | 2164 | pr_info("Regulatory domain changed " |
2165 | "to country: %c%c by Cell Station\n", | ||
2166 | rd->alpha2[0], rd->alpha2[1]); | ||
2167 | else | ||
2168 | pr_info("Regulatory domain changed " | ||
2169 | "to country: %c%c\n", | ||
2170 | rd->alpha2[0], rd->alpha2[1]); | ||
2171 | } | ||
2087 | } | 2172 | } |
2088 | print_dfs_region(rd->dfs_region); | 2173 | print_dfs_region(rd->dfs_region); |
2089 | print_rd_rules(rd); | 2174 | print_rd_rules(rd); |
@@ -2293,6 +2378,18 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
2293 | } | 2378 | } |
2294 | #endif /* CONFIG_HOTPLUG */ | 2379 | #endif /* CONFIG_HOTPLUG */ |
2295 | 2380 | ||
2381 | void wiphy_regulatory_register(struct wiphy *wiphy) | ||
2382 | { | ||
2383 | assert_cfg80211_lock(); | ||
2384 | |||
2385 | mutex_lock(®_mutex); | ||
2386 | |||
2387 | if (!reg_dev_ignore_cell_hint(wiphy)) | ||
2388 | reg_num_devs_support_basehint++; | ||
2389 | |||
2390 | mutex_unlock(®_mutex); | ||
2391 | } | ||
2392 | |||
2296 | /* Caller must hold cfg80211_mutex */ | 2393 | /* Caller must hold cfg80211_mutex */ |
2297 | void reg_device_remove(struct wiphy *wiphy) | 2394 | void reg_device_remove(struct wiphy *wiphy) |
2298 | { | 2395 | { |
@@ -2302,6 +2399,9 @@ void reg_device_remove(struct wiphy *wiphy) | |||
2302 | 2399 | ||
2303 | mutex_lock(®_mutex); | 2400 | mutex_lock(®_mutex); |
2304 | 2401 | ||
2402 | if (!reg_dev_ignore_cell_hint(wiphy)) | ||
2403 | reg_num_devs_support_basehint--; | ||
2404 | |||
2305 | kfree(wiphy->regd); | 2405 | kfree(wiphy->regd); |
2306 | 2406 | ||
2307 | if (last_request) | 2407 | if (last_request) |
@@ -2367,7 +2467,8 @@ int __init regulatory_init(void) | |||
2367 | * as a user hint. | 2467 | * as a user hint. |
2368 | */ | 2468 | */ |
2369 | if (!is_world_regdom(ieee80211_regdom)) | 2469 | if (!is_world_regdom(ieee80211_regdom)) |
2370 | regulatory_hint_user(ieee80211_regdom); | 2470 | regulatory_hint_user(ieee80211_regdom, |
2471 | NL80211_USER_REG_HINT_USER); | ||
2371 | 2472 | ||
2372 | return 0; | 2473 | return 0; |
2373 | } | 2474 | } |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index e2aaaf525a22..519492fdda3c 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -22,9 +22,11 @@ bool is_world_regdom(const char *alpha2); | |||
22 | bool reg_is_valid_request(const char *alpha2); | 22 | bool reg_is_valid_request(const char *alpha2); |
23 | bool reg_supported_dfs_region(u8 dfs_region); | 23 | bool reg_supported_dfs_region(u8 dfs_region); |
24 | 24 | ||
25 | int regulatory_hint_user(const char *alpha2); | 25 | int regulatory_hint_user(const char *alpha2, |
26 | enum nl80211_user_reg_hint_type user_reg_hint_type); | ||
26 | 27 | ||
27 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env); | 28 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env); |
29 | void wiphy_regulatory_register(struct wiphy *wiphy); | ||
28 | void reg_device_remove(struct wiphy *wiphy); | 30 | void reg_device_remove(struct wiphy *wiphy); |
29 | 31 | ||
30 | int __init regulatory_init(void); | 32 | int __init regulatory_init(void); |
@@ -33,6 +35,7 @@ void regulatory_exit(void); | |||
33 | int set_regdom(const struct ieee80211_regdomain *rd); | 35 | int set_regdom(const struct ieee80211_regdomain *rd); |
34 | 36 | ||
35 | void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); | 37 | void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); |
38 | bool reg_last_request_cell_base(void); | ||
36 | 39 | ||
37 | /** | 40 | /** |
38 | * regulatory_hint_found_beacon - hints a beacon was found on a channel | 41 | * regulatory_hint_found_beacon - hints a beacon was found on a channel |