[RFC v2 76/99] wpa_supplicant: Configure reported NAN device capabilities

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:52:20 PST 2025


Conifugre NAN module with NAN capabilities reported by driver.
While at it, aggregate all the NAN capabilities in nana_capa struct and
adjust the code accordingly.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/drivers/driver.h              | 74 ++++++++++++++++++-------------
 src/drivers/driver_nl80211.c      |  6 +--
 src/drivers/driver_nl80211_capa.c |  6 +--
 wpa_supplicant/nan_supplicant.c   | 55 ++++++++++++-----------
 wpa_supplicant/wpa_supplicant.c   |  7 +--
 wpa_supplicant/wpa_supplicant_i.h |  7 +--
 6 files changed, 79 insertions(+), 76 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 83b8f0727a..d08159e9ce 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2167,6 +2167,47 @@ enum wpa_driver_if_type {
 	WPA_IF_MAX
 };
 
+/**
+ * struct nan_capa - NAN capabilities
+ *
+ * @drv_flags: NAN capability flags (WPA_DRIVER_FLAGS_NAN_*)
+ * @num_radios: Maximum number of NAN radios
+ * @sched_chans: Maximum number of channels in NAN schedule (per map)
+ * @slot_duration: NAN schedule bitmap slot duration (16, 32, 64 or 128) in TUs
+ * @schedule_period: Schedule period (powers of 2 in range: 128 - 8192) in TUs
+ * @max_channel_switch_time: Max channel switch time in microseconds
+ * @num_antennas: Number of antennas (lower nibble TX, upper nibble RX)
+ * @op_modes: NAN capability operation modes
+ * @dev_capa: NAN device capabilities
+ *
+ * For the schedule capabilities, even if the driver/device supports multiple
+ * options, only a single option should be selected. For example, if both 16 TU
+ * and 32 TU slot durations are supported, the driver should report
+ * the shortest supported slot duration (16 TU). For schedule period, the
+ * driver should report the maximum supported period, as longer periods can
+ * always be represented by repetitions of the shorter schedule bitmap. In any
+ * case 512/16 configuration is recommended for better interoperability.
+ */
+struct nan_capa {
+/* Driver supports dual band NAN operation */
+#define WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND		0x00000001
+/* Driver supports NAN synchronization configuration */
+#define WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG	0x00000002
+/* Driver supports DW notifications and SDF TX/RX over NAN device interface */
+#define WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE	0x00000004
+/** Driver supports NAN Data path */
+#define WPA_DRIVER_FLAGS_NAN_SUPPORT_NDP		0x00000008
+	u32 drv_flags;
+	u8 num_radios;
+	u8 sched_chans;
+	u8 slot_duration;
+	u16 schedule_period;
+	u16 max_channel_switch_time;
+	u8 num_antennas;
+	u8 op_modes;
+	u8 dev_capa;
+};
+
 /**
  * struct wpa_driver_capa - Driver capability information
  */
