* [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations
@ 2025-08-13 14:10 Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 1/4] wifi: nl80211: Add more configuration options for NAN commands Andrei Otcheretianski
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Andrei Otcheretianski @ 2025-08-13 14:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, maheshkkv, quic_vganneva, Andrei Otcheretianski
This patch series extend exiting NAN APIs to support more
configuration options for NAN synchronization and a user space oriented
NAN Service Discovery implementation.
Existing NAN APIs are very limited and not really used, resulting in
vendors using proprietary vendor commands and a need to offload NAN
protocol implementations to the device firmware or driver.
In this series, additional APIs are added which allow to extend the
configuration of the NAN Synchronization logic and support user space
oriented NAN Service Discovery implementation.
With this design, wireless devices/drivers are still required to
implement NAN synchronization and cluster merging. NAN Discovery Engine,
may be either offloaded (keep using the existing APIs) or alternatively
implemented in user space.
To support user space oriented NAN Discovery Engine, the device will
notify user space with %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION about the
upcoming Discovery Window (DW). This notification should be used as a
trigger for transmission of uncsolicited multicast SDF's (i.e.
unsolicited publish and active subscribe). Once SDF transmission is
requested with %NL80211_CMD_FRAME, the device shall take care of the
actual frame transmission during the upcoming DW.
Note, this notification may be sent before the actual DW start time.
For devices that may require longer DW notification processing time,
user space may provide the expected latency to the device using
%NL80211_NAN_CONF_DW_LEAD_TIME attribute.
Note that such approach may not be appropriate for highly power
efficient devices or scenarios that require long discovery sessions, as
it may require the host to wake up for each DW.
User space can, in turn, turn off this notification using
%NL80211_NAN_CONF_NOTIFY_DW configuration flag if it doesn't intend to
send unsolicited multicast SDFs to prevent unneeded wake ups.
%NL80211_CMD_NAN_CLUSTER_JOINED notification shall be sent once after
new NAN cluster has been started or the device has joined an existing
cluster. In addition each time, cluster merge procedure results in
cluster merging, user space shall be notified. This is required, as
cluster ID is used as address 3 in SDF frames. Untransmitted frames
should be flushed, when this notification is generated in order to
prevent transmission of SDFs with invalid address 3.
This patch series goal is to provide APIs to support NAN synchronization
and user space oriented Service Discovery. It will be further extended
in a separate patch set to support user space implementation of NAN data
path (NDP) and NDL schedule establishment.
---
Changes in v3:
- Added %NL80211_NAN_CONF_DW_LEAD_TIME
- Added capabilities to limit extra NAN attributes and vendor IEs
- Changed NAN configuration parameters format/types etc
- Improved documentation and bugfixes
Andrei Otcheretianski (4):
wifi: nl80211: Add more configuration options for NAN commands
wifi: nl80211: Add NAN Discovery Window (DW) notification
wifi: cfg80211: Add cluster joined notification APIs
wifi: nl80211: Add more NAN capabilities
include/net/cfg80211.h | 91 ++++++++
include/uapi/linux/nl80211.h | 203 +++++++++++++++++-
net/wireless/nl80211.c | 389 +++++++++++++++++++++++++++++++----
net/wireless/trace.h | 35 ++++
4 files changed, 681 insertions(+), 37 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC v3 1/4] wifi: nl80211: Add more configuration options for NAN commands
2025-08-13 14:10 [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations Andrei Otcheretianski
@ 2025-08-13 14:10 ` Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 2/4] wifi: nl80211: Add NAN Discovery Window (DW) notification Andrei Otcheretianski
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Andrei Otcheretianski @ 2025-08-13 14:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, maheshkkv, quic_vganneva, Andrei Otcheretianski
Current NAN APIs have only basic configuration for master
preference and operating bands. Add and parse additional parameters
which provide more control over NAN synchronization. The newly added
attributes allow to publish additional NAN attributes and vendor
elements in NAN beacons, control scan and discovery beacons
periodicity, enable/disable DW notifications etc.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
include/net/cfg80211.h | 60 +++++++
include/uapi/linux/nl80211.h | 111 ++++++++++++-
net/wireless/nl80211.c | 298 +++++++++++++++++++++++++++++++----
3 files changed, 432 insertions(+), 37 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 406626ff6cc8..e53a4ed48c58 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3886,6 +3886,38 @@ struct cfg80211_qos_map {
struct cfg80211_dscp_range up[8];
};
+/**
+ * struct cfg80211_nan_band_config - NAN band specific configuration
+ *
+ * @chan: Pointer to the IEEE 802.11 channel structure. The channel to be used
+ * for NAN operations on this band. For 2.4 GHz band, this is always
+ * channel 6. For 5 GHz band, the channel is either 44 or 149, according
+ * to the regulatory constraints. If chan pointer is NULL the entire band
+ * configuration entry is considered invalid and should not be used.
+ * @rssi_close: RSSI close threshold used for NAN state transition algorithm
+ * as described in chapters 3.3.6 and 3.3.7 "NAN Device Role and State
+ * Transition" of Wi-Fi Aware Specification v4.0. If not
+ * specified (set to 0), default device value is used. The value should
+ * be greater than -60 dBm.
+ * @rssi_middle: RSSI middle threshold used for NAN state transition algorithm.
+ * as described in chapters 3.3.6 and 3.3.7 "NAN Device Role and State
+ * Transition" of Wi-Fi Aware Specification v4.0. If not
+ * specified (set to 0), default device value is used. The value should be
+ * greater than -75 dBm and less than rssi_close.
+ * @awake_dw_interval: Committed DW interval. Valid values range: 0-5. 0
+ * indicates no wakeup for DW and can't be used on 2.4GHz band, otherwise
+ * 2^(n-1).
+ * @disable_scan: If true, the device will not scan this band for cluster
+ * merge. Disabling scan on 2.4 GHz band is not allowed.
+ */
+struct cfg80211_nan_band_config {
+ struct ieee80211_channel *chan;
+ s8 rssi_close;
+ s8 rssi_middle;
+ u8 awake_dw_interval;
+ bool disable_scan;
+};
+
/**
* struct cfg80211_nan_conf - NAN configuration
*
@@ -3895,10 +3927,31 @@ struct cfg80211_qos_map {
* @bands: operating bands, a bitmap of &enum nl80211_band values.
* For instance, for NL80211_BAND_2GHZ, bit 0 would be set
* (i.e. BIT(NL80211_BAND_2GHZ)).
+ * @cluster_id: cluster ID used for NAN synchronization. This is a MAC address
+ * that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
+ * If NULL, the device will pick a random Cluster ID.
+ * @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.
+ * @band_cfgs: array of band specific configurations, indexed by
+ * &enum nl80211_band values.
+ * @extra_nan_attrs: pointer to additional NAN attributes.
+ * @extra_nan_attrs_len: length of the additional NAN attributes.
+ * @vendor_elems: pointer to vendor-specific elements.
+ * @vendor_elems_len: length of the vendor-specific elements.
*/
struct cfg80211_nan_conf {
u8 master_pref;
u8 bands;
+ const u8 *cluster_id;
+ u16 scan_period;
+ u16 scan_dwell_time;
+ u8 discovery_beacon_interval;
+ struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
+ const u8 *extra_nan_attrs;
+ u16 extra_nan_attrs_len;
+ const u8 *vendor_elems;
+ u16 vendor_elems_len;
};
/**
@@ -3907,10 +3960,17 @@ struct cfg80211_nan_conf {
*
* @CFG80211_NAN_CONF_CHANGED_PREF: master preference
* @CFG80211_NAN_CONF_CHANGED_BANDS: operating bands
+ * @CFG80211_NAN_CONF_CHANGED_CONFIG: changed additional configuration.
+ * When this flag is set, it indicates that some additional attribute(s)
+ * (other then master_pref and bands) have been changed. In this case,
+ * all the unchanged attributes will be properly configured to their
+ * previous values. The driver doesn't need to store any
+ * previous configuration besides master_pref and bands.
*/
enum cfg80211_nan_conf_changes {
CFG80211_NAN_CONF_CHANGED_PREF = BIT(0),
CFG80211_NAN_CONF_CHANGED_BANDS = BIT(1),
+ CFG80211_NAN_CONF_CHANGED_CONFIG = BIT(2),
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d1a14f2892d9..9c84f44deadd 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1085,8 +1085,9 @@
* %NL80211_ATTR_NAN_MASTER_PREF attribute and optional
* %NL80211_ATTR_BANDS attributes. If %NL80211_ATTR_BANDS is
* omitted or set to 0, it means don't-care and the device will
- * decide what to use. After this command NAN functions can be
- * added.
+ * decide what to use. Additional cluster configuration may be
+ * optionally provided with %NL80211_ATTR_NAN_CONFIG.
+ * After this command NAN functions can be added.
* @NL80211_CMD_STOP_NAN: Stop the NAN operation, identified by
* its %NL80211_ATTR_WDEV interface.
* @NL80211_CMD_ADD_NAN_FUNCTION: Add a NAN function. The function is defined
@@ -1115,6 +1116,10 @@
* current configuration is not changed. If it is present but
* set to zero, the configuration is changed to don't-care
* (i.e. the device can decide what to do).
+ * Additional parameters may be provided with
+ * %NL80211_ATTR_NAN_CONFIG. User space should provide all previously
+ * configured nested attributes under %NL80211_ATTR_NAN_CONFIG, even if
+ * only a subset was changed.
* @NL80211_CMD_NAN_MATCH: Notification sent when a match is reported.
* This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
* %NL80211_ATTR_COOKIE.
@@ -2928,6 +2933,12 @@ enum nl80211_commands {
* required alongside this attribute. Refer to
* @enum nl80211_s1g_short_beacon_attrs for the attribute definitions.
*
+ * @NL80211_ATTR_NAN_CONFIG: Nested attribute for
+ * extended NAN cluster configuration. This is used with
+ * %NL80211_CMD_START_NAN and %NL80211_CMD_CHANGE_NAN_CONFIG.
+ * See &enum nl80211_nan_conf_attributes for details.
+ * This attribute is optional.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3490,6 +3501,8 @@ enum nl80211_attrs {
NL80211_ATTR_S1G_LONG_BEACON_PERIOD,
NL80211_ATTR_S1G_SHORT_BEACON,
+ NL80211_ATTR_NAN_CONFIG,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -7278,6 +7291,100 @@ enum nl80211_nan_match_attributes {
NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
};
+/**
+ * enum nl80211_nan_band_conf_attributes - NAN band configuration attributes
+ * @__NL80211_NAN_BAND_CONF_INVALID: Invalid.
+ * @NL80211_NAN_BAND_CONF_BAND: Band for which the configuration is
+ * being set. The value is according to &enum nl80211_band (u8).
+ * @NL80211_NAN_BAND_CONF_FREQ: Discovery frequency. This attribute shall not
+ * be present on 2.4 GHZ band. On 5 GHz band its presence is optional.
+ * The allowed values are 5220 (channel 44) or 5745 (channel 149).
+ * If not present, channel 149 is used if allowed, otherwise channel 44
+ * will be selected. The value is in MHz (u16).
+ * @NL80211_NAN_BAND_CONF_RSSI_CLOSE: RSSI close threshold used for NAN state
+ * transition algorithm as described in chapters 3.3.6 and 3.3.7 "NAN
+ * Device Role and State Transition" of Wi-Fi Aware (TM) Specification
+ * v4.0. If not specified, default device value is used. The value should
+ * be greater than -60 dBm (s8).
+ * @NL80211_NAN_BAND_CONF_RSSI_MIDDLE: RSSI middle threshold used for NAN state
+ * transition algorithm as described in chapters 3.3.6 and 3.3.7 "NAN
+ * Device Role and State Transition" of Wi-Fi Aware (TM) Specification
+ * v4.0. If not present, default device value is used. The value should be
+ * greater than -75 dBm and less than %NL80211_NAN_BAND_CONF_RSSI_CLOSE
+ * (s8).
+ * @NL80211_NAN_BAND_CONF_WAKE_DW: Committed DW information (values 0-5).
+ * Value 0 means that the device will not wake up during the
+ * discovery window. Values 1-5 mean that the device will wake up
+ * during each 2^(n - 1) discovery window, where n is the value of
+ * this attribute. Setting this attribute to 0 is not allowed on
+ * 2.4 GHz band (u8). This is an optional parameter (default is 1).
+ * @NL80211_NAN_BAND_CONF_DISABLE_SCAN: Optional flag attribute to disable
+ * scanning (for cluster merge) on the band. If set, the device will not
+ * scan on this band anymore. Disabling scanning on 2.4 GHz band is not
+ * allowed.
+ * @NUM_NL80211_NAN_BAND_CONF_ATTR: Internal.
+ * @NL80211_NAN_BAND_CONF_ATTR_MAX: Highest NAN band configuration attribute.
+ *
+ * These attributes are used to configure NAN band-specific parameters. Note,
+ * that both RSSI attributes should be configured (or both left unset).
+ */
+enum nl80211_nan_band_conf_attributes {
+ __NL80211_NAN_BAND_CONF_INVALID,
+ NL80211_NAN_BAND_CONF_BAND,
+ NL80211_NAN_BAND_CONF_FREQ,
+ NL80211_NAN_BAND_CONF_RSSI_CLOSE,
+ NL80211_NAN_BAND_CONF_RSSI_MIDDLE,
+ NL80211_NAN_BAND_CONF_WAKE_DW,
+ NL80211_NAN_BAND_CONF_DISABLE_SCAN,
+
+ /* keep last */
+ NUM_NL80211_NAN_BAND_CONF_ATTR,
+ NL80211_NAN_BAND_CONF_ATTR_MAX = NUM_NL80211_NAN_BAND_CONF_ATTR - 1,
+};
+
+/**
+ * enum nl80211_nan_conf_attributes - NAN configuration attributes
+ * @__NL80211_NAN_CONF_INVALID: Invalid attribute, used for validation.
+ * @NL80211_NAN_CONF_CLUSTER_ID: ID for the NAN cluster. This is a MAC
+ * address that can take values from 50-6F-9A-01-00-00 to
+ * 50-6F-9A-01-FF-FF. This attribute is optional. If not present,
+ * a random Cluster ID will be chosen.
+ * @NL80211_NAN_CONF_EXTRA_ATTRS: Additional NAN attributes to be
+ * published in the beacons. This is an optional byte array.
+ * @NL80211_NAN_CONF_VENDOR_ELEMS: Vendor-specific elements that will
+ * be published in the beacons. This is an optional byte array.
+ * @NL80211_NAN_CONF_BAND_CONFIGS: This is a nested array attribute,
+ * containing multiple entries for each supported band. Each band
+ * configuration consists of &enum nl80211_nan_band_conf_attributes.
+ * @NL80211_NAN_CONF_SCAN_PERIOD: Scan period in seconds. If not configured,
+ * device default is used. Zero value will disable scanning.
+ * This is u16 (optional).
+ * @NL80211_NAN_CONF_SCAN_DWELL_TIME: Scan dwell time in TUs per channel.
+ * Only non-zero values are valid. If not configured the device default
+ * value is used. This is u16 (optional)
+ * @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)
+ * @NUM_NL80211_NAN_CONF_ATTR: Internal.
+ * @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
+ *
+ * These attributes are used to configure NAN-specific parameters.
+ */
+enum nl80211_nan_conf_attributes {
+ __NL80211_NAN_CONF_INVALID,
+ NL80211_NAN_CONF_CLUSTER_ID,
+ NL80211_NAN_CONF_EXTRA_ATTRS,
+ NL80211_NAN_CONF_VENDOR_ELEMS,
+ NL80211_NAN_CONF_BAND_CONFIGS,
+ NL80211_NAN_CONF_SCAN_PERIOD,
+ NL80211_NAN_CONF_SCAN_DWELL_TIME,
+ NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
+
+ /* keep last */
+ NUM_NL80211_NAN_CONF_ATTR,
+ NL80211_NAN_CONF_ATTR_MAX = NUM_NL80211_NAN_CONF_ATTR - 1,
+};
+
/**
* enum nl80211_external_auth_action - Action to perform with external
* authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 89519aa52893..0c79fd6f101d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -312,6 +312,26 @@ static int validate_supported_selectors(const struct nlattr *attr,
return 0;
}
+static int validate_nan_cluster_id(const struct nlattr *attr,
+ struct netlink_ext_ack *extack)
+{
+ const u8 *data = nla_data(attr);
+ unsigned int len = nla_len(attr);
+ static const u8 cluster_id_prefix[4] = {0x50, 0x6f, 0x9a, 0x1};
+
+ if (len != ETH_ALEN) {
+ NL_SET_ERR_MSG_ATTR(extack, attr, "bad cluster id length");
+ return -EINVAL;
+ }
+
+ if (memcmp(data, cluster_id_prefix, sizeof(cluster_id_prefix))) {
+ NL_SET_ERR_MSG_ATTR(extack, attr, "invalid cluster id prefix");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* policy for the attributes */
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
@@ -492,6 +512,35 @@ nl80211_s1g_short_beacon[NL80211_S1G_SHORT_BEACON_ATTR_MAX + 1] = {
IEEE80211_MAX_DATA_LEN),
};
+static const struct nla_policy
+nl80211_nan_band_conf_policy[NL80211_NAN_BAND_CONF_ATTR_MAX + 1] = {
+ [NL80211_NAN_BAND_CONF_BAND] = NLA_POLICY_MAX(NLA_U8,
+ NUM_NL80211_BANDS - 1),
+ [NL80211_NAN_BAND_CONF_FREQ] = { .type = NLA_U16 },
+ [NL80211_NAN_BAND_CONF_RSSI_CLOSE] = NLA_POLICY_MIN(NLA_S8, -59),
+ [NL80211_NAN_BAND_CONF_RSSI_MIDDLE] = NLA_POLICY_MIN(NLA_S8, -74),
+ [NL80211_NAN_BAND_CONF_WAKE_DW] = NLA_POLICY_MAX(NLA_U8, 5),
+ [NL80211_NAN_BAND_CONF_DISABLE_SCAN] = { .type = NLA_FLAG },
+};
+
+static const struct nla_policy
+nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {
+ [NL80211_NAN_CONF_CLUSTER_ID] =
+ NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_nan_cluster_id,
+ ETH_ALEN),
+ [NL80211_NAN_CONF_EXTRA_ATTRS] = { .type = NLA_BINARY,
+ .len = IEEE80211_MAX_DATA_LEN},
+ [NL80211_NAN_CONF_VENDOR_ELEMS] =
+ NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
+ IEEE80211_MAX_DATA_LEN),
+ [NL80211_NAN_CONF_BAND_CONFIGS] =
+ NLA_POLICY_NESTED_ARRAY(nl80211_nan_band_conf_policy),
+ [NL80211_NAN_CONF_SCAN_PERIOD] = { .type = NLA_U16 },
+ [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),
+};
+
static const struct netlink_range_validation nl80211_punct_bitmap_range = {
.min = 0,
.max = 0xffff,
@@ -761,6 +810,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
[NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
[NL80211_ATTR_BANDS] = { .type = NLA_U32 },
+ [NL80211_ATTR_NAN_CONFIG] = NLA_POLICY_NESTED(nl80211_nan_conf_policy),
[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
[NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
.len = FILS_MAX_KEK_LEN },
@@ -15105,6 +15155,211 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+static struct ieee80211_channel *nl80211_get_nan_channel(struct wiphy *wiphy,
+ int freq)
+{
+ struct ieee80211_channel *chan;
+ struct cfg80211_chan_def def;
+
+ /* Check if the frequency is valid for NAN */
+ if (freq != 5220 && freq != 5745 && freq != 2437)
+ return NULL;
+
+ chan = ieee80211_get_channel(wiphy, freq);
+ if (!chan)
+ return NULL;
+
+ cfg80211_chandef_create(&def, chan, NL80211_CHAN_NO_HT);
+
+ /* Check if the channel is allowed */
+ if (cfg80211_reg_can_beacon(wiphy, &def, NL80211_IFTYPE_NAN))
+ return chan;
+
+ return NULL;
+}
+
+static int nl80211_parse_nan_band_config(struct wiphy *wiphy,
+ struct nlattr **tb,
+ struct cfg80211_nan_band_config *cfg,
+ enum nl80211_band band)
+{
+ if (BIT(band) & ~(u32)wiphy->nan_supported_bands)
+ return -EINVAL;
+
+ if (tb[NL80211_NAN_BAND_CONF_FREQ]) {
+ u16 freq = nla_get_u16(tb[NL80211_NAN_BAND_CONF_FREQ]);
+
+ if (band != NL80211_BAND_5GHZ)
+ return -EINVAL;
+
+ cfg->chan = nl80211_get_nan_channel(wiphy, freq);
+ if (!cfg->chan)
+ return -EINVAL;
+ }
+
+ if (tb[NL80211_NAN_BAND_CONF_RSSI_CLOSE]) {
+ cfg->rssi_close =
+ nla_get_s8(tb[NL80211_NAN_BAND_CONF_RSSI_CLOSE]);
+ if (!tb[NL80211_NAN_BAND_CONF_RSSI_MIDDLE])
+ return -EINVAL;
+ }
+
+ if (tb[NL80211_NAN_BAND_CONF_RSSI_MIDDLE]) {
+ cfg->rssi_middle =
+ nla_get_s8(tb[NL80211_NAN_BAND_CONF_RSSI_MIDDLE]);
+ if (!cfg->rssi_close || cfg->rssi_middle >= cfg->rssi_close)
+ return -EINVAL;
+ }
+
+ if (tb[NL80211_NAN_BAND_CONF_WAKE_DW]) {
+ cfg->awake_dw_interval =
+ nla_get_u8(tb[NL80211_NAN_BAND_CONF_WAKE_DW]);
+
+ if (band == NL80211_BAND_2GHZ && cfg->awake_dw_interval == 0)
+ return -EINVAL;
+ }
+
+ cfg->disable_scan =
+ nla_get_flag(tb[NL80211_NAN_BAND_CONF_DISABLE_SCAN]);
+ return 0;
+}
+
+static int nl80211_parse_nan_conf(struct wiphy *wiphy,
+ struct genl_info *info,
+ struct cfg80211_nan_conf *conf,
+ u32 *changed_flags)
+{
+ struct nlattr *attrs[NL80211_NAN_CONF_ATTR_MAX + 1];
+ int err, rem;
+ u32 changed = 0;
+ struct nlattr *band_config;
+
+ if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
+ conf->master_pref =
+ nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
+
+ changed |= CFG80211_NAN_CONF_CHANGED_PREF;
+ }
+
+ if (info->attrs[NL80211_ATTR_BANDS]) {
+ u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
+
+ if (bands & ~(u32)wiphy->nan_supported_bands)
+ return -EOPNOTSUPP;
+
+ if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
+ return -EINVAL;
+
+ conf->bands = bands;
+ changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
+ }
+
+ conf->band_cfgs[NL80211_BAND_2GHZ].awake_dw_interval = 1;
+ if (conf->bands & BIT(NL80211_BAND_5GHZ) || !conf->bands)
+ conf->band_cfgs[NL80211_BAND_5GHZ].awake_dw_interval = 1;
+
+ /* On 2.4 GHz band use channel 6 */
+ conf->band_cfgs[NL80211_BAND_2GHZ].chan =
+ nl80211_get_nan_channel(wiphy, 2437);
+ if (!conf->band_cfgs[NL80211_BAND_2GHZ].chan)
+ return -EINVAL;
+
+ if (!info->attrs[NL80211_ATTR_NAN_CONFIG])
+ goto out;
+
+ err = nla_parse_nested(attrs, NL80211_NAN_CONF_ATTR_MAX,
+ info->attrs[NL80211_ATTR_NAN_CONFIG], NULL,
+ info->extack);
+ if (err)
+ return err;
+
+ changed |= CFG80211_NAN_CONF_CHANGED_CONFIG;
+ if (attrs[NL80211_NAN_CONF_CLUSTER_ID])
+ conf->cluster_id =
+ nla_data(attrs[NL80211_NAN_CONF_CLUSTER_ID]);
+
+ if (attrs[NL80211_NAN_CONF_EXTRA_ATTRS]) {
+ conf->extra_nan_attrs =
+ nla_data(attrs[NL80211_NAN_CONF_EXTRA_ATTRS]);
+ conf->extra_nan_attrs_len =
+ nla_len(attrs[NL80211_NAN_CONF_EXTRA_ATTRS]);
+ }
+
+ if (attrs[NL80211_NAN_CONF_VENDOR_ELEMS]) {
+ conf->vendor_elems =
+ nla_data(attrs[NL80211_NAN_CONF_VENDOR_ELEMS]);
+ conf->vendor_elems_len =
+ nla_len(attrs[NL80211_NAN_CONF_VENDOR_ELEMS]);
+ }
+
+ if (attrs[NL80211_NAN_CONF_BAND_CONFIGS]) {
+ nla_for_each_nested(band_config,
+ attrs[NL80211_NAN_CONF_BAND_CONFIGS],
+ rem) {
+ enum nl80211_band band;
+ struct cfg80211_nan_band_config *cfg;
+ struct nlattr *tb[NL80211_NAN_BAND_CONF_ATTR_MAX + 1];
+
+ err = nla_parse_nested(tb,
+ NL80211_NAN_BAND_CONF_ATTR_MAX,
+ band_config, NULL,
+ info->extack);
+ if (err)
+ return err;
+
+ if (!tb[NL80211_NAN_BAND_CONF_BAND])
+ return -EINVAL;
+
+ band = nla_get_u8(tb[NL80211_NAN_BAND_CONF_BAND]);
+ if (conf->bands && !(conf->bands & BIT(band)))
+ return -EINVAL;
+
+ cfg = &conf->band_cfgs[band];
+
+ err = nl80211_parse_nan_band_config(wiphy, tb, cfg,
+ band);
+ if (err)
+ return err;
+ }
+ }
+
+ if (attrs[NL80211_NAN_CONF_SCAN_PERIOD])
+ conf->scan_period =
+ nla_get_u16(attrs[NL80211_NAN_CONF_SCAN_PERIOD]);
+
+ if (attrs[NL80211_NAN_CONF_SCAN_DWELL_TIME])
+ conf->scan_dwell_time =
+ nla_get_u16(attrs[NL80211_NAN_CONF_SCAN_DWELL_TIME]);
+
+ if (attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL])
+ conf->discovery_beacon_interval =
+ nla_get_u8(attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL]);
+out:
+ if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
+ (!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
+ /* If no 5GHz channel is specified use default, if possible */
+ conf->band_cfgs[NL80211_BAND_5GHZ].chan =
+ nl80211_get_nan_channel(wiphy, 5745);
+ if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan)
+ conf->band_cfgs[NL80211_BAND_5GHZ].chan =
+ nl80211_get_nan_channel(wiphy, 5220);
+
+ /* Return error if user space asked explicitly for 5 GHz */
+ if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
+ conf->bands & BIT(NL80211_BAND_5GHZ)) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ info->attrs[NL80211_ATTR_BANDS],
+ "5 GHz band operation is not allowed");
+ return -EINVAL;
+ }
+ }
+
+ if (changed_flags)
+ *changed_flags = changed;
+
+ return 0;
+}
+
static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -15121,23 +15376,13 @@ static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
if (rfkill_blocked(rdev->wiphy.rfkill))
return -ERFKILL;
+ /* Master preference is mandatory for START_NAN */
if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
return -EINVAL;
- conf.master_pref =
- nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
-
- if (info->attrs[NL80211_ATTR_BANDS]) {
- u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
-
- if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
- return -EOPNOTSUPP;
-
- if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
- return -EINVAL;
-
- conf.bands = bands;
- }
+ err = nl80211_parse_nan_conf(&rdev->wiphy, info, &conf, NULL);
+ if (err)
+ return err;
err = rdev_start_nan(rdev, wdev, &conf);
if (err)
@@ -15493,6 +15738,7 @@ static int nl80211_nan_change_config(struct sk_buff *skb,
struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_nan_conf conf = {};
u32 changed = 0;
+ int err;
if (wdev->iftype != NL80211_IFTYPE_NAN)
return -EOPNOTSUPP;
@@ -15500,27 +15746,9 @@ static int nl80211_nan_change_config(struct sk_buff *skb,
if (!wdev_running(wdev))
return -ENOTCONN;
- if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
- conf.master_pref =
- nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
- if (conf.master_pref <= 1 || conf.master_pref == 255)
- return -EINVAL;
-
- changed |= CFG80211_NAN_CONF_CHANGED_PREF;
- }
-
- if (info->attrs[NL80211_ATTR_BANDS]) {
- u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
-
- if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
- return -EOPNOTSUPP;
-
- if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
- return -EINVAL;
-
- conf.bands = bands;
- changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
- }
+ err = nl80211_parse_nan_conf(&rdev->wiphy, info, &conf, &changed);
+ if (err)
+ return err;
if (!changed)
return -EINVAL;
--
2.47.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC v3 2/4] wifi: nl80211: Add NAN Discovery Window (DW) notification
2025-08-13 14:10 [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 1/4] wifi: nl80211: Add more configuration options for NAN commands Andrei Otcheretianski
@ 2025-08-13 14:10 ` Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 3/4] wifi: cfg80211: Add cluster joined notification APIs Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 4/4] wifi: nl80211: Add more NAN capabilities Andrei Otcheretianski
3 siblings, 0 replies; 5+ messages in thread
From: Andrei Otcheretianski @ 2025-08-13 14:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, maheshkkv, quic_vganneva, Andrei Otcheretianski
This notification will be used by the device to inform user space
about upcoming DW. When received, user space will be able to prepare
multicast Service Discovery Frames (SDFs) to be transmitted during the
next DW using %NL80211_CMD_FRAME command on the NAN management interface.
The device/driver will take care to transmit the frames in the correct
timing. This allows to implement a synchronized Discovery Engine (DE)
in user space, if the device doesn't support DE offload.
Note that this notification can be sent before the actual DW starts as
long as the driver/device handles the actual timing of the SDF
transmission.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
include/net/cfg80211.h | 17 ++++++++++++
include/uapi/linux/nl80211.h | 23 +++++++++++++++++
net/wireless/nl80211.c | 50 ++++++++++++++++++++++++++++++++++++
net/wireless/trace.h | 16 ++++++++++++
4 files changed, 106 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e53a4ed48c58..0556dd6718dc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3933,6 +3933,12 @@ 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.
+ * @dw_lead_time: anticipated host processing time in TUs to process DW
+ * notifications. This is an optional parameter, zero value means
+ * 'unknown'. The device may use this value to adjust DW notification
+ * timing. Max allowed value is 496 TUs.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -3947,6 +3953,8 @@ struct cfg80211_nan_conf {
u16 scan_period;
u16 scan_dwell_time;
u8 discovery_beacon_interval;
+ bool enable_dw_notification;
+ u16 dw_lead_time;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -10030,6 +10038,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 9c84f44deadd..3b9c9f2a7d27 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 */
@@ -7365,6 +7376,16 @@ 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.
+ * @NL80211_NAN_CONF_DW_LEAD_TIME: Anticipated time in TUs it takes
+ * the host to process %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
+ * The device may use this value to adjust the timing of the notification.
+ * This is an optional u16 attribute. Maximum allowed value is 496 TUs.
+ * If set to zero or the attriubute is not present, it means that such
+ * information is not available.
* @NUM_NL80211_NAN_CONF_ATTR: Internal.
* @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
*
@@ -7379,6 +7400,8 @@ 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,
+ NL80211_NAN_CONF_DW_LEAD_TIME,
/* keep last */
NUM_NL80211_NAN_CONF_ATTR,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0c79fd6f101d..6b77d9c7a901 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -539,6 +539,8 @@ 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 },
+ [NL80211_NAN_CONF_DW_LEAD_TIME] = NLA_POLICY_MAX(NLA_U16, 512),
};
static const struct netlink_range_validation nl80211_punct_bitmap_range = {
@@ -15334,6 +15336,15 @@ 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]);
+
+ if (attrs[NL80211_NAN_CONF_DW_LEAD_TIME])
+ conf->dw_lead_time =
+ nla_get_u16(attrs[NL80211_NAN_CONF_DW_LEAD_TIME]);
+
out:
if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
(!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
@@ -21471,6 +21482,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 34c584a215e5..2ed1b090d519 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4222,6 +4222,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
--
2.47.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC v3 3/4] wifi: cfg80211: Add cluster joined notification APIs
2025-08-13 14:10 [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 1/4] wifi: nl80211: Add more configuration options for NAN commands Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 2/4] wifi: nl80211: Add NAN Discovery Window (DW) notification Andrei Otcheretianski
@ 2025-08-13 14:10 ` Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 4/4] wifi: nl80211: Add more NAN capabilities Andrei Otcheretianski
3 siblings, 0 replies; 5+ messages in thread
From: Andrei Otcheretianski @ 2025-08-13 14:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, maheshkkv, quic_vganneva, Andrei Otcheretianski
The drivers should notify upper layers and user space when a NAN device
joins a cluster. This is needed, for example, to set the correct addr3
in SDF frames. Add API to report cluster join event.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
include/net/cfg80211.h | 14 ++++++++++++
include/uapi/linux/nl80211.h | 8 +++++++
net/wireless/nl80211.c | 41 ++++++++++++++++++++++++++++++++++++
net/wireless/trace.h | 19 +++++++++++++++++
4 files changed, 82 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0556dd6718dc..2f054e8a1cc2 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -10047,6 +10047,20 @@ void cfg80211_epcs_changed(struct net_device *netdev, bool enabled);
void cfg80211_next_nan_dw_notif(struct wireless_dev *wdev,
struct ieee80211_channel *chan, gfp_t gfp);
+/**
+ * cfg80211_nan_cluster_joined - Notify about NAN cluster join
+ * @wdev: Pointer to the wireless device structure
+ * @cluster_id: Cluster ID of the NAN cluster that was joined or started
+ * @new_cluster: Indicates if this is a new cluster or an existing one
+ * @gfp: Memory allocation flags
+ *
+ * This function is used to notify user space when a NAN cluster has been
+ * joined, providing the cluster ID and a flag whether it is a new cluster.
+ */
+void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
+ const u8 *cluster_id, bool new_cluster,
+ 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 3b9c9f2a7d27..0a5915b33705 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1357,6 +1357,9 @@
* 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_NAN_CLUSTER_JOINED: This command is used to notify
+ * user space that the NAN new cluster has been joined. The cluster ID is
+ * indicated by %NL80211_ATTR_MAC.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -1619,6 +1622,7 @@ enum nl80211_commands {
NL80211_CMD_EPCS_CFG,
NL80211_CMD_NAN_NEXT_DW_NOTIFICATION,
+ NL80211_CMD_NAN_CLUSTER_JOINED,
/* add new commands above here */
@@ -2949,6 +2953,9 @@ enum nl80211_commands {
* %NL80211_CMD_START_NAN and %NL80211_CMD_CHANGE_NAN_CONFIG.
* See &enum nl80211_nan_conf_attributes for details.
* This attribute is optional.
+ * @NL80211_ATTR_NAN_NEW_CLUSTER: Flag attribute indicating that a new
+ * NAN cluster has been created. This is used with
+ * %NL80211_CMD_NAN_CLUSTER_JOINED
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3513,6 +3520,7 @@ enum nl80211_attrs {
NL80211_ATTR_S1G_SHORT_BEACON,
NL80211_ATTR_NAN_CONFIG,
+ NL80211_ATTR_NAN_NEW_CLUSTER,
/* add attributes here, update the policy in nl80211.c */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6b77d9c7a901..2ffc3cd6edb9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -21521,6 +21521,47 @@ void cfg80211_next_nan_dw_notif(struct wireless_dev *wdev,
}
EXPORT_SYMBOL(cfg80211_next_nan_dw_notif);
+void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
+ const u8 *cluster_id, bool new_cluster,
+ 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_nan_cluster_joined(wdev, cluster_id, new_cluster);
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_CLUSTER_JOINED);
+ 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(msg, NL80211_ATTR_MAC, ETH_ALEN, cluster_id) ||
+ (new_cluster && nla_put_flag(msg, NL80211_ATTR_NAN_NEW_CLUSTER)))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ if (!wdev->owner_nlportid)
+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy),
+ msg, 0, NL80211_MCGRP_NAN, gfp);
+ else
+ genlmsg_unicast(wiphy_net(wiphy), msg,
+ wdev->owner_nlportid);
+ return;
+
+ nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_cluster_joined);
+
/* initialisation/exit functions */
int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 2ed1b090d519..2173741c9a62 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4238,6 +4238,25 @@ TRACE_EVENT(cfg80211_next_nan_dw_notif,
WDEV_PR_ARG, CHAN_PR_ARG)
);
+TRACE_EVENT(cfg80211_nan_cluster_joined,
+ TP_PROTO(struct wireless_dev *wdev,
+ const u8 *cluster_id,
+ bool new_cluster),
+ TP_ARGS(wdev, cluster_id, new_cluster),
+ TP_STRUCT__entry(
+ WDEV_ENTRY
+ MAC_ENTRY(cluster_id)
+ __field(bool, new_cluster)
+ ),
+ TP_fast_assign(
+ WDEV_ASSIGN;
+ MAC_ASSIGN(cluster_id, cluster_id);
+ __entry->new_cluster = new_cluster;
+ ),
+ TP_printk(WDEV_PR_FMT " cluster_id %pMF%s",
+ WDEV_PR_ARG, __entry->cluster_id,
+ __entry->new_cluster ? " [new]" : "")
+);
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
2.47.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC v3 4/4] wifi: nl80211: Add more NAN capabilities
2025-08-13 14:10 [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations Andrei Otcheretianski
` (2 preceding siblings ...)
2025-08-13 14:10 ` [RFC v3 3/4] wifi: cfg80211: Add cluster joined notification APIs Andrei Otcheretianski
@ 2025-08-13 14:10 ` Andrei Otcheretianski
3 siblings, 0 replies; 5+ messages in thread
From: Andrei Otcheretianski @ 2025-08-13 14:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, maheshkkv, quic_vganneva, Andrei Otcheretianski
Add better break down for NAN capabilities, as NAN has multiple optional
features. This allows to better indicate which features are supported or
or offloaded to the device.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
include/uapi/linux/nl80211.h | 61 ++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 0a5915b33705..8452d4470068 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2956,6 +2956,10 @@ enum nl80211_commands {
* @NL80211_ATTR_NAN_NEW_CLUSTER: Flag attribute indicating that a new
* NAN cluster has been created. This is used with
* %NL80211_CMD_NAN_CLUSTER_JOINED
+ * @NL80211_ATTR_NAN_CAPABILITIES: Nested attribute for NAN capabilities.
+ * This is used with %NL80211_CMD_GET_WIPHY to indicate the NAN
+ * capabilities supported by the driver. See &enum nl80211_nan_capabilities
+ * for details.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3521,6 +3525,7 @@ enum nl80211_attrs {
NL80211_ATTR_NAN_CONFIG,
NL80211_ATTR_NAN_NEW_CLUSTER,
+ NL80211_ATTR_NAN_CAPABILITIES,
/* add attributes here, update the policy in nl80211.c */
@@ -8325,4 +8330,60 @@ enum nl80211_s1g_short_beacon_attrs {
__NL80211_S1G_SHORT_BEACON_ATTR_LAST - 1
};
+/**
+ * enum nl80211_nan_capabilities - NAN (Neighbor Aware Networking)
+ * capabilities.
+ *
+ * @__NL80211_NAN_CAPABILITIES_INVALID: Invalid.
+ * @NL80211_NAN_CAPA_CONFIGURABLE_SYNC: Flag attribute indicating that
+ * the device supports configurable synchronization. If set, the device
+ * should be able to handle %NL80211_ATTR_NAN_CONFIG
+ * attribute in the %NL80211_CMD_START_NAN (and change) command.
+ * @NL80211_NAN_CAPA_USERSPACE_DE: Flag attribute indicating that
+ * NAN Discovery Engine (DE) is not offloaded and the driver assumes
+ * user space DE implementation. When set, %NL80211_CMD_ADD_NAN_FUNCTION,
+ * %NL80211_CMD_DEL_NAN_FUNCTION and %NL80211_CMD_NAN_MATCH commands
+ * should not be used. In addition, the device/driver should support
+ * sending discovery window (DW) notifications using
+ * %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION and handling transmission and
+ * reception of NAN SDF frames on NAN device interface during DW windows.
+ * (%NL80211_CMD_FRAME is used to transmit SDFs)
+ * @NL80211_NAN_CAPA_OP_MODE: u8 attribute indicating the supported operation
+ * modes as defined in Wi-Fi Aware (TM) specification Table 81 (Operation
+ * Mode field format).
+ * @NL80211_NAN_CAPA_NUM_ANTENNAS: u8 attribute indicating the number of
+ * TX and RX antennas supported by the device. Lower nibble indicates
+ * the number of TX antennas and upper nibble indicates the number of RX
+ * antennas. Value 0 indicates the information is not available.
+ * See table 79 of Wi-Fi Aware (TM) specification (Number of
+ * Antennas field).
+ * @NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME: u16 attribute indicating the
+ * maximum time in microseconds that the device requires to switch
+ * channels.
+ * @NL80211_NAN_CAPA_CAPABILITIES: u8 attribute containing the
+ * capabilities of the device as defined in Wi-Fi Aware (TM)
+ * specification Table 79 (Capabilities field).
+ * @NL80211_NAN_CONF_EXTRA_ATTRS_MAX_LEN: Maximum length of extra NAN
+ * attributes. See %NL80211_NAN_CONF_EXTRA_ATTRS. This is u16.
+ * @NL80211_NAN_CONF_VENDOR_ELEMS_MAX_LEN: Maximum length of NAN vendor
+ * elements. See %NL80211_NAN_CONF_VENDOR_ELEMS. This is u16.
+ * @__NL80211_NAN_CAPABILITIES_LAST: Internal
+ * @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.
+ */
+enum nl80211_nan_capabilities {
+ __NL80211_NAN_CAPABILITIES_INVALID,
+
+ NL80211_NAN_CAPA_CONFIGURABLE_SYNC,
+ NL80211_NAN_CAPA_USERSPACE_DE,
+ NL80211_NAN_CAPA_OP_MODE,
+ NL80211_NAN_CAPA_NUM_ANTENNAS,
+ NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,
+ NL80211_NAN_CAPA_CAPABILITIES,
+ NL80211_NAN_CONF_EXTRA_ATTRS_MAX_LEN,
+ NL80211_NAN_CONF_VENDOR_ELEMS_MAX_LEN,
+ /* keep last */
+ __NL80211_NAN_CAPABILITIES_LAST,
+ NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,
+};
+
#endif /* __LINUX_NL80211_H */
--
2.47.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-08-13 11:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-13 14:10 [RFC v3 0/4] wifi: nl80211: Extend NAN APIs to allow more flexible implementations Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 1/4] wifi: nl80211: Add more configuration options for NAN commands Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 2/4] wifi: nl80211: Add NAN Discovery Window (DW) notification Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 3/4] wifi: cfg80211: Add cluster joined notification APIs Andrei Otcheretianski
2025-08-13 14:10 ` [RFC v3 4/4] wifi: nl80211: Add more NAN capabilities Andrei Otcheretianski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).