[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