Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support
@ 2026-10-01 13:33 Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 1/7] wifi: cfg80211: nan: add " Miri Korenblit
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Hi,
This series adds support for NAN Instant Communication, including hwsim
support.

Thanks,
Miri
--- 

Ilan Peer (7):
  wifi: cfg80211: nan: add Instant Communication support
  wifi: mac80211: nan: Update NAN configuration copy
  wifi: cfg80211: nan: check Rx registration for NAN beacons
  wifi: mac80211: nan: allow Rx registration for NAN beacons
  wifi: ieee80211: add NAN service ID list attribute definitions
  wifi: mac80211_hwsim: nan: use ieee80211_is_nan_beacon() helper
  wifi: mac80211_hwsim: add NAN Instant Communication support

 .../wireless/virtual/mac80211_hwsim_main.c    |   7 +-
 .../net/wireless/virtual/mac80211_hwsim_nan.c | 246 +++++++++++++++---
 .../net/wireless/virtual/mac80211_hwsim_nan.h |   8 +
 include/linux/ieee80211-nan.h                 |  28 ++
 include/net/cfg80211.h                        |   9 +-
 include/uapi/linux/nl80211.h                  |  12 +
 net/mac80211/cfg.c                            |   1 +
 net/mac80211/main.c                           |   7 +-
 net/mac80211/rx.c                             |  11 +-
 net/mac80211/scan.c                           |   4 +
 net/wireless/core.c                           |   5 +
 net/wireless/mlme.c                           |   9 +
 net/wireless/nl80211.c                        |  22 ++
 13 files changed, 323 insertions(+), 46 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 1/7] wifi: cfg80211: nan: add Instant Communication support
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 2/7] wifi: mac80211: nan: Update NAN configuration copy Miri Korenblit
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Add NL80211_NAN_CONF_INSTANT_COMM flag to let user space request that
the NAN synchronization logic starts Instant Communication (IC) as
defined in Chapter 13 of the Wi-Fi Aware Specification v4.0.

Add NL80211_NAN_CAPA_INSTANT_COMM for drivers to advertise it. The
capability requires configurable synchronization support, and IC
requests are rejected if it isn't advertised.

