blob: 4c9198fc7fc701dc16c9dda4e254ccab34ea89e2 [file] [log] [blame]
developer99b59a92023-10-13 21:55:14 +08001From 125ddf12e213498dbddda005b1b84587bc1f1a46 Mon Sep 17 00:00:00 2001
developerc978ea12022-11-09 15:58:31 +08002From: Lian Chen <lian.chen@mediatek.com>
3Date: Mon, 7 Nov 2022 14:47:44 +0800
developer60412772023-09-22 10:06:10 +08004Subject: [PATCH] wifi: mt76: mt7915: wed: HW ATF support for mt7986
developerc978ea12022-11-09 15:58:31 +08005
6Signed-off-by: Lian Chen <lian.chen@mediatek.com>
developer60412772023-09-22 10:06:10 +08007Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
developerc978ea12022-11-09 15:58:31 +08008---
9 mt76_connac_mcu.h | 2 +
10 mt7915/debugfs.c | 405 +++++++++++++++++++++++++++++++++++++++++++
developer60412772023-09-22 10:06:10 +080011 mt7915/init.c | 58 +++++++
developer3524ece2023-10-12 10:46:59 +080012 mt7915/main.c | 14 ++
developer60412772023-09-22 10:06:10 +080013 mt7915/mcu.c | 169 +++++++++++++++++-
14 mt7915/mt7915.h | 69 ++++++++
developerab4a0b82023-08-18 19:56:34 +080015 mt7915/mtk_debugfs.c | 131 +++++++++++++-
developer3524ece2023-10-12 10:46:59 +080016 7 files changed, 844 insertions(+), 4 deletions(-)
developerc978ea12022-11-09 15:58:31 +080017
18diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer3524ece2023-10-12 10:46:59 +080019index 49258905..9ad18833 100644
developerc978ea12022-11-09 15:58:31 +080020--- a/mt76_connac_mcu.h
21+++ b/mt76_connac_mcu.h
developer0443cd32023-09-19 14:11:49 +080022@@ -1175,6 +1175,7 @@ enum {
developerc978ea12022-11-09 15:58:31 +080023 MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
24 MCU_EXT_CMD_WTBL_UPDATE = 0x32,
25 MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
26+ MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
27 MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
28 MCU_EXT_CMD_ATE_CTRL = 0x3d,
29 MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
developer0443cd32023-09-19 14:11:49 +080030@@ -1184,6 +1185,7 @@ enum {
developerc978ea12022-11-09 15:58:31 +080031 MCU_EXT_CMD_MUAR_UPDATE = 0x48,
32 MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
33 MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
34+ MCU_EXT_CMD_AT_PROC_MODULE = 0x4b,
35 MCU_EXT_CMD_SET_RX_PATH = 0x4e,
36 MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
37 MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
38diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
developer3524ece2023-10-12 10:46:59 +080039index 6dcee10c..ca42b698 100644
developerc978ea12022-11-09 15:58:31 +080040--- a/mt7915/debugfs.c
41+++ b/mt7915/debugfs.c
42@@ -12,6 +12,10 @@
43 #define FW_BIN_LOG_MAGIC_V2 0x44d9c99a
44 #endif
45
46+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
47+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
48+
49+
50 /** global debugfs **/
51
52 struct hw_queue_map {
developer2157bf82023-06-26 02:27:49 +080053@@ -223,6 +227,406 @@ static const struct file_operations mt7915_sys_recovery_ops = {
developerc978ea12022-11-09 15:58:31 +080054 .llseek = default_llseek,
55 };
56
57+static ssize_t mt7915_vow_get(struct file *file, char __user *user_buf,
58+ size_t count, loff_t *ppos)
59+{
60+ char *buff;
61+ int desc = 0;
62+ ssize_t ret;
63+ static const size_t bufsz = 1000;
64+
65+ buff = kmalloc(bufsz, GFP_KERNEL);
66+ if (!buff)
67+ return -ENOMEM;
68+
69+ desc += scnprintf(buff + desc, bufsz - desc,
70+ "======== Control =============\n"
71+ "vow_atf_en=<0/1> 0:disable, 1:enable\n"
72+ "vow_watf_en=<0/1> 0:disable, 1:enable\n"
73+ "vow_watf_quantum=<level>-<quantum> unit 256us\n"
74+ "======== Station table =============\n"
75+ "vow_sta_dwrr_quantum_id=<wlanidx>-<WMM AC>-<Qid>\n"
76+ "vow_dwrr_max_wait_time=<time> 256us\n"
77+ "======== Debug =============\n"
78+ "vow_show_en=<0/1> 0:dieable, 1:enable\n"
79+ "vow_show_sta=<STA num>\n"
80+ "show_vow_info\n"
81+ "show_vow_sta_conf=<STA num> 0:all\n");
82+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
83+ kfree(buff);
84+ return ret;
85+}
86+
87+static int mt7915_set_vow_sta_dwrr_quantum_id(struct mt7915_dev *dev,
88+ u32 wcid_id,
89+ u32 ac, u32 val)
90+{
91+ struct mt7915_sta *msta;
92+ struct mt76_wcid *wcid;
93+ int ret;
94+
95+ wcid = rcu_dereference(dev->mt76.wcid[wcid_id]);
96+ if ((!wcid) || (!wcid->sta)) {
97+ dev_err(dev->mt76.dev, "%s: error station.\n", __func__);
98+ return 0;
99+ }
100+
101+ msta = container_of(wcid, struct mt7915_sta, wcid);
102+
103+ msta->vow_sta_cfg.dwrr_quantum[ac] = val;
104+
105+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_AC0_QUA_ID + ac);
106+ dev_info(dev->mt76.dev, "%s: set sta %d, ac %d, quantum id %u.\n",
107+ __func__, wcid_id, ac, val);
108+
109+ return ret;
110+}
111+
112+static int mt7915_set_vow_atf_en(struct mt7915_dev *dev, u32 val)
113+{
114+ int ret;
115+
116+ dev->vow_cfg.vow_atf_en = !!val;
117+ dev->vow_cfg.sta_max_wait_time = val ? 0x40 : 0x1;
118+ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
119+ dev_info(dev->mt76.dev, "%s: set vow_atf_en %u.\n",
120+ __func__, val);
121+
122+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
123+ VOW_DRR_AIRTIME_DEFICIT_BOUND);
124+ dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n",
125+ __func__, dev->vow_cfg.sta_max_wait_time);
126+
127+ return ret;
128+}
129+
130+static int mt7915_set_vow_dwrr_max_wait_time(struct mt7915_dev *dev,
131+ u32 val)
132+{
133+ int ret;
134+
135+ dev->vow_cfg.sta_max_wait_time = val;
136+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
137+ VOW_DRR_AIRTIME_DEFICIT_BOUND);
138+ dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n",
139+ __func__, val);
140+
141+ return ret;
142+}
143+
144+static int mt7915_set_vow_watf_en(struct mt7915_dev *dev, u32 val)
145+{
146+ int ret;
147+
148+ dev->vow_cfg.vow_watf_en = !!val;
149+ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
150+ dev_info(dev->mt76.dev, "%s: set vow_watf_en %u.\n", __func__, val);
151+
152+ return ret;
153+}
154+
155+static int mt7915_set_vow_watf_quantum(struct mt7915_dev *dev,
156+ u32 id, u32 val)
157+{
158+ int ret;
159+
160+ dev->vow_cfg.vow_sta_dwrr_quantum[id] = val;
161+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
162+ VOW_DRR_AIRTIME_QUANTUM_L0 + id);
163+ dev_info(dev->mt76.dev, "%s: set quantum id %u, val %d.\n",
164+ __func__, id, val);
165+
166+ return ret;
167+}
168+
169+extern int mt7915_vow_pleinfo_read(struct mt7915_dev *dev);
170+static void mt7915_show_station_tx_airtime(struct work_struct *work){
171+ struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
172+ vow_work.work);
173+ static u32 vow_last_tx_time[MT7916_WTBL_SIZE];
174+ struct ieee80211_sta *ieee80211_sta;
175+ struct mt7915_sta *msta;
176+ struct mt76_wcid *wcid;
177+ int idx = 0;
178+ int i = 0;
179+ u32 addr;
180+ int tx_airtime_sum = 0;
181+ int tx_add_airtime = 0;
182+
183+ if (!dev->vow_cfg.vow_show_en)
184+ return;
185+
186+ rcu_read_lock();
187+ for (idx = 1; (idx < dev->vow_cfg.vow_show_sta) &&
188+ (idx < MT7915_WTBL_STA); idx++) {
189+ if (idx >= ARRAY_SIZE(dev->mt76.wcid))
190+ return;
191+
192+ wcid = rcu_dereference(dev->mt76.wcid[idx]);
193+ if (!wcid || !wcid->sta)
194+ continue;
195+
196+ msta = container_of(wcid, struct mt7915_sta, wcid);
197+ addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20);
198+ tx_airtime_sum = 0;
199+
200+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
201+ tx_airtime_sum += mt76_rr(dev, addr);
202+ addr += 8;
203+ }
204+ tx_add_airtime = tx_airtime_sum - vow_last_tx_time[idx];
205+ vow_last_tx_time[idx] = tx_airtime_sum;
206+
207+ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
208+ drv_priv);
209+
210+ dev_info(dev->mt76.dev, "sta%u:" MACSTR " tx -> %u)\n",
211+ idx, MAC2STR(ieee80211_sta->addr), tx_add_airtime);
212+ }
213+ mt7915_vow_pleinfo_read(dev);
214+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ);
215+ rcu_read_unlock();
216+ return;
217+}
218+
219+
220+static int mt7915_set_vow_show_en(struct mt7915_dev *dev, u32 val)
221+{
222+ if (!!dev->vow_cfg.vow_show_en == !!val)
223+ return 0;
224+ dev->vow_cfg.vow_show_en = val;
225+ mt7915_mcu_set_vow_feature_ctrl(dev);
226+ if (dev->vow_cfg.vow_show_en) {
227+ INIT_DELAYED_WORK(&dev->vow_work, mt7915_show_station_tx_airtime);
228+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ);
229+ }
230+ else {
231+ cancel_delayed_work_sync(&dev->vow_work);
232+ }
233+ return 0;
234+}
235+
236+static int mt7915_set_vow_show_sta(struct mt7915_dev *dev, u32 val)
237+{
238+ dev->vow_cfg.vow_show_sta = val;
239+ dev_info(dev->mt76.dev, "%s: show station up to %d.\n",
240+ __func__, dev->vow_cfg.vow_show_sta);
241+ return 0;
242+}
243+static int mt7915_set_show_vow_info(struct mt7915_dev *dev)
244+{
245+ dev_info(dev->mt76.dev, "====== VOW Control Information ======\n");
246+ dev_info(dev->mt76.dev, "ATF Enbale: %d\n",
247+ dev->vow_cfg.vow_atf_en);
248+ dev_info(dev->mt76.dev, "WATF Enable: %d\n",
249+ dev->vow_cfg.vow_watf_en);
250+ dev_info(dev->mt76.dev, "refill_period: %d\n",
251+ dev->vow_cfg.refill_period);
252+ dev_info(dev->mt76.dev, "===== VOW Max Deficit Information =====\n");
253+ dev_info(dev->mt76.dev, "VOW Max Deficit(unit 256us): %d\n",
254+ dev->vow_cfg.sta_max_wait_time);
255+ dev_info(dev->mt76.dev, "===== VOW Quantum Information =====\n");
256+ dev_info(dev->mt76.dev, "Quantum ID 0 value(unit 256us): %d\n",
257+ dev->vow_cfg.vow_sta_dwrr_quantum[0]);
258+ dev_info(dev->mt76.dev, "Quantum ID 1 value(unit 256us): %d\n",
259+ dev->vow_cfg.vow_sta_dwrr_quantum[1]);
260+ dev_info(dev->mt76.dev, "Quantum ID 2 value(unit 256us): %d\n",
261+ dev->vow_cfg.vow_sta_dwrr_quantum[2]);
262+ dev_info(dev->mt76.dev, "Quantum ID 3 value(unit 256us): %d\n",
263+ dev->vow_cfg.vow_sta_dwrr_quantum[3]);
264+ return 0;
265+}
266+
267+static int mt7915_show_vow_sta_conf(struct mt7915_dev *dev, u32 val)
268+{
269+ struct ieee80211_sta *ieee80211_sta;
270+ struct mt7915_sta *msta;
271+ struct mt76_wcid *wcid;
272+ u32 i;
273+ u8 q;
274+
275+ if (val > 0 && val < MT7915_WTBL_STA) {
276+ wcid = rcu_dereference(dev->mt76.wcid[val]);
277+ if (!wcid || !wcid->sta)
278+ return 0;
279+ msta = container_of(wcid, struct mt7915_sta, wcid);
280+ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
281+ drv_priv);
282+ dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n",
283+ __func__, val, MAC2STR(ieee80211_sta->addr));
284+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO];
285+ dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n",
286+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
287+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI];
288+ dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n",
289+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
290+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE];
291+ dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n",
292+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
293+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK];
294+ dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n",
295+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
296+ }
297+ else{
298+ for (i = 1; i < MT7915_WTBL_STA; i++) {
299+ wcid = rcu_dereference(dev->mt76.wcid[i]);
300+ if (!wcid || !wcid->sta)
301+ continue;
302+ msta = container_of(wcid, struct mt7915_sta, wcid);
303+ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
304+ drv_priv);
305+ dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n",
306+ __func__, i, MAC2STR(ieee80211_sta->addr));
307+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO];
308+ dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n",
309+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
310+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI];
311+ dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n",
312+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
313+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE];
314+ dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n",
315+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
316+ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK];
317+ dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n",
318+ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
319+ }
320+ }
321+ return 0;
322+}
323+
324+static ssize_t
325+mt7915_vow_set(struct file *file, const char __user *user_buf,
326+ size_t count, loff_t *ppos)
327+{
328+ struct mt7915_phy *phy = file->private_data;
329+ struct mt7915_dev *dev = phy->dev;
330+ u32 rv, param1, param2, param3;
331+ char buf[128];
332+ int ret = 0;
333+
334+ if (count >= sizeof(buf))
335+ return -EINVAL;
336+
337+ if (copy_from_user(buf, user_buf, count))
338+ return -EFAULT;
339+
340+ if (count && buf[count - 1] == '\n')
341+ buf[count - 1] = '\0';
342+ else
343+ buf[count] = '\0';
344+
345+ if (!strncmp(buf, "vow_sta_dwrr_quantum_id",
346+ strlen("vow_sta_dwrr_quantum_id")))
347+ {
348+ rv = sscanf(buf, "vow_sta_dwrr_quantum_id=%d-%d-%d",
349+ &param1, &param2, &param3);
350+ if ((rv > 2) && (param2 < IEEE80211_NUM_ACS) &&
351+ (param3 < VOW_WATF_LEVEL_NUM)) {
352+ ret = mt7915_set_vow_sta_dwrr_quantum_id(dev, param1,
353+ param2, param3);
354+ }
355+ else {
356+ goto out;
357+ }
358+ }
359+ else if (!strncmp(buf, "vow_atf_en", strlen("vow_atf_en")))
360+ {
361+ rv = sscanf(buf, "vow_atf_en=%d", &param1);
362+ if (rv > 0) {
363+ ret = mt7915_set_vow_atf_en(dev, param1);
364+ }
365+ else {
366+ goto out;
367+ }
368+ }
369+ else if (!strncmp(buf, "vow_dwrr_max_wait_time",
370+ strlen("vow_dwrr_max_wait_time")))
371+ {
372+ rv = sscanf(buf, "vow_dwrr_max_wait_time=%d", &param1);
373+ if (rv > 0) {
374+ ret = mt7915_set_vow_dwrr_max_wait_time(dev, param1);
375+ }
376+ else {
377+ goto out;
378+ }
379+ }
380+ else if (!strncmp(buf, "vow_watf_en", strlen("vow_watf_en")))
381+ {
382+ rv = sscanf(buf, "vow_watf_en=%d", &param1);
383+ if (rv > 0) {
384+ ret = mt7915_set_vow_watf_en(dev, param1);
385+ }
386+ else {
387+ goto out;
388+ }
389+ }
390+ else if (!strncmp(buf, "vow_watf_quantum",
391+ strlen("vow_watf_quantum")))
392+ {
393+ rv = sscanf(buf, "vow_watf_quantum=%d-%d",
394+ &param1, &param2);
395+ if ((dev->vow_cfg.vow_watf_en) && (rv > 1) &&
396+ (param1 < VOW_WATF_LEVEL_NUM)) {
397+ ret = mt7915_set_vow_watf_quantum(dev, param1, param2);
398+ }
399+ else {
400+ goto out;
401+ }
402+ }
403+ else if (!strncmp(buf, "vow_show_en", strlen("vow_show_en")))
404+ {
405+ rv = sscanf(buf, "vow_show_en=%d", &param1);
406+ if (rv > 0) {
407+ ret = mt7915_set_vow_show_en(dev, param1);
408+ }
409+ else {
410+ goto out;
411+ }
412+ }
413+ else if (!strncmp(buf, "vow_show_sta", strlen("vow_show_sta")))
414+ {
415+ rv = sscanf(buf, "vow_show_sta=%d", &param1);
416+ if ((rv > 0)&& (param1 < MT7915_WTBL_STA)) {
417+ ret = mt7915_set_vow_show_sta(dev, param1);
418+ }
419+ else {
420+ goto out;
421+ }
422+ }
423+ else if (!strncmp(buf, "show_vow_info", strlen("show_vow_info")))
424+ {
425+ if (rv == 0) {
426+ ret = mt7915_set_show_vow_info(dev);
427+ }
428+ else {
429+ dev_err(dev->mt76.dev, "show_vow_info\n");
430+ goto out;
431+ }
432+ }
433+ else if (!strncmp(buf, "show_vow_sta_conf", strlen("show_vow_sta_conf")))
434+ {
435+ rv = sscanf(buf, "show_vow_sta_conf=%d", &param1);
436+ if ((rv > 0) && (param1 < MT7915_WTBL_STA)) {
437+ ret = mt7915_show_vow_sta_conf(dev, param1);
438+ }
439+ else {
440+ goto out;
441+ }
442+ }
443+
444+ if (ret)
445+ return ret;
446+out:
447+ return count;
448+}
449+
450+static const struct file_operations mt7915_vow_ops = {
451+ .write = mt7915_vow_set,
452+ .read = mt7915_vow_get,
453+ .open = simple_open,
454+ .llseek = default_llseek,
455+};
456+
457 static int
458 mt7915_radar_trigger(void *data, u64 val)
459 {
developerab4a0b82023-08-18 19:56:34 +0800460@@ -1476,6 +1880,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
developerc978ea12022-11-09 15:58:31 +0800461 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
462 mt7915_twt_stats);
463 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
464+ debugfs_create_file("vow", 0600, dir, phy, &mt7915_vow_ops);
465
developereb6a0182022-12-12 18:53:32 +0800466 if (!dev->dbdc_support || phy->mt76->band_idx) {
developerc978ea12022-11-09 15:58:31 +0800467 debugfs_create_u32("dfs_hw_pattern", 0400, dir,
468diff --git a/mt7915/init.c b/mt7915/init.c
developer3524ece2023-10-12 10:46:59 +0800469index 36621ad3..db627500 100644
developerc978ea12022-11-09 15:58:31 +0800470--- a/mt7915/init.c
471+++ b/mt7915/init.c
developer60412772023-09-22 10:06:10 +0800472@@ -600,10 +600,65 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
developereb6a0182022-12-12 18:53:32 +0800473 }
developerc978ea12022-11-09 15:58:31 +0800474 }
475
476+void mt7915_vow_init(struct mt7915_dev *dev)
477+{
478+ struct mt7915_vow_cfg *vow_cfg = &dev->vow_cfg;
479+ bool ret;
480+ int i;
481+
482+ if (!(is_mt7915(&dev->mt76)))
483+ vow_cfg->vow_feature |= VOW_FEATURE_BWCG;
484+
485+ vow_cfg->vow_atf_en = 0x1;
486+ vow_cfg->sta_max_wait_time = 0x40;
487+ vow_cfg->refill_period = 0x5;
488+
489+ vow_cfg->vow_sta_dwrr_quantum[0] = 0x06;
490+ vow_cfg->vow_sta_dwrr_quantum[1] = 0x0c;
491+ vow_cfg->vow_sta_dwrr_quantum[2] = 0x10;
492+ vow_cfg->vow_sta_dwrr_quantum[3] = 0x14;
493+ vow_cfg->vow_sta_dwrr_quantum[4] = 0x18;
494+ vow_cfg->vow_sta_dwrr_quantum[5] = 0x1c;
495+ vow_cfg->vow_sta_dwrr_quantum[6] = 0x20;
496+ vow_cfg->vow_sta_dwrr_quantum[7] = 0x24;
497+
498+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
499+ VOW_DRR_AIRTIME_DEFICIT_BOUND);
500+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
501+ VOW_DRR_AIRTIME_QUANTUM_ALL);
502+
503+ for(i = 0; i < 4; i++)
504+ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
505+ VOW_DRR_AIRTIME_QUANTUM_L0 + i);
506+
507+ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
508+ return;
509+}
510+
developer60412772023-09-22 10:06:10 +0800511+/* Assignment of BSS group index aligns FW.
512+ * 0: Band 0 - BSS 0
513+ * 4: Band 1 - BSS 0
514+ * 9..23: Band 0 - BSS 0x11..0x1f
515+ * 25..39: Band 1 - BSS 0x11..0x1f
516+ */
517+void mt7915_vow_init_sta_bss_grp(struct mt7915_sta *sta)
518+{
519+ const u8 hw_bssid_num = HW_BSSID_MAX + 1;
520+ struct mt76_vif *vif = &sta->vif->mt76;
521+
522+ if (vif->omac_idx < hw_bssid_num)
523+ sta->vow_sta_cfg.bss_grp_idx = vif->band_idx * hw_bssid_num + vif->omac_idx;
524+ else { /* Extended BSS */
525+ u8 ext_bss_ofs = hw_bssid_num * 2 + (vif->band_idx == 0 ? 1 : 17);
526+ sta->vow_sta_cfg.bss_grp_idx = ext_bss_ofs + vif->omac_idx - EXT_BSSID_1;
527+ }
528+}
529+
developerc978ea12022-11-09 15:58:31 +0800530 void mt7915_mac_init(struct mt7915_dev *dev)
531 {
532 int i;
533 u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680;
534+ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
535
536 /* config pse qid6 wfdma port selection */
537 if (!is_mt7915(&dev->mt76) && dev->hif2)
developer60412772023-09-22 10:06:10 +0800538@@ -627,6 +682,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
developereb6a0182022-12-12 18:53:32 +0800539 mt7915_mac_init_band(dev, i);
540
541 mt7915_init_led_mux(dev);
developerc978ea12022-11-09 15:58:31 +0800542+
developereb6a0182022-12-12 18:53:32 +0800543+ if (mt7915_is_atf_default_on(wiphy, dev))
developerc978ea12022-11-09 15:58:31 +0800544+ mt7915_vow_init(dev);
545 }
546
547 int mt7915_txbf_init(struct mt7915_dev *dev)
548diff --git a/mt7915/main.c b/mt7915/main.c
developer3524ece2023-10-12 10:46:59 +0800549index 2dd4881f..8bcffd3f 100644
developerc978ea12022-11-09 15:58:31 +0800550--- a/mt7915/main.c
551+++ b/mt7915/main.c
developer2324aa22023-04-12 11:30:15 +0800552@@ -217,6 +217,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
developerc978ea12022-11-09 15:58:31 +0800553 {
554 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
developer1346ce52022-12-15 21:36:14 +0800555 struct mt7915_dev *dev = phy->dev;
developerc978ea12022-11-09 15:58:31 +0800556+ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
developerc978ea12022-11-09 15:58:31 +0800557 struct mt76_txq *mtxq;
558 bool ext_phy = phy != &dev->phy;
developer1346ce52022-12-15 21:36:14 +0800559 int idx, ret = 0;
developer3524ece2023-10-12 10:46:59 +0800560@@ -279,6 +280,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
developerc978ea12022-11-09 15:58:31 +0800561 mt7915_mcu_add_sta(dev, vif, NULL, true);
562 rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
563
developer1346ce52022-12-15 21:36:14 +0800564+ if (mt7915_is_atf_default_on(wiphy, dev))
developerc978ea12022-11-09 15:58:31 +0800565+ mt7915_mcu_set_vow_band(dev, mvif);
developerc978ea12022-11-09 15:58:31 +0800566+
developer1346ce52022-12-15 21:36:14 +0800567 return ret;
568 }
developerc978ea12022-11-09 15:58:31 +0800569
developer3524ece2023-10-12 10:46:59 +0800570@@ -769,6 +773,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
developerc978ea12022-11-09 15:58:31 +0800571 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
572 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
573 bool ext_phy = mvif->phy != &dev->phy;
574+ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
575 #ifdef CONFIG_MTK_VENDOR
developerfd8e1152023-02-14 11:29:23 +0800576 struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
developerc978ea12022-11-09 15:58:31 +0800577 #endif
developer3524ece2023-10-12 10:46:59 +0800578@@ -819,6 +824,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
developerfd8e1152023-02-14 11:29:23 +0800579 if (phy->muru_onoff & MUMIMO_DL_CERT)
developerc978ea12022-11-09 15:58:31 +0800580 mt7915_mcu_set_mimo(phy, 0);
developerc978ea12022-11-09 15:58:31 +0800581 #endif
developereb6a0182022-12-12 18:53:32 +0800582+ if (mt7915_is_atf_default_on(wiphy, dev)) {
developerc978ea12022-11-09 15:58:31 +0800583+ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] = 2;
584+ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] = 2;
585+ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] = 1;
586+ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] = 0;
developerc978ea12022-11-09 15:58:31 +0800587+ mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_PAUSE_SETTING);
588+ mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_ALL);
589+ }
590+
591 return 0;
592 }
593
594diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer3524ece2023-10-12 10:46:59 +0800595index d8b93180..e5bfca3d 100644
developerc978ea12022-11-09 15:58:31 +0800596--- a/mt7915/mcu.c
597+++ b/mt7915/mcu.c
developer60412772023-09-22 10:06:10 +0800598@@ -1674,7 +1674,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
599 {
600 #define MT_STA_BSS_GROUP 1
601 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
602- struct mt7915_sta *msta;
603+ struct mt7915_sta *msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
604 struct {
605 __le32 action;
606 u8 wlan_idx_lo;
607@@ -1685,10 +1685,9 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
608 u8 rsv1[8];
609 } __packed req = {
610 .action = cpu_to_le32(MT_STA_BSS_GROUP),
611- .val = cpu_to_le32(mvif->mt76.idx % 16),
612+ .val = cpu_to_le32(msta->vow_sta_cfg.bss_grp_idx)
613 };
614
615- msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
616 req.wlan_idx_lo = to_wcid_lo(msta->wcid.idx);
617 req.wlan_idx_hi = to_wcid_hi(msta->wcid.idx);
618
619@@ -1746,6 +1745,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
620 mt7915_mcu_sta_bfee_tlv(dev, skb, vif, sta);
621 }
622
623+ mt7915_vow_init_sta_bss_grp(msta);
624 ret = mt7915_mcu_add_group(dev, vif, sta);
625 if (ret) {
626 dev_kfree_skb(skb);
627@@ -3568,6 +3568,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
developerc978ea12022-11-09 15:58:31 +0800628 &req, sizeof(req), false);
629 }
630
631+int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev,
632+ struct mt7915_sta *msta,
633+ u32 subcmd)
634+{
635+ u32 setting = 0;
636+ u32 i;
637+
638+ struct {
639+ __le32 action;
640+ u8 wlan_idx_lo;
641+ u8 status;
642+ u8 wlan_idx_hi;
643+ u8 rsv0[5];
644+ union {
645+ __le32 com_value;
646+ struct {
647+ u8 air_time_quantum[VOW_MAX_STA_DWRR_NUM];
648+ }air_time_quantum_all;
649+ }air_time_ctrl;
650+ } __packed req = {
651+ .action = cpu_to_le32(subcmd),
652+ .wlan_idx_lo = msta ? to_wcid_lo(msta->wcid.idx) : to_wcid_lo(0x0),
653+ .wlan_idx_hi = msta ? to_wcid_hi(msta->wcid.idx) : to_wcid_hi(0x0),
654+ };
655+
656+ switch (subcmd) {
657+ case VOW_DRR_STA_ALL:{
developer60412772023-09-22 10:06:10 +0800658+ setting |= msta->vow_sta_cfg.bss_grp_idx;
developerc978ea12022-11-09 15:58:31 +0800659+ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] << 8);
660+ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] << 12);
661+ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] << 16);
662+ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] << 20);
663+ if (dev->vow_cfg.vow_feature & VOW_FEATURE_BWCG)
664+ setting |= ((UMAC_BWC_GROUP_MIN) << 24);
665+ req.air_time_ctrl.com_value = cpu_to_le32(setting);
666+ break;
667+ }
668+
669+ case VOW_DRR_STA_BSS_GROUP:
developer60412772023-09-22 10:06:10 +0800670+ req.air_time_ctrl.com_value = cpu_to_le32(msta->vow_sta_cfg.bss_grp_idx);
developerc978ea12022-11-09 15:58:31 +0800671+ break;
672+
673+ case VOW_DRR_STA_PAUSE_SETTING:
674+ req.air_time_ctrl.com_value = cpu_to_le32(msta->vow_sta_cfg.paused);
675+ break;
676+
677+ case VOW_DRR_STA_AC0_QUA_ID:
678+ req.air_time_ctrl.com_value =
679+ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO]);
680+ break;
681+
682+ case VOW_DRR_STA_AC1_QUA_ID:
683+ req.air_time_ctrl.com_value =
684+ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI]);
685+ break;
686+
687+ case VOW_DRR_STA_AC2_QUA_ID:
688+ req.air_time_ctrl.com_value =
689+ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE]);
690+ break;
691+
692+ case VOW_DRR_STA_AC3_QUA_ID:
693+ req.air_time_ctrl.com_value =
694+ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK]);
695+ break;
696+
697+ case VOW_DRR_AIRTIME_DEFICIT_BOUND:
698+ req.air_time_ctrl.com_value =
699+ cpu_to_le32(dev->vow_cfg.sta_max_wait_time);
700+ break;
701+
702+ case VOW_DRR_AIRTIME_QUANTUM_L0:
703+ case VOW_DRR_AIRTIME_QUANTUM_L1:
704+ case VOW_DRR_AIRTIME_QUANTUM_L2:
705+ case VOW_DRR_AIRTIME_QUANTUM_L3:
706+ case VOW_DRR_AIRTIME_QUANTUM_L4:
707+ case VOW_DRR_AIRTIME_QUANTUM_L5:
708+ case VOW_DRR_AIRTIME_QUANTUM_L6:
709+ case VOW_DRR_AIRTIME_QUANTUM_L7:
710+ req.air_time_ctrl.com_value =
711+ cpu_to_le32(dev->vow_cfg.vow_sta_dwrr_quantum[subcmd -
712+ VOW_DRR_AIRTIME_QUANTUM_L0]);
713+ break;
714+
715+ case VOW_DRR_AIRTIME_QUANTUM_ALL: {
716+ for (i = 0; i < VOW_MAX_STA_DWRR_NUM; i++) {
717+ req.air_time_ctrl.air_time_quantum_all.air_time_quantum[i] =
718+ dev->vow_cfg.vow_sta_dwrr_quantum[i];
719+ }
720+ break;
721+ }
722+
723+ default:
724+ break;
725+ }
726+
727+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_DRR_CTRL),
728+ &req, sizeof(req), false);
729+}
730+
731+int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev)
732+{
733+ u16 value = 0;
734+ u32 sch_value = 0;
735+
736+ struct vow_feature_ctrl {
737+ __le16 bss_flag;
738+ __le16 vow_ctrl_flag;
739+ __le16 bss_value[9];
740+ __le16 vow_ctrl_val;
741+ __le16 time_token_value[2];
742+ __le16 length_token_value[2];
743+ __le32 tx_ctrl;
744+ __le32 sch_ctrl;
745+ } __packed req = {
746+ .bss_flag = cpu_to_le16(0xffff),
747+ .vow_ctrl_flag = cpu_to_le16(0xf231),
748+ .bss_value[0] = cpu_to_le16(0xffff),
749+ .bss_value[2] = cpu_to_le16(0xffff),
750+ .bss_value[8] = cpu_to_le16(0xffff),
751+ .time_token_value[0] = cpu_to_le16(0xffff),
752+ };
753+
754+ value |= dev->vow_cfg.refill_period;
755+ value |= 1 << 4;
756+ value |= 1 << 5;
757+ value |= dev->vow_cfg.vow_watf_en << 9;
758+ value |= 1 << 12;
759+ value |= dev->vow_cfg.vow_atf_en << 13;
760+ value |= 1 << 14;
761+ req.vow_ctrl_val = value;
762+ if (dev->vow_cfg.vow_atf_en)
763+ req.tx_ctrl = cpu_to_le32(0x6bf69e1f);
764+ sch_value |= 1 << 6;
765+ sch_value |= (((dev->vow_cfg.vow_show_en == 0) ? 0 :
766+ (dev->vow_cfg.vow_show_en - 1 )) << 4);
767+ req.sch_ctrl = sch_value;
768+
769+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_FEATURE_CTRL),
770+ &req, sizeof(req), false);
771+}
772+
773+int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif)
774+{
775+ struct module_ctrl {
776+ __le16 action;
777+ __le16 sub_action;
778+ __le32 rsv1[5];
779+ u8 rsv2[72];
780+ u8 group_idx;
781+ u8 band_idx;
782+ u8 rsv3[2];
783+ } __packed req = {
784+ .action = cpu_to_le16(0x1),
785+ .sub_action = cpu_to_le16(0x4),
developer60412772023-09-22 10:06:10 +0800786+ .group_idx = mvif->sta.vow_sta_cfg.bss_grp_idx,
developerc978ea12022-11-09 15:58:31 +0800787+ .band_idx = mvif->mt76.band_idx,
788+ };
789+
790+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(AT_PROC_MODULE),
791+ &req, sizeof(req), false);
792+}
793+
794 int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
795 {
developer1346ce52022-12-15 21:36:14 +0800796 #define MT_BF_PROCESSING 4
developerc978ea12022-11-09 15:58:31 +0800797diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer3524ece2023-10-12 10:46:59 +0800798index 1d89814e..2b4ed04c 100644
developerc978ea12022-11-09 15:58:31 +0800799--- a/mt7915/mt7915.h
800+++ b/mt7915/mt7915.h
developer2157bf82023-06-26 02:27:49 +0800801@@ -141,6 +141,58 @@ struct mt7915_twt_flow {
developer356ecec2022-11-14 10:25:04 +0800802
803 DECLARE_EWMA(avg_signal, 10, 8)
developerc978ea12022-11-09 15:58:31 +0800804
805+#define VOW_MAX_STA_DWRR_NUM 8
806+#define VOW_WATF_LEVEL_NUM 4
807+#define VOW_FEATURE_BWCG BIT(3)
808+#define UMAC_BWC_GROUP_MIN 40
809+
810+
811+enum ext_cmd_vow_drr_ctrl {
812+ /* Type 1 */
813+ VOW_DRR_STA_ALL = 0x00,
814+ VOW_DRR_STA_BSS_GROUP = 0x01,
815+ VOW_DRR_STA_AC0_QUA_ID = 0x03,
816+ VOW_DRR_STA_AC1_QUA_ID = 0x04,
817+ VOW_DRR_STA_AC2_QUA_ID = 0x05,
818+ VOW_DRR_STA_AC3_QUA_ID = 0x06,
819+
820+ /* Type 2 */
821+ VOW_DRR_AIRTIME_DEFICIT_BOUND = 0x10,
822+
823+ /* Type 3 */
824+ VOW_DRR_AIRTIME_QUANTUM_L0 = 0x20,
825+ VOW_DRR_AIRTIME_QUANTUM_L1 = 0x21,
826+ VOW_DRR_AIRTIME_QUANTUM_L2 = 0x22,
827+ VOW_DRR_AIRTIME_QUANTUM_L3 = 0x23,
828+ VOW_DRR_AIRTIME_QUANTUM_L4 = 0x24,
829+ VOW_DRR_AIRTIME_QUANTUM_L5 = 0x25,
830+ VOW_DRR_AIRTIME_QUANTUM_L6 = 0x26,
831+ VOW_DRR_AIRTIME_QUANTUM_L7 = 0x27,
832+ VOW_DRR_AIRTIME_QUANTUM_ALL = 0x28,
833+ VOW_DRR_STA_PAUSE_SETTING = 0x30,
834+};
835+
836+struct mt7915_vow_sta_cfg{
developer60412772023-09-22 10:06:10 +0800837+ u8 bss_grp_idx;
developerc978ea12022-11-09 15:58:31 +0800838+ u8 dwrr_quantum[IEEE80211_NUM_ACS];
developerc978ea12022-11-09 15:58:31 +0800839+ bool paused;
840+};
841+
842+struct mt7915_vow_cfg{
843+ /*ATF setting */
844+ u32 vow_feature;
845+ bool vow_atf_en;
846+ u8 refill_period;
847+ u8 sta_max_wait_time;
848+ u8 vow_sta_dwrr_quantum[VOW_MAX_STA_DWRR_NUM];
849+ u8 vow_show_en;
850+ u32 vow_show_sta;
851+
852+ /*WATF setting */
853+ bool vow_watf_en;
854+};
855+
856+
857 struct mt7915_sta {
858 struct mt76_wcid wcid; /* must be first */
859
developer2157bf82023-06-26 02:27:49 +0800860@@ -161,6 +213,7 @@ struct mt7915_sta {
developerc978ea12022-11-09 15:58:31 +0800861 u8 flowid_mask;
862 struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT];
863 } twt;
864+ struct mt7915_vow_sta_cfg vow_sta_cfg;
865 };
866
developerc1571f92023-07-04 22:11:24 +0800867 struct mt7915_vif_cap {
developer3524ece2023-10-12 10:46:59 +0800868@@ -420,6 +473,8 @@ struct mt7915_dev {
developerc978ea12022-11-09 15:58:31 +0800869 } dbg;
870 const struct mt7915_dbg_reg_desc *dbg_reg;
871 #endif
872+ struct delayed_work vow_work;
873+ struct mt7915_vow_cfg vow_cfg;
874 };
875
876 enum {
developer3524ece2023-10-12 10:46:59 +0800877@@ -452,6 +507,15 @@ enum mt7915_rdd_cmd {
developerc978ea12022-11-09 15:58:31 +0800878 RDD_IRQ_OFF,
879 };
880
881+static inline bool
developereb6a0182022-12-12 18:53:32 +0800882+mt7915_is_atf_default_on(struct wiphy *wiphy, struct mt7915_dev *dev)
developerc978ea12022-11-09 15:58:31 +0800883+{
884+ return ((!wiphy_ext_feature_isset(wiphy,
885+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ||
886+ mtk_wed_device_active(&dev->mt76.mmio.wed));
887+}
888+
889+
890 static inline struct mt7915_phy *
891 mt7915_hw_phy(struct ieee80211_hw *hw)
892 {
developer3524ece2023-10-12 10:46:59 +0800893@@ -581,6 +645,11 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
developerc978ea12022-11-09 15:58:31 +0800894 int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
895 u8 en);
896 int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
897+int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev, struct mt7915_sta *msta,
898+ u32 subcmd);
899+int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev);
900+int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif);
developer60412772023-09-22 10:06:10 +0800901+void mt7915_vow_init_sta_bss_grp(struct mt7915_sta *sta);
developerc978ea12022-11-09 15:58:31 +0800902 int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
903 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
developerfe7be7f2022-12-13 21:40:24 +0800904 int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
developerc978ea12022-11-09 15:58:31 +0800905diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
developer99b59a92023-10-13 21:55:14 +0800906index 9fe7dcb1..9ff4c5cd 100644
developerc978ea12022-11-09 15:58:31 +0800907--- a/mt7915/mtk_debugfs.c
908+++ b/mt7915/mtk_debugfs.c
developerd75d3632023-01-05 14:31:01 +0800909@@ -1368,7 +1368,6 @@ static EMPTY_QUEUE_INFO_T ple_txcmd_queue_empty_info[] = {
developerc978ea12022-11-09 15:58:31 +0800910 };
911
912
913-
914 static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
915 static u32 chip_show_sta_acq_info(struct seq_file *s, struct mt7915_dev *dev, u32 *ple_stat,
916 u32 *sta_pause, u32 *dis_sta_map,
developerab4a0b82023-08-18 19:56:34 +0800917@@ -1520,6 +1519,136 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause)
developerc978ea12022-11-09 15:58:31 +0800918 }
919 }
920
921+u32 vow_chip_show_sta_acq_info(struct mt7915_dev *dev, u32 *ple_stat,
922+ u32 *sta_pause, u32 *dis_sta_map,
923+ u32 dumptxd)
924+{
925+ int i, j;
926+ u32 total_nonempty_cnt = 0;
927+ u32 ac_num = 9, all_ac_num;
928+ static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
929+ if (!is_mt7915(&dev->mt76))
930+ ac_num = 17;
931+
932+ all_ac_num = ac_num * 4;
933+
934+ for (j = 0; j < all_ac_num; j++) { /* show AC Q info */
935+ for (i = 0; i < 32; i++) {
936+ if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) {
937+ u32 hfid, tfid, pktcnt, ac_n = j / ac_num, ctrl = 0;
938+ u32 sta_num = i + (j % ac_num) * 32, fl_que_ctrl[3] = {0};
939+ u32 wmmidx = 0;
940+ struct mt7915_sta *msta;
941+ struct mt76_wcid *wcid;
developerc978ea12022-11-09 15:58:31 +0800942+
943+ wcid = rcu_dereference(dev->mt76.wcid[sta_num]);
developerab4a0b82023-08-18 19:56:34 +0800944+ if (!wcid) {
developerc978ea12022-11-09 15:58:31 +0800945+ printk("ERROR!! no found STA wcid=%d\n", sta_num);
946+ continue;
947+ }
948+ msta = container_of(wcid, struct mt7915_sta, wcid);
949+ wmmidx = msta->vif->mt76.wmm_idx;
950+
951+ dev_info(dev->mt76.dev, "\tSTA%d AC%d: ", sta_num, ac_n);
952+
953+ fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK;
954+ fl_que_ctrl[0] |= (ENUM_UMAC_LMAC_PORT_2 <<
955+ MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT);
956+ fl_que_ctrl[0] |= (ac_n << MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT);
957+ fl_que_ctrl[0] |= sta_num;
958+ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]);
959+ fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2);
960+ fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3);
961+ hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK,
962+ fl_que_ctrl[1]);
963+ tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK,
964+ fl_que_ctrl[1]);
965+ pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK,
966+ fl_que_ctrl[2]);
967+ dev_info(dev->mt76.dev, "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x",
968+ tfid, hfid, pktcnt);
969+
developer99b59a92023-10-13 21:55:14 +0800970+ if (((sta_pause[j % ac_num] & 0x1 << i) >> i) == 1)
developerc978ea12022-11-09 15:58:31 +0800971+ ctrl = 2;
972+
developer99b59a92023-10-13 21:55:14 +0800973+ if (((dis_sta_map[j % ac_num] & 0x1 << i) >> i) == 1)
developerc978ea12022-11-09 15:58:31 +0800974+ ctrl = 1;
975+
976+ dev_info(dev->mt76.dev, " ctrl = %s", sta_ctrl_reg[ctrl]);
977+ dev_info(dev->mt76.dev, " (wmmidx=%d)\n", wmmidx);
978+
979+ total_nonempty_cnt++;
980+ }
981+ }
982+ }
983+
984+ return total_nonempty_cnt;
985+}
986+
987+int mt7915_vow_pleinfo_read(struct mt7915_dev *dev)
988+{
989+ u32 ple_stat[70] = {0}, pg_flow_ctrl[8] = {0};
990+ u32 ple_txcmd_stat;
991+ u32 sta_pause[CR_NUM_OF_AC] = {0}, dis_sta_map[CR_NUM_OF_AC] = {0};
992+ int i;
993+
994+ chip_get_ple_acq_stat(dev, ple_stat);
995+ ple_txcmd_stat = mt76_rr(dev, MT_DBG_PLE_TXCMD_Q_EMPTY);
996+ pg_flow_ctrl[0] = mt76_rr(dev, MT_DBG_PLE_FREEPG_CNT);
997+ pg_flow_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FREEPG_HEAD_TAIL);
998+ pg_flow_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_GROUP);
999+ pg_flow_ctrl[3] = mt76_rr(dev, MT_DBG_PLE_HIF_PG_INFO);
1000+ pg_flow_ctrl[4] = mt76_rr(dev, MT_DBG_PLE_PG_CPU_GROUP);
1001+ pg_flow_ctrl[5] = mt76_rr(dev, MT_DBG_PLE_CPU_PG_INFO);
1002+ pg_flow_ctrl[6] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_TXCMD_GROUP);
1003+ pg_flow_ctrl[7] = mt76_rr(dev, MT_DBG_PLE_HIF_TXCMD_PG_INFO);
1004+ chip_get_dis_sta_map(dev, dis_sta_map);
1005+ chip_get_sta_pause(dev, sta_pause);
1006+
1007+ dev_info(dev->mt76.dev, "PLE Configuration Info:\n");
1008+
1009+ for (i = 0; i < 32; i++) {
1010+ if (((ple_stat[0] & (0x1 << i)) >> i) == 0) {
1011+ u32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0};
1012+
1013+ if (ple_queue_empty_info[i].QueueName != NULL) {
1014+ fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK;
1015+ fl_que_ctrl[0] |= (ple_queue_empty_info[i].Portid <<
1016+ MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT);
1017+ fl_que_ctrl[0] |= (ple_queue_empty_info[i].Queueid <<
1018+ MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT);
1019+ } else
1020+ continue;
1021+
1022+ if (ple_queue_empty_info[i].Queueid >=
1023+ ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0 &&
1024+ ple_queue_empty_info[i].Queueid <=
1025+ ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0)
1026+ /* band0 set TGID 0, bit31 = 0 */
1027+ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x0);
1028+ else if (ple_queue_empty_info[i].Queueid >=
1029+ ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1 &&
1030+ ple_queue_empty_info[i].Queueid <=
1031+ ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1)
1032+ /* band1 set TGID 1, bit31 = 1 */
1033+ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x80000000);
1034+
1035+ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]);
1036+ fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2);
1037+ fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3);
1038+ hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK,
1039+ fl_que_ctrl[1]);
1040+ tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK,
1041+ fl_que_ctrl[1]);
1042+ pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK,
1043+ fl_que_ctrl[2]);
1044+ }
1045+ }
1046+
1047+ vow_chip_show_sta_acq_info(dev, ple_stat, sta_pause, dis_sta_map, 0);
1048+
1049+ return 0;
1050+}
1051 static int mt7915_pleinfo_read(struct seq_file *s, void *data)
1052 {
1053 struct mt7915_dev *dev = dev_get_drvdata(s->private);
1054--
developerab4a0b82023-08-18 19:56:34 +080010552.18.0
developerc978ea12022-11-09 15:58:31 +08001056