// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2025-2026 MediaTek Inc. */
#include <asm/byteorder.h>
#include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#include "mt7925.h"
#include "mcu.h"
#include "nan.h"
#include "regd.h"
static void mt7925_nan_set_5g_channel(struct mt792x_dev *dev,
struct mt7925_nan_enable_req_tlv *req,
struct cfg80211_nan_conf *conf)
{
struct ieee80211_channel *chan;
u32 ch5g = 0;
chan = conf->band_cfgs[NL80211_BAND_5GHZ].chan;
if (!chan)
return;
if (!mt7925_regd_is_valid_channel(dev, NL80211_BAND_5GHZ, chan))
return;
req->config_5g_channel = 1;
if (chan->hw_value == NAN_5G_LOW_DISC_CHANNEL)
ch5g |= BIT(0);
else if (chan->hw_value == NAN_5G_HIGH_DISC_CHANNEL)
ch5g |= BIT(1);
req->channel_5g_val = cpu_to_le32(ch5g);
}
static void mt7925_nan_set_scan_params(struct mt7925_nan_enable_req_tlv *req,
struct cfg80211_nan_conf *conf)
{
req->scan_params_val.scan_period[0] =
cpu_to_le16(conf->scan_period < 255 ? conf->scan_period : 255);
req->scan_params_val.dwell_time[0] =
conf->scan_dwell_time < 255 ? conf->scan_dwell_time : 255;
}
static u16
mt7925_nan_avail_attr_ctrl(const struct ieee80211_nan_sched_cfg *sched)
{
if (sched->avail_blob_len < NAN_AVAIL_ATTR_CTRL_OFFSET + 2)
return 0;
return sched->avail_blob[NAN_AVAIL_ATTR_CTRL_OFFSET] |
sched->avail_blob[NAN_AVAIL_ATTR_CTRL_OFFSET + 1] << 8;
}
static void
mt7925_nan_update_conf(struct mt792x_vif *mvif,
const struct cfg80211_nan_conf *conf)
{
mvif->nan.conf.master_pref = conf->master_pref;
mvif->nan.conf.bands = conf->bands;
mvif->nan.conf.discovery_beacon_interval =
conf->discovery_beacon_interval;
mvif->nan.conf.enable_dw_notification =
conf->enable_dw_notification;
memcpy(mvif->nan.conf.cluster_id, conf->cluster_id