When IC is enabled, user space must also configure the discovery
beacon interval. The IC schedule is expected to be configured
by user space.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/net/cfg80211.h       |  9 ++++++++-
 include/uapi/linux/nl80211.h | 12 ++++++++++++
 net/wireless/core.c          |  5 +++++
 net/wireless/nl80211.c       | 22 ++++++++++++++++++++++
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b603f1804cc2..96b5bf8b8ff3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4191,9 +4191,12 @@ struct cfg80211_nan_band_config {
  *	that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
  * @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.
+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be
+ *	greater than 0 when @instant_comm is true.
  * @enable_dw_notification: flag to enable/disable discovery window
  *	notifications.
+ * @instant_comm: if true, start Instant Communication (IC) as defined in
+ *	Chapter 13 of the Wi-Fi Aware Specification v4.0.
  * @band_cfgs: array of band specific configurations, indexed by
  *	&enum nl80211_band values.
  * @extra_nan_attrs: pointer to additional NAN attributes.
@@ -4209,6 +4212,7 @@ struct cfg80211_nan_conf {
 	u16 scan_dwell_time;
 	u8 discovery_beacon_interval;
 	bool enable_dw_notification;
+	bool instant_comm;
 	struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
 	const u8 *extra_nan_attrs;
 	u16 extra_nan_attrs_len;
@@ -6305,10 +6309,13 @@ struct wiphy_radio {
  * @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable
  *     synchronization.
  * @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.
+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication
+ *     (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.
  */
 enum wiphy_nan_flags {
 	WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),
 	WIPHY_NAN_FLAGS_USERSPACE_DE   = BIT(1),
+	WIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 75d4c5d6a7a3..21d98c1ec424 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -7890,6 +7890,11 @@ enum nl80211_nan_band_conf_attributes {
  *	the upcoming discovery window with
  *	%NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
  *	This is a flag attribute.
+ * @NL80211_NAN_CONF_INSTANT_COMM: If set, the NAN synchronization logic will
+ *	start Instant Communication (IC) as defined in Chapter 13 of the
+ *	Wi-Fi Aware Specification v4.0.
+ *	%NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL must be set as well.
+ *	This is a flag attribute.
  * @NUM_NL80211_NAN_CONF_ATTR: Internal.
  * @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
  *
@@ -7905,6 +7910,7 @@ enum nl80211_nan_conf_attributes {
 	NL80211_NAN_CONF_SCAN_DWELL_TIME,
 	NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
 	NL80211_NAN_CONF_NOTIFY_DW,
+	NL80211_NAN_CONF_INSTANT_COMM,
 
 	/* keep last */
 	NUM_NL80211_NAN_CONF_ATTR,
@@ -9121,6 +9127,11 @@ enum nl80211_s1g_short_beacon_attrs {
  *	specification Table 79 (Capabilities field).
  * @NL80211_NAN_CAPA_PHY: nested attribute containing band-agnostic
  *	capabilities for NAN data path. See &enum nl80211_nan_phy_cap_attr.
+ * @NL80211_NAN_CAPA_INSTANT_COMM: Flag attribute indicating that the device
+ *	can switch to Instant Communication (IC) mode, as defined in Chapter 13
+ *	of the Wi-Fi Aware Specification v4.0. Can only be set if
+ *	%NL80211_NAN_CAPA_CONFIGURABLE_SYNC is set. When IC is enabled, the IC
+ *	schedule is expected to be configured by user space.
  * @__NL80211_NAN_CAPABILITIES_LAST: Internal
  * @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.
  */
@@ -9134,6 +9145,7 @@ enum nl80211_nan_capabilities {
 	NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,
 	NL80211_NAN_CAPA_CAPABILITIES,
 	NL80211_NAN_CAPA_PHY,
+	NL80211_NAN_CAPA_INSTANT_COMM,
 	/* keep last */
 	__NL80211_NAN_CAPABILITIES_LAST,
 	NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index dc1e0522340a..9176659345f0 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -964,6 +964,11 @@ int wiphy_register(struct wiphy *wiphy)
 		    (!wiphy->nan_capa.phy.ht.ht_supported || wiphy->n_radio > 1)))
 		return -EINVAL;
 
+	if (WARN_ON((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+		    !(wiphy->nan_capa.flags &
+		      WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC)))
+		return -EINVAL;
+
 	if (WARN_ON(wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)))
 		return -EINVAL;
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 16c63383923b..fa4379955dea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -687,6 +687,7 @@ nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {
 	[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL] =
 		NLA_POLICY_RANGE(NLA_U8, 50, 200),
 	[NL80211_NAN_CONF_NOTIFY_DW] = { .type = NLA_FLAG },
+	[NL80211_NAN_CONF_INSTANT_COMM] = { .type = NLA_FLAG },
 };
 
 static const struct netlink_range_validation nl80211_punct_bitmap_range = {
@@ -3036,6 +3037,10 @@ static int nl80211_put_nan_capa(struct wiphy *wiphy, struct sk_buff *msg)
 	    nla_put_flag(msg, NL80211_NAN_CAPA_USERSPACE_DE))
 		goto fail;
 
+	if ((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+	    nla_put_flag(msg, NL80211_NAN_CAPA_INSTANT_COMM))
+		goto fail;
+
 	if (nla_put_u8(msg, NL80211_NAN_CAPA_OP_MODE,
 		       wiphy->nan_capa.op_mode) ||
 	    nla_put_u8(msg, NL80211_NAN_CAPA_NUM_ANTENNAS,
@@ -16780,6 +16785,23 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,
 		conf->enable_dw_notification =
 			nla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);
 
+	conf->instant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);
+	if (conf->instant_comm) {
+		if (!(wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM)) {
+			NL_SET_ERR_MSG_ATTR(info->extack,
+					    attrs[NL80211_NAN_CONF_INSTANT_COMM],
+					    "Instant Communication is not supported");
+			return -EOPNOTSUPP;
+		}
+
+		if (!conf->discovery_beacon_interval) {
+			NL_SET_ERR_MSG_ATTR(info->extack,
+					    attrs[NL80211_NAN_CONF_INSTANT_COMM],
+					    "Instant Communication requires a discovery beacon interval");
+			return -EINVAL;
+		}
+	}
+
 out:
 	if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
 	    (!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 2/7] wifi: mac80211: nan: Update NAN configuration copy
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 1/7] wifi: cfg80211: nan: add " Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons Miri Korenblit
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Copy the Instant Communication flag when storing the NAN
configuration.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/mac80211/cfg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bd1a857c812d..eeab1b515e77 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -368,6 +368,7 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
 		dst->discovery_beacon_interval =
 			src->discovery_beacon_interval;
 		dst->enable_dw_notification = src->enable_dw_notification;
+		dst->instant_comm = src->instant_comm;
 		memcpy(&dst->band_cfgs, &src->band_cfgs,
 		       sizeof(dst->band_cfgs));
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 1/7] wifi: cfg80211: nan: add " Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 2/7] wifi: mac80211: nan: Update NAN configuration copy Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-02  7:03   ` Johannes Berg
  2026-10-01 13:33 ` [PATCH wireless-next 4/7] wifi: mac80211: nan: allow " Miri Korenblit
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Instant Communication requires user space to track the NAN beacons, so
let it register for Rx of beacons on a NAN interface, but allow it
only if the driver advertises Instant Communication support.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/wireless/mlme.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index a0d1cde26f0c..801d5b811ac1 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -749,6 +749,15 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 		return -EINVAL;
 	}
 
+	/* NAN beacons are only reported while Instant Communication is used */
+	if (wdev->iftype == NL80211_IFTYPE_NAN &&
+	    (frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON &&
+	    !(wdev->wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM)) {
+		NL_SET_ERR_MSG(extack,
+			       "Instant Communication is not supported");
+		return -EOPNOTSUPP;
+	}
+
 	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
 	if (!nreg)
 		return -ENOMEM;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 4/7] wifi: mac80211: nan: allow Rx registration for NAN beacons
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
                   ` (2 preceding siblings ...)
  2026-10-01 13:33 ` [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-02  7:10   ` Johannes Berg
  2026-10-01 13:33 ` [PATCH wireless-next 5/7] wifi: ieee80211: add NAN service ID list attribute definitions Miri Korenblit
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Instant Communication requires user space to track the NAN beacons, so
let it register for Rx of beacons on a NAN interface. Add support for
passing beacon on NAN Device interface when instant communication is
enabled.

Add a helper function to identify NAN beacons, based on the BSSID
and the beacon frame content. Skip NAN beacons so they would not
be used to update the BSS table.

Assisted-by: GitHubCopilot:claude-opus-5
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/linux/ieee80211-nan.h | 26 ++++++++++++++++++++++++++
 net/mac80211/main.c           |  7 ++++++-
 net/mac80211/rx.c             | 11 ++++++++++-
 net/mac80211/scan.c           |  4 ++++
 4 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h
index 455033955e54..b332a94671ba 100644
--- a/include/linux/ieee80211-nan.h
+++ b/include/linux/ieee80211-nan.h
@@ -74,4 +74,30 @@ struct ieee80211_nan_anchor_master_info {
 	     _attr = (const struct ieee80211_nan_attr *)		\
 		(_attr->data + le16_to_cpu(_attr->length)))
 
+static inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,
+					   size_t len)
+{
+	const struct element *elem;
+
+	/* The NAN IE is at least 6 octets */
+	if (len < offsetofend(struct ieee80211_mgmt, u.beacon) + 6)
+		return false;
+
+	if (!ieee80211_is_beacon(mgmt->frame_control))
+		return false;
+
+	/* NAN Cluster IDs range from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF */
+	if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
+		return false;
+
+	elem = (const struct element *)mgmt->u.beacon.variable;
+	if (elem->id != WLAN_EID_VENDOR_SPECIFIC ||
+	    elem->datalen < 4 ||
+	    get_unaligned_be32(elem->data) !=
+	    (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+		return false;
+
+	return true;
+}
+
 #endif /* LINUX_IEEE80211_NAN_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 7816395681fa..b889d2a7ef75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -745,8 +745,13 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 	},
 	[NL80211_IFTYPE_NAN] = {
 		.tx = 0xffff,
+		/*
+		 * Beacon Rx registration is needed to let user space handle
+		 * service discovery when Instant Communication is enabled.
+		 */
 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-			BIT(IEEE80211_STYPE_AUTH >> 4),
+			BIT(IEEE80211_STYPE_AUTH >> 4) |
+			BIT(IEEE80211_STYPE_BEACON >> 4),
 	},
 	[NL80211_IFTYPE_NAN_DATA] = {
 		.tx = 0xffff,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b3990b7a7299..8dde57a9112f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4536,7 +4536,10 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 	struct ieee80211_hdr *hdr = (void *)skb->data;
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
+	bool nan_beacon = ieee80211_is_nan_beacon((struct ieee80211_mgmt *)hdr,
+						  skb->len);
 	bool multicast;
+
 	static const u8 nan_network_id[ETH_ALEN] __aligned(2) = {
 		0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00
 	};
@@ -4545,6 +4548,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 		return sdata->vif.type == NL80211_IFTYPE_STATION && bssid;
 
 	multicast = is_multicast_ether_addr(hdr->addr1);
+	/* Only a NAN interface may handle NAN beacons */
+	if (nan_beacon && sdata->vif.type != NL80211_IFTYPE_NAN)
+		return false;
 
 	switch (sdata->vif.type) {
 	case NL80211_IFTYPE_STATION:
@@ -4681,7 +4687,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 		 * Accept only frames that are addressed to the NAN cluster
 		 * (based on the Cluster ID). From these frames, accept only
 		 *  - public action frames,
-		 *  - authentication frames to the local address, and
+		 *  - authentication frames to the local address,
+		 *  - NAN beacons, when Instant Communication is enabled, and
 		 *  - robust management frames except disassoc.
 		 */
 		if (!ether_addr_equal(sdata->u.nan.conf.cluster_id, hdr->addr3))
@@ -4691,6 +4698,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
 		if (ieee80211_is_auth(hdr->frame_control) &&
 		    ether_addr_equal(sdata->vif.addr, hdr->addr1))
 			return true;
+		if (nan_beacon)
+			return sdata->u.nan.conf.instant_comm;
 		if (!ieee80211_is_disassoc(hdr->frame_control) &&
 		    ieee80211_is_robust_mgmt_frame(skb))
 			return true;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index a4bca412e577..fc8d090bfd7c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -353,6 +353,10 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
 		if (!ieee80211_is_s1g_beacon(mgmt->frame_control) &&
 		    !is_broadcast_ether_addr(mgmt->da))
 			return;
+
+		/* NAN beacons are not a BSS, don't add to the BSS table */
+		if (ieee80211_is_nan_beacon(mgmt, skb->len))
+			return;
 	}
 
 	/* Do not update the BSS table in case of only monitor interfaces */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 5/7] wifi: ieee80211: add NAN service ID list attribute definitions
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
                   ` (3 preceding siblings ...)
  2026-10-01 13:33 ` [PATCH wireless-next 4/7] wifi: mac80211: nan: allow " Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 6/7] wifi: mac80211_hwsim: nan: use ieee80211_is_nan_beacon() helper Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support Miri Korenblit
  6 siblings, 0 replies; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Add the Service ID List and Subscribe Service ID List NAN attribute
IDs. These are needed to filter in NAN beacons during Instant
Communication.

Assisted-by: GitHubCopilot:claude-opus-5
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/linux/ieee80211-nan.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h
index b332a94671ba..7815a6cf8160 100644
--- a/include/linux/ieee80211-nan.h
+++ b/include/linux/ieee80211-nan.h
@@ -40,6 +40,8 @@
 /* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */
 #define NAN_ATTR_MASTER_INDICATION		0x00
 #define NAN_ATTR_CLUSTER_INFO			0x01
+#define NAN_ATTR_SERVICE_ID_LIST		0x02
+#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST	0x28
 
 struct ieee80211_nan_attr {
 	u8 attr;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 6/7] wifi: mac80211_hwsim: nan: use ieee80211_is_nan_beacon() helper
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
                   ` (4 preceding siblings ...)
  2026-10-01 13:33 ` [PATCH wireless-next 5/7] wifi: ieee80211: add NAN service ID list attribute definitions Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-01 13:33 ` [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support Miri Korenblit
  6 siblings, 0 replies; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer

From: Ilan Peer <ilan.peer@intel.com>

Use the new ieee80211_is_nan_beacon() helper to identify NAN beacons
instead of open-coding the cluster ID and vendor element checks.

Assisted-by: GitHubCopilot:claude-opus-5
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/virtual/mac80211_hwsim_nan.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
index 2d9f6d7b9251..fab6bd9e3cfb 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
@@ -230,9 +230,7 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
 	ssize_t data_len;
 	u8 slot;
 
-	/* Need a NAN vendor element at the start */
-	if (skb->len < (offsetofend(struct ieee80211_mgmt, u.beacon) + 6) ||
-	    !ieee80211_is_beacon(mgmt->frame_control))
+	if (!ieee80211_is_nan_beacon(mgmt, skb->len))
 		return;
 
 	data_len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
@@ -279,17 +277,6 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
 	if (rx_status.signal < NAN_RSSI_MIDDLE)
 		return;
 
-	/* Needs to be a valid NAN cluster ID in A3 */
-	if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
-		return;
-
-	/* We are only interested in NAN beacons */
-	if (nan_elem->id != WLAN_EID_VENDOR_SPECIFIC ||
-	    nan_elem->datalen < 4 ||
-	    get_unaligned_be32(nan_elem->data) !=
-	    (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
-		return;
-
 	u8 *nan_defragmented __free(kfree) = kzalloc(data_len, GFP_ATOMIC);
 	if (!nan_defragmented)
 		return;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support
  2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
                   ` (5 preceding siblings ...)
  2026-10-01 13:33 ` [PATCH wireless-next 6/7] wifi: mac80211_hwsim: nan: use ieee80211_is_nan_beacon() helper Miri Korenblit
@ 2026-10-01 13:33 ` Miri Korenblit
  2026-10-02  7:26   ` Johannes Berg
  6 siblings, 1 reply; 13+ messages in thread
From: Miri Korenblit @ 2026-10-01 13:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ilan Peer, Benjamin Berg

From: Ilan Peer <ilan.peer@intel.com>

Advertise Instant Communication support, and when it is enabled transmit
the discovery beacons disregarding the role and the state, with the
configured beacon interval and the NAN attributes set by user space.

In addition, accept beacons that carry a Service ID List or a Subscribe
Service ID List attribute at any time, so that they are forwarded to
mac80211.

When in instant communication, discovery beacons received during
non DW slots are processed for anchor master tracking and
synchronization.

Assisted-by: GitHubCopilot:claude-opus-5
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../wireless/virtual/mac80211_hwsim_main.c    |   7 +-
 .../net/wireless/virtual/mac80211_hwsim_nan.c | 231 +++++++++++++++---
 .../net/wireless/virtual/mac80211_hwsim_nan.h |   8 +
 3 files changed, 217 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 762f99eb15e4..7e65474c9df1 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -1775,6 +1775,7 @@ struct tx_iter_data {
 	struct ieee80211_channel *channel;
 	struct ieee80211_rx_status *rx_status;
 	struct ieee80211_hw *hw;
+	struct sk_buff *skb;
 	bool receive;
 };
 
@@ -1787,6 +1788,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
 	if (vif->type == NL80211_IFTYPE_NAN ||
 	    vif->type == NL80211_IFTYPE_NAN_DATA) {
 		data->receive = mac80211_hwsim_nan_receive(data->hw,
+							   data->skb,
 							   data->channel,
 							   data->rx_status);
 		return;
@@ -1968,6 +1970,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
 			.hw = data2->hw,
 			.channel = chan,
 			.rx_status = &rx_status,
+			.skb = skb,
 		};
 
 		if (data == data2)
@@ -5841,7 +5844,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 						 BIT(NL80211_BAND_5GHZ);
 
 		hw->wiphy->nan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC |
-					    WIPHY_NAN_FLAGS_USERSPACE_DE;
+					    WIPHY_NAN_FLAGS_USERSPACE_DE |
+					    WIPHY_NAN_FLAGS_INSTANT_COMM;
 		hw->wiphy->nan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK |
 					      NAN_OP_MODE_80P80MHZ |
 					      NAN_OP_MODE_160MHZ;
@@ -6643,6 +6647,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 		struct tx_iter_data iter_data = {
 			.hw = data2->hw,
 			.rx_status = &rx_status,
+			.skb = skb,
 		};
 
 		/* throw away off-channel packets, but allow both the temporary
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
index fab6bd9e3cfb..79c41a66a07e 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
@@ -33,6 +33,12 @@ static_assert(DW0_TSF_MASK + 1 == 8192 * 1024);
 #define NAN_RSSI_CLOSE (-60)
 #define NAN_RSSI_MIDDLE (-75)
 
+/* Size of the NAN vendor element carrying the mandatory attributes */
+#define NAN_BEACON_ELEM_LEN		27
+
+/* Space left in the NAN vendor element for the configured attributes */
+#define NAN_BEACON_EXTRA_ATTRS_LEN	(255 - (NAN_BEACON_ELEM_LEN - 2))
+
 /* Quiet time at the end of each slot where TX is suppressed */
 #define NAN_CHAN_SWITCH_TIME_US		256
 
@@ -213,6 +219,37 @@ mac80211_hwsim_nan_schedule_slot(struct mac80211_hwsim_data *data, u8 slot,
 			    mac80211_hwsim_tsf_to_boottime(data, tsf));
 }
 
+static bool hwsim_nan_beacon_has_service_ids(struct sk_buff *skb)
+{
+	const struct ieee80211_mgmt *mgmt = (void *)skb->data;
+	const struct ieee80211_nan_attr *nan_attr;
+	const struct element *elem;
+	size_t len;
+
+	if (skb->len < offsetofend(struct ieee80211_mgmt, u.beacon) ||
+	    !ieee80211_is_beacon(mgmt->frame_control))
+		return false;
+
+	len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
+
+	/* TODO: fragmented NAN elements are not supported */
+	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,
+			    mgmt->u.beacon.variable, len) {
+		if (elem->datalen < 4 ||
+		    get_unaligned_be32(elem->data) !=
+		    (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+			continue;
+
+		for_each_nan_attr(nan_attr, elem->data + 4, elem->datalen - 4)
+			if (nan_attr->attr == NAN_ATTR_SERVICE_ID_LIST ||
+			    nan_attr->attr ==
+			    NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST)
+				return true;
+	}
+
+	return false;
+}
+
 void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
 			   struct sk_buff *skb)
 {
@@ -263,15 +300,26 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
 		slot = hwsim_nan_slot_from_tsf(rx_status.mactime);
 	}
 
+	/* (overly) simplify things, only track 2.4 GHz here */
+	if (rx_status.freq != 2437)
+		return;
+
 	/*
-	 * (overly) simplify things, only track 2.4 GHz here. Also, ignore
-	 * frames outside of the 2.4 GHz DW slot, unless in the initial SCAN
-	 * phase.
+	 * Ignore frames outside of the 2.4 GHz DW slot, unless in the initial
+	 * SCAN phase or in Instant Communication, where discovery beacons are
+	 * received outside the DW.
 	 */
-	if ((slot != SLOT_24GHZ_DW &&
-	     data->nan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||
-	    rx_status.freq != 2437)
-		return;
+	if (slot != SLOT_24GHZ_DW) {
+		bool rx_outside_dw;
+
+		scoped_guard(spinlock_bh, &data->nan.state_lock)
+			rx_outside_dw = data->nan.instant_comm ||
+				data->nan.phase ==
+				MAC80211_HWSIM_NAN_PHASE_SCAN;
+
+		if (!rx_outside_dw)
+			return;
+	}
 
 	/* Just ignore low RSSI beacons that we cannot sync to */
 	if (rx_status.signal < NAN_RSSI_MIDDLE)
@@ -623,10 +671,12 @@ mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)
 
 	/*
 	 * The discovery beacon timer will stop automatically. Make sure it is
-	 * running if we are master. Do not bother with a proper alignment it
-	 * will sync itself to the TSF after the first TX.
+	 * running if we are master or if Instant Communication is enabled. Do
+	 * not bother with a proper alignment it will sync itself to the TSF
+	 * after the first TX.
 	 */
-	if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER &&
+	if ((data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||
+	     data->nan.instant_comm) &&
 	    !hrtimer_active(&data->nan.discovery_beacon_timer))
 		hrtimer_start(&data->nan.discovery_beacon_timer,
 			      ns_to_ktime(10 * NSEC_PER_USEC),
@@ -685,7 +735,7 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
 {
 	struct ieee80211_vendor_ie nan_ie = {
 		.element_id = WLAN_EID_VENDOR_SPECIFIC,
-		.len = 27 - 2,
+		.len = NAN_BEACON_ELEM_LEN - 2,
 		.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),
 			 u32_get_bits(WLAN_OUI_WFA, 0xff00),
 			 u32_get_bits(WLAN_OUI_WFA, 0xff) },
@@ -694,23 +744,39 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
 	size_t alloc_size =
 		IEEE80211_TX_STATUS_HEADROOM +
 		offsetofend(struct ieee80211_mgmt, u.beacon) +
-		27 /* size of NAN vendor element */;
+		NAN_BEACON_ELEM_LEN;
 	struct ieee80211_nan_master_indication master_indication;
 	struct ieee80211_nan_attr nan_attr;
 	struct ieee80211_mgmt *mgmt;
 	struct sk_buff *skb;
+	u16 beacon_int;
 
 	/*
-	 * TODO: Should the configured vendor elements or NAN attributes be
-	 * included in some of these beacons?
+	 * TODO: Should the configured vendor elements be included in some of
+	 * these beacons?
 	 */
 
+	/* Allocate maximal size for NAN IE */
+	if (is_discovery)
+		alloc_size += NAN_BEACON_EXTRA_ATTRS_LEN;
+
 	skb = alloc_skb(alloc_size, GFP_ATOMIC);
 	if (!skb)
 		return;
 
 	spin_lock(&data->nan.state_lock);
 
+	/*
+	 * The attributes configured by user space, e.g. the Service ID List
+	 * and Subscribe Service ID List attributes (needed for Instant
+	 * Communication), are appended to the mandatory ones.
+	 */
+	if (is_discovery)
+		nan_ie.len += data->nan.extra_nan_attrs_len;
+
+	beacon_int = is_discovery ? data->nan.discovery_beacon_interval :
+		DWST_TU;
+
 	skb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);
 	mgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));
 
@@ -721,7 +787,7 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
 
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_BEACON);
-	mgmt->u.beacon.beacon_int = cpu_to_le16(is_discovery ? 100 : DWST_TU);
+	mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
 	mgmt->u.beacon.capab_info =
 		cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |
 			    WLAN_CAPABILITY_SHORT_PREAMBLE);
@@ -752,6 +818,10 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
 	skb_put_data(skb, &data->nan.current_ami,
 		     sizeof(data->nan.current_ami));
 
+	if (is_discovery && data->nan.extra_nan_attrs_len)
+		skb_put_data(skb, data->nan.extra_nan_attrs,
+			     data->nan.extra_nan_attrs_len);
+
 	spin_unlock(&data->nan.state_lock);
 
 	mac80211_hwsim_tx_frame(data->hw, skb, channel);
@@ -856,6 +926,7 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
 	struct mac80211_hwsim_data *data =
 		container_of(timer, struct mac80211_hwsim_data,
 			     nan.discovery_beacon_timer);
+	u16 beacon_int;
 	u32 remainder;
 	u64 tsf_now;
 	u64 tbtt;
@@ -864,11 +935,21 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
 		return HRTIMER_NORESTART;
 
 	scoped_guard(spinlock, &data->nan.state_lock) {
-		if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||
+		if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
+			return HRTIMER_NORESTART;
+
+		/*
+		 * With Instant Communication the discovery beacons are
+		 * transmitted disregarding the role and the state, see
+		 * Wi-Fi Aware version 4.0 section 13.
+		 */
+		if (!data->nan.instant_comm &&
 		    data->nan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)
 			return HRTIMER_NORESTART;
 	}
 
+	beacon_int = data->nan.discovery_beacon_interval;
+
 	mac80211_hwsim_nan_tx_beacon(
 		data, true, ieee80211_get_channel(data->hw->wiphy, 2437));
 
@@ -881,10 +962,10 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
 	tsf_now = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
 
 	/* Wrap value to be after the next TBTT */
-	tbtt = tsf_now + ieee80211_tu_to_usec(100);
+	tbtt = tsf_now + ieee80211_tu_to_usec(beacon_int);
 
 	/* Round TBTT down to the correct time */
-	div_u64_rem(tbtt, ieee80211_tu_to_usec(100), &remainder);
+	div_u64_rem(tbtt, ieee80211_tu_to_usec(beacon_int), &remainder);
 	tbtt = tbtt - remainder;
 
 	hrtimer_set_expires(&data->nan.discovery_beacon_timer,
@@ -905,11 +986,51 @@ mac80211_hwsim_nan_sched_update_work(struct wiphy *wiphy,
 		ieee80211_nan_sched_update_done(data->nan.device_vif);
 }
 
+static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,
+					 struct cfg80211_nan_conf *conf)
+{
+	const u8 *extra_nan_attrs = NULL;
+	const u8 *old;
+
+	if (conf->extra_nan_attrs_len > NAN_BEACON_EXTRA_ATTRS_LEN)
+		return -EINVAL;
+
+	if (conf->extra_nan_attrs_len) {
+		extra_nan_attrs = kmemdup(conf->extra_nan_attrs,
+					  conf->extra_nan_attrs_len,
+					  GFP_KERNEL);
+		if (!extra_nan_attrs)
+			return -ENOMEM;
+	}
+
+	data->nan.notify_dw = conf->enable_dw_notification;
+
+	scoped_guard(spinlock_bh, &data->nan.state_lock) {
+		/*
+		 * Fall back to the device default if user space did not
+		 * configure it
+		 */
+		data->nan.discovery_beacon_interval =
+			conf->discovery_beacon_interval ? : 100;
+
+		data->nan.instant_comm = conf->instant_comm;
+
+		old = data->nan.extra_nan_attrs;
+		data->nan.extra_nan_attrs = extra_nan_attrs;
+		data->nan.extra_nan_attrs_len = conf->extra_nan_attrs_len;
+	}
+
+	kfree(old);
+
+	return 0;
+}
+
 int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     struct cfg80211_nan_conf *conf)
 {
 	struct mac80211_hwsim_data *data = hw->priv;
+	int err;
 
 	if (vif->type != NL80211_IFTYPE_NAN)
 		return -EINVAL;
@@ -917,6 +1038,10 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
 	if (data->nan.device_vif)
 		return -EALREADY;
 
+	err = mac80211_hwsim_nan_set_config(data, conf);
+	if (err)
+		return err;
+
 	/* set this before starting the timer, as preemption might occur */
 	data->nan.device_vif = vif;
 	data->nan.bands = conf->bands;
@@ -925,9 +1050,13 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
 				mac80211_hwsim_nan_sched_update_work);
 
 	scoped_guard(spinlock_bh, &data->nan.state_lock) {
-		/* Start in the "scan" phase and stay there for a little bit */
+		/*
+		 * Start in the "scan" phase and stay there for a little bit,
+		 * unless Instant Communication is configured, in which case an
+		 * own cluster is started immediately.
+		 */
 		data->nan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;
-		data->nan.random_factor_valid_dwst = 1;
+		data->nan.random_factor_valid_dwst = conf->instant_comm ? 0 : 1;
 		data->nan.random_factor = 0;
 		data->nan.master_pref = conf->master_pref;
 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;
@@ -945,8 +1074,6 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
 
 	ether_addr_copy(data->nan.cluster_id, conf->cluster_id);
 
-	data->nan.notify_dw = conf->enable_dw_notification;
-
 	return 0;
 }
 
@@ -954,6 +1081,7 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
 			    struct ieee80211_vif *vif)
 {
 	struct mac80211_hwsim_data *data = hw->priv;
+	const u8 *old;
 
 	if (vif->type != NL80211_IFTYPE_NAN || !data->nan.device_vif ||
 	    data->nan.device_vif != vif)
@@ -965,6 +1093,15 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
 	wiphy_delayed_work_cancel(hw->wiphy, &data->nan.sched_update_work);
 	data->nan.device_vif = NULL;
 
+	scoped_guard(spinlock_bh, &data->nan.state_lock) {
+		old = data->nan.extra_nan_attrs;
+		data->nan.extra_nan_attrs = NULL;
+		data->nan.extra_nan_attrs_len = 0;
+		data->nan.instant_comm = false;
+	}
+
+	kfree(old);
+
 	return 0;
 }
 
@@ -983,13 +1120,27 @@ int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,
 
 	wiphy_debug(hw->wiphy, "nan_config_changed: changes=0x%x\n", changes);
 
+	if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG) {
+		int err = mac80211_hwsim_nan_set_config(data, conf);
+
+		if (err)
+			return err;
+
+		/*
+		 * When Instant Communication is enabled discovery beacons are
+		 * transmitted regardless of the role and the state.
+		 */
+		if (conf->instant_comm &&
+		    !hrtimer_active(&data->nan.discovery_beacon_timer))
+			hrtimer_start(&data->nan.discovery_beacon_timer,
+				      ns_to_ktime(10 * NSEC_PER_USEC),
+				      HRTIMER_MODE_REL_SOFT);
+	}
+
 	/* Handle only the changes we care about for simulation purposes */
 	if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
 		data->nan.bands = conf->bands;
 
