blob: c25f9b2620642470d59c1333594e17406715d04e [file] [log] [blame]
developerbfbd31a2022-06-28 13:53:07 +08001From c1e72950b8f7df7c36c64e27613637f88e3c1ba3 Mon Sep 17 00:00:00 2001
2From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Fri, 24 Jun 2022 11:15:45 +0800
4Subject: [PATCH 1117/1117] mt76: mt7915: add vendor subcmd EDCCA ctrl
5
6Change-Id: I92dabf8be9c5a7ecec78f35325bc5645af8d15ab
7---
8 mt76_connac_mcu.h | 1 +
9 mt7915/main.c | 3 +++
10 mt7915/mcu.c | 38 ++++++++++++++++++++++++++++
11 mt7915/mcu.h | 12 +++++++++
12 mt7915/mt7915.h | 2 ++
13 mt7915/vendor.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
14 mt7915/vendor.h | 19 ++++++++++++++
15 7 files changed, 138 insertions(+)
16
17diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
18index a0e6fa6e..1747e06d 100644
19--- a/mt76_connac_mcu.h
20+++ b/mt76_connac_mcu.h
21@@ -1147,6 +1147,7 @@ enum {
22 MCU_EXT_CMD_SMESH_CTRL = 0xae,
23 MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
24 MCU_EXT_CMD_CERT_CFG = 0xb7,
25+ MCU_EXT_CMD_EDCCA = 0xba,
26 MCU_EXT_CMD_CSI_CTRL = 0xc2,
27 };
28
29diff --git a/mt7915/main.c b/mt7915/main.c
30index 6c97ce78..1dc41ab6 100644
31--- a/mt7915/main.c
32+++ b/mt7915/main.c
33@@ -456,6 +456,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
34 mutex_unlock(&dev->mt76.mutex);
35 }
36 #endif
37+ ret = mt7915_mcu_set_edcca(phy, EDCCA_CTRL_SET_EN, NULL, 0);
38+ if (ret)
39+ return ret;
40 ieee80211_stop_queues(hw);
41 ret = mt7915_set_channel(phy);
42 if (ret)
43diff --git a/mt7915/mcu.c b/mt7915/mcu.c
44index 46eef36a..205ecbab 100644
45--- a/mt7915/mcu.c
46+++ b/mt7915/mcu.c
47@@ -4217,3 +4217,41 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
48
49 return 0;
50 }
51+
52+int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value,
53+ s8 compensation)
54+{
55+ static const u8 ch_band[] = {
56+ [NL80211_BAND_2GHZ] = 0,
57+ [NL80211_BAND_5GHZ] = 1,
58+ [NL80211_BAND_6GHZ] = 2,
59+ };
60+ struct mt7915_dev *dev = phy->dev;
61+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
62+ struct {
63+ u8 band_idx;
64+ u8 cmd_idx;
65+ u8 setting[3];
66+ bool record_in_fw;
67+ u8 region;
68+ s8 thres_compensation;
69+ } __packed req = {
70+ .band_idx = phy->band_idx,
71+ .cmd_idx = mode,
72+ .record_in_fw = false,
73+ .region = dev->mt76.region,
74+ .thres_compensation = compensation,
75+ };
76+
77+ if (ch_band[chandef->chan->band] != 2)
78+ return 0;
79+
80+ if (mode == EDCCA_CTRL_SET_EN) {
81+ if (!value)
82+ req.setting[0] = EDCCA_MODE_AUTO;
83+ else
84+ req.setting[0] = value[0];
85+ }
86+
87+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCCA), &req, sizeof(req), true);
88+}
89diff --git a/mt7915/mcu.h b/mt7915/mcu.h
90index 873a8055..72c2cfc6 100644
91--- a/mt7915/mcu.h
92+++ b/mt7915/mcu.h
93@@ -785,4 +785,16 @@ enum {
94 };
95 #endif
96
97+enum {
98+ EDCCA_CTRL_SET_EN = 0,
99+ EDCCA_CTRL_SET_THERS,
100+ EDCCA_CTRL_GET_EN,
101+ EDCCA_CTRL_GET_THERS,
102+ EDCCA_CTRL_NUM,
103+};
104+
105+enum {
106+ EDCCA_MODE_FORCE_DISABLE,
107+ EDCCA_MODE_AUTO,
108+};
109 #endif
110diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
111index 0b7f73b3..5c58a29c 100644
112--- a/mt7915/mt7915.h
113+++ b/mt7915/mt7915.h
114@@ -718,6 +718,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
115 int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
116 struct ieee80211_sta *sta);
117 #endif
118+int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value,
119+ s8 compensation);
120
121 #ifdef MTK_DEBUG
122 int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
123diff --git a/mt7915/vendor.c b/mt7915/vendor.c
124index 77d71e48..5a28a554 100644
125--- a/mt7915/vendor.c
126+++ b/mt7915/vendor.c
127@@ -62,6 +62,17 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = {
128 [MTK_VENDOR_ATTR_PHY_CAPA_DUMP_MAX_SUPPORTED_STA] = { .type = NLA_U16 },
129 };
130
131+static const struct nla_policy
132+edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
133+ [MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
134+ [MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
135+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
136+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
137+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
138+ [MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_S8 },
139+};
140+
141+
142 struct csi_null_tone {
143 u8 start;
144 u8 end;
145@@ -1015,6 +1026,47 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
146 return len;
147 }
148
149+static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy,
150+ struct wireless_dev *wdev,
151+ const void *data,
152+ int data_len)
153+{
154+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
155+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
156+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL];
157+ int err;
158+ u8 edcca_mode;
159+ s8 edcca_compensation;
160+
161+ err = nla_parse(tb, MTK_VENDOR_ATTR_EDCCA_CTRL_MAX, data, data_len,
162+ edcca_ctrl_policy, NULL);
163+ if (err)
164+ return err;
165+
166+ if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE])
167+ return -EINVAL;
168+
169+ edcca_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE]);
170+ if (edcca_mode == EDCCA_CTRL_SET_EN) {
171+ u8 edcca_value[3] = {0};
172+ if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] ||
173+ !tb[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE]) {
174+ return -EINVAL;
175+ }
176+ edcca_value[0] =
177+ nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL]);
178+ edcca_compensation =
179+ nla_get_s8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE]);
180+
181+ err = mt7915_mcu_set_edcca(phy, edcca_mode, edcca_value,
182+ edcca_compensation);
183+ if (err)
184+ return err;
185+ }
186+ return 0;
187+}
188+
189+
190 static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
191 {
192 .info = {
193@@ -1083,6 +1135,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
194 .dumpit = mt7915_vendor_phy_capa_ctrl_dump,
195 .policy = phy_capa_ctrl_policy,
196 .maxattr = MTK_VENDOR_ATTR_PHY_CAPA_CTRL_MAX,
197+ },
198+ {
199+ .info = {
200+ .vendor_id = MTK_NL80211_VENDOR_ID,
201+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL,
202+ },
203+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
204+ WIPHY_VENDOR_CMD_NEED_RUNNING,
205+ .doit = mt7915_vendor_edcca_ctrl,
206+ .policy = edcca_ctrl_policy,
207+ .maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
208 }
209 };
210
211diff --git a/mt7915/vendor.h b/mt7915/vendor.h
212index 719b851f..83c41bc1 100644
213--- a/mt7915/vendor.h
214+++ b/mt7915/vendor.h
215@@ -10,8 +10,27 @@ enum mtk_nl80211_vendor_subcmds {
216 MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
217 MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL = 0xc5,
218 MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL = 0xc6,
219+ MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
220 };
221
222+
223+enum mtk_vendor_attr_edcca_ctrl {
224+ MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0,
225+
226+ MTK_VENDOR_ATTR_EDCCA_CTRL_MODE,
227+ MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL,
228+ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL,
229+ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL,
230+ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL,
231+ MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE,
232+
233+ /* keep last */
234+ NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL,
235+ MTK_VENDOR_ATTR_EDCCA_CTRL_MAX =
236+ NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL - 1
237+};
238+
239+
240 enum mtk_capi_control_changed {
241 CAPI_RFEATURE_CHANGED = BIT(16),
242 CAPI_WIRELESS_CHANGED = BIT(17),
243--
2442.18.0
245