[PATCH 13/18] driver_nl80211: Support NAN set non-evac channels command

Andrei Otcheretianski andrei.otcheretianski at intel.com
Mon Oct 12 08:46:47 PDT 2026


Add support for the NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS command that
marks a set of NAN channels as non-evacuable.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/drivers/driver.h         | 18 ++++++++++
 src/drivers/driver_nl80211.c | 70 ++++++++++++++++++++++++++++++++----
 2 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 32fcb4ec81..844b36e884 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3549,6 +3549,8 @@ struct nan_schedule_config {
 	 *     on the channel.
 	 * @rx_nss: Number of spatial streams supported for RX on the
 	 *     channel
+	 * @no_evacuate: The channel must not be evacuated for concurrent
+	 *     operations
 	 * @chan_entry: Channel Entry as defined in Wi-Fi Aware spec v4.0,
 	 *     Table 100 (Channel Entry format for the NAN Availability
 	 *     attribute).
@@ -3564,6 +3566,7 @@ struct nan_schedule_config {
 		int bandwidth;
 		struct wpabuf *time_bitmap;
 		u8 rx_nss;
+		bool no_evacuate;
 
 		u8 chan_entry[6];
 	} channels[MAX_NUM_NAN_SCHEDULE_CHANNELS];
@@ -5993,6 +5996,21 @@ struct wpa_driver_ops {
 					u16 max_chan_switch_time,
 					const struct wpabuf *ulw,
 					struct nan_peer_schedule_config *sched);
+
+	/**
+	 * nan_set_non_evac_channels - Set NAN non-evacuable channels
+	 * @priv: Private driver interface data
+	 * @conf: NAN schedule configuration. Channels whose %no_evacuate flag
+	 *	is set are reported to the kernel as non-evacuable; the reported
+	 *	list replaces the previous set of non-evacuable channels.
+	 * Returns 0 on success, -1 on failure
+	 *
+	 * This command sets the list of local schedule channels that must not
+	 * be evacuated for concurrent operations. It should be executed on the
+	 * NAN device interface after the local schedule has been configured.
+	 */
+	int (*nan_set_non_evac_channels)(void *priv,
+					 struct nan_schedule_config *conf);
 #endif /* CONFIG_NAN */
 
 #ifdef CONFIG_PR
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e2029c2a97..10c278af52 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -16121,16 +16121,17 @@ static void wpa_driver_nl80211_nan_stop(void *priv)
 }
 
 
+/* @set_avail_attrs: also encode the availability-specific attributes */
 static int
 wpa_driver_nl80211_nan_set_channel(struct wpa_driver_nl80211_data *drv,
 				   struct nan_schedule_channel *chan,
-				   struct nl_msg *msg)
+				   struct nl_msg *msg, bool set_avail_attrs)
 {
 	struct nlattr *chan_attr;
 	enum nl80211_chan_width cw;
 
 	chan_attr = nla_nest_start(msg, NL80211_ATTR_NAN_CHANNEL);
-	if (!chan)
+	if (!chan_attr)
 		return -ENOBUFS;
 
 	if (nl80211_bw_to_nl(chan->bandwidth, &cw, chan->center_freq2))
@@ -16139,15 +16140,21 @@ wpa_driver_nl80211_nan_set_channel(struct wpa_driver_nl80211_data *drv,
 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->freq) ||
 	    nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chan->center_freq1) ||
 	    nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chan->center_freq2) ||
-	    nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
+	    nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw)) {
+		wpa_printf(MSG_INFO,
+			   "nl80211: NAN: Failed to put channel attributes");
+		return -EINVAL;
+	}
+
+	if (set_avail_attrs &&
 	    nla_put(msg, NL80211_ATTR_NAN_CHANNEL_ENTRY,
 		    sizeof(chan->chan_entry), chan->chan_entry)) {
 		wpa_printf(MSG_INFO,
-			   "nl80211: NAN: Failed to put channel attributes");
+			   "nl80211: NAN: Failed to put channel entry");
 		return -EINVAL;
 	}
 
-	if (chan->rx_nss &&
+	if (set_avail_attrs && chan->rx_nss &&
 	    nla_put_u8(msg, NL80211_ATTR_NAN_RX_NSS, chan->rx_nss)) {
 		wpa_printf(MSG_INFO,
 			   "nl80211: NAN: Failed to put RX NSS attribute");
@@ -16212,7 +16219,7 @@ wpa_driver_nl80211_nan_set_schedule(struct wpa_driver_nl80211_data *drv,
 		int ret;
 
 		ret = wpa_driver_nl80211_nan_set_channel(
-			drv, &sched->channels[i], msg);
+			drv, &sched->channels[i], msg, true);
 		if (ret)
 			return ret;
 
@@ -16280,6 +16287,54 @@ fail:
 }
 
 
+static int
+wpa_driver_nl80211_nan_set_non_evac_channels(void *priv,
+					     struct nan_schedule_config *conf)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	size_t i;
+	int ret;
+
+	if (drv->nlmode != NL80211_IFTYPE_NAN || !drv->nan_started)
+		return -EOPNOTSUPP;
+
+	if (!conf)
+		return -EINVAL;
+
+	msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS);
+	if (!msg) {
+		wpa_printf(MSG_INFO,
+			   "nl80211: Failed to alloc NAN non-evac channels command");
+		return -ENOMEM;
+	}
+
+	/* An empty list clears the previous set of non-evacuable channels */
+	for (i = 0; i < conf->num_channels; i++) {
+		if (!conf->channels[i].no_evacuate)
+			continue;
+
+		ret = wpa_driver_nl80211_nan_set_channel(
+			drv, &conf->channels[i], msg, false);
+		if (ret)
+			goto fail;
+	}
+
+	ret = send_and_recv_cmd(bss->drv, msg);
+	if (ret)
+		wpa_printf(MSG_INFO,
+			   "nl80211: Failed to send NAN non-evac channels command: %d",
+			   ret);
+
+	return ret;
+
+fail:
+	nlmsg_free(msg);
+	return ret;
+}
+
+
 static int
 wpa_driver_nl80211_nan_config_peer_schedule(
 	void *priv, const u8 *peer, u16 cdw, u8 sequence_id,
@@ -16369,7 +16424,7 @@ wpa_driver_nl80211_nan_config_peer_schedule(
 	for (chan_idx = 0; chan_idx < n_channels; chan_idx++) {
 		ret = wpa_driver_nl80211_nan_set_channel(drv,
 							 channels[chan_idx],
-							 msg);
+							 msg, true);
 		if (ret)
 			goto fail;
 	}
@@ -17082,6 +17137,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.nan_change_config = wpa_driver_nl80211_nan_change_config,
 	.nan_config_schedule = wpa_driver_nl80211_nan_config_schedule,
 	.nan_config_peer_schedule = wpa_driver_nl80211_nan_config_peer_schedule,
+	.nan_set_non_evac_channels = wpa_driver_nl80211_nan_set_non_evac_channels,
 #endif /* CONFIG_NAN */
 #ifdef CONFIG_PR
 	.pd_start = nl80211_pd_start,
-- 
2.53.0




More information about the Hostap mailing list