From c862fc74acc7a3567153c2ed854eaad3351c2331 Mon Sep 17 00:00:00 2001
From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
Date: Wed, 3 May 2023 05:08:07 +0800
Subject: [PATCH 1012/1014] wifi: mt76: mt7996: add vendor cmd to get available
 color bitmap

Add a vendor cmd to notify user space available color bitmap.
The OBSS BSS color bitmap is maintained in mac80211, so mt76 will make use of that.

Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
---
 mt7996/vendor.c | 36 ++++++++++++++++++++++++++++++++++++
 mt7996/vendor.h | 11 +++++++++++
 2 files changed, 47 insertions(+)

diff --git a/mt7996/vendor.c b/mt7996/vendor.c
index 6442beb..170495d 100644
--- a/mt7996/vendor.c
+++ b/mt7996/vendor.c
@@ -34,6 +34,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
 	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
 };
 
+static struct nla_policy
+bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = {
+	[MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP] = { .type = NLA_U64 },
+};
+
 struct mt7996_amnt_data {
 	u8 idx;
 	u8 addr[ETH_ALEN];
@@ -409,6 +414,26 @@ mt7966_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
 	return len + 1;
 }
 
+static int
+mt7996_vendor_bss_color_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+				  struct sk_buff *skb, const void *data, int data_len,
+				  unsigned long *storage)
+{
+	struct ieee80211_vif *vif = wdev_to_ieee80211_vif(wdev);
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	int len = 0;
+
+	if (*storage == 1)
+		return -ENOENT;
+	*storage = 1;
+
+	if (nla_put_u64_64bit(skb, MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP,
+			      ~bss_conf->used_color_bitmap, NL80211_ATTR_PAD))
+		return -ENOMEM;
+	len += 1;
+
+	return len;
+}
 
 static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
 	{
@@ -435,6 +460,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
 		.policy = amnt_ctrl_policy,
 		.maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
 	},
+	{
+		.info = {
+			.vendor_id = MTK_NL80211_VENDOR_ID,
+			.subcmd = MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL,
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.dumpit = mt7996_vendor_bss_color_ctrl_dump,
+		.policy = bss_color_ctrl_policy,
+		.maxattr = MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX,
+	},
 };
 
 void mt7996_vendor_register(struct mt7996_phy *phy)
diff --git a/mt7996/vendor.h b/mt7996/vendor.h
index 2078caf..eec9e74 100644
--- a/mt7996/vendor.h
+++ b/mt7996/vendor.h
@@ -6,6 +6,7 @@
 enum mtk_nl80211_vendor_subcmds {
 	MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
+	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
 };
 
 enum mtk_vendor_attr_mu_ctrl {
@@ -57,5 +58,15 @@ enum mtk_vendor_attr_mnt_dump {
 		NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1
 };
 
+enum mtk_vendor_attr_bss_color_ctrl {
+	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
+
+	MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP,
+
+	/* keep last */
+	NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL,
+	MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX =
+		NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 1
+};
 
 #endif
-- 
2.18.0

