summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h12
-rw-r--r--include/uapi/linux/nl80211.h16
-rw-r--r--net/wireless/nl80211.c45
-rw-r--r--net/wireless/trace.h16
4 files changed, 89 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e2f4ca500ea3..0c1311d254be 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3959,6 +3959,8 @@ struct cfg80211_nan_band_config {
* @scan_period: period (in seconds) between NAN scans.
* @scan_dwell_time: dwell time (in milliseconds) for NAN scans.
* @discovery_beacon_interval: interval (in TUs) for discovery beacons.
+ * @enable_dw_notification: flag to enable/disable discovery window
+ * notifications.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -3973,6 +3975,7 @@ struct cfg80211_nan_conf {
u16 scan_period;
u16 scan_dwell_time;
u8 discovery_beacon_interval;
+ bool enable_dw_notification;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -10062,6 +10065,15 @@ void cfg80211_schedule_channels_check(struct wireless_dev *wdev);
*/
void cfg80211_epcs_changed(struct net_device *netdev, bool enabled);
+/**
+ * cfg80211_next_nan_dw_notif - Notify about the next NAN Discovery Window (DW)
+ * @wdev: Pointer to the wireless device structure
+ * @chan: DW channel (6, 44 or 149)
+ * @gfp: Memory allocation flags
+ */
+void cfg80211_next_nan_dw_notif(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan, gfp_t gfp);
+
#ifdef CONFIG_CFG80211_DEBUGFS
/**
* wiphy_locked_debugfs_read - do a locked read in debugfs
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 20b8202a3d58..d674608e2635 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1349,6 +1349,15 @@
* control EPCS configuration. Used to notify userland on the current state
* of EPCS.
*
+ * @NL80211_CMD_NAN_NEXT_DW_NOTIFICATION: This command is used to notify
+ * user space about the next NAN Discovery Window (DW). User space may use
+ * it to prepare frames to be sent in the next DW.
+ * %NL80211_ATTR_WIPHY_FREQ is used to indicate the frequency of the next
+ * DW. SDF transmission should be requested with %NL80211_CMD_FRAME and
+ * the device/driver shall take care of the actual transmission timing.
+ * This notification is only sent to the NAN interface owning socket
+ * (see %NL80211_ATTR_SOCKET_OWNER flag).
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1609,6 +1618,8 @@ enum nl80211_commands {
NL80211_CMD_ASSOC_MLO_RECONF,
NL80211_CMD_EPCS_CFG,
+ NL80211_CMD_NAN_NEXT_DW_NOTIFICATION,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -7409,6 +7420,10 @@ enum nl80211_nan_band_conf_attributes {
* @NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL: Discovery beacon interval
* in TUs. Valid range is 50-200 TUs. If not configured the device default
* value is used. This is u8 (optional)
+ * @NL80211_NAN_CONF_NOTIFY_DW: If set, the driver will notify userspace about
+ * the upcoming discovery window with
+ * %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
+ * This is a flag attribute.
* @NUM_NL80211_NAN_CONF_ATTR: Internal.
* @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
*
@@ -7423,6 +7438,7 @@ enum nl80211_nan_conf_attributes {
NL80211_NAN_CONF_SCAN_PERIOD,
NL80211_NAN_CONF_SCAN_DWELL_TIME,
NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
+ NL80211_NAN_CONF_NOTIFY_DW,
/* keep last */
NUM_NL80211_NAN_CONF_ATTR,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 04679acc8135..d64145746b65 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -547,6 +547,7 @@ nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {
[NL80211_NAN_CONF_SCAN_DWELL_TIME] = NLA_POLICY_RANGE(NLA_U16, 50, 512),
[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL] =
NLA_POLICY_RANGE(NLA_U8, 50, 200),
+ [NL80211_NAN_CONF_NOTIFY_DW] = { .type = NLA_FLAG },
};
static const struct netlink_range_validation nl80211_punct_bitmap_range = {
@@ -15627,6 +15628,11 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,
if (attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL])
conf->discovery_beacon_interval =
nla_get_u8(attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL]);
+
+ if (attrs[NL80211_NAN_CONF_NOTIFY_DW])
+ conf->enable_dw_notification =
+ nla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);
+
out:
if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
(!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
@@ -21764,6 +21770,45 @@ void cfg80211_epcs_changed(struct net_device *netdev, bool enabled)
}
EXPORT_SYMBOL(cfg80211_epcs_changed);
+void cfg80211_next_nan_dw_notif(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan, gfp_t gfp)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_next_nan_dw_notif(wdev, chan);
+
+ if (!wdev->owner_nlportid)
+ return;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0,
+ NL80211_CMD_NAN_NEXT_DW_NOTIFICATION);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_unicast(wiphy_net(wiphy), msg, wdev->owner_nlportid);
+
+ return;
+
+ nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_next_nan_dw_notif);
+
/* initialisation/exit functions */
int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 9b6074155d59..ff47e9bffd4f 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4166,6 +4166,22 @@ TRACE_EVENT(cfg80211_epcs_changed,
WDEV_PR_ARG, __entry->enabled)
);
+TRACE_EVENT(cfg80211_next_nan_dw_notif,
+ TP_PROTO(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan),
+ TP_ARGS(wdev, chan),
+ TP_STRUCT__entry(
+ WDEV_ENTRY
+ CHAN_ENTRY
+ ),
+ TP_fast_assign(
+ WDEV_ASSIGN;
+ CHAN_ASSIGN(chan);
+ ),
+ TP_printk(WDEV_PR_FMT " " CHAN_PR_FMT,
+ WDEV_PR_ARG, CHAN_PR_ARG)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH