From 8573266a26123ce7568240989a9f660b1098037e Mon Sep 17 00:00:00 2001 From: Stella Liu Date: Mon, 24 Aug 2026 14:52:22 -0500 Subject: [PATCH] wifi: mt76: mt7925: fill all DW intervals in NAN avail_map Fill avail_map for all DW intervals instead of only DW index 0. FW requires the bitmap to be set across all 16 DW intervals for correct NAN scheduling. Without this, NDP ping latency is extremely high (~200ms) because FW only schedules data in the first DW interval. Also set ch_type = 1 for new channel entries to indicate channel-based (non-band) availability. Fixes: a5487a682406 ("wifi: mt76: mt7925: add NAN MCU helpers") Co-developed-by: Sean Wang Signed-off-by: Sean Wang Signed-off-by: Stella Liu Link: https://patch.msgid.link/20260824195227.12589-11-sean.wang@kernel.org Signed-off-by: Felix Fietkau --- mt7925/nan.c | 27 ++++++++++++++++++++------- mt7925/nan.h | 3 +++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/mt7925/nan.c b/mt7925/nan.c index 8194e767..79e57bae 100644 --- a/mt7925/nan.c +++ b/mt7925/nan.c @@ -491,9 +491,14 @@ static u32 mt7925_nan_slot_to_bitmap(struct ieee80211_vif *vif, if (FIELD_GET(NAN_CH_CTRL_PRIMARY_CH, raw) == slot_chan->chan->hw_value) { - u32 map = le32_to_cpu(ch_list[j].avail_map[0]); + u32 dw; - ch_list[j].avail_map[0] = cpu_to_le32(map | BIT(i)); + for (dw = 0; dw < NAN_TOTAL_DW; dw++) { + u32 map = le32_to_cpu(ch_list[j].avail_map[dw]); + + ch_list[j].avail_map[dw] = + cpu_to_le32(map | BIT(i)); + } le32_add_cpu(&ch_list[j].num, 1); is_found = true; break; @@ -501,12 +506,18 @@ static u32 mt7925_nan_slot_to_bitmap(struct ieee80211_vif *vif, } if (!is_found && num_channels < NAN_TIMELINE_MGMT_CHNL_LIST_NUM) { + u32 dw; + ch_list[num_channels].ch_info = - cpu_to_le32(FIELD_PREP(NAN_CH_CTRL_OP_CLASS, + cpu_to_le32(FIELD_PREP(NAN_CH_CTRL_CH_TYPE, + NAN_BAND_CHANNEL_ENTRY_LIST_TYPE_CHANNEL) | + FIELD_PREP(NAN_CH_CTRL_OP_CLASS, slot->channel_entry[0]) | FIELD_PREP(NAN_CH_CTRL_PRIMARY_CH, slot_chan->chan->hw_value)); - ch_list[num_channels].avail_map[0] = cpu_to_le32(BIT(i)); + for (dw = 0; dw < NAN_TOTAL_DW; dw++) + ch_list[num_channels].avail_map[dw] = + cpu_to_le32(BIT(i)); le32_add_cpu(&ch_list[num_channels].num, 1); ch_list[num_channels].is_valid++; num_channels++; @@ -681,17 +692,19 @@ mt7925_nan_fill_crb_committed(struct mt7925_nan_sched_update_crb_tlv *crb_tlv, /* * Convert peer schedule slots to FW avail_map bitmap. - * Each bit in avail_map[0] represents one time slot where - * the peer has committed availability. + * Each bit represents one time slot where the peer has + * committed availability. Fill all DW intervals the same. */ for (slot = 0; slot < CFG80211_NAN_SCHED_NUM_TIME_SLOTS; slot++) { struct ieee80211_nan_channel *ch = map->slots[slot]; + u32 dw; if (!ch || !ch->chanctx_conf) continue; - tl->avail_map[0] |= cpu_to_le32(BIT(slot)); + for (dw = 0; dw < NAN_TOTAL_DW; dw++) + tl->avail_map[dw] |= cpu_to_le32(BIT(slot)); } } } diff --git a/mt7925/nan.h b/mt7925/nan.h index 4b424e0e..eadb07e3 100644 --- a/mt7925/nan.h +++ b/mt7925/nan.h @@ -118,12 +118,15 @@ enum nan_peer_supported_bands { NAN_SUPPORTED_BN_NUM }; +#define NAN_CH_CTRL_CH_TYPE BIT(0) #define NAN_CH_CTRL_OP_CLASS GENMASK(15, 8) #define NAN_CH_CTRL_PRIMARY_CH GENMASK(23, 16) #define NAN_CRB_USE_DATA_PATH BIT(0) #define NAN_CRB_AVAIL_6G_FORMAT GENMASK(2, 1) +#define NAN_BAND_CHANNEL_ENTRY_LIST_TYPE_CHANNEL 1 + struct mt7925_nan_social_ch_scan_params { u8 dwell_time[NAN_MAX_SOCIAL_CHANNELS]; __le16 scan_period[NAN_MAX_SOCIAL_CHANNELS];