blob: f0528a981c0bf8a29b6ff1385273fc90bda20a10 [file] [log] [blame]
developerd0c89452024-10-11 16:53:27 +08001From fdf267776932e3bab7c0d87f2c9c8a96ac9a4e0f Mon Sep 17 00:00:00 2001
developer05f3b2b2024-08-19 19:17:34 +08002From: Allen Ye <allen.ye@mediatek.com>
3Date: Tue, 28 May 2024 15:39:06 +0800
developerd0c89452024-10-11 16:53:27 +08004Subject: [PATCH 164/223] mtk: mt76: Add dynamic pp vendor and debug pp algo
developer05f3b2b2024-08-19 19:17:34 +08005 cmd support
6
7Add dynamic pp vendor and debug pp algo cmd support.
81. Add support channel switch with a punct bitmap.
92. Add pp event for fw mode and trigger a channel switch by hostapd.
103. Add pp algo dump cmd to get current fw punct bitmap and mode.
11
12When extender sta have not connected to root ap and the chandef is null.
13mt76 just ignore the event. Once the sta connect to ap, the sta part would
14send a new fw cmd to update the pp bitmap.
15
developerd0c89452024-10-11 16:53:27 +080016Change-Id: I3574940a3f4165f136df8e07a819a32a5bc02b41
17Change-Id: I1e9955ac0cecafa481fe851502880f6ea1a44469
developer05f3b2b2024-08-19 19:17:34 +080018Signed-off-by: Allen Ye <allen.ye@mediatek.com>
19---
20 mt7996/mcu.c | 70 ++++++++++++++++++++++++++++-
21 mt7996/mcu.h | 38 ++++++++++++++++
22 mt7996/mt7996.h | 2 +
23 mt7996/mtk_debugfs.c | 14 ++++++
24 mt7996/vendor.c | 103 +++++++++++++++++++++++++++++++------------
25 mt7996/vendor.h | 8 +++-
26 6 files changed, 205 insertions(+), 30 deletions(-)
27
28diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +080029index fce92046..77d3b2c8 100644
developer05f3b2b2024-08-19 19:17:34 +080030--- a/mt7996/mcu.c
31+++ b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +080032@@ -1285,6 +1285,39 @@ mt7996_mcu_wed_rro_event(struct mt7996_dev *dev, struct sk_buff *skb)
developer05f3b2b2024-08-19 19:17:34 +080033 }
34 }
35
36+void
37+mt7996_dump_pp_statistic_event(struct mt7996_dev *dev,
38+ struct mt7996_mcu_pp_alg_ctrl_event *event)
39+{
40+ u32 unit_time = le32_to_cpu(event->pp_timer_intv);
41+
42+ dev_info(dev->mt76.dev, "band idx = %u\n", le32_to_cpu(event->band_idx));
43+ dev_info(dev->mt76.dev, "x2 value = %u\n", le32_to_cpu(event->thr_x2_value));
44+ dev_info(dev->mt76.dev, "x2 shift = %u\n", le32_to_cpu(event->thr_x2_shift));
45+ dev_info(dev->mt76.dev, "x3 value = %u\n", le32_to_cpu(event->thr_x3_value));
46+ dev_info(dev->mt76.dev, "x3 shift = %u\n", le32_to_cpu(event->thr_x3_shift));
47+ dev_info(dev->mt76.dev, "x4 value = %u\n", le32_to_cpu(event->thr_x4_value));
48+ dev_info(dev->mt76.dev, "x4 shift = %u\n", le32_to_cpu(event->thr_x4_shift));
49+ dev_info(dev->mt76.dev, "x5 value = %u\n", le32_to_cpu(event->thr_x5_value));
50+ dev_info(dev->mt76.dev, "x5 shift = %u\n", le32_to_cpu(event->thr_x5_shift));
51+ dev_info(dev->mt76.dev, "x6 value = %u\n", le32_to_cpu(event->thr_x6_value));
52+ dev_info(dev->mt76.dev, "x6 shift = %u\n", le32_to_cpu(event->thr_x6_shift));
53+ dev_info(dev->mt76.dev, "x7 value = %u\n", le32_to_cpu(event->thr_x7_value));
54+ dev_info(dev->mt76.dev, "x7 shift = %u\n", le32_to_cpu(event->thr_x7_shift));
55+ dev_info(dev->mt76.dev, "x8 value = %u\n", le32_to_cpu(event->thr_x8_value));
56+ dev_info(dev->mt76.dev, "x8 shift = %u\n", le32_to_cpu(event->thr_x8_shift));
57+ dev_info(dev->mt76.dev, "sw_pp_time = %u (Unit: %u ms)\n",
58+ le32_to_cpu(event->sw_pp_time), unit_time);
59+ dev_info(dev->mt76.dev, "hw_pp_time = %u (Unit: %u ms)\n",
60+ le32_to_cpu(event->hw_pp_time), unit_time);
61+ dev_info(dev->mt76.dev, "no_pp_time = %u (Unit: %u ms)\n",
62+ le32_to_cpu(event->no_pp_time), unit_time);
63+ dev_info(dev->mt76.dev, "auto_bw_time = %u (Unit: %u ms)\n",
64+ le32_to_cpu(event->auto_bw_time), unit_time);
65+ dev_info(dev->mt76.dev, "punct_bitmap = 0x%04x\n",
66+ le16_to_cpu(event->punct_bitmap));
67+}
68+
69 static void
70 mt7996_mcu_pp_event(struct mt7996_dev *dev, struct sk_buff *skb)
71 {
developerd0c89452024-10-11 16:53:27 +080072@@ -1311,9 +1344,13 @@ mt7996_mcu_pp_event(struct mt7996_dev *dev, struct sk_buff *skb)
developer05f3b2b2024-08-19 19:17:34 +080073 if (phy->punct_bitmap == report_bitmap)
74 return;
75
76- if (phy->pp_mode == PP_FW_MODE)
77+ if (phy->pp_mode == PP_FW_MODE) {
78 phy->punct_bitmap = report_bitmap;
79-
80+ mt7996_vendor_pp_bitmap_update(phy, report_bitmap);
81+ }
82+ break;
83+ case UNI_EVENT_PP_TAG_ALG_CTRL:
84+ mt7996_dump_pp_statistic_event(dev, (struct mt7996_mcu_pp_alg_ctrl_event *)event);
85 break;
86 }
87 }
developerd0c89452024-10-11 16:53:27 +080088@@ -6415,6 +6452,35 @@ int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy,
developer05f3b2b2024-08-19 19:17:34 +080089 &req, sizeof(req), false);
90 }
91
92+int mt7996_mcu_set_pp_alg_ctrl(struct mt7996_phy *phy, u8 action)
93+{
94+ struct mt7996_dev *dev = phy->dev;
95+ struct {
96+ u8 _rsv1[4];
97+
98+ __le16 tag;
99+ __le16 len;
100+
101+ __le32 pp_timer_intv;
102+ __le32 rsv2[14];
103+ u8 band_idx;
104+ u8 pp_action;
105+ u8 reset;
106+ u8 _rsv3;
107+ } __packed req = {
108+ .tag = cpu_to_le16(UNI_CMD_PP_ALG_CTRL),
109+ .len = cpu_to_le16(sizeof(req) - 4),
110+
111+ .pp_timer_intv = action == PP_ALG_SET_TIMER ? 2000 : 0,
112+ .band_idx = phy->mt76->band_idx,
113+ .pp_action = action,
114+ .reset = 0,
115+ };
116+
117+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
118+ &req, sizeof(req), false);
119+}
120+
121 int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
122 {
123 struct mt7996_dev *dev = phy->dev;
124diff --git a/mt7996/mcu.h b/mt7996/mcu.h
125index 011b6c7a..01eb0ea1 100644
126--- a/mt7996/mcu.h
127+++ b/mt7996/mcu.h
128@@ -1162,6 +1162,7 @@ enum {
129
130 enum {
131 UNI_CMD_PP_EN_CTRL,
132+ UNI_CMD_PP_ALG_CTRL,
133 UNI_CMD_PP_DSCB_CTRL,
134 };
135
136@@ -1171,6 +1172,11 @@ enum pp_mode {
137 PP_USR_MODE,
138 };
139
140+enum pp_alg_action {
141+ PP_ALG_SET_TIMER,
142+ PP_ALG_GET_STATISTICS = 2,
143+};
144+
145 enum {
146 UNI_EVENT_PP_TAG_ALG_CTRL = 1,
147 UNI_EVENT_STATIC_PP_TAG_DSCB_IE,
148@@ -1204,6 +1210,38 @@ struct mt7996_mcu_pp_dscb_event {
149 u8 __rsv3[2];
150 } __packed;
151
152+struct mt7996_mcu_pp_alg_ctrl_event {
153+ struct mt7996_mcu_rxd rxd;
154+
155+ u8 __rsv1[4];
156+
157+ __le16 tag;
158+ __le16 len;
159+
160+ __le32 pp_timer_intv;
161+ __le32 thr_x2_value;
162+ __le32 thr_x2_shift;
163+ __le32 thr_x3_value;
164+ __le32 thr_x3_shift;
165+ __le32 thr_x4_value;
166+ __le32 thr_x4_shift;
167+ __le32 thr_x5_value;
168+ __le32 thr_x5_shift;
169+ __le32 thr_x6_value;
170+ __le32 thr_x6_shift;
171+ __le32 thr_x7_value;
172+ __le32 thr_x7_shift;
173+ __le32 thr_x8_value;
174+ __le32 thr_x8_shift;
175+ __le32 sw_pp_time;
176+ __le32 hw_pp_time;
177+ __le32 no_pp_time;
178+ __le32 auto_bw_time;
179+ u8 band_idx;
180+ u8 __rsv2;
181+ __le16 punct_bitmap;
182+} __packed;
183+
184 enum {
185 UNI_CMD_SCS_SEND_DATA,
186 UNI_CMD_SCS_SET_PD_THR_RANGE = 2,
187diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800188index 58151ed0..755b4cf0 100644
developer05f3b2b2024-08-19 19:17:34 +0800189--- a/mt7996/mt7996.h
190+++ b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800191@@ -1282,6 +1282,7 @@ int mt7996_mcu_cp_support(struct mt7996_dev *dev, u8 mode);
developer05f3b2b2024-08-19 19:17:34 +0800192 int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, u8 mode, u16 bitmap);
193 int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef,
194 u8 omac_idx);
195+int mt7996_mcu_set_pp_alg_ctrl(struct mt7996_phy *phy, u8 action);
196 int mt7996_mcu_set_eml_omn(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 link_id,
197 struct ieee80211_sta *sta, struct mt7996_eml_omn *eml_omn);
198 #ifdef CONFIG_MAC80211_DEBUGFS
developerd0c89452024-10-11 16:53:27 +0800199@@ -1311,6 +1312,7 @@ int mt7996_mcu_set_muru_cfg(struct mt7996_dev *dev, void *data);
developer05f3b2b2024-08-19 19:17:34 +0800200 void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
201 int mt7996_mcu_set_csi(struct mt7996_phy *phy, u8 mode,
202 u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
203+int mt7996_vendor_pp_bitmap_update(struct mt7996_phy *phy, u16 bitmap);
204 #endif
205
206 int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable);
207diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
developerd0c89452024-10-11 16:53:27 +0800208index 02a6ee81..2ded5f79 100644
developer05f3b2b2024-08-19 19:17:34 +0800209--- a/mt7996/mtk_debugfs.c
210+++ b/mt7996/mtk_debugfs.c
developerd0c89452024-10-11 16:53:27 +0800211@@ -4367,6 +4367,18 @@ static const struct file_operations fops_muru_dbg_info = {
developer05f3b2b2024-08-19 19:17:34 +0800212 .llseek = default_llseek,
213 };
214
215+static int mt7996_pp_alg_show(struct seq_file *s, void *data)
216+{
217+ struct mt7996_phy *phy = s->private;
218+ struct mt7996_dev *dev = phy->dev;
219+
220+ dev_info(dev->mt76.dev, "pp_mode = %d\n", phy->pp_mode);
221+ mt7996_mcu_set_pp_alg_ctrl(phy, PP_ALG_GET_STATISTICS);
222+
223+ return 0;
224+}
225+DEFINE_SHOW_ATTRIBUTE(mt7996_pp_alg);
226+
227 void mt7996_mtk_init_band_debugfs(struct mt7996_phy *phy, struct dentry *dir)
228 {
229 /* agg */
developerd0c89452024-10-11 16:53:27 +0800230@@ -4389,6 +4401,8 @@ void mt7996_mtk_init_band_debugfs(struct mt7996_phy *phy, struct dentry *dir)
developer05f3b2b2024-08-19 19:17:34 +0800231
232 debugfs_create_file("thermal_enable", 0600, dir, phy, &fops_thermal_enable);
233 debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
234+
235+ debugfs_create_file("pp_alg", 0200, dir, phy, &mt7996_pp_alg_fops);
236 }
237
238 void mt7996_mtk_init_dev_debugfs(struct mt7996_dev *dev, struct dentry *dir)
239diff --git a/mt7996/vendor.c b/mt7996/vendor.c
240index 33c682c0..d7973c5e 100644
241--- a/mt7996/vendor.c
242+++ b/mt7996/vendor.c
243@@ -96,7 +96,9 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
244 static struct nla_policy
245 pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
246 [MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
247- [MTK_VENDOR_ATTR_PP_BAND_IDX] = { .type = NLA_U8 },
248+ [MTK_VENDOR_ATTR_PP_LINK_ID] = { .type = NLA_U8 },
249+ [MTK_VENDOR_ATTR_PP_BITMAP] = { .type = NLA_U16 },
250+ [MTK_VENDOR_ATTR_PP_CURR_FREQ] = { .type = NLA_U32 },
251 };
252
253 static const struct nla_policy
254@@ -805,31 +807,44 @@ static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
255 const void *data, int data_len)
256 {
257 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
258+ struct ieee80211_vif *vif = wdev_to_ieee80211_vif(wdev);
259 struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_PP_CTRL];
260 struct mt7996_dev *dev = mt7996_hw_dev(hw);
261 struct mt7996_phy *phy;
262- struct mt76_phy *mphy;
263 struct cfg80211_chan_def *chandef;
264+ struct mt7996_bss_conf *mconf;
265+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
266 int err;
267- u8 val8, band_idx = 0;
268+ u8 mode = 0, link_id = 0;
269+ u16 punct_bitmap = 0;
270
271 err = nla_parse(tb, MTK_VENDOR_ATTR_PP_CTRL_MAX, data, data_len,
272 pp_ctrl_policy, NULL);
273
274- if (tb[MTK_VENDOR_ATTR_PP_BAND_IDX]) {
275- band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_BAND_IDX]);
276- }
277+ if (tb[MTK_VENDOR_ATTR_PP_MODE])
278+ mode = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_MODE]);
279+ else
280+ return -EINVAL;
281
282- if (!mt7996_band_valid(dev, band_idx))
283- goto error;
284+ if (ieee80211_vif_is_mld(vif) && tb[MTK_VENDOR_ATTR_PP_LINK_ID]) {
285+ link_id = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_LINK_ID]);
286+ if (link_id >= IEEE80211_LINK_UNSPECIFIED)
287+ return -EINVAL;
288+ }
289
290- mphy = dev->mt76.phys[band_idx];
291- if (!mphy)
292+ rcu_read_lock();
293+ mconf = rcu_dereference(mvif->link[link_id]);
294+ if (!mconf) {
295+ rcu_read_unlock();
296 goto error;
297+ }
298
299- phy = (struct mt7996_phy *)mphy->priv;
300- if (!phy)
301+ phy = mconf->phy;
302+ if (!phy) {
303+ rcu_read_unlock();
304 goto error;
305+ }
306+ rcu_read_unlock();
307
308 chandef = &phy->chanctx->chandef;
309 if (!chandef)
310@@ -838,28 +853,53 @@ static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
311 if (chandef->chan->band == NL80211_BAND_2GHZ)
312 return 0;
313
314- if (tb[MTK_VENDOR_ATTR_PP_MODE]) {
315- val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_MODE]);
316- switch (val8) {
317- case PP_DISABLE:
318- case PP_FW_MODE:
319- err = mt7996_mcu_set_pp_en(phy, val8, 0);
320- break;
321- case PP_USR_MODE:
322- /* handled by add_chanctx */
323- err = 0;
324- break;
325- default:
326- err = -EINVAL;
327- }
328+ switch (mode) {
329+ case PP_USR_MODE:
330+ if (tb[MTK_VENDOR_ATTR_PP_BITMAP])
331+ punct_bitmap = nla_get_u16(tb[MTK_VENDOR_ATTR_PP_BITMAP]);
332+ fallthrough;
333+ case PP_FW_MODE:
334+ case PP_DISABLE:
335+ err = mt7996_mcu_set_pp_en(phy, mode, punct_bitmap);
336+ break;
337+ default:
338+ return -EINVAL;
339 }
340
341 return err;
342 error:
343- dev_err(dev->mt76.dev, "Invalid band idx: %d\n", band_idx);
344+ dev_err(dev->mt76.dev, "Invalid link id: %d\n", link_id);
345 return -EINVAL;
346 }
347
348+int mt7996_vendor_pp_bitmap_update(struct mt7996_phy *phy, u16 bitmap)
349+{
350+ struct sk_buff *skb;
351+ struct mt76_phy *mphy = phy->mt76;
352+ struct cfg80211_chan_def *chandef = &phy->chanctx->chandef;
353+
354+ if (!chandef)
355+ return 0;
356+
357+ skb = cfg80211_vendor_event_alloc(mphy->hw->wiphy, NULL, 20,
358+ MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE,
359+ GFP_ATOMIC);
360+
361+ if (!skb)
362+ return -ENOMEM;
363+
364+ if (nla_put_u16(skb, MTK_VENDOR_ATTR_PP_BITMAP, bitmap) ||
365+ nla_put_u32(skb, MTK_VENDOR_ATTR_PP_CURR_FREQ,
366+ chandef->chan->center_freq)) {
367+ dev_kfree_skb(skb);
368+ return -ENOMEM;
369+ }
370+
371+ cfg80211_vendor_event(skb, GFP_ATOMIC);
372+
373+ return 0;
374+}
375+
376 static int mt7996_vendor_rfeature_ctrl(struct wiphy *wiphy,
377 struct wireless_dev *wdev,
378 const void *data,
379@@ -1490,10 +1530,19 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
380 },
381 };
382
383+static const struct nl80211_vendor_cmd_info mt7996_vendor_events[] = {
384+ [MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE] = {
385+ .vendor_id = MTK_NL80211_VENDOR_ID,
386+ .subcmd = MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE,
387+ },
388+};
389+
390 void mt7996_vendor_register(struct mt7996_phy *phy)
391 {
392 phy->mt76->hw->wiphy->vendor_commands = mt7996_vendor_commands;
393 phy->mt76->hw->wiphy->n_vendor_commands = ARRAY_SIZE(mt7996_vendor_commands);
394+ phy->mt76->hw->wiphy->vendor_events = mt7996_vendor_events;
395+ phy->mt76->hw->wiphy->n_vendor_events = ARRAY_SIZE(mt7996_vendor_events);
396
397 INIT_LIST_HEAD(&phy->csi.list);
398 spin_lock_init(&phy->csi.lock);
399diff --git a/mt7996/vendor.h b/mt7996/vendor.h
400index 714f0b3e..ca4f00ad 100644
401--- a/mt7996/vendor.h
402+++ b/mt7996/vendor.h
403@@ -21,6 +21,10 @@ enum mtk_nl80211_vendor_subcmds {
404 MTK_NL80211_VENDOR_SUBCMD_EML_CTRL = 0xd3,
405 };
406
407+enum mtk_nl80211_vendor_events {
408+ MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE = 0x5,
409+};
410+
411 enum mtk_vendor_attr_edcca_ctrl {
412 MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0,
413
414@@ -222,7 +226,9 @@ enum mtk_vendor_attr_pp_ctrl {
415 MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
416
417 MTK_VENDOR_ATTR_PP_MODE,
418- MTK_VENDOR_ATTR_PP_BAND_IDX,
419+ MTK_VENDOR_ATTR_PP_LINK_ID,
420+ MTK_VENDOR_ATTR_PP_BITMAP,
421+ MTK_VENDOR_ATTR_PP_CURR_FREQ,
422
423 /* keep last */
424 NUM_MTK_VENDOR_ATTRS_PP_CTRL,
425--
developerd0c89452024-10-11 16:53:27 +08004262.45.2
developer05f3b2b2024-08-19 19:17:34 +0800427