[][mac80211][mt76][csi][update connac2 csi]

[Description]
Add new content
1. add mac filter maintain logic
2. non-mt7915 use only 5 mac filter entry per band
3. add netlink api to report driver mac filter status

[Release-log]

Change-Id: Ie9d7f4c6dd67a69fdaf591d947706821f847ede1
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9129429
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
index c1e347e..115bb84 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
@@ -1,19 +1,20 @@
-From 852fc4ec3ad815f3cd38e1ce8c3c10929d3961fe Mon Sep 17 00:00:00 2001
+From c5e9e8836065c1651ab7b84a0d30953c45c7a35d Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Jun 2022 20:13:02 +0800
-Subject: [PATCH 1001/1051] wifi: mt76: mt7915: csi: implement csi support
+Subject: [PATCH] wifi: mt76: mt7915: csi: implement csi support
 
 ---
  mt76_connac_mcu.h |   2 +
  mt7915/Makefile   |   4 +-
- mt7915/init.c     |  38 ++++
- mt7915/main.c     |   4 +
- mt7915/mcu.c      | 203 ++++++++++++++++++++
- mt7915/mcu.h      |  74 ++++++++
- mt7915/mt7915.h   |  60 ++++++
- mt7915/vendor.c   | 470 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7915/vendor.h   |  63 +++++++
- 9 files changed, 916 insertions(+), 2 deletions(-)
+ mt7915/debugfs.c  |  48 ++++
+ mt7915/init.c     |  46 ++++
+ mt7915/main.c     |  13 +
+ mt7915/mcu.c      | 203 ++++++++++++++++
+ mt7915/mcu.h      |  74 ++++++
+ mt7915/mt7915.h   |  78 ++++++
+ mt7915/vendor.c   | 606 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/vendor.h   |  75 ++++++
+ 10 files changed, 1147 insertions(+), 2 deletions(-)
  create mode 100644 mt7915/vendor.c
  create mode 100644 mt7915/vendor.h
 
@@ -54,24 +55,92 @@
  
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
+index 2661386..909df24 100644
+--- a/mt7915/debugfs.c
++++ b/mt7915/debugfs.c
+@@ -1241,6 +1241,51 @@ mt7915_rf_regval_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get,
+ 			 mt7915_rf_regval_set, "0x%08llx\n");
+ 
++#ifdef CONFIG_MTK_VENDOR
++static ssize_t
++mt7915_get_csi_stats(struct file *file, char __user *user_buf,
++		size_t count, loff_t *ppos)
++
++{
++	struct mt7915_phy *phy = file->private_data;
++	struct csi_mac_filter *current_mac, *tmp_mac;
++	static const size_t sz = 4096;
++	char *buf;
++	u32 reg, len = 0;
++	int ret;
++
++	buf = kzalloc(sz, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++
++	len += scnprintf(buf + len, sz - len, "CSI enable: %d\n", phy->csi.enable);
++
++	if (phy->csi.enable) {
++		len += scnprintf(buf + len, sz - len, "CSI data_cnt: %d\n", phy->csi.count);
++
++		mutex_lock(&phy->csi.mac_filter_lock);
++
++		list_for_each_entry_safe(current_mac, tmp_mac, &phy->csi.mac_filter_list, node) {
++			len += scnprintf(buf + len, sz - len, "mac: %pM, interval: %d\n", current_mac->mac, current_mac->interval);
++		}
++
++		mutex_unlock(&phy->csi.mac_filter_lock);
++	}
++
++	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
++
++out:
++	kfree(buf);
++	return ret;
++}
++
++static const struct file_operations mt7915_csi_ops = {
++	.read = mt7915_get_csi_stats,
++	.open = simple_open,
++	.llseek = default_llseek,
++};
++#endif
++
+ int mt7915_init_debugfs(struct mt7915_phy *phy)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+@@ -1283,6 +1328,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+ 		debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir,
+ 					    mt7915_rdd_monitor);
+ 	}
++#ifdef CONFIG_MTK_VENDOR
++	debugfs_create_file("csi_stats", 0400, dir, phy, &mt7915_csi_ops);
++#endif
+ 
+ 	if (!ext_phy)
+ 		dev->debugfs_dir = dir;
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 2ae7977..3f06360 100644
+index 19a68c5..1200405 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -662,6 +662,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -697,6 +697,14 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
  	/* init wiphy according to mphy and phy */
  	mt7915_init_wiphy(phy);
  
 +#ifdef CONFIG_MTK_VENDOR
-+	INIT_LIST_HEAD(&phy->csi.csi_list);
-+	spin_lock_init(&phy->csi.csi_lock);
++	INIT_LIST_HEAD(&phy->csi.data_list);
++	spin_lock_init(&phy->csi.data_lock);
++	INIT_LIST_HEAD(&phy->csi.mac_filter_list);
++	mutex_init(&phy->csi.mac_filter_lock);
 +	mt7915_vendor_register(phy);
 +#endif
 +
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1143,6 +1149,24 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+@@ -1178,6 +1186,28 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
  	}
  }
  
@@ -80,14 +149,18 @@
 +{
 +	struct csi_data *c, *tmp_c;
 +
-+	spin_lock_bh(&phy->csi.csi_lock);
++	spin_lock_bh(&phy->csi.data_lock);
 +	phy->csi.enable = 0;
 +
-+	list_for_each_entry_safe(c, tmp_c, &phy->csi.csi_list, node) {
++	list_for_each_entry_safe(c, tmp_c, &phy->csi.data_list, node) {
 +		list_del(&c->node);
 +		kfree(c);
 +	}
-+	spin_unlock_bh(&phy->csi.csi_lock);
++	spin_unlock_bh(&phy->csi.data_lock);
++
++	mutex_lock(&phy->csi.mac_filter_lock);
++	mt7915_csi_mac_filter_clear(phy);
++	mutex_unlock(&phy->csi.mac_filter_lock);
 +
 +	return 0;
 +}
@@ -96,7 +169,7 @@
  static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  {
  	struct mt7915_phy *phy = mt7915_ext_phy(dev);
-@@ -1151,6 +1175,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
+@@ -1186,6 +1216,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  	if (!phy)
  		return;
  
@@ -107,7 +180,7 @@
  	mt7915_unregister_thermal(phy);
  	mt76_unregister_phy(mphy);
  	ieee80211_free_hw(mphy->hw);
-@@ -1163,6 +1191,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+@@ -1198,6 +1232,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
  	mt7915_dma_cleanup(dev);
  	tasklet_disable(&dev->mt76.irq_tasklet);
  
@@ -118,13 +191,15 @@
  	if (is_mt798x(&dev->mt76))
  		mt7986_wmac_disable(dev);
  }
-@@ -1207,6 +1239,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1242,6 +1280,14 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->mt76.test_ops = &mt7915_testmode_ops;
  #endif
  
 +#ifdef CONFIG_MTK_VENDOR
-+	INIT_LIST_HEAD(&dev->phy.csi.csi_list);
-+	spin_lock_init(&dev->phy.csi.csi_lock);
++	INIT_LIST_HEAD(&dev->phy.csi.data_list);
++	spin_lock_init(&dev->phy.csi.data_lock);
++	INIT_LIST_HEAD(&dev->phy.csi.mac_filter_list);
++	mutex_init(&dev->phy.csi.mac_filter_lock);
 +	mt7915_vendor_register(&dev->phy);
 +#endif
 +
@@ -132,22 +207,31 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 5523031..6b6e0fa 100644
+index 5523031..f3c3b7e 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -811,6 +811,10 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -810,6 +810,19 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
  	struct mt7915_phy *phy = msta->vif->phy;
  	int i;
- 
 +#ifdef CONFIG_MTK_VENDOR
-+	mt7915_mcu_set_csi(&dev->phy, 2, 8, 1, 0, sta->addr, 0);
-+#endif
++	struct csi_mac_filter *ent;
 +
++	mutex_lock(&phy->csi.mac_filter_lock);
++	ent = mt7915_csi_mac_filter_find(phy, sta->addr);
++	if (ent && !mt7915_mcu_set_csi(phy, 2, 8, 1, 0, sta->addr, 0)) {
++		list_del(&ent->node);
++		kfree(ent);
++		phy->csi.mac_filter_cnt--;
++	}
++
++	mutex_unlock(&phy->csi.mac_filter_lock);
++#endif
+ 
  	mt7915_mcu_add_sta(dev, vif, sta, false);
  
- 	mt7915_mac_wtbl_update(dev, msta->wcid.idx,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 37b1505..3f35ba3 100644
+index 37b1505..33dab71 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -40,6 +40,10 @@ static bool sr_scene_detect = true;
@@ -193,7 +277,7 @@
 +	if (is_valid_ether_addr(mac_addr)) {
 +		ether_addr_copy(req.mac_addr, mac_addr);
 +
-+		if (req.v2 == 1 && sta_interval)
++		if ((req.v2 == ADD_CSI_MAC) && sta_interval)
 +			req.sta_interval = sta_interval;
 +	}
 +
@@ -341,21 +425,21 @@
 +
 +	/* put the csi data into list */
 +	INIT_LIST_HEAD(&target_csi->node);
-+	spin_lock_bh(&phy->csi.csi_lock);
++	spin_lock_bh(&phy->csi.data_lock);
 +
 +	if (!phy->csi.enable) {
 +		kfree(target_csi);
-+		spin_unlock_bh(&phy->csi.csi_lock);
++		spin_unlock_bh(&phy->csi.data_lock);
 +		return 0;
 +	}
 +
-+	list_add_tail(&target_csi->node, &phy->csi.csi_list);
++	list_add_tail(&target_csi->node, &phy->csi.data_list);
 +	phy->csi.count++;
 +
 +	if (phy->csi.count > CSI_MAX_BUF_NUM) {
 +		struct csi_data *old;
 +
-+		old = list_first_entry(&phy->csi.csi_list,
++		old = list_first_entry(&phy->csi.data_list,
 +				       struct csi_data, node);
 +
 +		list_del(&old->node);
@@ -365,7 +449,7 @@
 +
 +	if (target_csi->chain_info & BIT(15)) /* last chain */
 +		phy->csi.last_record = target_csi->ts;
-+	spin_unlock_bh(&phy->csi.csi_lock);
++	spin_unlock_bh(&phy->csi.data_lock);
 +
 +	return 0;
 +}
@@ -458,10 +542,10 @@
 +
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d2224dc..559a34b 100644
+index d2224dc..4696171 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -197,6 +197,45 @@ struct mt7915_hif {
+@@ -197,6 +197,57 @@ struct mt7915_hif {
  	int irq;
  };
  
@@ -501,26 +585,42 @@
 +	u8 tr_stream;
 +
 +	struct list_head node;
++};
++struct csi_mac_filter {
++	struct list_head node;
++
++	u8 mac[ETH_ALEN];
++	u32 interval;
 +};
++
++#define DEL_CSI_MAC 0
++#define ADD_CSI_MAC 1
++#define SHOW_CSI_MAC 2
++
++#define MAX_CSI_MAC_NUM 10
 +#endif
 +
  struct mt7915_phy {
  	struct mt76_phy *mt76;
  	struct mt7915_dev *dev;
-@@ -245,6 +284,21 @@ struct mt7915_phy {
+@@ -245,6 +296,25 @@ struct mt7915_phy {
  		u8 spe_idx;
  	} test;
  #endif
 +
 +#ifdef CONFIG_MTK_VENDOR
 +	struct {
-+		struct list_head csi_list;
-+		spinlock_t csi_lock; /* used for csi data push/pop */
++		struct list_head data_list;
++		spinlock_t data_lock;
 +		u32 count;
 +		bool mask;
 +		bool reorder;
 +		bool enable;
 +
++		struct mutex mac_filter_lock;
++		struct list_head mac_filter_list;
++		u8 mac_filter_cnt;
++
 +		struct csi_data buffered_csi;
 +		u32 interval;
 +		u32 last_record;
@@ -529,7 +629,7 @@
  };
  
  #ifdef MTK_DEBUG
-@@ -649,6 +703,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -649,6 +719,14 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
@@ -537,6 +637,8 @@
 +void mt7915_vendor_register(struct mt7915_phy *phy);
 +int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
 +		       u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval);
++struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr);
++void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy);
 +#endif
 +
  #ifdef MTK_DEBUG
@@ -544,10 +646,10 @@
  int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp);
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
 new file mode 100644
-index 0000000..55da60a
+index 0000000..0476202
 --- /dev/null
 +++ b/mt7915/vendor.c
-@@ -0,0 +1,470 @@
+@@ -0,0 +1,606 @@
 +// SPDX-License-Identifier: ISC
 +/*
 + * Copyright (C) 2020, MediaTek Inc. All rights reserved.
@@ -571,6 +673,7 @@
 +	[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL] = { .type = NLA_U32 },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM] = { .type = NLA_U16 },
 +	[MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
++	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER] = { .type = NLA_NESTED },
 +};
 +
 +struct csi_null_tone {
@@ -728,6 +831,67 @@
 +		return mode * 11 + ch_bw * ch_bw + (data_bw + 1) * 2 + pri_ch_idx;
 +}
 +
++struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr)
++{
++	struct csi_mac_filter *ent, *tmp_ent;
++
++	list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) {
++		if (ether_addr_equal(ent->mac, addr))
++			return ent;
++	}
++
++	return NULL;
++}
++
++void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy)
++{
++	struct csi_mac_filter *ent, *tmp_ent;
++	list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) {
++		list_del(&ent->node);
++		kfree(ent);
++	}
++
++	phy->csi.mac_filter_cnt = 0;
++}
++
++static int mt7915_vendor_reply_csi_mac_filter(struct wiphy *wiphy, struct mt7915_phy *phy)
++{
++	struct sk_buff *skb;
++	struct csi_mac_filter *ent, *tmp_ent;
++	int idx = 0;
++	struct nlattr *a, *b;
++
++	mutex_lock(&phy->csi.mac_filter_lock);
++
++#define ENTRY_SIZE nla_total_size(nla_total_size(ETH_ALEN) + \
++				   nla_total_size(sizeof(ent->interval)))
++
++	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, ENTRY_SIZE *
++						  phy->csi.mac_filter_cnt);
++	if (!skb) {
++		mutex_unlock(&phy->csi.mac_filter_lock);
++		return -ENOMEM;
++	}
++
++	a = nla_nest_start(skb, MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER);
++
++	list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) {
++
++		b = nla_nest_start(skb, idx++);
++		nla_put(skb, MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC,
++				ETH_ALEN, ent->mac);
++		nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL, ent->interval);
++		nla_nest_end(skb, b);
++	}
++
++	nla_nest_end(skb, a);
++#undef ENTRY_SIZE
++
++	mutex_unlock(&phy->csi.mac_filter_lock);
++
++	return cfg80211_vendor_cmd_reply(skb);
++}
++
 +static int mt7915_vendor_csi_ctrl(struct wiphy *wiphy,
 +				  struct wireless_dev *wdev,
 +				  const void *data,
@@ -787,12 +951,86 @@
 +					nla_get_u32(tb[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL]);
 +		}
 +
-+		err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, mac_addr, sta_interval);
++		if (mode == 0) {
++			mutex_lock(&phy->csi.mac_filter_lock);
 +
-+		if (err < 0)
-+			return err;
++			err = mt7915_mcu_set_csi(phy, mode, type, v1, v2,
++			                         mac_addr, sta_interval);
++			if (err) {
++				mutex_unlock(&phy->csi.mac_filter_lock);
++				return err;
++			}
++
++			mt7915_csi_mac_filter_clear(phy);
++
++			mutex_unlock(&phy->csi.mac_filter_lock);
++		} else if (mode == 2 && type == 8 && v1 == 1 && (v2 == ADD_CSI_MAC || v2 == DEL_CSI_MAC)) {
++			struct csi_mac_filter *ent;
++
++			mutex_lock(&phy->csi.mac_filter_lock);
++
++			if (v2 == DEL_CSI_MAC) {
++				ent = mt7915_csi_mac_filter_find(phy, mac_addr);
++				if (!ent) {
++					mutex_unlock(&phy->csi.mac_filter_lock);
++					return -ENOENT;
++				}
++			} else {
++				if (is_mt7915(phy->mt76->dev)) {
++					if (phy->csi.mac_filter_cnt >= MAX_CSI_MAC_NUM) {
++						mutex_unlock(&phy->csi.mac_filter_lock);
++						return -ENOSPC;
++					}
++				} else {
++					if (phy->csi.mac_filter_cnt >= MAX_CSI_MAC_NUM/2) {
++						mutex_unlock(&phy->csi.mac_filter_lock);
++						return -ENOSPC;
++					}
++				}
++
++				ent = mt7915_csi_mac_filter_find(phy, mac_addr);
++				if (ent) {
++					mutex_unlock(&phy->csi.mac_filter_lock);
++					return -EEXIST;
++				}
++
++				ent = kzalloc(sizeof(*ent), GFP_KERNEL);
++				if (!ent) {
++					mutex_unlock(&phy->csi.mac_filter_lock);
++					return -ENOMEM;
++				}
++
++				ether_addr_copy(ent->mac, mac_addr);
++				ent->interval = sta_interval;
++			}
 +
-+		spin_lock_bh(&phy->csi.csi_lock);
++			err = mt7915_mcu_set_csi(phy, mode, type, v1, v2,
++						 mac_addr, sta_interval);
++			if (err) {
++				if (v2 == ADD_CSI_MAC)
++					kfree(ent);
++				mutex_unlock(&phy->csi.mac_filter_lock);
++				return err;
++			}
++
++			if (v2 == DEL_CSI_MAC) {
++				list_del(&ent->node);
++				kfree(ent);
++				phy->csi.mac_filter_cnt--;
++			} else {
++				list_add_tail(&ent->node, &phy->csi.mac_filter_list);
++				phy->csi.mac_filter_cnt++;
++			}
++
++			mutex_unlock(&phy->csi.mac_filter_lock);
++		} else if (mode == 2 && type == 8 && v1 == 1 && v2 == SHOW_CSI_MAC) {
++			return mt7915_vendor_reply_csi_mac_filter(wiphy, phy);
++		} else {
++			err = mt7915_mcu_set_csi(phy, mode, type, v1, v2,
++						 mac_addr, sta_interval);
++			if (err)
++				return err;
++		}
 +
 +		phy->csi.enable = !!mode;
 +
@@ -804,20 +1042,20 @@
 +		}
 +
 +		/* clean up old csi stats */
-+		if ((mode == 0 || mode == 2) && !list_empty(&phy->csi.csi_list)) {
++		if (mode == 0 && !list_empty(&phy->csi.data_list)) {
 +			struct csi_data *c, *tmp_c;
 +
-+			list_for_each_entry_safe(c, tmp_c, &phy->csi.csi_list,
++			spin_lock_bh(&phy->csi.data_lock);
++			list_for_each_entry_safe(c, tmp_c, &phy->csi.data_list,
 +						 node) {
 +				list_del(&c->node);
 +				kfree(c);
 +				phy->csi.count--;
 +			}
++			spin_unlock_bh(&phy->csi.data_lock);
 +		} else if (mode == 1) {
 +			phy->csi.last_record = 0;
 +		}
-+
-+		spin_unlock_bh(&phy->csi.csi_lock);
 +	}
 +
 +	if (tb[MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL])
@@ -933,14 +1171,14 @@
 +		*storage |= RESERVED_SET;
 +	}
 +
-+	spin_lock_bh(&phy->csi.csi_lock);
++	spin_lock_bh(&phy->csi.data_lock);
 +
-+	if (!list_empty(&phy->csi.csi_list)) {
++	if (!list_empty(&phy->csi.data_list)) {
 +		struct csi_data *csi;
 +		void *a, *b;
 +		int i;
 +
-+		csi = list_first_entry(&phy->csi.csi_list, struct csi_data, node);
++		csi = list_first_entry(&phy->csi.data_list, struct csi_data, node);
 +
 +		mt7915_vendor_csi_tone_mask(phy, csi);
 +
@@ -993,7 +1231,7 @@
 +		err = phy->csi.count;
 +	}
 +out:
-+	spin_unlock_bh(&phy->csi.csi_lock);
++	spin_unlock_bh(&phy->csi.data_lock);
 +
 +	return err;
 +}
@@ -1020,10 +1258,10 @@
 +}
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
 new file mode 100644