@@ -2582,38 +2623,7 @@ struct wpa_driver_capa {
 	u8 max_tx_sts_gt_80;
 
 #ifdef CONFIG_NAN
-/* Driver supports dual band NAN operation */
-#define WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND		0x00000001
-/* Driver supports NAN synchronization configuration */
-#define WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG	0x00000002
-/* Driver supports DW notifications and SDF TX/RX over NAN device interface */
-#define WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE	0x00000004
-/** Driver supports NAN Data path */
-#define WPA_DRIVER_FLAGS_NAN_SUPPORT_NDP		0x00000008
-	u32 nan_flags;
-
-	/* Maximum number of NAN radios */
-	u8 nan_num_radios;
-
-	/* Maximum number of channels in NAN schedule (per map) */
-	u8 nan_sched_chans;
-
-	/*
-	 * For the following NAN schedule capabilities, even if the
-	 * driver/device supports multiple options, only a single option
-	 * should be selected. For example, if both 16 TU and 32 TU slot
-	 * durations are supported, the driver should report the shortest
-	 * supported slot duration (16 TU). For schedule period,
-	 * the driver should report the maximum supported period, as shorter
-	 * periods can always be represented by repetitions of the shorter
-	 * schedule bitmap. In any case 512/16 configuration is recommended for
-	 * better interoperability.
-	 */
-
-	/* NAN schedule bitmap slot duration (16, 32, 64 or 128) in TUs */
-	u8 nan_slot_duration;
-	/* Schedule period (powers of 2 in range: 128 - 8192) in TUs */
-	u16 nan_schedule_period;
+	struct nan_capa nan_capa;
 #endif /* CONFIG_NAN */
 };
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 30a7bfd836..975b1257f7 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2736,7 +2736,7 @@ static int nl80211_mgmt_subscribe_nan(struct i802_bss *bss)
 #ifdef CONFIG_NAN
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 
-	if (!(drv->capa.nan_flags &
+	if (!(drv->capa.nan_capa.drv_flags &
 	      WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: User space DE is not supported, don't subscribe to NAN public action frames");
@@ -15259,7 +15259,7 @@ static int nl80211_nan_config(struct i802_bss *bss,
 	bands |= BIT(NL80211_BAND_2GHZ);
 
 	if (params->dual_band) {
-		if (drv->capa.nan_flags &
+		if (drv->capa.nan_capa.drv_flags &
 		    WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND) {
 			bands |= BIT(NL80211_BAND_5GHZ);
 		} else {
@@ -15282,7 +15282,7 @@ static int nl80211_nan_config(struct i802_bss *bss,
 		goto fail;
 
 	if (params->enable_dw_notif) {
-		if (!(drv->capa.nan_flags &
+		if (!(drv->capa.nan_capa.drv_flags &
 		      WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
 			wpa_printf(MSG_DEBUG,
 				   "nl80211: Driver doesn't support NAN DW notifications");
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 2ebb571147..485c0054ae 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1207,7 +1207,7 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
 			   bands);
 		if ((bands & BIT(NL80211_BAND_2GHZ)) &&
 		    (bands & BIT(NL80211_BAND_5GHZ)))
-			capa->nan_flags |=
+			capa->nan_capa.drv_flags |=
 				WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND;
 	}
 
@@ -1228,13 +1228,13 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
 
 		if (tb_nan_capa[NL80211_NAN_CAPA_CONFIGURABLE_SYNC]) {
 			wpa_printf(MSG_DEBUG, "nl80211: NAN sync offload supported");
-			capa->nan_flags |=
+			capa->nan_capa.drv_flags |=
 				WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG;
 		}
 
 		if (tb_nan_capa[NL80211_NAN_CAPA_USERSPACE_DE]) {
 			wpa_printf(MSG_DEBUG, "nl80211: NAN user space DE is supported");
-			capa->nan_flags |=
+			capa->nan_capa.drv_flags |=
 				WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE;
 		}
 	}
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 7c088c1e05..e9dd907f12 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -413,7 +413,8 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 	struct nan_config nan;
 
 	if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SUPPORT_NAN) ||
-	    !(wpa_s->nan_drv_flags & WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG)) {
+	    !(wpa_s->nan_capa.drv_flags &
+	      WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG)) {
 		wpa_printf(MSG_DEBUG, "NAN: NAN is not supported");
 		return -1;
 	}
@@ -445,14 +446,14 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 		((1 << NAN_CDW_INFO_5G_POS) & NAN_CDW_INFO_5G_MASK);
 
 	nan.dev_capa.supported_bands = NAN_DEV_CAPA_SBAND_2G;
-	if (wpa_s->nan_drv_flags &
+	if (wpa_s->nan_capa.drv_flags &
 	    WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND)
 		nan.dev_capa.supported_bands |= NAN_DEV_CAPA_SBAND_5G;
 
-	/* TODO: set based on driver capabilities */
-	nan.dev_capa.op_mode = NAN_DEV_CAPA_OP_MODE_PHY_MODE_VHT |
-		NAN_DEV_CAPA_OP_MODE_PHY_MODE_HE |
-		NAN_DEV_CAPA_OP_MODE_HE_VHT_160;
+	nan.dev_capa.op_mode = wpa_s->nan_capa.op_modes;
+	nan.dev_capa.n_antennas = wpa_s->nan_capa.num_antennas;
+	nan.dev_capa.channel_switch_time = wpa_s->nan_capa.max_channel_switch_time;
+	nan.dev_capa.capa = wpa_s->nan_capa.dev_capa;
 
 	wpa_s->nan = nan_init(&nan);
 	if (!wpa_s->nan) {
@@ -487,7 +488,7 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 	 * needed, i.e., when the DE is configured with unsolicited publish or
 	 * active subscribe
 	 */
-	wpa_s->nan_config.enable_dw_notif = !!(wpa_s->nan_drv_flags &
+	wpa_s->nan_config.enable_dw_notif = !!(wpa_s->nan_capa.drv_flags &
 					       WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE);
 
 	/* Currently support shared key suites only */
@@ -790,22 +791,22 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
 		return -1;
 	}
 
-	if (map_id > wpa_s->nan_num_radios) {
+	if (map_id > wpa_s->nan_capa.num_radios) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: map_id %d exceeds number of supported NAN radios %d",
-			   map_id, wpa_s->nan_num_radios);
+			   map_id, wpa_s->nan_capa.num_radios);
 		return -1;
 	}
 
-	if (!wpa_s->nan_schedule_period ||
-	    !wpa_s->nan_sched_slot_duration) {
+	if (!wpa_s->nan_capa.schedule_period ||
+	    !wpa_s->nan_capa.slot_duration) {
 		    wpa_printf(MSG_DEBUG,
 			       "NAN: Driver doesn't advertise support for NAN scheduling");
 		    return -1;
 	}
 
-	expected_bitmap_len =(wpa_s->nan_schedule_period /
-			      wpa_s->nan_sched_slot_duration + 7) / 8;
+	expected_bitmap_len =(wpa_s->nan_capa.schedule_period /
+			      wpa_s->nan_capa.slot_duration + 7) / 8;
 
 	os_memset(&sched_cfg, 0, sizeof(sched_cfg));
 
@@ -833,8 +834,8 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
 	unused_freqs_count = wpa_s->num_multichan_concurrent -
 		shared_freqs_count;
 
-	bf_total = bitfield_alloc(wpa_s->nan_schedule_period /
-				  wpa_s->nan_sched_slot_duration);
+	bf_total = bitfield_alloc(wpa_s->nan_capa.schedule_period /
+				  wpa_s->nan_capa.slot_duration);
 	if (!bf_total) {
 		wpa_printf(MSG_DEBUG,
 			  "NAN: Failed to allocate bitfield for total schedule");
@@ -848,10 +849,10 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
 		struct bitfield *bf_chan = NULL;
 		char *colon = os_strchr(token, ':');
 
-		if (i >= wpa_s->nan_max_channels_per_radio) {
+		if (i >= wpa_s->nan_capa.sched_chans) {
 			wpa_printf(MSG_DEBUG,
 				   "NAN: Exceeded max channels per radio %u",
-				   wpa_s->nan_max_channels_per_radio);
+				   wpa_s->nan_capa.sched_chans);
 			goto out;
 		}
 
@@ -913,8 +914,8 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
 			wpa_printf(MSG_DEBUG,
 				   "NAN: Invalid bitmap length (%zu) for period=%d, slot length=%d",
 				   wpabuf_len(sched_cfg.channels[i].time_bitmap),
-				   wpa_s->nan_schedule_period,
-				   wpa_s->nan_sched_slot_duration);
+				   wpa_s->nan_capa.schedule_period,
+				   wpa_s->nan_capa.slot_duration);
 			goto out;
 		}
 
@@ -1081,9 +1082,9 @@ static void wpas_nan_fill_ndp_schedule(struct wpa_supplicant *wpa_s,
 				sched_cfg->channels[i].bandwidth;
 
 			chan_sched->committed.duration =
-				wpa_s->nan_sched_slot_duration >> 5;
+				wpa_s->nan_capa.slot_duration >> 5;
 			chan_sched->committed.period =
-				ffs(wpa_s->nan_schedule_period) - 7;
+				ffs(wpa_s->nan_capa.schedule_period) - 7;
 			chan_sched->committed.offset = 0;
 			chan_sched->committed.len = bitmap_len;
 			os_memcpy(chan_sched->committed.bitmap, bitmap_data,
@@ -1098,7 +1099,7 @@ static void wpas_nan_fill_ndp_schedule(struct wpa_supplicant *wpa_s,
 		}
 	}
 	/* Mark all supported radios - for potential availability */
-	sched->map_ids_bitmap = (BIT(wpa_s->nan_num_radios) - 1) << 1;
+	sched->map_ids_bitmap = (BIT(wpa_s->nan_capa.num_radios) - 1) << 1;
 }
 
 
@@ -1204,8 +1205,8 @@ static int wpas_nan_select_ndc(struct wpa_supplicant *wpa_s,
 	    ndp->sched.chans[0].chan.freq == 5220) {
 		int dw_bit, byte_idx, bit_in_byte;
 
-		dw_bit = 128 / wpa_s->nan_sched_slot_duration;
-		dw_bit += !!(wpa_s->nan_sched_slot_duration == 16);
+		dw_bit = 128 / wpa_s->nan_capa.slot_duration;
+		dw_bit += !!(wpa_s->nan_capa.slot_duration == 16);
 		byte_idx = dw_bit / 8;
 		bit_in_byte = dw_bit % 8;
 
@@ -1215,7 +1216,7 @@ static int wpas_nan_select_ndc(struct wpa_supplicant *wpa_s,
 			return 0;
 		}
 	} else if (ndp->sched.chans[0].chan.freq == 2437 &&
-		   (wpa_s->nan_sched_slot_duration == 16)) {
+		   (wpa_s->nan_capa.slot_duration == 16)) {
 		if (ndp->sched.chans[0].committed.bitmap[0] & 0x02) {
 			ndp->sched.ndc.bitmap[0] = 0x02;
 			return 0;
@@ -2305,7 +2306,7 @@ int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
 
 #ifdef CONFIG_NAN
 	if (params->sync) {
-		if (!(wpa_s->nan_drv_flags &
+		if (!(wpa_s->nan_capa.drv_flags &
 		      WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
 			wpa_printf(MSG_DEBUG,
 				   "NAN: Can't advertise sync service, driver does not support user space DE");
@@ -2451,7 +2452,7 @@ int wpas_nan_subscribe(struct wpa_supplicant *wpa_s,
 
 #ifdef CONFIG_NAN
 	if (params->sync) {
-		if (!(wpa_s->nan_drv_flags &
+		if (!(wpa_s->nan_capa.drv_flags &
 		      WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE)) {
 			wpa_printf(MSG_DEBUG,
 				   "NAN: Can't subscribe sync, user space DE is not supported");
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7d07ebd649..75ca9d2b40 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7984,11 +7984,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		return -1;
 
 #ifdef CONFIG_NAN
-	wpa_s->nan_drv_flags = capa.nan_flags;
-	wpa_s->nan_num_radios = capa.nan_num_radios;
-	wpa_s->nan_sched_slot_duration = capa.nan_slot_duration;
-	wpa_s->nan_schedule_period = capa.nan_schedule_period;
-	wpa_s->nan_max_channels_per_radio = capa.nan_sched_chans;
+	os_memcpy(&wpa_s->nan_capa, &capa.nan_capa,
+		  sizeof(wpa_s->nan_capa));
 #endif /* CONFIG_NAN */
 
 	if (wpa_supplicant_init_eapol(wpa_s) < 0)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 246ce72ac8..0f17001e85 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1671,12 +1671,7 @@ struct wpa_supplicant {
 
 #ifdef CONFIG_NAN
 #define MAX_NAN_RADIOS 2
-	u32 nan_drv_flags;
-	u8 nan_num_radios;
-	u8 nan_max_channels_per_radio;
-	u8 nan_sched_slot_duration;
-	u16 nan_schedule_period;
-
+	struct nan_capa nan_capa;
 	struct nan_data *nan;
 	struct nan_cluster_config nan_config;
 	u8 schedule_sequence_id;
-- 
2.49.0




More information about the Hostap mailing list