summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-12-19 11:36:18 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-19 11:36:18 -0500
commit5a862f86b8e86562fc8532160c5530a13e1e944b (patch)
tree0fa13538752825a01dc98c34dc175271c9341815 /net/wireless
parent33f18c96afdf4da20014f834874e2820ee880cde (diff)
parentd359bbce0601c6a19203a4b813a7e3910fcba282 (diff)
Merge tag 'mac80211-next-for-davem-2018-12-19' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== This time we have too many changes to list, highlights: * virt_wifi - wireless control simulation on top of another network interface * hwsim configurability to test capabilities similar to real hardware * various mesh improvements * various radiotap vendor data fixes in mac80211 * finally the nl_set_extack_cookie_u64() we talked about previously, used for * peer measurement APIs, right now only with FTM (flight time measurement) for location * made nl80211 radio/interface announcements more complete * various new HE (802.11ax) things: updates, TWT support, ... ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Makefile1
-rw-r--r--net/wireless/chan.c3
-rw-r--r--net/wireless/core.c48
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/nl80211.c307
-rw-r--r--net/wireless/nl80211.h32
-rw-r--r--net/wireless/pmsr.c590
-rw-r--r--net/wireless/rdev-ops.h25
-rw-r--r--net/wireless/scan.c2
-rw-r--r--net/wireless/trace.h92
-rw-r--r--net/wireless/util.c15
11 files changed, 1065 insertions, 55 deletions
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 1d84f91bbfb0..72a224ce8e0a 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
12 12
13cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 13cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
14cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o 14cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o
15cfg80211-y += pmsr.o
15cfg80211-$(CONFIG_OF) += of.o 16cfg80211-$(CONFIG_OF) += of.o
16cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 17cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
17cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 18cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 2db713d18f71..7dc1bbd0888f 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,6 +6,7 @@
6 * 6 *
7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
8 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 * Copyright 2013-2014 Intel Mobile Communications GmbH
9 * Copyright 2018 Intel Corporation
9 */ 10 */
10 11
11#include <linux/export.h> 12#include <linux/export.h>
@@ -747,6 +748,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
747 case NL80211_CHAN_WIDTH_20: 748 case NL80211_CHAN_WIDTH_20:
748 if (!ht_cap->ht_supported) 749 if (!ht_cap->ht_supported)
749 return false; 750 return false;
751 /* fall through */
750 case NL80211_CHAN_WIDTH_20_NOHT: 752 case NL80211_CHAN_WIDTH_20_NOHT:
751 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ; 753 prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
752 width = 20; 754 width = 20;
@@ -769,6 +771,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
769 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; 771 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
770 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) 772 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
771 return false; 773 return false;
774 /* fall through */
772 case NL80211_CHAN_WIDTH_80: 775 case NL80211_CHAN_WIDTH_80:
773 if (!vht_cap->vht_supported) 776 if (!vht_cap->vht_supported)
774 return false; 777 return false;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 5bd01058b9e6..623dfe5e211c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -4,6 +4,7 @@
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
6 * Copyright 2015-2017 Intel Deutschland GmbH 6 * Copyright 2015-2017 Intel Deutschland GmbH
7 * Copyright (C) 2018 Intel Corporation
7 */ 8 */
8 9
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -190,11 +191,25 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
190 return err; 191 return err;
191 } 192 }
192 193
194 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
195 if (!wdev->netdev)
196 continue;
197 nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);
198 }
199 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
200
193 wiphy_net_set(&rdev->wiphy, net); 201 wiphy_net_set(&rdev->wiphy, net);
194 202
195 err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev)); 203 err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev));
196 WARN_ON(err); 204 WARN_ON(err);
197 205
206 nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
207 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
208 if (!wdev->netdev)
209 continue;
210 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
211 }
212
198 return 0; 213 return 0;
199} 214}
200 215
@@ -664,6 +679,34 @@ int wiphy_register(struct wiphy *wiphy)
664 return -EINVAL; 679 return -EINVAL;
665#endif 680#endif
666 681
682 if (WARN_ON(wiphy->pmsr_capa && !wiphy->pmsr_capa->ftm.supported))
683 return -EINVAL;
684
685 if (wiphy->pmsr_capa && wiphy->pmsr_capa->ftm.supported) {
686 if (WARN_ON(!wiphy->pmsr_capa->ftm.asap &&
687 !wiphy->pmsr_capa->ftm.non_asap))
688 return -EINVAL;
689 if (WARN_ON(!wiphy->pmsr_capa->ftm.preambles ||
690 !wiphy->pmsr_capa->ftm.bandwidths))
691 return -EINVAL;
692 if (WARN_ON(wiphy->pmsr_capa->ftm.preambles &
693 ~(BIT(NL80211_PREAMBLE_LEGACY) |
694 BIT(NL80211_PREAMBLE_HT) |
695 BIT(NL80211_PREAMBLE_VHT) |
696 BIT(NL80211_PREAMBLE_DMG))))
697 return -EINVAL;
698 if (WARN_ON(wiphy->pmsr_capa->ftm.bandwidths &
699 ~(BIT(NL80211_CHAN_WIDTH_20_NOHT) |
700 BIT(NL80211_CHAN_WIDTH_20) |
701 BIT(NL80211_CHAN_WIDTH_40) |
702 BIT(NL80211_CHAN_WIDTH_80) |
703 BIT(NL80211_CHAN_WIDTH_80P80) |
704 BIT(NL80211_CHAN_WIDTH_160) |
705 BIT(NL80211_CHAN_WIDTH_5) |
706 BIT(NL80211_CHAN_WIDTH_10))))
707 return -EINVAL;
708 }
709
667 /* 710 /*
668 * if a wiphy has unsupported modes for regulatory channel enforcement, 711 * if a wiphy has unsupported modes for regulatory channel enforcement,
669 * opt-out of enforcement checking 712 * opt-out of enforcement checking
@@ -1087,6 +1130,8 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
1087 ASSERT_RTNL(); 1130 ASSERT_RTNL();
1088 ASSERT_WDEV_LOCK(wdev); 1131 ASSERT_WDEV_LOCK(wdev);
1089 1132
1133 cfg80211_pmsr_wdev_down(wdev);
1134
1090 switch (wdev->iftype) { 1135 switch (wdev->iftype) {
1091 case NL80211_IFTYPE_ADHOC: 1136 case NL80211_IFTYPE_ADHOC:
1092 __cfg80211_leave_ibss(rdev, dev, true); 1137 __cfg80211_leave_ibss(rdev, dev, true);
@@ -1174,6 +1219,9 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
1174 spin_lock_init(&wdev->event_lock); 1219 spin_lock_init(&wdev->event_lock);
1175 INIT_LIST_HEAD(&wdev->mgmt_registrations); 1220 INIT_LIST_HEAD(&wdev->mgmt_registrations);
1176 spin_lock_init(&wdev->mgmt_registrations_lock); 1221 spin_lock_init(&wdev->mgmt_registrations_lock);
1222 INIT_LIST_HEAD(&wdev->pmsr_list);
1223 spin_lock_init(&wdev->pmsr_lock);
1224 INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
1177 1225
1178 /* 1226 /*
1179 * We get here also when the interface changes network namespaces, 1227 * We get here also when the interface changes network namespaces,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index c61dbba8bf47..c5d6f3418601 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -3,6 +3,7 @@
3 * Wireless configuration interface internals. 3 * Wireless configuration interface internals.
4 * 4 *
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright (C) 2018 Intel Corporation
6 */ 7 */
7#ifndef __NET_WIRELESS_CORE_H 8#ifndef __NET_WIRELESS_CORE_H
8#define __NET_WIRELESS_CORE_H 9#define __NET_WIRELESS_CORE_H
@@ -530,4 +531,8 @@ void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
530 531
531void cfg80211_cqm_config_free(struct wireless_dev *wdev); 532void cfg80211_cqm_config_free(struct wireless_dev *wdev);
532 533
534void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
535void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
536void cfg80211_pmsr_free_wk(struct work_struct *work);
537
533#endif /* __NET_WIRELESS_CORE_H */ 538#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8d763725498c..10ec05589795 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -240,7 +240,63 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
240 .len = U8_MAX }, 240 .len = U8_MAX },
241}; 241};
242 242
243static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { 243static const struct nla_policy
244nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
245 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
246 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
247 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
248 NLA_POLICY_MAX(NLA_U8, 15),
249 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
250 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
251 NLA_POLICY_MAX(NLA_U8, 15),
252 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
253 NLA_POLICY_MAX(NLA_U8, 15),
254 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
255 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
256 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
257};
258
259static const struct nla_policy
260nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
261 [NL80211_PMSR_TYPE_FTM] =
262 NLA_POLICY_NESTED(NL80211_PMSR_FTM_REQ_ATTR_MAX,
263 nl80211_pmsr_ftm_req_attr_policy),
264};
265
266static const struct nla_policy
267nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
268 [NL80211_PMSR_REQ_ATTR_DATA] =
269 NLA_POLICY_NESTED(NL80211_PMSR_TYPE_MAX,
270 nl80211_pmsr_req_data_policy),
271 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
272};
273
274static const struct nla_policy
275nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
276 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
277 /*
278 * we could specify this again to be the top-level policy,
279 * but that would open us up to recursion problems ...
280 */
281 [NL80211_PMSR_PEER_ATTR_CHAN] = { .type = NLA_NESTED },
282 [NL80211_PMSR_PEER_ATTR_REQ] =
283 NLA_POLICY_NESTED(NL80211_PMSR_REQ_ATTR_MAX,
284 nl80211_pmsr_req_attr_policy),
285 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
286};
287
288static const struct nla_policy
289nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
290 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
291 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
292 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
293 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
294 [NL80211_PMSR_ATTR_PEERS] =
295 NLA_POLICY_NESTED_ARRAY(NL80211_PMSR_PEER_ATTR_MAX,
296 nl80211_psmr_peer_attr_policy),
297};
298
299const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
244 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, 300 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
245 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 301 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
246 .len = 20-1 }, 302 .len = 20-1 },
@@ -497,6 +553,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
497 .type = NLA_NESTED, 553 .type = NLA_NESTED,
498 .validation_data = nl80211_ftm_responder_policy, 554 .validation_data = nl80211_ftm_responder_policy,
499 }, 555 },
556 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
557 [NL80211_ATTR_PEER_MEASUREMENTS] =
558 NLA_POLICY_NESTED(NL80211_PMSR_FTM_REQ_ATTR_MAX,
559 nl80211_pmsr_attr_policy),
500}; 560};
501 561
502/* policy for the key attributes */ 562/* policy for the key attributes */
@@ -637,9 +697,9 @@ nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
637 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, 697 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
638}; 698};
639 699
640static int nl80211_prepare_wdev_dump(struct netlink_callback *cb, 700int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
641 struct cfg80211_registered_device **rdev, 701 struct cfg80211_registered_device **rdev,
642 struct wireless_dev **wdev) 702 struct wireless_dev **wdev)
643{ 703{
644 int err; 704 int err;
645 705
@@ -684,8 +744,8 @@ static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
684} 744}
685 745
686/* message building helper */ 746/* message building helper */
687static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq, 747void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
688 int flags, u8 cmd) 748 int flags, u8 cmd)
689{ 749{
690 /* since there is no private header just add the generic one */ 750 /* since there is no private header just add the generic one */
691 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd); 751 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
@@ -1615,6 +1675,91 @@ static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1615 return -ENOBUFS; 1675 return -ENOBUFS;
1616} 1676}
1617 1677
1678static int
1679nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
1680 struct sk_buff *msg)
1681{
1682 struct nlattr *ftm;
1683
1684 if (!cap->ftm.supported)
1685 return 0;
1686
1687 ftm = nla_nest_start(msg, NL80211_PMSR_TYPE_FTM);
1688 if (!ftm)
1689 return -ENOBUFS;
1690
1691 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
1692 return -ENOBUFS;
1693 if (cap->ftm.non_asap &&
1694 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
1695 return -ENOBUFS;
1696 if (cap->ftm.request_lci &&
1697 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
1698 return -ENOBUFS;
1699 if (cap->ftm.request_civicloc &&
1700 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
1701 return -ENOBUFS;
1702 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
1703 cap->ftm.preambles))
1704 return -ENOBUFS;
1705 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
1706 cap->ftm.bandwidths))
1707 return -ENOBUFS;
1708 if (cap->ftm.max_bursts_exponent >= 0 &&
1709 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
1710 cap->ftm.max_bursts_exponent))
1711 return -ENOBUFS;
1712 if (cap->ftm.max_ftms_per_burst &&
1713 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
1714 cap->ftm.max_ftms_per_burst))
1715 return -ENOBUFS;
1716
1717 nla_nest_end(msg, ftm);
1718 return 0;
1719}
1720
1721static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
1722 struct sk_buff *msg)
1723{
1724 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
1725 struct nlattr *pmsr, *caps;
1726
1727 if (!cap)
1728 return 0;
1729
1730 /*
1731 * we don't need to clean up anything here since the caller
1732 * will genlmsg_cancel() if we fail
1733 */
1734
1735 pmsr = nla_nest_start(msg, NL80211_ATTR_PEER_MEASUREMENTS);
1736 if (!pmsr)
1737 return -ENOBUFS;
1738
1739 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
1740 return -ENOBUFS;
1741
1742 if (cap->report_ap_tsf &&
1743 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
1744 return -ENOBUFS;
1745
1746 if (cap->randomize_mac_addr &&
1747 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
1748 return -ENOBUFS;
1749
1750 caps = nla_nest_start(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
1751 if (!caps)
1752 return -ENOBUFS;
1753
1754 if (nl80211_send_pmsr_ftm_capa(cap, msg))
1755 return -ENOBUFS;
1756
1757 nla_nest_end(msg, caps);
1758 nla_nest_end(msg, pmsr);
1759
1760 return 0;
1761}
1762
1618struct nl80211_dump_wiphy_state { 1763struct nl80211_dump_wiphy_state {
1619 s64 filter_wiphy; 1764 s64 filter_wiphy;
1620 long start; 1765 long start;
@@ -1706,6 +1851,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1706 state->split_start++; 1851 state->split_start++;
1707 if (state->split) 1852 if (state->split)
1708 break; 1853 break;
1854 /* fall through */
1709 case 1: 1855 case 1:
1710 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, 1856 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1711 sizeof(u32) * rdev->wiphy.n_cipher_suites, 1857 sizeof(u32) * rdev->wiphy.n_cipher_suites,
@@ -1752,6 +1898,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1752 state->split_start++; 1898 state->split_start++;
1753 if (state->split) 1899 if (state->split)
1754 break; 1900 break;
1901 /* fall through */
1755 case 2: 1902 case 2:
1756 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, 1903 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1757 rdev->wiphy.interface_modes)) 1904 rdev->wiphy.interface_modes))
@@ -1759,6 +1906,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1759 state->split_start++; 1906 state->split_start++;
1760 if (state->split) 1907 if (state->split)
1761 break; 1908 break;
1909 /* fall through */
1762 case 3: 1910 case 3:
1763 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 1911 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1764 if (!nl_bands) 1912 if (!nl_bands)
@@ -1784,6 +1932,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1784 state->chan_start++; 1932 state->chan_start++;
1785 if (state->split) 1933 if (state->split)
1786 break; 1934 break;
1935 /* fall through */
1787 default: 1936 default:
1788 /* add frequencies */ 1937 /* add frequencies */
1789 nl_freqs = nla_nest_start( 1938 nl_freqs = nla_nest_start(
@@ -1837,6 +1986,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1837 state->split_start++; 1986 state->split_start++;
1838 if (state->split) 1987 if (state->split)
1839 break; 1988 break;
1989 /* fall through */
1840 case 4: 1990 case 4:
1841 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); 1991 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1842 if (!nl_cmds) 1992 if (!nl_cmds)
@@ -1863,6 +2013,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1863 state->split_start++; 2013 state->split_start++;
1864 if (state->split) 2014 if (state->split)
1865 break; 2015 break;
2016 /* fall through */
1866 case 5: 2017 case 5:
1867 if (rdev->ops->remain_on_channel && 2018 if (rdev->ops->remain_on_channel &&
1868 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && 2019 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
@@ -1880,6 +2031,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1880 state->split_start++; 2031 state->split_start++;
1881 if (state->split) 2032 if (state->split)
1882 break; 2033 break;
2034 /* fall through */
1883 case 6: 2035 case 6:
1884#ifdef CONFIG_PM 2036#ifdef CONFIG_PM
1885 if (nl80211_send_wowlan(msg, rdev, state->split)) 2037 if (nl80211_send_wowlan(msg, rdev, state->split))
@@ -1890,6 +2042,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1890#else 2042#else
1891 state->split_start++; 2043 state->split_start++;
1892#endif 2044#endif
2045 /* fall through */
1893 case 7: 2046 case 7:
1894 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, 2047 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1895 rdev->wiphy.software_iftypes)) 2048 rdev->wiphy.software_iftypes))
@@ -1902,6 +2055,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
1902 state->split_start++; 2055 state->split_start++;
1903 if (state->split) 2056 if (state->split)
1904 break; 2057 break;
2058 /* fall through */
1905 case 8: 2059 case 8:
1906 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && 2060 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
1907 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, 2061 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
@@ -2118,6 +2272,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
2118 goto nla_put_failure; 2272 goto nla_put_failure;
2119 } 2273 }
2120 2274
2275 state->split_start++;
2276 break;
2277 case 14:
2278 if (nl80211_send_pmsr_capa(rdev, msg))
2279 goto nla_put_failure;
2280
2121 /* done */ 2281 /* done */
2122 state->split_start = 0; 2282 state->split_start = 0;
2123 break; 2283 break;
@@ -2318,9 +2478,9 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2318 wdev->iftype == NL80211_IFTYPE_P2P_GO; 2478 wdev->iftype == NL80211_IFTYPE_P2P_GO;
2319} 2479}
2320 2480
2321static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, 2481int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2322 struct genl_info *info, 2482 struct genl_info *info,
2323 struct cfg80211_chan_def *chandef) 2483 struct cfg80211_chan_def *chandef)
2324{ 2484{
2325 struct netlink_ext_ack *extack = info->extack; 2485 struct netlink_ext_ack *extack = info->extack;
2326 struct nlattr **attrs = info->attrs; 2486 struct nlattr **attrs = info->attrs;
@@ -2794,12 +2954,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2794 return 0; 2954 return 0;
2795} 2955}
2796 2956
2797static inline u64 wdev_id(struct wireless_dev *wdev)
2798{
2799 return (u64)wdev->identifier |
2800 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
2801}
2802
2803static int nl80211_send_chandef(struct sk_buff *msg, 2957static int nl80211_send_chandef(struct sk_buff *msg,
2804 const struct cfg80211_chan_def *chandef) 2958 const struct cfg80211_chan_def *chandef)
2805{ 2959{
@@ -2832,14 +2986,15 @@ static int nl80211_send_chandef(struct sk_buff *msg,
2832 2986
2833static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 2987static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
2834 struct cfg80211_registered_device *rdev, 2988 struct cfg80211_registered_device *rdev,
2835 struct wireless_dev *wdev, bool removal) 2989 struct wireless_dev *wdev,
2990 enum nl80211_commands cmd)
2836{ 2991{
2837 struct net_device *dev = wdev->netdev; 2992 struct net_device *dev = wdev->netdev;
2838 u8 cmd = NL80211_CMD_NEW_INTERFACE;
2839 void *hdr; 2993 void *hdr;
2840 2994
2841 if (removal) 2995 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
2842 cmd = NL80211_CMD_DEL_INTERFACE; 2996 cmd != NL80211_CMD_DEL_INTERFACE &&
2997 cmd != NL80211_CMD_SET_INTERFACE);
2843 2998
2844 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); 2999 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2845 if (!hdr) 3000 if (!hdr)
@@ -2987,7 +3142,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2987 } 3142 }
2988 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, 3143 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
2989 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3144 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2990 rdev, wdev, false) < 0) { 3145 rdev, wdev,
3146 NL80211_CMD_NEW_INTERFACE) < 0) {
2991 goto out; 3147 goto out;
2992 } 3148 }
2993 if_idx++; 3149 if_idx++;
@@ -3017,7 +3173,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3017 return -ENOMEM; 3173 return -ENOMEM;
3018 3174
3019 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, 3175 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3020 rdev, wdev, false) < 0) { 3176 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
3021 nlmsg_free(msg); 3177 nlmsg_free(msg);
3022 return -ENOBUFS; 3178 return -ENOBUFS;
3023 } 3179 }
@@ -3207,6 +3363,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3207 if (!err && params.use_4addr != -1) 3363 if (!err && params.use_4addr != -1)
3208 dev->ieee80211_ptr->use_4addr = params.use_4addr; 3364 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3209 3365
3366 if (change && !err) {
3367 struct wireless_dev *wdev = dev->ieee80211_ptr;
3368
3369 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
3370 }
3371
3210 return err; 3372 return err;
3211} 3373}
3212 3374
@@ -3298,7 +3460,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3298 } 3460 }
3299 3461
3300 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, 3462 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3301 rdev, wdev, false) < 0) { 3463 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
3302 nlmsg_free(msg); 3464 nlmsg_free(msg);
3303 return -ENOBUFS; 3465 return -ENOBUFS;
3304 } 3466 }
@@ -4521,8 +4683,7 @@ static int parse_station_flags(struct genl_info *info,
4521 return 0; 4683 return 0;
4522} 4684}
4523 4685
4524static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, 4686bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
4525 int attr)
4526{ 4687{
4527 struct nlattr *rate; 4688 struct nlattr *rate;
4528 u32 bitrate; 4689 u32 bitrate;
@@ -4731,6 +4892,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4731 PUT_SINFO(LOCAL_PM, local_pm, u32); 4892 PUT_SINFO(LOCAL_PM, local_pm, u32);
4732 PUT_SINFO(PEER_PM, peer_pm, u32); 4893 PUT_SINFO(PEER_PM, peer_pm, u32);
4733 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32); 4894 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4895 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
4734 4896
4735 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) { 4897 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
4736 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); 4898 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
@@ -6122,7 +6284,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
6122 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW, 6284 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
6123 cur_params.dot11MeshAwakeWindowDuration) || 6285 cur_params.dot11MeshAwakeWindowDuration) ||
6124 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT, 6286 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
6125 cur_params.plink_timeout)) 6287 cur_params.plink_timeout) ||
6288 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
6289 cur_params.dot11MeshConnectedToMeshGate))
6126 goto nla_put_failure; 6290 goto nla_put_failure;
6127 nla_nest_end(msg, pinfoattr); 6291 nla_nest_end(msg, pinfoattr);
6128 genlmsg_end(msg, hdr); 6292 genlmsg_end(msg, hdr);
@@ -6179,6 +6343,7 @@ nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
6179 NL80211_MESH_POWER_MAX), 6343 NL80211_MESH_POWER_MAX),
6180 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, 6344 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
6181 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 }, 6345 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
6346 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
6182}; 6347};
6183 6348
6184static const struct nla_policy 6349static const struct nla_policy
@@ -6290,6 +6455,9 @@ do { \
6290 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask, 6455 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
6291 NL80211_MESHCONF_RSSI_THRESHOLD, 6456 NL80211_MESHCONF_RSSI_THRESHOLD,
6292 nla_get_s32); 6457 nla_get_s32);
6458 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
6459 NL80211_MESHCONF_CONNECTED_TO_GATE,
6460 nla_get_u8);
6293 /* 6461 /*
6294 * Check HT operation mode based on 6462 * Check HT operation mode based on
6295 * IEEE 802.11-2016 9.4.2.57 HT Operation element. 6463 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
@@ -6855,8 +7023,8 @@ static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6855 return 0; 7023 return 0;
6856} 7024}
6857 7025
6858static int nl80211_parse_random_mac(struct nlattr **attrs, 7026int nl80211_parse_random_mac(struct nlattr **attrs,
6859 u8 *mac_addr, u8 *mac_addr_mask) 7027 u8 *mac_addr, u8 *mac_addr_mask)
6860{ 7028{
6861 int i; 7029 int i;
6862 7030
@@ -7822,6 +7990,60 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
7822 return err; 7990 return err;
7823} 7991}
7824 7992
7993static int nl80211_notify_radar_detection(struct sk_buff *skb,
7994 struct genl_info *info)
7995{
7996 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7997 struct net_device *dev = info->user_ptr[1];
7998 struct wireless_dev *wdev = dev->ieee80211_ptr;
7999 struct wiphy *wiphy = wdev->wiphy;
8000 struct cfg80211_chan_def chandef;
8001 enum nl80211_dfs_regions dfs_region;
8002 int err;
8003
8004 dfs_region = reg_get_dfs_region(wiphy);
8005 if (dfs_region == NL80211_DFS_UNSET) {
8006 GENL_SET_ERR_MSG(info,
8007 "DFS Region is not set. Unexpected Radar indication");
8008 return -EINVAL;
8009 }
8010
8011 err = nl80211_parse_chandef(rdev, info, &chandef);
8012 if (err) {
8013 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
8014 return err;
8015 }
8016
8017 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
8018 if (err < 0) {
8019 GENL_SET_ERR_MSG(info, "chandef is invalid");
8020 return err;
8021 }
8022
8023 if (err == 0) {
8024 GENL_SET_ERR_MSG(info,
8025 "Unexpected Radar indication for chandef/iftype");
8026 return -EINVAL;
8027 }
8028
8029 /* Do not process this notification if radar is already detected
8030 * by kernel on this channel, and return success.
8031 */
8032 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
8033 return 0;
8034
8035 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
8036
8037 cfg80211_sched_dfs_chan_update(rdev);
8038
8039 memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
8040
8041 /* Propagate this notification to other radios as well */
8042 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
8043
8044 return 0;
8045}
8046
7825static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) 8047static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7826{ 8048{
7827 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8049 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -13899,6 +14121,22 @@ static const struct genl_ops nl80211_ops[] = {
13899 .internal_flags = NL80211_FLAG_NEED_NETDEV | 14121 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13900 NL80211_FLAG_NEED_RTNL, 14122 NL80211_FLAG_NEED_RTNL,
13901 }, 14123 },
14124 {
14125 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
14126 .doit = nl80211_pmsr_start,
14127 .policy = nl80211_policy,
14128 .flags = GENL_UNS_ADMIN_PERM,
14129 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14130 NL80211_FLAG_NEED_RTNL,
14131 },
14132 {
14133 .cmd = NL80211_CMD_NOTIFY_RADAR,
14134 .doit = nl80211_notify_radar_detection,
14135 .policy = nl80211_policy,
14136 .flags = GENL_UNS_ADMIN_PERM,
14137 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14138 NL80211_FLAG_NEED_RTNL,
14139 },
13902}; 14140};
13903 14141
13904static struct genl_family nl80211_fam __ro_after_init = { 14142static struct genl_family nl80211_fam __ro_after_init = {
@@ -13946,15 +14184,11 @@ void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
13946{ 14184{
13947 struct sk_buff *msg; 14185 struct sk_buff *msg;
13948 14186
13949 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
13950 cmd != NL80211_CMD_DEL_INTERFACE);
13951
13952 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 14187 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13953 if (!msg) 14188 if (!msg)
13954 return; 14189 return;
13955 14190
13956 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, 14191 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
13957 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
13958 nlmsg_free(msg); 14192 nlmsg_free(msg);
13959 return; 14193 return;
13960 } 14194 }
@@ -14573,7 +14807,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
14573} 14807}
14574 14808
14575void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, 14809void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14576 const u8* ie, u8 ie_len, gfp_t gfp) 14810 const u8 *ie, u8 ie_len,
14811 int sig_dbm, gfp_t gfp)
14577{ 14812{
14578 struct wireless_dev *wdev = dev->ieee80211_ptr; 14813 struct wireless_dev *wdev = dev->ieee80211_ptr;
14579 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 14814 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -14599,7 +14834,9 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14599 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || 14834 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14600 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || 14835 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
14601 (ie_len && ie && 14836 (ie_len && ie &&
14602 nla_put(msg, NL80211_ATTR_IE, ie_len , ie))) 14837 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
14838 (sig_dbm &&
14839 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
14603 goto nla_put_failure; 14840 goto nla_put_failure;
14604 14841
14605 genlmsg_end(msg, hdr); 14842 genlmsg_end(msg, hdr);
@@ -15882,6 +16119,8 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
15882 } else if (wdev->conn_owner_nlportid == notify->portid) { 16119 } else if (wdev->conn_owner_nlportid == notify->portid) {
15883 schedule_work(&wdev->disconnect_wk); 16120 schedule_work(&wdev->disconnect_wk);
15884 } 16121 }
16122
16123 cfg80211_release_pmsr(wdev, notify->portid);
15885 } 16124 }
15886 16125
15887 spin_lock_bh(&rdev->beacon_registrations_lock); 16126 spin_lock_bh(&rdev->beacon_registrations_lock);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 79e47fe60c35..531c82dcba6b 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -1,4 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Portions of this file
4 * Copyright (C) 2018 Intel Corporation
5 */
2#ifndef __NET_WIRELESS_NL80211_H 6#ifndef __NET_WIRELESS_NL80211_H
3#define __NET_WIRELESS_NL80211_H 7#define __NET_WIRELESS_NL80211_H
4 8
@@ -6,6 +10,30 @@
6 10
7int nl80211_init(void); 11int nl80211_init(void);
8void nl80211_exit(void); 12void nl80211_exit(void);
13
14extern const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
15
16void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
17 int flags, u8 cmd);
18bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
19 int attr);
20
21static inline u64 wdev_id(struct wireless_dev *wdev)
22{
23 return (u64)wdev->identifier |
24 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
25}
26
27int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
28 struct cfg80211_registered_device **rdev,
29 struct wireless_dev **wdev);
30
31int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
32 struct genl_info *info,
33 struct cfg80211_chan_def *chandef);
34int nl80211_parse_random_mac(struct nlattr **attrs,
35 u8 *mac_addr, u8 *mac_addr_mask);
36
9void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, 37void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
10 enum nl80211_commands cmd); 38 enum nl80211_commands cmd);
11void nl80211_notify_iface(struct cfg80211_registered_device *rdev, 39void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
@@ -95,4 +123,8 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev);
95 123
96void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev); 124void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
97 125
126/* peer measurement */
127int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info);
128int nl80211_pmsr_dump_results(struct sk_buff *skb, struct netlink_callback *cb);
129
98#endif /* __NET_WIRELESS_NL80211_H */ 130#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
new file mode 100644
index 000000000000..de9286703280
--- /dev/null
+++ b/net/wireless/pmsr.c
@@ -0,0 +1,590 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018 Intel Corporation
4 */
5#ifndef __PMSR_H
6#define __PMSR_H
7#include <net/cfg80211.h>
8#include "core.h"
9#include "nl80211.h"
10#include "rdev-ops.h"
11
12static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
13 struct nlattr *ftmreq,
14 struct cfg80211_pmsr_request_peer *out,
15 struct genl_info *info)
16{
17 const struct cfg80211_pmsr_capabilities *capa = rdev->wiphy.pmsr_capa;
18 struct nlattr *tb[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1];
19 u32 preamble = NL80211_PREAMBLE_DMG; /* only optional in DMG */
20
21 /* validate existing data */
22 if (!(rdev->wiphy.pmsr_capa->ftm.bandwidths & BIT(out->chandef.width))) {
23 NL_SET_ERR_MSG(info->extack, "FTM: unsupported bandwidth");
24 return -EINVAL;
25 }
26
27 /* no validation needed - was already done via nested policy */
28 nla_parse_nested(tb, NL80211_PMSR_FTM_REQ_ATTR_MAX, ftmreq, NULL, NULL);
29
30 if (tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE])
31 preamble = nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]);
32
33 /* set up values - struct is 0-initialized */
34 out->ftm.requested = true;
35
36 switch (out->chandef.chan->band) {
37 case NL80211_BAND_60GHZ:
38 /* optional */
39 break;
40 default:
41 if (!tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]) {
42 NL_SET_ERR_MSG(info->extack,
43 "FTM: must specify preamble");
44 return -EINVAL;
45 }
46 }
47
48 if (!(capa->ftm.preambles & BIT(preamble))) {
49 NL_SET_ERR_MSG_ATTR(info->extack,
50 tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE],
51 "FTM: invalid preamble");
52 return -EINVAL;
53 }
54
55 out->ftm.preamble = preamble;
56
57 out->ftm.burst_period = 0;
58 if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD])
59 out->ftm.burst_period =
60 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]);
61
62 out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP];
63 if (out->ftm.asap && !capa->ftm.asap) {
64 NL_SET_ERR_MSG_ATTR(info->extack,
65 tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP],
66 "FTM: ASAP mode not supported");
67 return -EINVAL;
68 }
69
70 if (!out->ftm.asap && !capa->ftm.non_asap) {
71 NL_SET_ERR_MSG(info->extack,
72 "FTM: non-ASAP mode not supported");
73 return -EINVAL;
74 }
75
76 out->ftm.num_bursts_exp = 0;
77 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP])
78 out->ftm.num_bursts_exp =
79 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]);
80
81 if (capa->ftm.max_bursts_exponent >= 0 &&
82 out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) {
83 NL_SET_ERR_MSG_ATTR(info->extack,
84 tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP],
85 "FTM: max NUM_BURSTS_EXP must be set lower than the device limit");
86 return -EINVAL;
87 }
88
89 out->ftm.burst_duration = 15;
90 if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION])
91 out->ftm.burst_duration =
92 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]);
93
94 out->ftm.ftms_per_burst = 0;
95 if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST])
96 out->ftm.ftms_per_burst =
97 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);
98
99 if (capa->ftm.max_ftms_per_burst &&
100 (out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst ||
101 out->ftm.ftms_per_burst == 0)) {
102 NL_SET_ERR_MSG_ATTR(info->extack,
103 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
104 "FTM: FTMs per burst must be set lower than the device limit but non-zero");
105 return -EINVAL;
106 }
107
108 out->ftm.ftmr_retries = 3;
109 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES])
110 out->ftm.ftmr_retries =
111 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]);
112
113 out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI];
114 if (out->ftm.request_lci && !capa->ftm.request_lci) {
115 NL_SET_ERR_MSG_ATTR(info->extack,
116 tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
117 "FTM: LCI request not supported");
118 }
119
120 out->ftm.request_civicloc =
121 !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC];
122 if (out->ftm.request_civicloc && !capa->ftm.request_civicloc) {
123 NL_SET_ERR_MSG_ATTR(info->extack,
124 tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
125 "FTM: civic location request not supported");
126 }
127
128 return 0;
129}
130
131static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
132 struct nlattr *peer,
133 struct cfg80211_pmsr_request_peer *out,
134 struct genl_info *info)
135{
136 struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
137 struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
138 struct nlattr *treq;
139 int err, rem;
140
141 /* no validation needed - was already done via nested policy */
142 nla_parse_nested(tb, NL80211_PMSR_PEER_ATTR_MAX, peer, NULL, NULL);
143
144 if (!tb[NL80211_PMSR_PEER_ATTR_ADDR] ||
145 !tb[NL80211_PMSR_PEER_ATTR_CHAN] ||
146 !tb[NL80211_PMSR_PEER_ATTR_REQ]) {
147 NL_SET_ERR_MSG_ATTR(info->extack, peer,
148 "insufficient peer data");
149 return -EINVAL;
150 }
151
152 memcpy(out->addr, nla_data(tb[NL80211_PMSR_PEER_ATTR_ADDR]), ETH_ALEN);
153
154 /* reuse info->attrs */
155 memset(info->attrs, 0, sizeof(*info->attrs) * (NL80211_ATTR_MAX + 1));
156 /* need to validate here, we don't want to have validation recursion */
157 err = nla_parse_nested(info->attrs, NL80211_ATTR_MAX,
158 tb[NL80211_PMSR_PEER_ATTR_CHAN],
159 nl80211_policy, info->extack);
160 if (err)
161 return err;
162
163 err = nl80211_parse_chandef(rdev, info, &out->chandef);
164 if (err)
165 return err;
166
167 /* no validation needed - was already done via nested policy */
168 nla_parse_nested(req, NL80211_PMSR_REQ_ATTR_MAX,
169 tb[NL80211_PMSR_PEER_ATTR_REQ],
170 NULL, NULL);
171
172 if (!req[NL80211_PMSR_REQ_ATTR_DATA]) {
173 NL_SET_ERR_MSG_ATTR(info->extack,
174 tb[NL80211_PMSR_PEER_ATTR_REQ],
175 "missing request type/data");
176 return -EINVAL;
177 }
178
179 if (req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF])
180 out->report_ap_tsf = true;
181
182 if (out->report_ap_tsf && !rdev->wiphy.pmsr_capa->report_ap_tsf) {
183 NL_SET_ERR_MSG_ATTR(info->extack,
184 req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF],
185 "reporting AP TSF is not supported");
186 return -EINVAL;
187 }
188
189 nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
190 switch (nla_type(treq)) {
191 case NL80211_PMSR_TYPE_FTM:
192 err = pmsr_parse_ftm(rdev, treq, out, info);
193 break;
194 default:
195 NL_SET_ERR_MSG_ATTR(info->extack, treq,
196 "unsupported measurement type");
197 err = -EINVAL;
198 }
199 }
200
201 if (err)
202 return err;
203
204 return 0;
205}
206
207int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
208{
209 struct nlattr *reqattr = info->attrs[NL80211_ATTR_PEER_MEASUREMENTS];
210 struct cfg80211_registered_device *rdev = info->user_ptr[0];
211 struct wireless_dev *wdev = info->user_ptr[1];
212 struct cfg80211_pmsr_request *req;
213 struct nlattr *peers, *peer;
214 int count, rem, err, idx;
215
216 if (!rdev->wiphy.pmsr_capa)
217 return -EOPNOTSUPP;
218
219 if (!reqattr)
220 return -EINVAL;
221
222 peers = nla_find(nla_data(reqattr), nla_len(reqattr),
223 NL80211_PMSR_ATTR_PEERS);
224 if (!peers)
225 return -EINVAL;
226
227 count = 0;
228 nla_for_each_nested(peer, peers, rem) {
229 count++;
230
231 if (count > rdev->wiphy.pmsr_capa->max_peers) {
232 NL_SET_ERR_MSG_ATTR(info->extack, peer,
233 "Too many peers used");
234 return -EINVAL;
235 }
236 }
237
238 req = kzalloc(struct_size(req, peers, count), GFP_KERNEL);
239 if (!req)
240 return -ENOMEM;
241
242 if (info->attrs[NL80211_ATTR_TIMEOUT])
243 req->timeout = nla_get_u32(info->attrs[NL80211_ATTR_TIMEOUT]);
244
245 if (info->attrs[NL80211_ATTR_MAC]) {
246 if (!rdev->wiphy.pmsr_capa->randomize_mac_addr) {
247 NL_SET_ERR_MSG_ATTR(info->extack,
248 info->attrs[NL80211_ATTR_MAC],
249 "device cannot randomize MAC address");
250 err = -EINVAL;
251 goto out_err;
252 }
253
254 err = nl80211_parse_random_mac(info->attrs, req->mac_addr,
255 req->mac_addr_mask);
256 if (err)
257 goto out_err;
258 } else {
259 memcpy(req->mac_addr, nla_data(info->attrs[NL80211_ATTR_MAC]),
260 ETH_ALEN);
261 memset(req->mac_addr_mask, 0xff, ETH_ALEN);
262 }
263
264 idx = 0;
265 nla_for_each_nested(peer, peers, rem) {
266 /* NB: this reuses info->attrs, but we no longer need it */
267 err = pmsr_parse_peer(rdev, peer, &req->peers[idx], info);
268 if (err)
269 goto out_err;
270 idx++;
271 }
272
273 req->n_peers = count;
274 req->cookie = cfg80211_assign_cookie(rdev);
275
276 err = rdev_start_pmsr(rdev, wdev, req);
277 if (err)
278 goto out_err;
279
280 list_add_tail(&req->list, &wdev->pmsr_list);
281
282 nl_set_extack_cookie_u64(info->extack, req->cookie);
283 return 0;
284out_err:
285 kfree(req);
286 return err;
287}
288
289void cfg80211_pmsr_complete(struct wireless_dev *wdev,
290 struct cfg80211_pmsr_request *req,
291 gfp_t gfp)
292{
293 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
294 struct sk_buff *msg;
295 void *hdr;
296
297 trace_cfg80211_pmsr_complete(wdev->wiphy, wdev, req->cookie);
298
299 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
300 if (!msg)
301 goto free_request;
302
303 hdr = nl80211hdr_put(msg, 0, 0, 0,
304 NL80211_CMD_PEER_MEASUREMENT_COMPLETE);
305 if (!hdr)
306 goto free_msg;
307
308 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
309 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
310 NL80211_ATTR_PAD))
311 goto free_msg;
312
313 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie,
314 NL80211_ATTR_PAD))
315 goto free_msg;
316
317 genlmsg_end(msg, hdr);
318 genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid);
319 goto free_request;
320free_msg:
321 nlmsg_free(msg);
322free_request:
323 spin_lock_bh(&wdev->pmsr_lock);
324 list_del(&req->list);
325 spin_unlock_bh(&wdev->pmsr_lock);
326 kfree(req);
327}
328EXPORT_SYMBOL_GPL(cfg80211_pmsr_complete);
329
330static int nl80211_pmsr_send_ftm_res(struct sk_buff *msg,
331 struct cfg80211_pmsr_result *res)
332{
333 if (res->status == NL80211_PMSR_STATUS_FAILURE) {
334 if (nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_FAIL_REASON,
335 res->ftm.failure_reason))
336 goto error;
337
338 if (res->ftm.failure_reason ==
339 NL80211_PMSR_FTM_FAILURE_PEER_BUSY &&
340 res->ftm.busy_retry_time &&
341 nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME,
342 res->ftm.busy_retry_time))
343 goto error;
344
345 return 0;
346 }
347
348#define PUT(tp, attr, val) \
349 do { \
350 if (nla_put_##tp(msg, \
351 NL80211_PMSR_FTM_RESP_ATTR_##attr, \
352 res->ftm.val)) \
353 goto error; \
354 } while (0)
355
356#define PUTOPT(tp, attr, val) \
357 do { \
358 if (res->ftm.val##_valid) \
359 PUT(tp, attr, val); \
360 } while (0)
361
362#define PUT_U64(attr, val) \
363 do { \
364 if (nla_put_u64_64bit(msg, \
365 NL80211_PMSR_FTM_RESP_ATTR_##attr,\
366 res->ftm.val, \
367 NL80211_PMSR_FTM_RESP_ATTR_PAD)) \
368 goto error; \
369 } while (0)
370
371#define PUTOPT_U64(attr, val) \
372 do { \
373 if (res->ftm.val##_valid) \
374 PUT_U64(attr, val); \
375 } while (0)
376
377 if (res->ftm.burst_index >= 0)
378 PUT(u32, BURST_INDEX, burst_index);
379 PUTOPT(u32, NUM_FTMR_ATTEMPTS, num_ftmr_attempts);
380 PUTOPT(u32, NUM_FTMR_SUCCESSES, num_ftmr_successes);
381 PUT(u8, NUM_BURSTS_EXP, num_bursts_exp);
382 PUT(u8, BURST_DURATION, burst_duration);
383 PUT(u8, FTMS_PER_BURST, ftms_per_burst);
384 PUTOPT(s32, RSSI_AVG, rssi_avg);
385 PUTOPT(s32, RSSI_SPREAD, rssi_spread);
386 if (res->ftm.tx_rate_valid &&
387 !nl80211_put_sta_rate(msg, &res->ftm.tx_rate,
388 NL80211_PMSR_FTM_RESP_ATTR_TX_RATE))
389 goto error;
390 if (res->ftm.rx_rate_valid &&
391 !nl80211_put_sta_rate(msg, &res->ftm.rx_rate,
392 NL80211_PMSR_FTM_RESP_ATTR_RX_RATE))
393 goto error;
394 PUTOPT_U64(RTT_AVG, rtt_avg);
395 PUTOPT_U64(RTT_VARIANCE, rtt_variance);
396 PUTOPT_U64(RTT_SPREAD, rtt_spread);
397 PUTOPT_U64(DIST_AVG, dist_avg);
398 PUTOPT_U64(DIST_VARIANCE, dist_variance);
399 PUTOPT_U64(DIST_SPREAD, dist_spread);
400 if (res->ftm.lci && res->ftm.lci_len &&
401 nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_LCI,
402 res->ftm.lci_len, res->ftm.lci))
403 goto error;
404 if (res->ftm.civicloc && res->ftm.civicloc_len &&
405 nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC,
406 res->ftm.civicloc_len, res->ftm.civicloc))
407 goto error;
408#undef PUT
409#undef PUTOPT
410#undef PUT_U64
411#undef PUTOPT_U64
412
413 return 0;
414error:
415 return -ENOSPC;
416}
417
418static int nl80211_pmsr_send_result(struct sk_buff *msg,
419 struct cfg80211_pmsr_result *res)
420{
421 struct nlattr *pmsr, *peers, *peer, *resp, *data, *typedata;
422
423 pmsr = nla_nest_start(msg, NL80211_ATTR_PEER_MEASUREMENTS);
424 if (!pmsr)
425 goto error;
426
427 peers = nla_nest_start(msg, NL80211_PMSR_ATTR_PEERS);
428 if (!peers)
429 goto error;
430
431 peer = nla_nest_start(msg, 1);
432 if (!peer)
433 goto error;
434
435 if (nla_put(msg, NL80211_PMSR_PEER_ATTR_ADDR, ETH_ALEN, res->addr))
436 goto error;
437
438 resp = nla_nest_start(msg, NL80211_PMSR_PEER_ATTR_RESP);
439 if (!resp)
440 goto error;
441
442 if (nla_put_u32(msg, NL80211_PMSR_RESP_ATTR_STATUS, res->status) ||
443 nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_HOST_TIME,
444 res->host_time, NL80211_PMSR_RESP_ATTR_PAD))
445 goto error;
446
447 if (res->ap_tsf_valid &&
448 nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_AP_TSF,
449 res->host_time, NL80211_PMSR_RESP_ATTR_PAD))
450 goto error;
451
452 if (res->final && nla_put_flag(msg, NL80211_PMSR_RESP_ATTR_FINAL))
453 goto error;
454
455 data = nla_nest_start(msg, NL80211_PMSR_RESP_ATTR_DATA);
456 if (!data)
457 goto error;
458
459 typedata = nla_nest_start(msg, res->type);
460 if (!typedata)
461 goto error;
462
463 switch (res->type) {
464 case NL80211_PMSR_TYPE_FTM:
465 if (nl80211_pmsr_send_ftm_res(msg, res))
466 goto error;
467 break;
468 default:
469 WARN_ON(1);
470 }
471
472 nla_nest_end(msg, typedata);
473 nla_nest_end(msg, data);
474 nla_nest_end(msg, resp);
475 nla_nest_end(msg, peer);
476 nla_nest_end(msg, peers);
477 nla_nest_end(msg, pmsr);
478
479 return 0;
480error:
481 return -ENOSPC;
482}
483
484void cfg80211_pmsr_report(struct wireless_dev *wdev,
485 struct cfg80211_pmsr_request *req,
486 struct cfg80211_pmsr_result *result,
487 gfp_t gfp)
488{
489 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
490 struct sk_buff *msg;
491 void *hdr;
492 int err;
493
494 trace_cfg80211_pmsr_report(wdev->wiphy, wdev, req->cookie,
495 result->addr);
496
497 /*
498 * Currently, only variable items are LCI and civic location,
499 * both of which are reasonably short so we don't need to
500 * worry about them here for the allocation.
501 */
502 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
503 if (!msg)
504 return;
505
506 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PEER_MEASUREMENT_RESULT);
507 if (!hdr)
508 goto free;
509
510 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
511 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
512 NL80211_ATTR_PAD))
513 goto free;
514
515 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie,
516 NL80211_ATTR_PAD))
517 goto free;
518
519 err = nl80211_pmsr_send_result(msg, result);
520 if (err) {
521 pr_err_ratelimited("peer measurement result: message didn't fit!");
522 goto free;
523 }
524
525 genlmsg_end(msg, hdr);
526 genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid);
527 return;
528free:
529 nlmsg_free(msg);
530}
531EXPORT_SYMBOL_GPL(cfg80211_pmsr_report);
532
533void cfg80211_pmsr_free_wk(struct work_struct *work)
534{
535 struct wireless_dev *wdev = container_of(work, struct wireless_dev,
536 pmsr_free_wk);
537 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
538 struct cfg80211_pmsr_request *req, *tmp;
539 LIST_HEAD(free_list);
540
541 spin_lock_bh(&wdev->pmsr_lock);
542 list_for_each_entry_safe(req, tmp, &wdev->pmsr_list, list) {
543 if (req->nl_portid)
544 continue;
545 list_move_tail(&req->list, &free_list);
546 }
547 spin_unlock_bh(&wdev->pmsr_lock);
548
549 list_for_each_entry_safe(req, tmp, &free_list, list) {
550 wdev_lock(wdev);
551 rdev_abort_pmsr(rdev, wdev, req);
552 wdev_unlock(wdev);
553
554 kfree(req);
555 }
556}
557
558void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
559{
560 struct cfg80211_pmsr_request *req;
561 bool found = false;
562
563 spin_lock_bh(&wdev->pmsr_lock);
564 list_for_each_entry(req, &wdev->pmsr_list, list) {
565 found = true;
566 req->nl_portid = 0;
567 }
568 spin_unlock_bh(&wdev->pmsr_lock);
569
570 if (found)
571 schedule_work(&wdev->pmsr_free_wk);
572 flush_work(&wdev->pmsr_free_wk);
573 WARN_ON(!list_empty(&wdev->pmsr_list));
574}
575
576void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
577{
578 struct cfg80211_pmsr_request *req;
579
580 spin_lock_bh(&wdev->pmsr_lock);
581 list_for_each_entry(req, &wdev->pmsr_list, list) {
582 if (req->nl_portid == portid) {
583 req->nl_portid = 0;
584 schedule_work(&wdev->pmsr_free_wk);
585 }
586 }
587 spin_unlock_bh(&wdev->pmsr_lock);
588}
589
590#endif /* __PMSR_H */
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 51380b5c32f2..5cb48d135fab 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1247,4 +1247,29 @@ rdev_get_ftm_responder_stats(struct cfg80211_registered_device *rdev,
1247 return ret; 1247 return ret;
1248} 1248}
1249 1249
1250static inline int
1251rdev_start_pmsr(struct cfg80211_registered_device *rdev,
1252 struct wireless_dev *wdev,
1253 struct cfg80211_pmsr_request *request)
1254{
1255 int ret = -EOPNOTSUPP;
1256
1257 trace_rdev_start_pmsr(&rdev->wiphy, wdev, request->cookie);
1258 if (rdev->ops->start_pmsr)
1259 ret = rdev->ops->start_pmsr(&rdev->wiphy, wdev, request);
1260 trace_rdev_return_int(&rdev->wiphy, ret);
1261 return ret;
1262}
1263
1264static inline void
1265rdev_abort_pmsr(struct cfg80211_registered_device *rdev,
1266 struct wireless_dev *wdev,
1267 struct cfg80211_pmsr_request *request)
1268{
1269 trace_rdev_abort_pmsr(&rdev->wiphy, wdev, request->cookie);
1270 if (rdev->ops->abort_pmsr)
1271 rdev->ops->abort_pmsr(&rdev->wiphy, wdev, request);
1272 trace_rdev_return_void(&rdev->wiphy);
1273}
1274
1250#endif /* __CFG80211_RDEV_OPS */ 1275#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index d0e7472dd9fd..5123667f4569 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1183,7 +1183,7 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
1183 switch (ftype) { 1183 switch (ftype) {
1184 case CFG80211_BSS_FTYPE_BEACON: 1184 case CFG80211_BSS_FTYPE_BEACON:
1185 ies->from_beacon = true; 1185 ies->from_beacon = true;
1186 /* fall through to assign */ 1186 /* fall through */
1187 case CFG80211_BSS_FTYPE_UNKNOWN: 1187 case CFG80211_BSS_FTYPE_UNKNOWN:
1188 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 1188 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
1189 break; 1189 break;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index c6a9446b4e6b..44b2ce1bb13a 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -361,6 +361,24 @@ DECLARE_EVENT_CLASS(wiphy_wdev_evt,
361 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) 361 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
362); 362);
363 363
364DECLARE_EVENT_CLASS(wiphy_wdev_cookie_evt,
365 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie),
366 TP_ARGS(wiphy, wdev, cookie),
367 TP_STRUCT__entry(
368 WIPHY_ENTRY
369 WDEV_ENTRY
370 __field(u64, cookie)
371 ),
372 TP_fast_assign(
373 WIPHY_ASSIGN;
374 WDEV_ASSIGN;
375 __entry->cookie = cookie;
376 ),
377 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %lld",
378 WIPHY_PR_ARG, WDEV_PR_ARG,
379 (unsigned long long)__entry->cookie)
380);
381
364DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, 382DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev,
365 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), 383 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
366 TP_ARGS(wiphy, wdev) 384 TP_ARGS(wiphy, wdev)
@@ -770,9 +788,9 @@ DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_set_wds_peer,
770); 788);
771 789
772TRACE_EVENT(rdev_dump_station, 790TRACE_EVENT(rdev_dump_station,
773 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, 791 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx,
774 u8 *mac), 792 u8 *mac),
775 TP_ARGS(wiphy, netdev, idx, mac), 793 TP_ARGS(wiphy, netdev, _idx, mac),
776 TP_STRUCT__entry( 794 TP_STRUCT__entry(
777 WIPHY_ENTRY 795 WIPHY_ENTRY
778 NETDEV_ENTRY 796 NETDEV_ENTRY
@@ -783,7 +801,7 @@ TRACE_EVENT(rdev_dump_station,
783 WIPHY_ASSIGN; 801 WIPHY_ASSIGN;
784 NETDEV_ASSIGN; 802 NETDEV_ASSIGN;
785 MAC_ASSIGN(sta_mac, mac); 803 MAC_ASSIGN(sta_mac, mac);
786 __entry->idx = idx; 804 __entry->idx = _idx;
787 ), 805 ),
788 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d", 806 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d",
789 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), 807 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
@@ -847,9 +865,9 @@ DEFINE_EVENT(mpath_evt, rdev_get_mpath,
847); 865);
848 866
849TRACE_EVENT(rdev_dump_mpath, 867TRACE_EVENT(rdev_dump_mpath,
850 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, 868 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx,
851 u8 *dst, u8 *next_hop), 869 u8 *dst, u8 *next_hop),
852 TP_ARGS(wiphy, netdev, idx, dst, next_hop), 870 TP_ARGS(wiphy, netdev, _idx, dst, next_hop),
853 TP_STRUCT__entry( 871 TP_STRUCT__entry(
854 WIPHY_ENTRY 872 WIPHY_ENTRY
855 NETDEV_ENTRY 873 NETDEV_ENTRY
@@ -862,7 +880,7 @@ TRACE_EVENT(rdev_dump_mpath,
862 NETDEV_ASSIGN; 880 NETDEV_ASSIGN;
863 MAC_ASSIGN(dst, dst); 881 MAC_ASSIGN(dst, dst);
864 MAC_ASSIGN(next_hop, next_hop); 882 MAC_ASSIGN(next_hop, next_hop);
865 __entry->idx = idx; 883 __entry->idx = _idx;
866 ), 884 ),
867 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " 885 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
868 MAC_PR_FMT ", next hop: " MAC_PR_FMT, 886 MAC_PR_FMT ", next hop: " MAC_PR_FMT,
@@ -892,9 +910,9 @@ TRACE_EVENT(rdev_get_mpp,
892); 910);
893 911
894TRACE_EVENT(rdev_dump_mpp, 912TRACE_EVENT(rdev_dump_mpp,
895 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, 913 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx,
896 u8 *dst, u8 *mpp), 914 u8 *dst, u8 *mpp),
897 TP_ARGS(wiphy, netdev, idx, mpp, dst), 915 TP_ARGS(wiphy, netdev, _idx, mpp, dst),
898 TP_STRUCT__entry( 916 TP_STRUCT__entry(
899 WIPHY_ENTRY 917 WIPHY_ENTRY
900 NETDEV_ENTRY 918 NETDEV_ENTRY
@@ -907,7 +925,7 @@ TRACE_EVENT(rdev_dump_mpp,
907 NETDEV_ASSIGN; 925 NETDEV_ASSIGN;
908 MAC_ASSIGN(dst, dst); 926 MAC_ASSIGN(dst, dst);
909 MAC_ASSIGN(mpp, mpp); 927 MAC_ASSIGN(mpp, mpp);
910 __entry->idx = idx; 928 __entry->idx = _idx;
911 ), 929 ),
912 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " 930 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
913 MAC_PR_FMT ", mpp: " MAC_PR_FMT, 931 MAC_PR_FMT ", mpp: " MAC_PR_FMT,
@@ -1673,8 +1691,8 @@ TRACE_EVENT(rdev_tdls_mgmt,
1673); 1691);
1674 1692
1675TRACE_EVENT(rdev_dump_survey, 1693TRACE_EVENT(rdev_dump_survey,
1676 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx), 1694 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx),
1677 TP_ARGS(wiphy, netdev, idx), 1695 TP_ARGS(wiphy, netdev, _idx),
1678 TP_STRUCT__entry( 1696 TP_STRUCT__entry(
1679 WIPHY_ENTRY 1697 WIPHY_ENTRY
1680 NETDEV_ENTRY 1698 NETDEV_ENTRY
@@ -1683,7 +1701,7 @@ TRACE_EVENT(rdev_dump_survey,
1683 TP_fast_assign( 1701 TP_fast_assign(
1684 WIPHY_ASSIGN; 1702 WIPHY_ASSIGN;
1685 NETDEV_ASSIGN; 1703 NETDEV_ASSIGN;
1686 __entry->idx = idx; 1704 __entry->idx = _idx;
1687 ), 1705 ),
1688 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d", 1706 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d",
1689 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx) 1707 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx)
@@ -2502,6 +2520,16 @@ TRACE_EVENT(rdev_get_ftm_responder_stats,
2502 __entry->out_of_window) 2520 __entry->out_of_window)
2503); 2521);
2504 2522
2523DEFINE_EVENT(wiphy_wdev_cookie_evt, rdev_start_pmsr,
2524 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie),
2525 TP_ARGS(wiphy, wdev, cookie)
2526);
2527
2528DEFINE_EVENT(wiphy_wdev_cookie_evt, rdev_abort_pmsr,
2529 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie),
2530 TP_ARGS(wiphy, wdev, cookie)
2531);
2532
2505/************************************************************* 2533/*************************************************************
2506 * cfg80211 exported functions traces * 2534 * cfg80211 exported functions traces *
2507 *************************************************************/ 2535 *************************************************************/
@@ -3294,6 +3322,46 @@ TRACE_EVENT(cfg80211_stop_iface,
3294 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, 3322 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
3295 WIPHY_PR_ARG, WDEV_PR_ARG) 3323 WIPHY_PR_ARG, WDEV_PR_ARG)
3296); 3324);
3325
3326TRACE_EVENT(cfg80211_pmsr_report,
3327 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
3328 u64 cookie, const u8 *addr),
3329 TP_ARGS(wiphy, wdev, cookie, addr),
3330 TP_STRUCT__entry(
3331 WIPHY_ENTRY
3332 WDEV_ENTRY
3333 __field(u64, cookie)
3334 MAC_ENTRY(addr)
3335 ),
3336 TP_fast_assign(
3337 WIPHY_ASSIGN;
3338 WDEV_ASSIGN;
3339 __entry->cookie = cookie;
3340 MAC_ASSIGN(addr, addr);
3341 ),
3342 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie:%lld, " MAC_PR_FMT,
3343 WIPHY_PR_ARG, WDEV_PR_ARG,
3344 (unsigned long long)__entry->cookie,
3345 MAC_PR_ARG(addr))
3346);
3347
3348TRACE_EVENT(cfg80211_pmsr_complete,
3349 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie),
3350 TP_ARGS(wiphy, wdev, cookie),
3351 TP_STRUCT__entry(
3352 WIPHY_ENTRY
3353 WDEV_ENTRY
3354 __field(u64, cookie)
3355 ),
3356 TP_fast_assign(
3357 WIPHY_ASSIGN;
3358 WDEV_ASSIGN;
3359 __entry->cookie = cookie;
3360 ),
3361 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie:%lld",
3362 WIPHY_PR_ARG, WDEV_PR_ARG,
3363 (unsigned long long)__entry->cookie)
3364);
3297#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 3365#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
3298 3366
3299#undef TRACE_INCLUDE_PATH 3367#undef TRACE_INCLUDE_PATH
diff --git a/net/wireless/util.c b/net/wireless/util.c
index d473bd135da8..cd48cdd582c0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2015,33 +2015,32 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
2015 case IEEE80211_VHT_CHANWIDTH_160MHZ: 2015 case IEEE80211_VHT_CHANWIDTH_160MHZ:
2016 if (supp_width == 0 && 2016 if (supp_width == 0 &&
2017 (ext_nss_bw == 1 || ext_nss_bw == 2)) 2017 (ext_nss_bw == 1 || ext_nss_bw == 2))
2018 return DIV_ROUND_UP(max_vht_nss, 2); 2018 return max_vht_nss / 2;
2019 if (supp_width == 0 && 2019 if (supp_width == 0 &&
2020 ext_nss_bw == 3) 2020 ext_nss_bw == 3)
2021 return DIV_ROUND_UP(3 * max_vht_nss, 4); 2021 return (3 * max_vht_nss) / 4;
2022 if (supp_width == 1 && 2022 if (supp_width == 1 &&
2023 ext_nss_bw == 3) 2023 ext_nss_bw == 3)
2024 return 2 * max_vht_nss; 2024 return 2 * max_vht_nss;
2025 break; 2025 break;
2026 case IEEE80211_VHT_CHANWIDTH_80P80MHZ: 2026 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
2027 if (supp_width == 0 && 2027 if (supp_width == 0 && ext_nss_bw == 1)
2028 (ext_nss_bw == 1 || ext_nss_bw == 2))
2029 return 0; /* not possible */ 2028 return 0; /* not possible */
2030 if (supp_width == 0 && 2029 if (supp_width == 0 &&
2031 ext_nss_bw == 2) 2030 ext_nss_bw == 2)
2032 return DIV_ROUND_UP(max_vht_nss, 2); 2031 return max_vht_nss / 2;
2033 if (supp_width == 0 && 2032 if (supp_width == 0 &&
2034 ext_nss_bw == 3) 2033 ext_nss_bw == 3)
2035 return DIV_ROUND_UP(3 * max_vht_nss, 4); 2034 return (3 * max_vht_nss) / 4;
2036 if (supp_width == 1 && 2035 if (supp_width == 1 &&
2037 ext_nss_bw == 0) 2036 ext_nss_bw == 0)
2038 return 0; /* not possible */ 2037 return 0; /* not possible */
2039 if (supp_width == 1 && 2038 if (supp_width == 1 &&
2040 ext_nss_bw == 1) 2039 ext_nss_bw == 1)
2041 return DIV_ROUND_UP(max_vht_nss, 2); 2040 return max_vht_nss / 2;
2042 if (supp_width == 1 && 2041 if (supp_width == 1 &&
2043 ext_nss_bw == 2) 2042 ext_nss_bw == 2)
2044 return DIV_ROUND_UP(3 * max_vht_nss, 4); 2043 return (3 * max_vht_nss) / 4;
2045 break; 2044 break;
2046 } 2045 }
2047 2046