-index 0000000..e1f5fd3
+index 0000000..d2b90aa
 --- /dev/null
 +++ b/mt7915/vendor.h
-@@ -0,0 +1,63 @@
+@@ -0,0 +1,75 @@
 +/* SPDX-License-Identifier: ISC */
 +#ifndef __MT7915_VENDOR_H
 +#define __MT7915_VENDOR_H
@@ -1049,6 +1287,7 @@
 +	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM,
 +
 +	MTK_VENDOR_ATTR_CSI_CTRL_DATA,
++	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER,
 +
 +	/* keep last */
 +	NUM_MTK_VENDOR_ATTRS_CSI_CTRL,
@@ -1086,6 +1325,17 @@
 +		NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1
 +};
 +
++enum mtk_vendor_attr_csi_mac_filter {
++	MTK_VENDOR_ATTR_CSI_MAC_FILTER_UNSPEC,
++
++	MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC,
++	MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER,
++	MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX =
++		NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER - 1
++};
 +#endif
 -- 
 2.18.0
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
index 0532a6e..1bbc85f 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
@@ -1,16 +1,16 @@
-From d8ff7fe3f60f210e1f5e17387d0366934ca4e18b Mon Sep 17 00:00:00 2001
+From 703dc34c3f03017062f03a74add408ece14914a9 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Tue, 11 Jan 2022 12:03:23 +0800
-Subject: [PATCH 1002/1051] wifi: mt76: mt7915: air monitor support
+Subject: [PATCH] wifi: mt76: mt7915: air monitor support
 
 ---
  mt76_connac_mcu.h |   2 +
  mt7915/mac.c      |   4 +
  mt7915/main.c     |   3 +
- mt7915/mt7915.h   |  32 ++++
+ mt7915/mt7915.h   |  33 +++++
  mt7915/vendor.c   | 361 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7915/vendor.h   |  38 +++++
- 6 files changed, 440 insertions(+)
+ 6 files changed, 441 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
 index cda7559..3aa4e59 100644
@@ -26,7 +26,7 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  };
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 8268c19..778f04f 100644
+index d99864f..e38905a 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -531,6 +531,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
@@ -41,7 +41,7 @@
  		status->flag |= RX_FLAG_8023;
  		mt7915_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 6b6e0fa..9fd65f0 100644
+index f3c3b7e..707afcc 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -800,6 +800,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -55,14 +55,22 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 559a34b..57a9da3 100644
+index 4696171..1acf938 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -234,6 +234,33 @@ struct csi_data {
+@@ -234,6 +234,7 @@ struct csi_data {
  
  	struct list_head node;
  };
 +
+ struct csi_mac_filter {
+ 	struct list_head node;
+ 
+@@ -246,6 +247,33 @@ struct csi_mac_filter {
+ #define SHOW_CSI_MAC 2
+ 
+ #define MAX_CSI_MAC_NUM 10
++
 +#define MT7915_AIR_MONITOR_MAX_ENTRY	16
 +#define MT7915_AIR_MONITOR_MAX_GROUP	MT7915_AIR_MONITOR_MAX_ENTRY >> 1
 +
@@ -92,7 +100,7 @@
  #endif
  
  struct mt7915_phy {
-@@ -298,6 +325,8 @@ struct mt7915_phy {
+@@ -314,6 +342,8 @@ struct mt7915_phy {
  		u32 interval;
  		u32 last_record;
  	} csi;
@@ -101,10 +109,10 @@
  #endif
  };
  
-@@ -707,6 +736,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
- void mt7915_vendor_register(struct mt7915_phy *phy);
- int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
+@@ -725,6 +755,9 @@ int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
  		       u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval);
+ struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr);
+ void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy);
 +void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
 +int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
 +				  struct ieee80211_sta *sta);
@@ -112,10 +120,10 @@
  
  #ifdef MTK_DEBUG
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 55da60a..c964b14 100644
+index 0476202..4c11ed1 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
-@@ -448,6 +448,355 @@ out:
+@@ -584,6 +584,355 @@ out:
  	return err;
  }
  
@@ -471,7 +479,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -460,6 +809,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -596,6 +945,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_csi_ctrl_dump,
  		.policy = csi_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_CSI_CTRL_MAX,
@@ -491,7 +499,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index e1f5fd3..1863eee 100644
+index d2b90aa..429b25b 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -5,6 +5,7 @@
@@ -502,10 +510,11 @@
  	MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
  };
  
-@@ -60,4 +61,41 @@ enum mtk_vendor_attr_csi_data {
- 		NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1
+@@ -72,4 +73,41 @@ enum mtk_vendor_attr_csi_mac_filter {
+ 	MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX =
+ 		NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER - 1
  };
- 
++
 +enum mtk_vendor_attr_mnt_ctrl {
 +	MTK_VENDOR_ATTR_AMNT_CTRL_UNSPEC,
 +
@@ -542,7 +551,6 @@
 +	MTK_VENDOR_ATTR_AMNT_DUMP_MAX =
 +		NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1
 +};
-+
  #endif
 -- 
 2.18.0
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
index 1d23e78..2e16650 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
@@ -1,17 +1,16 @@
-From f2c03b7513cd302acab9ef9ad5f60677e541a331 Mon Sep 17 00:00:00 2001
+From 3982aaa49810c8f0b2c754bd6c7a2d2b21c45407 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <Yi-Chia.Hsieh@mediatek.com>
 Date: Tue, 12 Jul 2022 10:04:35 -0700
-Subject: [PATCH 1014/1051] wifi: mt76: mt7915: add phy capability vendor
- command
+Subject: [PATCH] wifi: mt76: mt7915: add phy capability vendor command
 
 ---
  mt7915/mt7915.h |  1 +
  mt7915/vendor.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
- mt7915/vendor.h | 25 ++++++++++++++++++++++++
- 3 files changed, 78 insertions(+)
+ mt7915/vendor.h | 26 +++++++++++++++++++++++++
+ 3 files changed, 79 insertions(+)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 43f5ea4..2c13d3a 100644
+index 1c1b3a1..f8ae363 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -11,6 +11,7 @@
@@ -23,10 +22,10 @@
  #define MT7916_WTBL_SIZE		544
  #define MT7915_WTBL_RESERVED		(mt7915_wtbl_size(dev) - 1)
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index a8b1fa8..757aecb 100644
+index 1beb603..e6cd79f 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
-@@ -51,6 +51,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
+@@ -52,6 +52,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
  	[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
  };
  
@@ -45,7 +44,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -995,6 +1007,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1131,6 +1143,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  	return 0;
  }
  
@@ -81,7 +80,7 @@
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
  		.info = {
-@@ -1052,6 +1093,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1188,6 +1229,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.doit = mt7915_vendor_mu_ctrl,
  		.policy = mu_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
@@ -100,7 +99,7 @@
  };
  
 diff --git a/mt7915/vendor.h b/mt7915/vendor.h
-index a4a9180..34dd7d0 100644
+index 9cb6755..e58884c 100644
 --- a/mt7915/vendor.h
 +++ b/mt7915/vendor.h
 @@ -10,6 +10,7 @@ enum mtk_nl80211_vendor_subcmds {
@@ -111,10 +110,11 @@
  };
  
  enum mtk_capi_control_changed {
-@@ -152,4 +153,28 @@ enum mtk_vendor_attr_mnt_dump {
+@@ -164,4 +165,29 @@ enum mtk_vendor_attr_mnt_dump {
+ 	MTK_VENDOR_ATTR_AMNT_DUMP_MAX =
  		NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1
  };
- 
++
 +enum mtk_vendor_attr_phy_capa_ctrl {
 +	MTK_VENDOR_ATTR_PHY_CAPA_CTRL_UNSPEC,
 +
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
index aa596a7..7b56f68 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
@@ -1,7 +1,7 @@
-From d9da478994e78ed307ad2a1fac7b300c8251fbc2 Mon Sep 17 00:00:00 2001
+From 4f16df4de5a3b2d9080a7c07bfc1f0496de442cd Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 30 Mar 2023 15:12:37 +0800
-Subject: [PATCH 1020/1051] wifi: mt76: mt7915: add cal free data merge support
+Subject: [PATCH] wifi: mt76: mt7915: add cal free data merge support
 
 1. add basic cal free data support
 2. add E3 low yield rate workaround for panther E3 with 7976 adie
@@ -19,12 +19,12 @@
  5 files changed, 250 insertions(+), 6 deletions(-)
 
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 2661386..5c08910 100644
+index 909df24..c369296 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
-@@ -1241,6 +1241,46 @@ mt7915_rf_regval_set(void *data, u64 val)
- DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get,
- 			 mt7915_rf_regval_set, "0x%08llx\n");
+@@ -1286,6 +1286,46 @@ static const struct file_operations mt7915_csi_ops = {
+ };
+ #endif
  
 +static ssize_t
 +mt7915_efuse_get(struct file *file, char __user *user_buf,
@@ -69,14 +69,14 @@
  int mt7915_init_debugfs(struct mt7915_phy *phy)
  {
  	struct mt7915_dev *dev = phy->dev;
-@@ -1283,6 +1323,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+@@ -1328,6 +1368,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
  		debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir,
  					    mt7915_rdd_monitor);
  	}
 +	debugfs_create_file("otp", 0400, dir, dev, &mt7915_efuse_ops);
- 
- 	if (!ext_phy)
- 		dev->debugfs_dir = dir;
+ #ifdef CONFIG_MTK_VENDOR
+ 	debugfs_create_file("csi_stats", 0400, dir, phy, &mt7915_csi_ops);
+ #endif
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
 index c8b1c18..6133c20 100644
 --- a/mt7915/eeprom.c
@@ -322,7 +322,7 @@
  	MT7976_ONE_ADIE_DBDC = 0x7,
  	MT7975_ONE_ADIE	= 0x8,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 89b35e8..372168d 100644
+index cf622de..7bc5182 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -2968,6 +2968,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
@@ -353,10 +353,10 @@
  	dev_kfree_skb(skb);
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d9a885d..d32b12f 100644
+index 3fe901d..5ba6986 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -564,6 +564,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+@@ -581,6 +581,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  
  int mt7915_register_device(struct mt7915_dev *dev);
  void mt7915_unregister_device(struct mt7915_dev *dev);
diff --git a/feed/app/mt76-vendor/src/csi.c b/feed/app/mt76-vendor/src/csi.c
index ca7732e..f24fa9c 100644
--- a/feed/app/mt76-vendor/src/csi.c
+++ b/feed/app/mt76-vendor/src/csi.c
@@ -17,6 +17,7 @@
 	[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL] = { .type = NLA_U32 },
 	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM] = { .type = NLA_U16 },
 	[MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
+	[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER] = { .type = NLA_NESTED },
 };
 
 static struct nla_policy csi_data_policy[NUM_MTK_VENDOR_ATTRS_CSI_DATA] = {
@@ -37,6 +38,10 @@
 	[MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO] = { .type = NLA_U32 },
 };
 
+static struct nla_policy csi_filter_policy[NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER] = {
+	[MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL] = { .type = NLA_U32 },
+};
+
 static int mt76_csi_dump_cb(struct nl_msg *msg, void *arg)
 {
 	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_CSI_CTRL];
@@ -335,6 +340,48 @@
 	return 0;
 }
 
+static int mt76_csi_set_cb(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_CSI_CTRL];
+	struct nlattr *cur, *tb_entry[NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER];
+	int rem;
+	struct nlattr *attr;
+
+	attr = unl_find_attr(&unl, msg, NL80211_ATTR_VENDOR_DATA);
+	if (!attr) {
+		fprintf(stderr, "Testdata attribute not found\n");
+		return NL_SKIP;
+	}
+
+	nla_parse_nested(tb, MTK_VENDOR_ATTR_CSI_CTRL_MAX, attr, csi_ctrl_policy);
+
+	if (!tb[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER])
+		return NL_SKIP;
+
+	nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER], rem) {
+		struct nlattr *tb[MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX + 1];
+		u8 entry_mac[ETH_ALEN] = {0};
+		u32 entry_interval = 0;
+
+		nla_parse_nested(tb_entry, MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX,
+				 cur, csi_filter_policy);
+
+		if (!tb_entry[MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC] ||
+		    !tb_entry[MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL])
+			continue;
+
+		memcpy(entry_mac, nla_data(tb_entry[MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC]), ETH_ALEN);
+		entry_interval = nla_get_u32(tb_entry[MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL]);
+
+		printf("mac: %02x:%02x:%02x:%02x:%02x:%02x, interval: %d\n",
+			entry_mac[0], entry_mac[1], entry_mac[2],
+			entry_mac[3], entry_mac[4], entry_mac[5],
+			entry_interval);
+	}
+
+	return NL_SKIP;
+}
+
 int mt76_csi_set(int idx, int argc, char **argv)
 {
 	struct nl_msg *msg;
@@ -364,7 +411,7 @@
 
 	nla_nest_end(msg, data);
 
-	ret = unl_genl_request(&unl, msg, NULL, NULL);
+	ret = unl_genl_request(&unl, msg, mt76_csi_set_cb, NULL);
 	if (ret)
 		fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret));
 
diff --git a/feed/app/mt76-vendor/src/mt76-vendor.h b/feed/app/mt76-vendor/src/mt76-vendor.h
index b591575..cafe32b 100644
--- a/feed/app/mt76-vendor/src/mt76-vendor.h
+++ b/feed/app/mt76-vendor/src/mt76-vendor.h
@@ -57,6 +57,7 @@
 	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM,
 
 	MTK_VENDOR_ATTR_CSI_CTRL_DATA,
+	MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER,
 
 	/* keep last */
 	NUM_MTK_VENDOR_ATTRS_CSI_CTRL,
@@ -94,6 +95,18 @@
 		NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1
 };
 
+enum mtk_vendor_attr_csi_mac_filter {
+	MTK_VENDOR_ATTR_CSI_MAC_FILTER_UNSPEC,
+
+	MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC,
+	MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL,
+
+	/* keep last */
+	NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER,
+	MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX =
+		NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER - 1
+};
+
 enum mtk_vendor_attr_mnt_ctrl {
 	MTK_VENDOR_ATTR_AMNT_CTRL_UNSPEC,