-	if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG)
-		data->nan.notify_dw = conf->enable_dw_notification;
-
 	if (changes & CFG80211_NAN_CONF_CHANGED_PREF) {
 		scoped_guard(spinlock_bh, &data->nan.state_lock)
 			data->nan.master_pref = conf->master_pref;
@@ -1172,9 +1323,16 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
 	is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
 
 	if (!txq->sta) {
-		/* Non-STA TXQ: allow management frames during DW */
-		if (txq->vif->type == NL80211_IFTYPE_NAN)
-			return is_dw_slot;
+		/* Non-STA TXQ: allow management frames during DW or IC */
+		if (txq->vif->type == NL80211_IFTYPE_NAN) {
+			if (is_dw_slot)
+				return true;
+
+			/* Outside the DW the local schedule must allow it */
+			guard(spinlock_bh)(&data->nan.state_lock);
+			return data->nan.instant_comm &&
+				data->nan.local_sched[slot].chan;
+		}
 
 		/* Allow multicast data when all the peers are available
 		 * on this slot
@@ -1227,15 +1385,32 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
 }
 
 bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+				struct sk_buff *skb,
 				struct ieee80211_channel *channel,
 				struct ieee80211_rx_status *rx_status)
 {
 	struct mac80211_hwsim_data *data = hw->priv;
+	bool instant_comm;
 	u8 slot;
 
 	if (WARN_ON_ONCE(!data->nan.device_vif))
 		return false;
 
+	scoped_guard(spinlock_bh, &data->nan.state_lock)
+		instant_comm = data->nan.instant_comm;
+
+	/*
+	 * During Instant Communication a peer advertises its services in the
+	 * discovery beacons, which are transmitted disregarding the roles and
+	 * the states, see Section 13 in Wi-Fi Aware v4.0.
+	 * Note that while according to the specification Instant communication
+	 * should be enabled only on the NAN discovery channels, do not force
+	 * this here, and allow receiving NAN frames on any channel if Instant
+	 * Communication is enabled.
+	 */
+	if (instant_comm && hwsim_nan_beacon_has_service_ids(skb))
+		return true;
+
 	if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
 		return channel->center_freq == 2437;
 
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
index 2801a1d8dcf0..7d1a05868eaa 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
@@ -32,6 +32,9 @@ struct mac80211_hwsim_nan_data {
 	/* Later members are protected by this lock */
 	spinlock_t state_lock;
 
+	const u8 *extra_nan_attrs;
+	u16 extra_nan_attrs_len;
+
 	u8 master_pref;
 	u8 random_factor;
 
@@ -53,6 +56,10 @@ struct mac80211_hwsim_nan_data {
 	bool tsf_adjusted;
 	bool tsf_discontinuity;
 
+	/* Wi-Fi Aware version 4.0, Section 13 */
+	bool instant_comm;
+	u8 discovery_beacon_interval;
+
 	/*
 	 * Local schedule - stores channel definition for each 16TU slot.
 	 * Derived from NMI vif->cfg.nan_schedule. chan == NULL means not
@@ -93,6 +100,7 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
 				       struct cfg80211_chan_def *chandef);
 
 bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+				struct sk_buff *skb,
 				struct ieee80211_channel *channel,
 				struct ieee80211_rx_status *rx_status);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons
  2026-10-01 13:33 ` [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons Miri Korenblit
@ 2026-10-02  7:03   ` Johannes Berg
  0 siblings, 0 replies; 13+ messages in thread
From: Johannes Berg @ 2026-10-02  7:03 UTC (permalink / raw)
  To: Miri Korenblit; +Cc: linux-wireless, Ilan Peer

On Thu, 2026-10-01 at 16:33 +0300, Miri Korenblit wrote:
> From: Ilan Peer <ilan.peer@intel.com>
> 
> Instant Communication requires user space to track the NAN beacons, so
> let it register for Rx of beacons on a NAN interface, but allow it
> only if the driver advertises Instant Communication support.

I think that commit message is misleading - this change doesn't let
userspace register for beacons, it only *doesn't* let it do that if IC
isn't supported.

But is that even useful? Even with the change you could still register
for beacons when IC isn't even turned on, so the check doesn't do much.

It seems to me a check at wiphy registration time that beacons were
allowed if NAN IC is supported would be clearer, and the opposite is
kind of pointless anyway since NAN IC doesn't need to be enabled, and
then you can probably register for beacons all you want without ever
getting them.

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH wireless-next 4/7] wifi: mac80211: nan: allow Rx registration for NAN beacons
  2026-10-01 13:33 ` [PATCH wireless-next 4/7] wifi: mac80211: nan: allow " Miri Korenblit
@ 2026-10-02  7:10   ` Johannes Berg
  2026-10-04 12:40     ` Peer, Ilan
  0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2026-10-02  7:10 UTC (permalink / raw)
  To: Miri Korenblit; +Cc: linux-wireless, Ilan Peer

On Thu, 2026-10-01 at 16:33 +0300, Miri Korenblit wrote:
> From: Ilan Peer <ilan.peer@intel.com>
> 
> Instant Communication requires user space to track the NAN beacons, so
> let it register for Rx of beacons on a NAN interface. Add support for
> passing beacon on NAN Device interface when instant communication is
> enabled.
> 
> Add a helper function to identify NAN beacons, based on the BSSID
> and the beacon frame content. Skip NAN beacons so they would not
> be used to update the BSS table.

This does two things, please split it.


> +++ b/net/mac80211/rx.c
> @@ -4536,7 +4536,10 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
>  	struct ieee80211_hdr *hdr = (void *)skb->data;
>  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
>  	u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
> +	bool nan_beacon = ieee80211_is_nan_beacon((struct ieee80211_mgmt *)hdr,
> +						  skb->len);

Doing that fairly long inline here for every single frame seems like a
bad idea. It's also really not necessary at this spot, we accept just
about every beacon frame here and today even every NAN beacon if it
bubbles up. Also, BSSID filter will reject it anyway in most cases, so
is it even needed at all?

We can always be attacked in some way with this, so that's not an excuse
either, could even trivially just put a non-vendor-element into what
otherwise looks like a NAN beacon and then it'd be rejected by
"is_nan_beacon()" but parse exactly the same way as one.

> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -353,6 +353,10 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
>  		if (!ieee80211_is_s1g_beacon(mgmt->frame_control) &&
>  		    !is_broadcast_ether_addr(mgmt->da))
>  			return;
> +
> +		/* NAN beacons are not a BSS, don't add to the BSS table */
> +		if (ieee80211_is_nan_beacon(mgmt, skb->len))
> +			return;

If that's such a hard general rule, why in mac80211?

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support
  2026-10-01 13:33 ` [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support Miri Korenblit
@ 2026-10-02  7:26   ` Johannes Berg
  2026-10-04 13:12     ` Peer, Ilan
  0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2026-10-02  7:26 UTC (permalink / raw)
  To: Miri Korenblit; +Cc: linux-wireless, Ilan Peer, Benjamin Berg

On Thu, 2026-10-01 at 16:33 +0300, Miri Korenblit wrote:

> @@ -263,15 +300,26 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
>  		slot = hwsim_nan_slot_from_tsf(rx_status.mactime);
>  	}
>  
> +	/* (overly) simplify things, only track 2.4 GHz here */
> +	if (rx_status.freq != 2437)
> +		return;

comments should generally help ... I see it removed below but maybe make
it better while touching it :)


> +	scoped_guard(spinlock_bh, &data->nan.state_lock) {
> +		/*
> +		 * Fall back to the device default if user space did not
> +		 * configure it
> +		 */
> +		data->nan.discovery_beacon_interval =
> +			conf->discovery_beacon_interval ? : 100;

That seems like the totally wrong place - should probably make that
default in cfg80211? Or is there a reason to believe it would need to be
device-specific?

> -	data->nan.notify_dw = conf->enable_dw_notification;

Some of the refactoring in this commit is just confusing, like this just
disappearing. Please split the refactoring off first.

johannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH wireless-next 4/7] wifi: mac80211: nan: allow Rx registration for NAN beacons
  2026-10-02  7:10   ` Johannes Berg
@ 2026-10-04 12:40     ` Peer, Ilan
  0 siblings, 0 replies; 13+ messages in thread
From: Peer, Ilan @ 2026-10-04 12:40 UTC (permalink / raw)
  To: Johannes Berg, Korenblit, Miriam Rachel; +Cc: linux-wireless@vger.kernel.org

Hi,

> -----Original Message-----
> From: Johannes Berg <johannes@sipsolutions.net>
> Sent: Friday, October 2, 2026 10:11 AM
> To: Korenblit, Miriam Rachel <miriam.rachel.korenblit@intel.com>
> Cc: linux-wireless@vger.kernel.org; Peer, Ilan <ilan.peer@intel.com>
> Subject: Re: [PATCH wireless-next 4/7] wifi: mac80211: nan: allow Rx
> registration for NAN beacons
> 
> On Thu, 2026-10-01 at 16:33 +0300, Miri Korenblit wrote:
> > From: Ilan Peer <ilan.peer@intel.com>
> >
> > Instant Communication requires user space to track the NAN beacons, so
> > let it register for Rx of beacons on a NAN interface. Add support for
> > passing beacon on NAN Device interface when instant communication is
> > enabled.
> >
> > Add a helper function to identify NAN beacons, based on the BSSID and
> > the beacon frame content. Skip NAN beacons so they would not be used
> > to update the BSS table.
> 
> This does two things, please split it.
>

Sure.
 
> 
> > +++ b/net/mac80211/rx.c
> > @@ -4536,7 +4536,10 @@ static bool ieee80211_accept_frame(struct
> ieee80211_rx_data *rx)
> >  	struct ieee80211_hdr *hdr = (void *)skb->data;
> >  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
> >  	u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
> > +	bool nan_beacon = ieee80211_is_nan_beacon((struct
> ieee80211_mgmt *)hdr,
> > +						  skb->len);
> 
> Doing that fairly long inline here for every single frame seems like a bad
> idea. It's also really not necessary at this spot, we accept just about every
> beacon frame here and today even every NAN beacon if it bubbles up. Also,
> BSSID filter will reject it anyway in most cases, so is it even needed at all?
> 
> We can always be attacked in some way with this, so that's not an excuse
> either, could even trivially just put a non-vendor-element into what
> otherwise looks like a NAN beacon and then it'd be rejected by
> "is_nan_beacon()" but parse exactly the same way as one.
> 

I've moved the check to be NAN Device specific, conditioned on IC being
enabled, so that beacon frames won’t be forwarded to user space when
not needed (as currently there is not way to remove Rx mgmt. frame
registrations).

> > --- a/net/mac80211/scan.c
> > +++ b/net/mac80211/scan.c
> > @@ -353,6 +353,10 @@ void ieee80211_scan_rx(struct ieee80211_local
> *local, struct sk_buff *skb)
> >  		if (!ieee80211_is_s1g_beacon(mgmt->frame_control) &&
> >  		    !is_broadcast_ether_addr(mgmt->da))
> >  			return;
> > +
> > +		/* NAN beacons are not a BSS, don't add to the BSS table */
> > +		if (ieee80211_is_nan_beacon(mgmt, skb->len))
> > +			return;
> 
> If that's such a hard general rule, why in mac80211?
> 

Moved this check to cfg80211.

Regards,

Ilan.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support
  2026-10-02  7:26   ` Johannes Berg
@ 2026-10-04 13:12     ` Peer, Ilan
  0 siblings, 0 replies; 13+ messages in thread
From: Peer, Ilan @ 2026-10-04 13:12 UTC (permalink / raw)
  To: Johannes Berg, Korenblit, Miriam Rachel
  Cc: linux-wireless@vger.kernel.org, Berg, Benjamin

Hi,

> -----Original Message-----
> From: Johannes Berg <johannes@sipsolutions.net>
> Sent: Friday, October 2, 2026 10:26 AM
> To: Korenblit, Miriam Rachel <miriam.rachel.korenblit@intel.com>
> Cc: linux-wireless@vger.kernel.org; Peer, Ilan <ilan.peer@intel.com>; Berg,
> Benjamin <benjamin.berg@intel.com>
> Subject: Re: [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN
> Instant Communication support
> 
> On Thu, 2026-10-01 at 16:33 +0300, Miri Korenblit wrote:
> 
> > @@ -263,15 +300,26 @@ void mac80211_hwsim_nan_rx(struct
> ieee80211_hw *hw,
> >  		slot = hwsim_nan_slot_from_tsf(rx_status.mactime);
> >  	}
> >
> > +	/* (overly) simplify things, only track 2.4 GHz here */
> > +	if (rx_status.freq != 2437)
> > +		return;
> 
> comments should generally help ... I see it removed below but maybe make
> it better while touching it :)
> 

I'll try 😊

> > +	scoped_guard(spinlock_bh, &data->nan.state_lock) {
> > +		/*
> > +		 * Fall back to the device default if user space did not
> > +		 * configure it
> > +		 */
> > +		data->nan.discovery_beacon_interval =
> > +			conf->discovery_beacon_interval ? : 100;
> 
> That seems like the totally wrong place - should probably make that default
> in cfg80211? Or is there a reason to believe it would need to be device-
> specific?
> 

If not configured by user space, it makes sense to have this device specific,
to allow the device more flexibility in multi-interface and multi-channel
scenarios.

> > -	data->nan.notify_dw = conf->enable_dw_notification;
> 
> Some of the refactoring in this commit is just confusing, like this just
> disappearing. Please split the refactoring off first.
> 

Done.

Regards,

Ilan.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-10-04 13:12 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-01 13:33 [PATCH wireless-next 0/7] wifi: cfg80211/mac80211: add NAN Instant Communication support Miri Korenblit
2026-10-01 13:33 ` [PATCH wireless-next 1/7] wifi: cfg80211: nan: add " Miri Korenblit
2026-10-01 13:33 ` [PATCH wireless-next 2/7] wifi: mac80211: nan: Update NAN configuration copy Miri Korenblit
2026-10-01 13:33 ` [PATCH wireless-next 3/7] wifi: cfg80211: nan: check Rx registration for NAN beacons Miri Korenblit
2026-10-02  7:03   ` Johannes Berg
2026-10-01 13:33 ` [PATCH wireless-next 4/7] wifi: mac80211: nan: allow " Miri Korenblit
2026-10-02  7:10   ` Johannes Berg
2026-10-04 12:40     ` Peer, Ilan
2026-10-01 13:33 ` [PATCH wireless-next 5/7] wifi: ieee80211: add NAN service ID list attribute definitions Miri Korenblit
2026-10-01 13:33 ` [PATCH wireless-next 6/7] wifi: mac80211_hwsim: nan: use ieee80211_is_nan_beacon() helper Miri Korenblit
2026-10-01 13:33 ` [PATCH wireless-next 7/7] wifi: mac80211_hwsim: add NAN Instant Communication support Miri Korenblit
2026-10-02  7:26   ` Johannes Berg
2026-10-04 13:12     ` Peer, Ilan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox