aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-01-15 19:16:56 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-15 19:16:56 -0500
commit27f097177defdd5858f03500e4b5aa8a97b1627b (patch)
tree186ea28b6f15075df1803acbab7b5a0e9f21cc31 /net/wireless
parent615612dc4e583ae5eeb8eb1ece2d3c70be72296d (diff)
parentbaf1b99ba169bdd3324ac9d99bc2a00c25534429 (diff)
Merge tag 'mac80211-next-for-davem-2015-01-15' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Here's a big pile of changes for this round. We have * a lot of regulatory code changes to deal with the way newer Intel devices handle this * a change to drop packets while disconnecting from an AP instead of trying to wait for them * a new attempt at improving the tailroom accounting to not kick in too much for performance reasons * improvements in wireless link statistics * many other small improvements and small fixes that didn't seem necessary for 3.19 (e.g. in hwsim which is testing only code) Conflicts: drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c Minor overlapping changes. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c40
-rw-r--r--net/wireless/core.h11
-rw-r--r--net/wireless/nl80211.c627
-rw-r--r--net/wireless/nl80211.h16
-rw-r--r--net/wireless/reg.c160
-rw-r--r--net/wireless/reg.h1
-rw-r--r--net/wireless/scan.c13
-rw-r--r--net/wireless/trace.h31
-rw-r--r--net/wireless/wext-compat.c10
9 files changed, 676 insertions, 233 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 53dda7728f86..456e4c38c279 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -21,6 +21,7 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <net/genetlink.h> 22#include <net/genetlink.h>
23#include <net/cfg80211.h> 23#include <net/cfg80211.h>
24#include <net/rtnetlink.h>
24#include "nl80211.h" 25#include "nl80211.h"
25#include "core.h" 26#include "core.h"
26#include "sysfs.h" 27#include "sysfs.h"
@@ -320,6 +321,20 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work)
320 rtnl_unlock(); 321 rtnl_unlock();
321} 322}
322 323
324static void cfg80211_sched_scan_stop_wk(struct work_struct *work)
325{
326 struct cfg80211_registered_device *rdev;
327
328 rdev = container_of(work, struct cfg80211_registered_device,
329 sched_scan_stop_wk);
330
331 rtnl_lock();
332
333 __cfg80211_stop_sched_scan(rdev, false);
334
335 rtnl_unlock();
336}
337
323/* exported functions */ 338/* exported functions */
324 339
325struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, 340struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -406,6 +421,7 @@ use_default_name:
406 INIT_LIST_HEAD(&rdev->destroy_list); 421 INIT_LIST_HEAD(&rdev->destroy_list);
407 spin_lock_init(&rdev->destroy_list_lock); 422 spin_lock_init(&rdev->destroy_list_lock);
408 INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk); 423 INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
424 INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
409 425
410#ifdef CONFIG_CFG80211_DEFAULT_PS 426#ifdef CONFIG_CFG80211_DEFAULT_PS
411 rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 427 rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -560,6 +576,14 @@ int wiphy_register(struct wiphy *wiphy)
560 BIT(NL80211_IFTYPE_MONITOR))) 576 BIT(NL80211_IFTYPE_MONITOR)))
561 wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; 577 wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
562 578
579 if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) &&
580 (wiphy->regulatory_flags &
581 (REGULATORY_CUSTOM_REG |
582 REGULATORY_STRICT_REG |
583 REGULATORY_COUNTRY_IE_FOLLOW_POWER |
584 REGULATORY_COUNTRY_IE_IGNORE))))
585 return -EINVAL;
586
563 if (WARN_ON(wiphy->coalesce && 587 if (WARN_ON(wiphy->coalesce &&
564 (!wiphy->coalesce->n_rules || 588 (!wiphy->coalesce->n_rules ||
565 !wiphy->coalesce->n_patterns) && 589 !wiphy->coalesce->n_patterns) &&
@@ -778,6 +802,7 @@ void wiphy_unregister(struct wiphy *wiphy)
778 flush_work(&rdev->event_work); 802 flush_work(&rdev->event_work);
779 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); 803 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
780 flush_work(&rdev->destroy_work); 804 flush_work(&rdev->destroy_work);
805 flush_work(&rdev->sched_scan_stop_wk);
781 806
782#ifdef CONFIG_PM 807#ifdef CONFIG_PM
783 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) 808 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
@@ -858,6 +883,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
858 struct wireless_dev *wdev) 883 struct wireless_dev *wdev)
859{ 884{
860 struct net_device *dev = wdev->netdev; 885 struct net_device *dev = wdev->netdev;
886 struct cfg80211_sched_scan_request *sched_scan_req;
861 887
862 ASSERT_RTNL(); 888 ASSERT_RTNL();
863 ASSERT_WDEV_LOCK(wdev); 889 ASSERT_WDEV_LOCK(wdev);
@@ -868,7 +894,8 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
868 break; 894 break;
869 case NL80211_IFTYPE_P2P_CLIENT: 895 case NL80211_IFTYPE_P2P_CLIENT:
870 case NL80211_IFTYPE_STATION: 896 case NL80211_IFTYPE_STATION:
871 if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) 897 sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
898 if (sched_scan_req && dev == sched_scan_req->dev)
872 __cfg80211_stop_sched_scan(rdev, false); 899 __cfg80211_stop_sched_scan(rdev, false);
873 900
874#ifdef CONFIG_CFG80211_WEXT 901#ifdef CONFIG_CFG80211_WEXT
@@ -937,12 +964,17 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
937} 964}
938EXPORT_SYMBOL(cfg80211_stop_iface); 965EXPORT_SYMBOL(cfg80211_stop_iface);
939 966
967static const struct rtnl_link_ops wireless_link_ops = {
968 .kind = "wlan",
969};
970
940static int cfg80211_netdev_notifier_call(struct notifier_block *nb, 971static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
941 unsigned long state, void *ptr) 972 unsigned long state, void *ptr)
942{ 973{
943 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 974 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
944 struct wireless_dev *wdev = dev->ieee80211_ptr; 975 struct wireless_dev *wdev = dev->ieee80211_ptr;
945 struct cfg80211_registered_device *rdev; 976 struct cfg80211_registered_device *rdev;
977 struct cfg80211_sched_scan_request *sched_scan_req;
946 978
947 if (!wdev) 979 if (!wdev)
948 return NOTIFY_DONE; 980 return NOTIFY_DONE;
@@ -954,6 +986,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
954 switch (state) { 986 switch (state) {
955 case NETDEV_POST_INIT: 987 case NETDEV_POST_INIT:
956 SET_NETDEV_DEVTYPE(dev, &wiphy_type); 988 SET_NETDEV_DEVTYPE(dev, &wiphy_type);
989 dev->rtnl_link_ops = &wireless_link_ops;
957 break; 990 break;
958 case NETDEV_REGISTER: 991 case NETDEV_REGISTER:
959 /* 992 /*
@@ -1007,8 +1040,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1007 ___cfg80211_scan_done(rdev, false); 1040 ___cfg80211_scan_done(rdev, false);
1008 } 1041 }
1009 1042
1010 if (WARN_ON(rdev->sched_scan_req && 1043 sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
1011 rdev->sched_scan_req->dev == wdev->netdev)) { 1044 if (WARN_ON(sched_scan_req &&
1045 sched_scan_req->dev == wdev->netdev)) {
1012 __cfg80211_stop_sched_scan(rdev, false); 1046 __cfg80211_stop_sched_scan(rdev, false);
1013 } 1047 }
1014 1048
diff --git a/net/wireless/core.h b/net/wireless/core.h
index faa5b1609aae..801cd49c5a0c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -36,6 +36,13 @@ struct cfg80211_registered_device {
36 * the country on the country IE changed. */ 36 * the country on the country IE changed. */
37 char country_ie_alpha2[2]; 37 char country_ie_alpha2[2];
38 38
39 /*
40 * the driver requests the regulatory core to set this regulatory
41 * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED
42 * devices using the regulatory_set_wiphy_regd() API
43 */
44 const struct ieee80211_regdomain *requested_regd;
45
39 /* If a Country IE has been received this tells us the environment 46 /* If a Country IE has been received this tells us the environment
40 * which its telling us its in. This defaults to ENVIRON_ANY */ 47 * which its telling us its in. This defaults to ENVIRON_ANY */
41 enum environment_cap env; 48 enum environment_cap env;
@@ -63,7 +70,7 @@ struct cfg80211_registered_device {
63 u32 bss_generation; 70 u32 bss_generation;
64 struct cfg80211_scan_request *scan_req; /* protected by RTNL */ 71 struct cfg80211_scan_request *scan_req; /* protected by RTNL */
65 struct sk_buff *scan_msg; 72 struct sk_buff *scan_msg;
66 struct cfg80211_sched_scan_request *sched_scan_req; 73 struct cfg80211_sched_scan_request __rcu *sched_scan_req;
67 unsigned long suspend_at; 74 unsigned long suspend_at;
68 struct work_struct scan_done_wk; 75 struct work_struct scan_done_wk;
69 struct work_struct sched_scan_results_wk; 76 struct work_struct sched_scan_results_wk;
@@ -84,6 +91,8 @@ struct cfg80211_registered_device {
84 struct list_head destroy_list; 91 struct list_head destroy_list;
85 struct work_struct destroy_work; 92 struct work_struct destroy_work;
86 93
94 struct work_struct sched_scan_stop_wk;
95
87 /* must be last because of the way we do wiphy_priv(), 96 /* must be last because of the way we do wiphy_priv(),
88 * and it should at least be aligned to NETDEV_ALIGN */ 97 * and it should at least be aligned to NETDEV_ALIGN */
89 struct wiphy wiphy __aligned(NETDEV_ALIGN); 98 struct wiphy wiphy __aligned(NETDEV_ALIGN);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7ca4b5133123..380784378df8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -59,13 +59,13 @@ enum nl80211_multicast_groups {
59}; 59};
60 60
61static const struct genl_multicast_group nl80211_mcgrps[] = { 61static const struct genl_multicast_group nl80211_mcgrps[] = {
62 [NL80211_MCGRP_CONFIG] = { .name = "config", }, 62 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
63 [NL80211_MCGRP_SCAN] = { .name = "scan", }, 63 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
64 [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, 64 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
65 [NL80211_MCGRP_MLME] = { .name = "mlme", }, 65 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
66 [NL80211_MCGRP_VENDOR] = { .name = "vendor", }, 66 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
67#ifdef CONFIG_NL80211_TESTMODE 67#ifdef CONFIG_NL80211_TESTMODE
68 [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } 68 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
69#endif 69#endif
70}; 70};
71 71
@@ -396,6 +396,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
396 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, 396 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
397 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, 397 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
398 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, 398 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
399 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
399}; 400};
400 401
401/* policy for the key attributes */ 402/* policy for the key attributes */
@@ -1087,6 +1088,11 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
1087 return -ENOBUFS; 1088 return -ENOBUFS;
1088 } 1089 }
1089 1090
1091 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1092 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1093 rdev->wiphy.wowlan->max_nd_match_sets))
1094 return -ENOBUFS;
1095
1090 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) 1096 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
1091 return -ENOBUFS; 1097 return -ENOBUFS;
1092 1098
@@ -1701,6 +1707,15 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1701 rdev->wiphy.max_num_csa_counters)) 1707 rdev->wiphy.max_num_csa_counters))
1702 goto nla_put_failure; 1708 goto nla_put_failure;
1703 1709
1710 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
1711 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
1712 goto nla_put_failure;
1713
1714 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
1715 sizeof(rdev->wiphy.ext_features),
1716 rdev->wiphy.ext_features))
1717 goto nla_put_failure;
1718
1704 /* done */ 1719 /* done */
1705 state->split_start = 0; 1720 state->split_start = 0;
1706 break; 1721 break;
@@ -3640,8 +3655,8 @@ static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
3640 return true; 3655 return true;
3641} 3656}
3642 3657
3643static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 3658static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
3644 int flags, 3659 u32 seq, int flags,
3645 struct cfg80211_registered_device *rdev, 3660 struct cfg80211_registered_device *rdev,
3646 struct net_device *dev, 3661 struct net_device *dev,
3647 const u8 *mac_addr, struct station_info *sinfo) 3662 const u8 *mac_addr, struct station_info *sinfo)
@@ -3649,7 +3664,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3649 void *hdr; 3664 void *hdr;
3650 struct nlattr *sinfoattr, *bss_param; 3665 struct nlattr *sinfoattr, *bss_param;
3651 3666
3652 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); 3667 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3653 if (!hdr) 3668 if (!hdr)
3654 return -1; 3669 return -1;
3655 3670
@@ -3661,115 +3676,77 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3661 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); 3676 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
3662 if (!sinfoattr) 3677 if (!sinfoattr)
3663 goto nla_put_failure; 3678 goto nla_put_failure;
3664 if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) && 3679
3665 nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME, 3680#define PUT_SINFO(attr, memb, type) do { \
3666 sinfo->connected_time)) 3681 if (sinfo->filled & BIT(NL80211_STA_INFO_ ## attr) && \
3667 goto nla_put_failure; 3682 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
3668 if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) && 3683 sinfo->memb)) \
3669 nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, 3684 goto nla_put_failure; \
3670 sinfo->inactive_time)) 3685 } while (0)
3671 goto nla_put_failure; 3686
3672 if ((sinfo->filled & (STATION_INFO_RX_BYTES | 3687 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
3673 STATION_INFO_RX_BYTES64)) && 3688 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
3689
3690 if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
3691 BIT(NL80211_STA_INFO_RX_BYTES64)) &&
3674 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, 3692 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
3675 (u32)sinfo->rx_bytes)) 3693 (u32)sinfo->rx_bytes))
3676 goto nla_put_failure; 3694 goto nla_put_failure;
3677 if ((sinfo->filled & (STATION_INFO_TX_BYTES | 3695
3678 STATION_INFO_TX_BYTES64)) && 3696 if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
3697 BIT(NL80211_STA_INFO_TX_BYTES64)) &&
3679 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, 3698 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
3680 (u32)sinfo->tx_bytes)) 3699 (u32)sinfo->tx_bytes))
3681 goto nla_put_failure; 3700 goto nla_put_failure;
3682 if ((sinfo->filled & STATION_INFO_RX_BYTES64) && 3701
3683 nla_put_u64(msg, NL80211_STA_INFO_RX_BYTES64, 3702 PUT_SINFO(RX_BYTES64, rx_bytes, u64);
3684 sinfo->rx_bytes)) 3703 PUT_SINFO(TX_BYTES64, tx_bytes, u64);
3685 goto nla_put_failure; 3704 PUT_SINFO(LLID, llid, u16);
3686 if ((sinfo->filled & STATION_INFO_TX_BYTES64) && 3705 PUT_SINFO(PLID, plid, u16);
3687 nla_put_u64(msg, NL80211_STA_INFO_TX_BYTES64, 3706 PUT_SINFO(PLINK_STATE, plink_state, u8);
3688 sinfo->tx_bytes)) 3707
3689 goto nla_put_failure;
3690 if ((sinfo->filled & STATION_INFO_LLID) &&
3691 nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid))
3692 goto nla_put_failure;
3693 if ((sinfo->filled & STATION_INFO_PLID) &&
3694 nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid))
3695 goto nla_put_failure;
3696 if ((sinfo->filled & STATION_INFO_PLINK_STATE) &&
3697 nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE,
3698 sinfo->plink_state))
3699 goto nla_put_failure;
3700 switch (rdev->wiphy.signal_type) { 3708 switch (rdev->wiphy.signal_type) {
3701 case CFG80211_SIGNAL_TYPE_MBM: 3709 case CFG80211_SIGNAL_TYPE_MBM:
3702 if ((sinfo->filled & STATION_INFO_SIGNAL) && 3710 PUT_SINFO(SIGNAL, signal, u8);
3703 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL, 3711 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
3704 sinfo->signal))
3705 goto nla_put_failure;
3706 if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) &&
3707 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG,
3708 sinfo->signal_avg))
3709 goto nla_put_failure;
3710 break; 3712 break;
3711 default: 3713 default:
3712 break; 3714 break;
3713 } 3715 }
3714 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) { 3716 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
3715 if (!nl80211_put_signal(msg, sinfo->chains, 3717 if (!nl80211_put_signal(msg, sinfo->chains,
3716 sinfo->chain_signal, 3718 sinfo->chain_signal,
3717 NL80211_STA_INFO_CHAIN_SIGNAL)) 3719 NL80211_STA_INFO_CHAIN_SIGNAL))
3718 goto nla_put_failure; 3720 goto nla_put_failure;
3719 } 3721 }
3720 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) { 3722 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
3721 if (!nl80211_put_signal(msg, sinfo->chains, 3723 if (!nl80211_put_signal(msg, sinfo->chains,
3722 sinfo->chain_signal_avg, 3724 sinfo->chain_signal_avg,
3723 NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) 3725 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
3724 goto nla_put_failure; 3726 goto nla_put_failure;
3725 } 3727 }
3726 if (sinfo->filled & STATION_INFO_TX_BITRATE) { 3728 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
3727 if (!nl80211_put_sta_rate(msg, &sinfo->txrate, 3729 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
3728 NL80211_STA_INFO_TX_BITRATE)) 3730 NL80211_STA_INFO_TX_BITRATE))
3729 goto nla_put_failure; 3731 goto nla_put_failure;
3730 } 3732 }
3731 if (sinfo->filled & STATION_INFO_RX_BITRATE) { 3733 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
3732 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, 3734 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
3733 NL80211_STA_INFO_RX_BITRATE)) 3735 NL80211_STA_INFO_RX_BITRATE))
3734 goto nla_put_failure; 3736 goto nla_put_failure;
3735 } 3737 }
3736 if ((sinfo->filled & STATION_INFO_RX_PACKETS) && 3738
3737 nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS, 3739 PUT_SINFO(RX_PACKETS, rx_packets, u32);
3738 sinfo->rx_packets)) 3740 PUT_SINFO(TX_PACKETS, tx_packets, u32);
3739 goto nla_put_failure; 3741 PUT_SINFO(TX_RETRIES, tx_retries, u32);
3740 if ((sinfo->filled & STATION_INFO_TX_PACKETS) && 3742 PUT_SINFO(TX_FAILED, tx_failed, u32);
3741 nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS, 3743 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
3742 sinfo->tx_packets)) 3744 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
3743 goto nla_put_failure; 3745 PUT_SINFO(LOCAL_PM, local_pm, u32);
3744 if ((sinfo->filled & STATION_INFO_TX_RETRIES) && 3746 PUT_SINFO(PEER_PM, peer_pm, u32);
3745 nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES, 3747 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
3746 sinfo->tx_retries)) 3748
3747 goto nla_put_failure; 3749 if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
3748 if ((sinfo->filled & STATION_INFO_TX_FAILED) &&
3749 nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED,
3750 sinfo->tx_failed))
3751 goto nla_put_failure;
3752 if ((sinfo->filled & STATION_INFO_EXPECTED_THROUGHPUT) &&
3753 nla_put_u32(msg, NL80211_STA_INFO_EXPECTED_THROUGHPUT,
3754 sinfo->expected_throughput))
3755 goto nla_put_failure;
3756 if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) &&
3757 nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
3758 sinfo->beacon_loss_count))
3759 goto nla_put_failure;
3760 if ((sinfo->filled & STATION_INFO_LOCAL_PM) &&
3761 nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM,
3762 sinfo->local_pm))
3763 goto nla_put_failure;
3764 if ((sinfo->filled & STATION_INFO_PEER_PM) &&
3765 nla_put_u32(msg, NL80211_STA_INFO_PEER_PM,
3766 sinfo->peer_pm))
3767 goto nla_put_failure;
3768 if ((sinfo->filled & STATION_INFO_NONPEER_PM) &&
3769 nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM,
3770 sinfo->nonpeer_pm))
3771 goto nla_put_failure;
3772 if (sinfo->filled & STATION_INFO_BSS_PARAM) {
3773 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); 3750 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
3774 if (!bss_param) 3751 if (!bss_param)
3775 goto nla_put_failure; 3752 goto nla_put_failure;
@@ -3788,18 +3765,62 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3788 3765
3789 nla_nest_end(msg, bss_param); 3766 nla_nest_end(msg, bss_param);
3790 } 3767 }
3791 if ((sinfo->filled & STATION_INFO_STA_FLAGS) && 3768 if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
3792 nla_put(msg, NL80211_STA_INFO_STA_FLAGS, 3769 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
3793 sizeof(struct nl80211_sta_flag_update), 3770 sizeof(struct nl80211_sta_flag_update),
3794 &sinfo->sta_flags)) 3771 &sinfo->sta_flags))
3795 goto nla_put_failure; 3772 goto nla_put_failure;
3796 if ((sinfo->filled & STATION_INFO_T_OFFSET) && 3773
3797 nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET, 3774 PUT_SINFO(T_OFFSET, t_offset, u64);
3798 sinfo->t_offset)) 3775 PUT_SINFO(RX_DROP_MISC, rx_dropped_misc, u64);
3799 goto nla_put_failure; 3776 PUT_SINFO(BEACON_RX, rx_beacon, u64);
3777 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
3778
3779#undef PUT_SINFO
3780
3781 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
3782 struct nlattr *tidsattr;
3783 int tid;
3784
3785 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
3786 if (!tidsattr)
3787 goto nla_put_failure;
3788
3789 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
3790 struct cfg80211_tid_stats *tidstats;
3791 struct nlattr *tidattr;
3792
3793 tidstats = &sinfo->pertid[tid];
3794
3795 if (!tidstats->filled)
3796 continue;
3797
3798 tidattr = nla_nest_start(msg, tid + 1);
3799 if (!tidattr)
3800 goto nla_put_failure;
3801
3802#define PUT_TIDVAL(attr, memb, type) do { \
3803 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
3804 nla_put_ ## type(msg, NL80211_TID_STATS_ ## attr, \
3805 tidstats->memb)) \
3806 goto nla_put_failure; \
3807 } while (0)
3808
3809 PUT_TIDVAL(RX_MSDU, rx_msdu, u64);
3810 PUT_TIDVAL(TX_MSDU, tx_msdu, u64);
3811 PUT_TIDVAL(TX_MSDU_RETRIES, tx_msdu_retries, u64);
3812 PUT_TIDVAL(TX_MSDU_FAILED, tx_msdu_failed, u64);
3813
3814#undef PUT_TIDVAL
3815 nla_nest_end(msg, tidattr);
3816 }
3817
3818 nla_nest_end(msg, tidsattr);
3819 }
3820
3800 nla_nest_end(msg, sinfoattr); 3821 nla_nest_end(msg, sinfoattr);
3801 3822
3802 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && 3823 if (sinfo->assoc_req_ies_len &&
3803 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, 3824 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
3804 sinfo->assoc_req_ies)) 3825 sinfo->assoc_req_ies))
3805 goto nla_put_failure; 3826 goto nla_put_failure;
@@ -3844,7 +3865,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
3844 if (err) 3865 if (err)
3845 goto out_err; 3866 goto out_err;
3846 3867
3847 if (nl80211_send_station(skb, 3868 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
3848 NETLINK_CB(cb->skb).portid, 3869 NETLINK_CB(cb->skb).portid,
3849 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3870 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3850 rdev, wdev->netdev, mac_addr, 3871 rdev, wdev->netdev, mac_addr,
@@ -3891,7 +3912,8 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
3891 if (!msg) 3912 if (!msg)
3892 return -ENOMEM; 3913 return -ENOMEM;
3893 3914
3894 if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, 3915 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
3916 info->snd_portid, info->snd_seq, 0,
3895 rdev, dev, mac_addr, &sinfo) < 0) { 3917 rdev, dev, mac_addr, &sinfo) < 0) {
3896 nlmsg_free(msg); 3918 nlmsg_free(msg);
3897 return -ENOBUFS; 3919 return -ENOBUFS;
@@ -5327,42 +5349,20 @@ static int nl80211_update_mesh_config(struct sk_buff *skb,
5327 return err; 5349 return err;
5328} 5350}
5329 5351
5330static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) 5352static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
5353 struct sk_buff *msg)
5331{ 5354{
5332 const struct ieee80211_regdomain *regdom;
5333 struct sk_buff *msg;
5334 void *hdr = NULL;
5335 struct nlattr *nl_reg_rules; 5355 struct nlattr *nl_reg_rules;
5336 unsigned int i; 5356 unsigned int i;
5337 5357
5338 if (!cfg80211_regdomain)
5339 return -EINVAL;
5340
5341 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5342 if (!msg)
5343 return -ENOBUFS;
5344
5345 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
5346 NL80211_CMD_GET_REG);
5347 if (!hdr)
5348 goto put_failure;
5349
5350 if (reg_last_request_cell_base() &&
5351 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
5352 NL80211_USER_REG_HINT_CELL_BASE))
5353 goto nla_put_failure;
5354
5355 rcu_read_lock();
5356 regdom = rcu_dereference(cfg80211_regdomain);
5357
5358 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) || 5358 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
5359 (regdom->dfs_region && 5359 (regdom->dfs_region &&
5360 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region))) 5360 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
5361 goto nla_put_failure_rcu; 5361 goto nla_put_failure;
5362 5362
5363 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); 5363 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
5364 if (!nl_reg_rules) 5364 if (!nl_reg_rules)
5365 goto nla_put_failure_rcu; 5365 goto nla_put_failure;
5366 5366
5367 for (i = 0; i < regdom->n_reg_rules; i++) { 5367 for (i = 0; i < regdom->n_reg_rules; i++) {
5368 struct nlattr *nl_reg_rule; 5368 struct nlattr *nl_reg_rule;
@@ -5377,7 +5377,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
5377 5377
5378 nl_reg_rule = nla_nest_start(msg, i); 5378 nl_reg_rule = nla_nest_start(msg, i);
5379 if (!nl_reg_rule) 5379 if (!nl_reg_rule)
5380 goto nla_put_failure_rcu; 5380 goto nla_put_failure;
5381 5381
5382 max_bandwidth_khz = freq_range->max_bandwidth_khz; 5382 max_bandwidth_khz = freq_range->max_bandwidth_khz;
5383 if (!max_bandwidth_khz) 5383 if (!max_bandwidth_khz)
@@ -5398,13 +5398,74 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
5398 power_rule->max_eirp) || 5398 power_rule->max_eirp) ||
5399 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME, 5399 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
5400 reg_rule->dfs_cac_ms)) 5400 reg_rule->dfs_cac_ms))
5401 goto nla_put_failure_rcu; 5401 goto nla_put_failure;
5402 5402
5403 nla_nest_end(msg, nl_reg_rule); 5403 nla_nest_end(msg, nl_reg_rule);
5404 } 5404 }
5405 rcu_read_unlock();
5406 5405
5407 nla_nest_end(msg, nl_reg_rules); 5406 nla_nest_end(msg, nl_reg_rules);
5407 return 0;
5408
5409nla_put_failure:
5410 return -EMSGSIZE;
5411}
5412
5413static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
5414{
5415 const struct ieee80211_regdomain *regdom = NULL;
5416 struct cfg80211_registered_device *rdev;
5417 struct wiphy *wiphy = NULL;
5418 struct sk_buff *msg;
5419 void *hdr;
5420
5421 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5422 if (!msg)
5423 return -ENOBUFS;
5424
5425 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
5426 NL80211_CMD_GET_REG);
5427 if (!hdr)
5428 goto put_failure;
5429
5430 if (info->attrs[NL80211_ATTR_WIPHY]) {
5431 bool self_managed;
5432
5433 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
5434 if (IS_ERR(rdev)) {
5435 nlmsg_free(msg);
5436 return PTR_ERR(rdev);
5437 }
5438
5439 wiphy = &rdev->wiphy;
5440 self_managed = wiphy->regulatory_flags &
5441 REGULATORY_WIPHY_SELF_MANAGED;
5442 regdom = get_wiphy_regdom(wiphy);
5443
5444 /* a self-managed-reg device must have a private regdom */
5445 if (WARN_ON(!regdom && self_managed)) {
5446 nlmsg_free(msg);
5447 return -EINVAL;
5448 }
5449
5450 if (regdom &&
5451 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
5452 goto nla_put_failure;
5453 }
5454
5455 if (!wiphy && reg_last_request_cell_base() &&
5456 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
5457 NL80211_USER_REG_HINT_CELL_BASE))
5458 goto nla_put_failure;
5459
5460 rcu_read_lock();
5461
5462 if (!regdom)
5463 regdom = rcu_dereference(cfg80211_regdomain);
5464
5465 if (nl80211_put_regdom(regdom, msg))
5466 goto nla_put_failure_rcu;
5467
5468 rcu_read_unlock();
5408 5469
5409 genlmsg_end(msg, hdr); 5470 genlmsg_end(msg, hdr);
5410 return genlmsg_reply(msg, info); 5471 return genlmsg_reply(msg, info);
@@ -5418,6 +5479,83 @@ put_failure:
5418 return -EMSGSIZE; 5479 return -EMSGSIZE;
5419} 5480}
5420 5481
5482static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
5483 u32 seq, int flags, struct wiphy *wiphy,
5484 const struct ieee80211_regdomain *regdom)
5485{
5486 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
5487 NL80211_CMD_GET_REG);
5488
5489 if (!hdr)
5490 return -1;
5491
5492 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
5493
5494 if (nl80211_put_regdom(regdom, msg))
5495 goto nla_put_failure;
5496
5497 if (!wiphy && reg_last_request_cell_base() &&
5498 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
5499 NL80211_USER_REG_HINT_CELL_BASE))
5500 goto nla_put_failure;
5501
5502 if (wiphy &&
5503 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
5504 goto nla_put_failure;
5505
5506 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
5507 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
5508 goto nla_put_failure;
5509
5510 return genlmsg_end(msg, hdr);
5511
5512nla_put_failure:
5513 genlmsg_cancel(msg, hdr);
5514 return -EMSGSIZE;
5515}
5516
5517static int nl80211_get_reg_dump(struct sk_buff *skb,
5518 struct netlink_callback *cb)
5519{
5520 const struct ieee80211_regdomain *regdom = NULL;
5521 struct cfg80211_registered_device *rdev;
5522 int err, reg_idx, start = cb->args[2];
5523
5524 rtnl_lock();
5525
5526 if (cfg80211_regdomain && start == 0) {
5527 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
5528 NLM_F_MULTI, NULL,
5529 rtnl_dereference(cfg80211_regdomain));
5530 if (err < 0)
5531 goto out_err;
5532 }
5533
5534 /* the global regdom is idx 0 */
5535 reg_idx = 1;
5536 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
5537 regdom = get_wiphy_regdom(&rdev->wiphy);
5538 if (!regdom)
5539 continue;
5540
5541 if (++reg_idx <= start)
5542 continue;
5543
5544 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
5545 NLM_F_MULTI, &rdev->wiphy, regdom);
5546 if (err < 0) {
5547 reg_idx--;
5548 break;
5549 }
5550 }
5551
5552 cb->args[2] = reg_idx;
5553 err = skb->len;
5554out_err:
5555 rtnl_unlock();
5556 return err;
5557}
5558
5421static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 5559static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5422{ 5560{
5423 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; 5561 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -6069,6 +6207,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
6069 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6207 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6070 struct net_device *dev = info->user_ptr[1]; 6208 struct net_device *dev = info->user_ptr[1];
6071 struct wireless_dev *wdev = dev->ieee80211_ptr; 6209 struct wireless_dev *wdev = dev->ieee80211_ptr;
6210 struct cfg80211_sched_scan_request *sched_scan_req;
6072 int err; 6211 int err;
6073 6212
6074 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 6213 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
@@ -6078,27 +6217,32 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
6078 if (rdev->sched_scan_req) 6217 if (rdev->sched_scan_req)
6079 return -EINPROGRESS; 6218 return -EINPROGRESS;
6080 6219
6081 rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, 6220 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
6082 info->attrs); 6221 info->attrs);
6083 err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); 6222
6223 err = PTR_ERR_OR_ZERO(sched_scan_req);
6084 if (err) 6224 if (err)
6085 goto out_err; 6225 goto out_err;
6086 6226
6087 err = rdev_sched_scan_start(rdev, dev, rdev->sched_scan_req); 6227 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
6088 if (err) 6228 if (err)
6089 goto out_free; 6229 goto out_free;
6090 6230
6091 rdev->sched_scan_req->dev = dev; 6231 sched_scan_req->dev = dev;
6092 rdev->sched_scan_req->wiphy = &rdev->wiphy; 6232 sched_scan_req->wiphy = &rdev->wiphy;
6233
6234 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
6235 sched_scan_req->owner_nlportid = info->snd_portid;
6236
6237 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
6093 6238
6094 nl80211_send_sched_scan(rdev, dev, 6239 nl80211_send_sched_scan(rdev, dev,
6095 NL80211_CMD_START_SCHED_SCAN); 6240 NL80211_CMD_START_SCHED_SCAN);
6096 return 0; 6241 return 0;
6097 6242
6098out_free: 6243out_free:
6099 kfree(rdev->sched_scan_req); 6244 kfree(sched_scan_req);
6100out_err: 6245out_err:
6101 rdev->sched_scan_req = NULL;
6102 return err; 6246 return err;
6103} 6247}
6104 6248
@@ -6481,12 +6625,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
6481} 6625}
6482 6626
6483static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, 6627static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6484 int flags, struct net_device *dev, 6628 int flags, struct net_device *dev,
6485 struct survey_info *survey) 6629 bool allow_radio_stats,
6630 struct survey_info *survey)
6486{ 6631{
6487 void *hdr; 6632 void *hdr;
6488 struct nlattr *infoattr; 6633 struct nlattr *infoattr;
6489 6634
6635 /* skip radio stats if userspace didn't request them */
6636 if (!survey->channel && !allow_radio_stats)
6637 return 0;
6638
6490 hdr = nl80211hdr_put(msg, portid, seq, flags, 6639 hdr = nl80211hdr_put(msg, portid, seq, flags,
6491 NL80211_CMD_NEW_SURVEY_RESULTS); 6640 NL80211_CMD_NEW_SURVEY_RESULTS);
6492 if (!hdr) 6641 if (!hdr)
@@ -6499,7 +6648,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6499 if (!infoattr) 6648 if (!infoattr)
6500 goto nla_put_failure; 6649 goto nla_put_failure;
6501 6650
6502 if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, 6651 if (survey->channel &&
6652 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
6503 survey->channel->center_freq)) 6653 survey->channel->center_freq))
6504 goto nla_put_failure; 6654 goto nla_put_failure;
6505 6655
@@ -6509,25 +6659,29 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6509 if ((survey->filled & SURVEY_INFO_IN_USE) && 6659 if ((survey->filled & SURVEY_INFO_IN_USE) &&
6510 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) 6660 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
6511 goto nla_put_failure; 6661 goto nla_put_failure;
6512 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) && 6662 if ((survey->filled & SURVEY_INFO_TIME) &&
6513 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, 6663 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME,
6514 survey->channel_time)) 6664 survey->time))
6515 goto nla_put_failure; 6665 goto nla_put_failure;
6516 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) && 6666 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
6517 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, 6667 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_BUSY,
6518 survey->channel_time_busy)) 6668 survey->time_busy))
6519 goto nla_put_failure; 6669 goto nla_put_failure;
6520 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) && 6670 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
6521 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, 6671 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
6522 survey->channel_time_ext_busy)) 6672 survey->time_ext_busy))
6523 goto nla_put_failure; 6673 goto nla_put_failure;
6524 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) && 6674 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
6525 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, 6675 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_RX,
6526 survey->channel_time_rx)) 6676 survey->time_rx))
6527 goto nla_put_failure; 6677 goto nla_put_failure;
6528 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) && 6678 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
6529 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, 6679 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_TX,
6530 survey->channel_time_tx)) 6680 survey->time_tx))
6681 goto nla_put_failure;
6682 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
6683 nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_SCAN,
6684 survey->time_scan))
6531 goto nla_put_failure; 6685 goto nla_put_failure;
6532 6686
6533 nla_nest_end(msg, infoattr); 6687 nla_nest_end(msg, infoattr);
@@ -6539,19 +6693,22 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6539 return -EMSGSIZE; 6693 return -EMSGSIZE;
6540} 6694}
6541 6695
6542static int nl80211_dump_survey(struct sk_buff *skb, 6696static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
6543 struct netlink_callback *cb)
6544{ 6697{
6545 struct survey_info survey; 6698 struct survey_info survey;
6546 struct cfg80211_registered_device *rdev; 6699 struct cfg80211_registered_device *rdev;
6547 struct wireless_dev *wdev; 6700 struct wireless_dev *wdev;
6548 int survey_idx = cb->args[2]; 6701 int survey_idx = cb->args[2];
6549 int res; 6702 int res;
6703 bool radio_stats;
6550 6704
6551 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); 6705 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
6552 if (res) 6706 if (res)
6553 return res; 6707 return res;
6554 6708
6709 /* prepare_wdev_dump parsed the attributes */
6710 radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
6711
6555 if (!wdev->netdev) { 6712 if (!wdev->netdev) {
6556 res = -EINVAL; 6713 res = -EINVAL;
6557 goto out_err; 6714 goto out_err;
@@ -6569,13 +6726,9 @@ static int nl80211_dump_survey(struct sk_buff *skb,
6569 if (res) 6726 if (res)
6570 goto out_err; 6727 goto out_err;
6571 6728
6572 /* Survey without a channel doesn't make sense */ 6729 /* don't send disabled channels, but do send non-channel data */
6573 if (!survey.channel) { 6730 if (survey.channel &&
6574 res = -EINVAL; 6731 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
6575 goto out;
6576 }
6577
6578 if (survey.channel->flags & IEEE80211_CHAN_DISABLED) {
6579 survey_idx++; 6732 survey_idx++;
6580 continue; 6733 continue;
6581 } 6734 }
@@ -6583,7 +6736,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
6583 if (nl80211_send_survey(skb, 6736 if (nl80211_send_survey(skb,
6584 NETLINK_CB(cb->skb).portid, 6737 NETLINK_CB(cb->skb).portid,
6585 cb->nlh->nlmsg_seq, NLM_F_MULTI, 6738 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6586 wdev->netdev, &survey) < 0) 6739 wdev->netdev, radio_stats, &survey) < 0)
6587 goto out; 6740 goto out;
6588 survey_idx++; 6741 survey_idx++;
6589 } 6742 }
@@ -8599,6 +8752,48 @@ static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
8599 return 0; 8752 return 0;
8600} 8753}
8601 8754
8755static int nl80211_send_wowlan_nd(struct sk_buff *msg,
8756 struct cfg80211_sched_scan_request *req)
8757{
8758 struct nlattr *nd, *freqs, *matches, *match;
8759 int i;
8760
8761 if (!req)
8762 return 0;
8763
8764 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
8765 if (!nd)
8766 return -ENOBUFS;
8767
8768 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, req->interval))
8769 return -ENOBUFS;
8770
8771 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
8772 if (!freqs)
8773 return -ENOBUFS;
8774
8775 for (i = 0; i < req->n_channels; i++)
8776 nla_put_u32(msg, i, req->channels[i]->center_freq);
8777
8778 nla_nest_end(msg, freqs);
8779
8780 if (req->n_match_sets) {
8781 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
8782 for (i = 0; i < req->n_match_sets; i++) {
8783 match = nla_nest_start(msg, i);
8784 nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
8785 req->match_sets[i].ssid.ssid_len,
8786 req->match_sets[i].ssid.ssid);
8787 nla_nest_end(msg, match);
8788 }
8789 nla_nest_end(msg, matches);
8790 }
8791
8792 nla_nest_end(msg, nd);
8793
8794 return 0;
8795}
8796
8602static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) 8797static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
8603{ 8798{
8604 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8799 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -8656,6 +8851,11 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
8656 rdev->wiphy.wowlan_config->tcp)) 8851 rdev->wiphy.wowlan_config->tcp))
8657 goto nla_put_failure; 8852 goto nla_put_failure;
8658 8853
8854 if (nl80211_send_wowlan_nd(
8855 msg,
8856 rdev->wiphy.wowlan_config->nd_config))
8857 goto nla_put_failure;
8858
8659 nla_nest_end(msg, nl_wowlan); 8859 nla_nest_end(msg, nl_wowlan);
8660 } 8860 }
8661 8861
@@ -10225,7 +10425,8 @@ static const struct genl_ops nl80211_ops[] = {
10225 }, 10425 },
10226 { 10426 {
10227 .cmd = NL80211_CMD_GET_REG, 10427 .cmd = NL80211_CMD_GET_REG,
10228 .doit = nl80211_get_reg, 10428 .doit = nl80211_get_reg_do,
10429 .dumpit = nl80211_get_reg_dump,
10229 .policy = nl80211_policy, 10430 .policy = nl80211_policy,
10230 .internal_flags = NL80211_FLAG_NEED_RTNL, 10431 .internal_flags = NL80211_FLAG_NEED_RTNL,
10231 /* can be retrieved by unprivileged users */ 10432 /* can be retrieved by unprivileged users */
@@ -10939,25 +11140,9 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
10939 NL80211_MCGRP_SCAN, GFP_KERNEL); 11140 NL80211_MCGRP_SCAN, GFP_KERNEL);
10940} 11141}
10941 11142
10942/* 11143static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
10943 * This can happen on global regulatory changes or device specific settings 11144 struct regulatory_request *request)
10944 * based on custom world regulatory domains.
10945 */
10946void nl80211_send_reg_change_event(struct regulatory_request *request)
10947{ 11145{
10948 struct sk_buff *msg;
10949 void *hdr;
10950
10951 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10952 if (!msg)
10953 return;
10954
10955 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
10956 if (!hdr) {
10957 nlmsg_free(msg);
10958 return;
10959 }
10960
10961 /* Userspace can always count this one always being set */ 11146 /* Userspace can always count this one always being set */
10962 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) 11147 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
10963 goto nla_put_failure; 11148 goto nla_put_failure;
@@ -10983,8 +11168,46 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
10983 goto nla_put_failure; 11168 goto nla_put_failure;
10984 } 11169 }
10985 11170
10986 if (request->wiphy_idx != WIPHY_IDX_INVALID && 11171 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
10987 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) 11172 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
11173
11174 if (wiphy &&
11175 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
11176 goto nla_put_failure;
11177
11178 if (wiphy &&
11179 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
11180 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
11181 goto nla_put_failure;
11182 }
11183
11184 return true;
11185
11186nla_put_failure:
11187 return false;
11188}
11189
11190/*
11191 * This can happen on global regulatory changes or device specific settings
11192 * based on custom regulatory domains.
11193 */
11194void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
11195 struct regulatory_request *request)
11196{
11197 struct sk_buff *msg;
11198 void *hdr;
11199
11200 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11201 if (!msg)
11202 return;
11203
11204 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
11205 if (!hdr) {
11206 nlmsg_free(msg);
11207 return;
11208 }
11209
11210 if (nl80211_reg_change_event_fill(msg, request) == false)
10988 goto nla_put_failure; 11211 goto nla_put_failure;
10989 11212
10990 genlmsg_end(msg, hdr); 11213 genlmsg_end(msg, hdr);
@@ -11523,7 +11746,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
11523 if (!msg) 11746 if (!msg)
11524 return; 11747 return;
11525 11748
11526 if (nl80211_send_station(msg, 0, 0, 0, 11749 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
11527 rdev, dev, mac_addr, sinfo) < 0) { 11750 rdev, dev, mac_addr, sinfo) < 0) {
11528 nlmsg_free(msg); 11751 nlmsg_free(msg);
11529 return; 11752 return;
@@ -11534,12 +11757,16 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
11534} 11757}
11535EXPORT_SYMBOL(cfg80211_new_sta); 11758EXPORT_SYMBOL(cfg80211_new_sta);
11536 11759
11537void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) 11760void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
11761 struct station_info *sinfo, gfp_t gfp)
11538{ 11762{
11539 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 11763 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
11540 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 11764 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11541 struct sk_buff *msg; 11765 struct sk_buff *msg;
11542 void *hdr; 11766 struct station_info empty_sinfo = {};
11767
11768 if (!sinfo)
11769 sinfo = &empty_sinfo;
11543 11770
11544 trace_cfg80211_del_sta(dev, mac_addr); 11771 trace_cfg80211_del_sta(dev, mac_addr);
11545 11772
@@ -11547,27 +11774,16 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
11547 if (!msg) 11774 if (!msg)
11548 return; 11775 return;
11549 11776
11550 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); 11777 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
11551 if (!hdr) { 11778 rdev, dev, mac_addr, sinfo)) {
11552 nlmsg_free(msg); 11779 nlmsg_free(msg);
11553 return; 11780 return;
11554 } 11781 }
11555 11782
11556 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
11557 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
11558 goto nla_put_failure;
11559
11560 genlmsg_end(msg, hdr);
11561
11562 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 11783 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
11563 NL80211_MCGRP_MLME, gfp); 11784 NL80211_MCGRP_MLME, gfp);
11564 return;
11565
11566 nla_put_failure:
11567 genlmsg_cancel(msg, hdr);
11568 nlmsg_free(msg);
11569} 11785}
11570EXPORT_SYMBOL(cfg80211_del_sta); 11786EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
11571 11787
11572void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, 11788void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
11573 enum nl80211_connect_failed_reason reason, 11789 enum nl80211_connect_failed_reason reason,
@@ -12471,6 +12687,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
12471 12687
12472 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { 12688 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
12473 bool schedule_destroy_work = false; 12689 bool schedule_destroy_work = false;
12690 bool schedule_scan_stop = false;
12691 struct cfg80211_sched_scan_request *sched_scan_req =
12692 rcu_dereference(rdev->sched_scan_req);
12693
12694 if (sched_scan_req && notify->portid &&
12695 sched_scan_req->owner_nlportid == notify->portid)
12696 schedule_scan_stop = true;
12474 12697
12475 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { 12698 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) {
12476 cfg80211_mlme_unregister_socket(wdev, notify->portid); 12699 cfg80211_mlme_unregister_socket(wdev, notify->portid);
@@ -12501,6 +12724,12 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
12501 spin_unlock(&rdev->destroy_list_lock); 12724 spin_unlock(&rdev->destroy_list_lock);
12502 schedule_work(&rdev->destroy_work); 12725 schedule_work(&rdev->destroy_work);
12503 } 12726 }
12727 } else if (schedule_scan_stop) {
12728 sched_scan_req->owner_nlportid = 0;
12729
12730 if (rdev->ops->sched_scan_stop &&
12731 rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
12732 schedule_work(&rdev->sched_scan_stop_wk);
12504 } 12733 }
12505 } 12734 }
12506 12735
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 7ad70d6f0cc6..84d4edf1d545 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -17,7 +17,21 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
17 struct net_device *netdev, u32 cmd); 17 struct net_device *netdev, u32 cmd);
18void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, 18void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
19 struct net_device *netdev); 19 struct net_device *netdev);
20void nl80211_send_reg_change_event(struct regulatory_request *request); 20void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
21 struct regulatory_request *request);
22
23static inline void
24nl80211_send_reg_change_event(struct regulatory_request *request)
25{
26 nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
27}
28
29static inline void
30nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
31{
32 nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
33}
34
21void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, 35void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
22 struct net_device *netdev, 36 struct net_device *netdev,
23 const u8 *buf, size_t len, gfp_t gfp); 37 const u8 *buf, size_t len, gfp_t gfp);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 7b8309840d4e..886cc7cb5566 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -109,7 +109,7 @@ static struct regulatory_request core_request_world = {
109 * protected by RTNL (and can be accessed with RCU protection) 109 * protected by RTNL (and can be accessed with RCU protection)
110 */ 110 */
111static struct regulatory_request __rcu *last_request = 111static struct regulatory_request __rcu *last_request =
112 (void __rcu *)&core_request_world; 112 (void __force __rcu *)&core_request_world;
113 113
114/* To trigger userspace events */ 114/* To trigger userspace events */
115static struct platform_device *reg_pdev; 115static struct platform_device *reg_pdev;
@@ -142,7 +142,7 @@ static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
142 return rtnl_dereference(cfg80211_regdomain); 142 return rtnl_dereference(cfg80211_regdomain);
143} 143}
144 144
145static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) 145const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
146{ 146{
147 return rtnl_dereference(wiphy->regd); 147 return rtnl_dereference(wiphy->regd);
148} 148}
@@ -1307,6 +1307,9 @@ static bool ignore_reg_update(struct wiphy *wiphy,
1307{ 1307{
1308 struct regulatory_request *lr = get_last_request(); 1308 struct regulatory_request *lr = get_last_request();
1309 1309
1310 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
1311 return true;
1312
1310 if (!lr) { 1313 if (!lr) {
1311 REG_DBG_PRINT("Ignoring regulatory request set by %s " 1314 REG_DBG_PRINT("Ignoring regulatory request set by %s "
1312 "since last_request is not set\n", 1315 "since last_request is not set\n",
@@ -1683,8 +1686,12 @@ static void handle_channel_custom(struct wiphy *wiphy,
1683 if (IS_ERR(reg_rule)) { 1686 if (IS_ERR(reg_rule)) {
1684 REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", 1687 REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n",
1685 chan->center_freq); 1688 chan->center_freq);
1686 chan->orig_flags |= IEEE80211_CHAN_DISABLED; 1689 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
1687 chan->flags = chan->orig_flags; 1690 chan->flags |= IEEE80211_CHAN_DISABLED;
1691 } else {
1692 chan->orig_flags |= IEEE80211_CHAN_DISABLED;
1693 chan->flags = chan->orig_flags;
1694 }
1688 return; 1695 return;
1689 } 1696 }
1690 1697
@@ -1709,7 +1716,13 @@ static void handle_channel_custom(struct wiphy *wiphy,
1709 chan->dfs_state = NL80211_DFS_USABLE; 1716 chan->dfs_state = NL80211_DFS_USABLE;
1710 1717
1711 chan->beacon_found = false; 1718 chan->beacon_found = false;
1712 chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; 1719
1720 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
1721 chan->flags = chan->orig_flags | bw_flags |
1722 map_regdom_flags(reg_rule->flags);
1723 else
1724 chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
1725
1713 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); 1726 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
1714 chan->max_reg_power = chan->max_power = 1727 chan->max_reg_power = chan->max_power =
1715 (int) MBM_TO_DBM(power_rule->max_eirp); 1728 (int) MBM_TO_DBM(power_rule->max_eirp);
@@ -2095,6 +2108,26 @@ out_free:
2095 reg_free_request(reg_request); 2108 reg_free_request(reg_request);
2096} 2109}
2097 2110
2111static bool reg_only_self_managed_wiphys(void)
2112{
2113 struct cfg80211_registered_device *rdev;
2114 struct wiphy *wiphy;
2115 bool self_managed_found = false;
2116
2117 ASSERT_RTNL();
2118
2119 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2120 wiphy = &rdev->wiphy;
2121 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
2122 self_managed_found = true;
2123 else
2124 return false;
2125 }
2126
2127 /* make sure at least one self-managed wiphy exists */
2128 return self_managed_found;
2129}
2130
2098/* 2131/*
2099 * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* 2132 * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_*
2100 * Regulatory hints come on a first come first serve basis and we 2133 * Regulatory hints come on a first come first serve basis and we
@@ -2126,6 +2159,11 @@ static void reg_process_pending_hints(void)
2126 2159
2127 spin_unlock(&reg_requests_lock); 2160 spin_unlock(&reg_requests_lock);
2128 2161
2162 if (reg_only_self_managed_wiphys()) {
2163 reg_free_request(reg_request);
2164 return;
2165 }
2166
2129 reg_process_hint(reg_request); 2167 reg_process_hint(reg_request);
2130} 2168}
2131 2169
@@ -2153,11 +2191,52 @@ static void reg_process_pending_beacon_hints(void)
2153 spin_unlock_bh(&reg_pending_beacons_lock); 2191 spin_unlock_bh(&reg_pending_beacons_lock);
2154} 2192}
2155 2193
2194static void reg_process_self_managed_hints(void)
2195{
2196 struct cfg80211_registered_device *rdev;
2197 struct wiphy *wiphy;
2198 const struct ieee80211_regdomain *tmp;
2199 const struct ieee80211_regdomain *regd;
2200 enum ieee80211_band band;
2201 struct regulatory_request request = {};
2202
2203 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2204 wiphy = &rdev->wiphy;
2205
2206 spin_lock(&reg_requests_lock);
2207 regd = rdev->requested_regd;
2208 rdev->requested_regd = NULL;
2209 spin_unlock(&reg_requests_lock);
2210
2211 if (regd == NULL)
2212 continue;
2213
2214 tmp = get_wiphy_regdom(wiphy);
2215 rcu_assign_pointer(wiphy->regd, regd);
2216 rcu_free_regdom(tmp);
2217
2218 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
2219 handle_band_custom(wiphy, wiphy->bands[band], regd);
2220
2221 reg_process_ht_flags(wiphy);
2222
2223 request.wiphy_idx = get_wiphy_idx(wiphy);
2224 request.alpha2[0] = regd->alpha2[0];
2225 request.alpha2[1] = regd->alpha2[1];
2226 request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
2227
2228 nl80211_send_wiphy_reg_change_event(&request);
2229 }
2230
2231 reg_check_channels();
2232}
2233
2156static void reg_todo(struct work_struct *work) 2234static void reg_todo(struct work_struct *work)
2157{ 2235{
2158 rtnl_lock(); 2236 rtnl_lock();
2159 reg_process_pending_hints(); 2237 reg_process_pending_hints();
2160 reg_process_pending_beacon_hints(); 2238 reg_process_pending_beacon_hints();
2239 reg_process_self_managed_hints();
2161 rtnl_unlock(); 2240 rtnl_unlock();
2162} 2241}
2163 2242
@@ -2438,6 +2517,8 @@ static void restore_regulatory_settings(bool reset_user)
2438 world_alpha2[1] = cfg80211_world_regdom->alpha2[1]; 2517 world_alpha2[1] = cfg80211_world_regdom->alpha2[1];
2439 2518
2440 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2519 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2520 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
2521 continue;
2441 if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG) 2522 if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG)
2442 restore_custom_reg_settings(&rdev->wiphy); 2523 restore_custom_reg_settings(&rdev->wiphy);
2443 } 2524 }
@@ -2841,10 +2922,79 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2841 return 0; 2922 return 0;
2842} 2923}
2843 2924
2925static int __regulatory_set_wiphy_regd(struct wiphy *wiphy,
2926 struct ieee80211_regdomain *rd)
2927{
2928 const struct ieee80211_regdomain *regd;
2929 const struct ieee80211_regdomain *prev_regd;
2930 struct cfg80211_registered_device *rdev;
2931
2932 if (WARN_ON(!wiphy || !rd))
2933 return -EINVAL;
2934
2935 if (WARN(!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED),
2936 "wiphy should have REGULATORY_WIPHY_SELF_MANAGED\n"))
2937 return -EPERM;
2938
2939 if (WARN(!is_valid_rd(rd), "Invalid regulatory domain detected\n")) {
2940 print_regdomain_info(rd);
2941 return -EINVAL;
2942 }
2943
2944 regd = reg_copy_regd(rd);
2945 if (IS_ERR(regd))
2946 return PTR_ERR(regd);
2947
2948 rdev = wiphy_to_rdev(wiphy);
2949
2950 spin_lock(&reg_requests_lock);
2951 prev_regd = rdev->requested_regd;
2952 rdev->requested_regd = regd;
2953 spin_unlock(&reg_requests_lock);
2954
2955 kfree(prev_regd);
2956 return 0;
2957}
2958
2959int regulatory_set_wiphy_regd(struct wiphy *wiphy,
2960 struct ieee80211_regdomain *rd)
2961{
2962 int ret = __regulatory_set_wiphy_regd(wiphy, rd);
2963
2964 if (ret)
2965 return ret;
2966
2967 schedule_work(&reg_work);
2968 return 0;
2969}
2970EXPORT_SYMBOL(regulatory_set_wiphy_regd);
2971
2972int regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy,
2973 struct ieee80211_regdomain *rd)
2974{
2975 int ret;
2976
2977 ASSERT_RTNL();
2978
2979 ret = __regulatory_set_wiphy_regd(wiphy, rd);
2980 if (ret)
2981 return ret;
2982
2983 /* process the request immediately */
2984 reg_process_self_managed_hints();
2985 return 0;
2986}
2987EXPORT_SYMBOL(regulatory_set_wiphy_regd_sync_rtnl);
2988
2844void wiphy_regulatory_register(struct wiphy *wiphy) 2989void wiphy_regulatory_register(struct wiphy *wiphy)
2845{ 2990{
2846 struct regulatory_request *lr; 2991 struct regulatory_request *lr;
2847 2992
2993 /* self-managed devices ignore external hints */
2994 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
2995 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
2996 REGULATORY_COUNTRY_IE_IGNORE;
2997
2848 if (!reg_dev_ignore_cell_hint(wiphy)) 2998 if (!reg_dev_ignore_cell_hint(wiphy))
2849 reg_num_devs_support_basehint++; 2999 reg_num_devs_support_basehint++;
2850 3000
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 5e48031ccb9a..4b45d6e61d24 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -38,6 +38,7 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
38 const struct ieee80211_reg_rule *rule); 38 const struct ieee80211_reg_rule *rule);
39 39
40bool reg_last_request_cell_base(void); 40bool reg_last_request_cell_base(void);
41const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy);
41 42
42/** 43/**
43 * regulatory_hint_found_beacon - hints a beacon was found on a channel 44 * regulatory_hint_found_beacon - hints a beacon was found on a channel
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index bda39f149810..c705c3e2b751 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -257,7 +257,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
257 257
258 rtnl_lock(); 258 rtnl_lock();
259 259
260 request = rdev->sched_scan_req; 260 request = rtnl_dereference(rdev->sched_scan_req);
261 261
262 /* we don't have sched_scan_req anymore if the scan is stopping */ 262 /* we don't have sched_scan_req anymore if the scan is stopping */
263 if (request) { 263 if (request) {
@@ -279,7 +279,8 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy)
279{ 279{
280 trace_cfg80211_sched_scan_results(wiphy); 280 trace_cfg80211_sched_scan_results(wiphy);
281 /* ignore if we're not scanning */ 281 /* ignore if we're not scanning */
282 if (wiphy_to_rdev(wiphy)->sched_scan_req) 282
283 if (rcu_access_pointer(wiphy_to_rdev(wiphy)->sched_scan_req))
283 queue_work(cfg80211_wq, 284 queue_work(cfg80211_wq,
284 &wiphy_to_rdev(wiphy)->sched_scan_results_wk); 285 &wiphy_to_rdev(wiphy)->sched_scan_results_wk);
285} 286}
@@ -308,6 +309,7 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
308int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 309int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
309 bool driver_initiated) 310 bool driver_initiated)
310{ 311{
312 struct cfg80211_sched_scan_request *sched_scan_req;
311 struct net_device *dev; 313 struct net_device *dev;
312 314
313 ASSERT_RTNL(); 315 ASSERT_RTNL();
@@ -315,7 +317,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
315 if (!rdev->sched_scan_req) 317 if (!rdev->sched_scan_req)
316 return -ENOENT; 318 return -ENOENT;
317 319
318 dev = rdev->sched_scan_req->dev; 320 sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
321 dev = sched_scan_req->dev;
319 322
320 if (!driver_initiated) { 323 if (!driver_initiated) {
321 int err = rdev_sched_scan_stop(rdev, dev); 324 int err = rdev_sched_scan_stop(rdev, dev);
@@ -325,8 +328,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
325 328
326 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); 329 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
327 330
328 kfree(rdev->sched_scan_req); 331 RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
329 rdev->sched_scan_req = NULL; 332 kfree_rcu(sched_scan_req, rcu_head);
330 333
331 return 0; 334 return 0;
332} 335}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ad38910f7036..b17b3692f8c2 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1604,11 +1604,12 @@ TRACE_EVENT(rdev_return_int_survey_info,
1604 WIPHY_ENTRY 1604 WIPHY_ENTRY
1605 CHAN_ENTRY 1605 CHAN_ENTRY
1606 __field(int, ret) 1606 __field(int, ret)
1607 __field(u64, channel_time) 1607 __field(u64, time)
1608 __field(u64, channel_time_busy) 1608 __field(u64, time_busy)
1609 __field(u64, channel_time_ext_busy) 1609 __field(u64, time_ext_busy)
1610 __field(u64, channel_time_rx) 1610 __field(u64, time_rx)
1611 __field(u64, channel_time_tx) 1611 __field(u64, time_tx)
1612 __field(u64, time_scan)
1612 __field(u32, filled) 1613 __field(u32, filled)
1613 __field(s8, noise) 1614 __field(s8, noise)
1614 ), 1615 ),
@@ -1616,22 +1617,24 @@ TRACE_EVENT(rdev_return_int_survey_info,
1616 WIPHY_ASSIGN; 1617 WIPHY_ASSIGN;
1617 CHAN_ASSIGN(info->channel); 1618 CHAN_ASSIGN(info->channel);
1618 __entry->ret = ret; 1619 __entry->ret = ret;
1619 __entry->channel_time = info->channel_time; 1620 __entry->time = info->time;
1620 __entry->channel_time_busy = info->channel_time_busy; 1621 __entry->time_busy = info->time_busy;
1621 __entry->channel_time_ext_busy = info->channel_time_ext_busy; 1622 __entry->time_ext_busy = info->time_ext_busy;
1622 __entry->channel_time_rx = info->channel_time_rx; 1623 __entry->time_rx = info->time_rx;
1623 __entry->channel_time_tx = info->channel_time_tx; 1624 __entry->time_tx = info->time_tx;
1625 __entry->time_scan = info->time_scan;
1624 __entry->filled = info->filled; 1626 __entry->filled = info->filled;
1625 __entry->noise = info->noise; 1627 __entry->noise = info->noise;
1626 ), 1628 ),
1627 TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT 1629 TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT
1628 ", channel time: %llu, channel time busy: %llu, " 1630 ", channel time: %llu, channel time busy: %llu, "
1629 "channel time extension busy: %llu, channel time rx: %llu, " 1631 "channel time extension busy: %llu, channel time rx: %llu, "
1630 "channel time tx: %llu, filled: %u, noise: %d", 1632 "channel time tx: %llu, scan time: %llu, filled: %u, noise: %d",
1631 WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG, 1633 WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG,
1632 __entry->channel_time, __entry->channel_time_busy, 1634 __entry->time, __entry->time_busy,
1633 __entry->channel_time_ext_busy, __entry->channel_time_rx, 1635 __entry->time_ext_busy, __entry->time_rx,
1634 __entry->channel_time_tx, __entry->filled, __entry->noise) 1636 __entry->time_tx, __entry->time_scan,
1637 __entry->filled, __entry->noise)
1635); 1638);
1636 1639
1637TRACE_EVENT(rdev_tdls_oper, 1640TRACE_EVENT(rdev_tdls_oper,
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0f47948c572f..5b24d39d7903 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1300,7 +1300,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
1300 if (err) 1300 if (err)
1301 return err; 1301 return err;
1302 1302
1303 if (!(sinfo.filled & STATION_INFO_TX_BITRATE)) 1303 if (!(sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)))
1304 return -EOPNOTSUPP; 1304 return -EOPNOTSUPP;
1305 1305
1306 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate); 1306 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
@@ -1340,7 +1340,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1340 1340
1341 switch (rdev->wiphy.signal_type) { 1341 switch (rdev->wiphy.signal_type) {
1342 case CFG80211_SIGNAL_TYPE_MBM: 1342 case CFG80211_SIGNAL_TYPE_MBM:
1343 if (sinfo.filled & STATION_INFO_SIGNAL) { 1343 if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) {
1344 int sig = sinfo.signal; 1344 int sig = sinfo.signal;
1345 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; 1345 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
1346 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; 1346 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
@@ -1354,7 +1354,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1354 break; 1354 break;
1355 } 1355 }
1356 case CFG80211_SIGNAL_TYPE_UNSPEC: 1356 case CFG80211_SIGNAL_TYPE_UNSPEC:
1357 if (sinfo.filled & STATION_INFO_SIGNAL) { 1357 if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) {
1358 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; 1358 wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
1359 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; 1359 wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
1360 wstats.qual.level = sinfo.signal; 1360 wstats.qual.level = sinfo.signal;
@@ -1367,9 +1367,9 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1367 } 1367 }
1368 1368
1369 wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1369 wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1370 if (sinfo.filled & STATION_INFO_RX_DROP_MISC) 1370 if (sinfo.filled & BIT(NL80211_STA_INFO_RX_DROP_MISC))
1371 wstats.discard.misc = sinfo.rx_dropped_misc; 1371 wstats.discard.misc = sinfo.rx_dropped_misc;
1372 if (sinfo.filled & STATION_INFO_TX_FAILED) 1372 if (sinfo.filled & BIT(NL80211_STA_INFO_TX_FAILED))
1373 wstats.discard.retries = sinfo.tx_failed; 1373 wstats.discard.retries = sinfo.tx_failed;
1374 1374
1375 return &wstats; 1375 return &wstats;