@@ -7529,6 +7529,39 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
enum nl80211_connect_failed_reason reason,
gfp_t gfp);
+/**
+ * struct cfg80211_rx_info - received management frame info
+ *
+ * @freq: Frequency on which the frame was received in kHz
+ * @sig_dbm: signal strength in dBm, or 0 if unknown
+ * @buf: Management frame (header + body)
+ * @len: length of the frame data
+ * @flags: flags, as defined in enum nl80211_rxmgmt_flags
+ */
+struct cfg80211_rx_info {
+ int freq;
+ int sig_dbm;
+ const u8 *buf;
+ size_t len;
+ u32 flags;
+};
+
+/**
+ * cfg80211_rx_mgmt_ext - management frame notification with extended info
+ * @wdev: wireless device receiving the frame
+ * @info: RX info as defined in struct cfg80211_rx_info
+ *
+ * This function is called whenever an Action frame is received for a station
+ * mode interface, but is not processed in kernel.
+ *
+ * Return: %true if a user space application has registered for this frame.
+ * For action frames, that makes it responsible for rejecting unrecognized
+ * action frames; %false otherwise, in which case for action frames the
+ * driver is responsible for rejecting the frame.
+ */
+bool cfg80211_rx_mgmt_ext(struct wireless_dev *wdev,
+ struct cfg80211_rx_info *info);
+
/**
* cfg80211_rx_mgmt_khz - notification of received, unprocessed management frame
* @wdev: wireless device receiving the frame
@@ -7546,8 +7579,20 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
* action frames; %false otherwise, in which case for action frames the
* driver is responsible for rejecting the frame.
*/
-bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
- const u8 *buf, size_t len, u32 flags);
+static inline bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq,
+ int sig_dbm, const u8 *buf, size_t len,
+ u32 flags)
+{
+ struct cfg80211_rx_info info = {
+ .freq = freq,
+ .sig_dbm = sig_dbm,
+ .buf = buf,
+ .len = len,
+ .flags = flags
+ };
+
+ return cfg80211_rx_mgmt_ext(wdev, &info);
+}
/**
* cfg80211_rx_mgmt - notification of received, unprocessed management frame
@@ -7570,8 +7615,15 @@ static inline bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq,
int sig_dbm, const u8 *buf, size_t len,
u32 flags)
{
- return cfg80211_rx_mgmt_khz(wdev, MHZ_TO_KHZ(freq), sig_dbm, buf, len,
- flags);
+ struct cfg80211_rx_info info = {
+ .freq = MHZ_TO_KHZ(freq),
+ .sig_dbm = sig_dbm,
+ .buf = buf,
+ .len = len,
+ .flags = flags
+ };
+
+ return cfg80211_rx_mgmt_ext(wdev, &info);
}
/**
@@ -4,7 +4,7 @@
*
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* Copyright (c) 2015 Intel Deutschland GmbH
- * Copyright (C) 2019-2020 Intel Corporation
+ * Copyright (C) 2019-2020, 2022 Intel Corporation
*/
#include <linux/kernel.h>
@@ -759,15 +759,15 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
return rdev_mgmt_tx(rdev, wdev, params, cookie);
}
-bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
- const u8 *buf, size_t len, u32 flags)
+bool cfg80211_rx_mgmt_ext(struct wireless_dev *wdev,
+ struct cfg80211_rx_info *info)
{
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct cfg80211_mgmt_registration *reg;
const struct ieee80211_txrx_stypes *stypes =
&wiphy->mgmt_stypes[wdev->iftype];
- struct ieee80211_mgmt *mgmt = (void *)buf;
+ struct ieee80211_mgmt *mgmt = (void *)info->buf;
const u8 *data;
int data_len;
bool result = false;
@@ -775,7 +775,7 @@ bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
u16 stype;
- trace_cfg80211_rx_mgmt(wdev, freq, sig_dbm);
+ trace_cfg80211_rx_mgmt(wdev, info);
stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
if (!(stypes->rx & BIT(stype))) {
@@ -783,8 +783,8 @@ bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
return false;
}
- data = buf + ieee80211_hdrlen(mgmt->frame_control);
- data_len = len - ieee80211_hdrlen(mgmt->frame_control);
+ data = info->buf + ieee80211_hdrlen(mgmt->frame_control);
+ data_len = info->len - ieee80211_hdrlen(mgmt->frame_control);
spin_lock_bh(&rdev->mgmt_registrations_lock);
@@ -801,9 +801,8 @@ bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
/* found match! */
/* Indicate the received Action frame to user space */
- if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
- freq, sig_dbm,
- buf, len, flags, GFP_ATOMIC))
+ if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, info,
+ GFP_ATOMIC))
continue;
result = true;
@@ -815,7 +814,7 @@ bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
trace_cfg80211_return_bool(result);
return result;
}
-EXPORT_SYMBOL(cfg80211_rx_mgmt_khz);
+EXPORT_SYMBOL(cfg80211_rx_mgmt_ext);
void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
{
@@ -17420,14 +17420,13 @@ EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, u32 nlportid,
- int freq, int sig_dbm,
- const u8 *buf, size_t len, u32 flags, gfp_t gfp)
+ struct cfg80211_rx_info *info, gfp_t gfp)
{
struct net_device *netdev = wdev->netdev;
struct sk_buff *msg;
void *hdr;
- msg = nlmsg_new(100 + len, gfp);
+ msg = nlmsg_new(100 + info->len, gfp);
if (!msg)
return -ENOMEM;
@@ -17442,13 +17441,13 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
netdev->ifindex)) ||
nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
NL80211_ATTR_PAD) ||
- nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
- nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
- (sig_dbm &&
- nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
- nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
- (flags &&
- nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(info->freq)) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, info->freq % 1000) ||
+ (info->sig_dbm &&
+ nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, info->sig_dbm)) ||
+ nla_put(msg, NL80211_ATTR_FRAME, info->len, info->buf) ||
+ (info->flags &&
+ nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, info->flags)))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Portions of this file
- * Copyright (C) 2018, 2020-2021 Intel Corporation
+ * Copyright (C) 2018, 2020-2022 Intel Corporation
*/
#ifndef __NET_WIRELESS_NL80211_H
#define __NET_WIRELESS_NL80211_H
@@ -107,8 +107,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, u32 nlpid,
- int freq, int sig_dbm,
- const u8 *buf, size_t len, u32 flags, gfp_t gfp);
+ struct cfg80211_rx_info *info, gfp_t gfp);
void
nl80211_radar_notify(struct cfg80211_registered_device *rdev,
@@ -2892,8 +2892,8 @@ DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_del_sta,
);
TRACE_EVENT(cfg80211_rx_mgmt,
- TP_PROTO(struct wireless_dev *wdev, int freq, int sig_dbm),
- TP_ARGS(wdev, freq, sig_dbm),
+ TP_PROTO(struct wireless_dev *wdev, struct cfg80211_rx_info *info),
+ TP_ARGS(wdev, info),
TP_STRUCT__entry(
WDEV_ENTRY
__field(int, freq)
@@ -2901,8 +2901,8 @@ TRACE_EVENT(cfg80211_rx_mgmt,
),
TP_fast_assign(
WDEV_ASSIGN;
- __entry->freq = freq;
- __entry->sig_dbm = sig_dbm;
+ __entry->freq = info->freq;
+ __entry->sig_dbm = info->sig_dbm;
),
TP_printk(WDEV_PR_FMT ", freq: "KHZ_F", sig dbm: %d",
WDEV_PR_ARG, PR_KHZ(__entry->freq), __entry->sig_dbm)