blob: 189d40927e974ef80e77e368a6d72e466968207a [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/*
2 * Copyright (C) 2018 MediaTek Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
14 * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
15 * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
16 */
17
18#include <linux/trace_seq.h>
19#include <linux/seq_file.h>
20#include <linux/proc_fs.h>
21#include <linux/u64_stats_sync.h>
22#include <linux/dma-mapping.h>
23#include <linux/netdevice.h>
24#include <linux/ctype.h>
25#include <linux/debugfs.h>
26#include <linux/of_mdio.h>
developer089e8852022-09-28 14:43:46 +080027#include <linux/of_address.h>
developerfd40db22021-04-29 10:08:25 +080028
29#include "mtk_eth_soc.h"
30#include "mtk_eth_dbg.h"
developer8051e042022-04-08 13:26:36 +080031#include "mtk_eth_reset.h"
developerfd40db22021-04-29 10:08:25 +080032
developer77d03a72021-06-06 00:06:00 +080033u32 hw_lro_agg_num_cnt[MTK_HW_LRO_RING_NUM][MTK_HW_LRO_MAX_AGG_CNT + 1];
34u32 hw_lro_agg_size_cnt[MTK_HW_LRO_RING_NUM][16];
35u32 hw_lro_tot_agg_cnt[MTK_HW_LRO_RING_NUM];
36u32 hw_lro_tot_flush_cnt[MTK_HW_LRO_RING_NUM];
37u32 hw_lro_agg_flush_cnt[MTK_HW_LRO_RING_NUM];
38u32 hw_lro_age_flush_cnt[MTK_HW_LRO_RING_NUM];
39u32 hw_lro_seq_flush_cnt[MTK_HW_LRO_RING_NUM];
40u32 hw_lro_timestamp_flush_cnt[MTK_HW_LRO_RING_NUM];
41u32 hw_lro_norule_flush_cnt[MTK_HW_LRO_RING_NUM];
42u32 mtk_hwlro_stats_ebl;
developer7979ddb2023-04-24 17:19:21 +080043u32 dbg_show_level;
developere3d0de22023-05-30 17:45:00 +080044u32 cur_rss_num;
developer7979ddb2023-04-24 17:19:21 +080045
developere3d0de22023-05-30 17:45:00 +080046static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb,
47 *proc_rss_ctrl;
developer77d03a72021-06-06 00:06:00 +080048typedef int (*mtk_lro_dbg_func) (int par);
49
developerfd40db22021-04-29 10:08:25 +080050struct mtk_eth_debug {
developer089e8852022-09-28 14:43:46 +080051 struct dentry *root;
52 void __iomem *base;
53 int direct_access;
developerfd40db22021-04-29 10:08:25 +080054};
55
56struct mtk_eth *g_eth;
57
58struct mtk_eth_debug eth_debug;
59
developer089e8852022-09-28 14:43:46 +080060int mt798x_iomap(void)
61{
62 struct device_node *np = NULL;
63
64 np = of_find_node_by_name(NULL, "switch0");
65 if (np) {
66 eth_debug.base = of_iomap(np, 0);
67 if (!eth_debug.base) {
68 pr_err("of_iomap failed\n");
69 of_node_put(np);
70 return -ENOMEM;
71 }
72
73 of_node_put(np);
74 eth_debug.direct_access = 1;
75 }
76
77 return 0;
78}
79
80int mt798x_iounmap(void)
81{
82 eth_debug.direct_access = 0;
83 if (eth_debug.base)
84 iounmap(eth_debug.base);
85
86 return 0;
87}
88
developer3957a912021-05-13 16:44:31 +080089void mt7530_mdio_w32(struct mtk_eth *eth, u16 reg, u32 val)
developerfd40db22021-04-29 10:08:25 +080090{
91 mutex_lock(&eth->mii_bus->mdio_lock);
92
developer089e8852022-09-28 14:43:46 +080093 if (eth_debug.direct_access)
94 __raw_writel(val, eth_debug.base + reg);
95 else {
96 _mtk_mdio_write(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
97 _mtk_mdio_write(eth, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
98 _mtk_mdio_write(eth, 0x1f, 0x10, val >> 16);
99 }
developerfd40db22021-04-29 10:08:25 +0800100
101 mutex_unlock(&eth->mii_bus->mdio_lock);
102}
103
104u32 mt7530_mdio_r32(struct mtk_eth *eth, u32 reg)
105{
106 u16 high, low;
developer089e8852022-09-28 14:43:46 +0800107 u32 ret;
developerfd40db22021-04-29 10:08:25 +0800108
109 mutex_lock(&eth->mii_bus->mdio_lock);
110
developer089e8852022-09-28 14:43:46 +0800111 if (eth_debug.direct_access) {
112 ret = __raw_readl(eth_debug.base + reg);
113 mutex_unlock(&eth->mii_bus->mdio_lock);
114 return ret;
115 }
developerfd40db22021-04-29 10:08:25 +0800116 _mtk_mdio_write(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
117 low = _mtk_mdio_read(eth, 0x1f, (reg >> 2) & 0xf);
118 high = _mtk_mdio_read(eth, 0x1f, 0x10);
119
120 mutex_unlock(&eth->mii_bus->mdio_lock);
121
122 return (high << 16) | (low & 0xffff);
123}
124
125void mtk_switch_w32(struct mtk_eth *eth, u32 val, unsigned reg)
126{
127 mtk_w32(eth, val, reg + 0x10000);
128}
129EXPORT_SYMBOL(mtk_switch_w32);
130
131u32 mtk_switch_r32(struct mtk_eth *eth, unsigned reg)
132{
133 return mtk_r32(eth, reg + 0x10000);
134}
135EXPORT_SYMBOL(mtk_switch_r32);
136
137static int mtketh_debug_show(struct seq_file *m, void *private)
138{
139 struct mtk_eth *eth = m->private;
140 struct mtk_mac *mac = 0;
developer77d03a72021-06-06 00:06:00 +0800141 int i = 0;
developerfd40db22021-04-29 10:08:25 +0800142
143 for (i = 0 ; i < MTK_MAX_DEVS ; i++) {
144 if (!eth->mac[i] ||
145 of_phy_is_fixed_link(eth->mac[i]->of_node))
146 continue;
147 mac = eth->mac[i];
148#if 0 //FIXME
149 while (j < 30) {
150 d = _mtk_mdio_read(eth, mac->phy_dev->addr, j);
151
152 seq_printf(m, "phy=%d, reg=0x%08x, data=0x%08x\n",
153 mac->phy_dev->addr, j, d);
154 j++;
155 }
156#endif
157 }
158 return 0;
159}
160
161static int mtketh_debug_open(struct inode *inode, struct file *file)
162{
163 return single_open(file, mtketh_debug_show, inode->i_private);
164}
165
166static const struct file_operations mtketh_debug_fops = {
developer089e8852022-09-28 14:43:46 +0800167 .owner = THIS_MODULE,
developerfd40db22021-04-29 10:08:25 +0800168 .open = mtketh_debug_open,
169 .read = seq_read,
170 .llseek = seq_lseek,
171 .release = single_release,
172};
173
174static int mtketh_mt7530sw_debug_show(struct seq_file *m, void *private)
175{
176 struct mtk_eth *eth = m->private;
177 u32 offset, data;
178 int i;
179 struct mt7530_ranges {
180 u32 start;
181 u32 end;
182 } ranges[] = {
183 {0x0, 0xac},
184 {0x1000, 0x10e0},
185 {0x1100, 0x1140},
186 {0x1200, 0x1240},
187 {0x1300, 0x1340},
188 {0x1400, 0x1440},
189 {0x1500, 0x1540},
190 {0x1600, 0x1640},
191 {0x1800, 0x1848},
192 {0x1900, 0x1948},
193 {0x1a00, 0x1a48},
194 {0x1b00, 0x1b48},
195 {0x1c00, 0x1c48},
196 {0x1d00, 0x1d48},
197 {0x1e00, 0x1e48},
198 {0x1f60, 0x1ffc},
199 {0x2000, 0x212c},
200 {0x2200, 0x222c},
201 {0x2300, 0x232c},
202 {0x2400, 0x242c},
203 {0x2500, 0x252c},
204 {0x2600, 0x262c},
205 {0x3000, 0x3014},
206 {0x30c0, 0x30f8},
207 {0x3100, 0x3114},
208 {0x3200, 0x3214},
209 {0x3300, 0x3314},
210 {0x3400, 0x3414},
211 {0x3500, 0x3514},
212 {0x3600, 0x3614},
213 {0x4000, 0x40d4},
214 {0x4100, 0x41d4},
215 {0x4200, 0x42d4},
216 {0x4300, 0x43d4},
217 {0x4400, 0x44d4},
218 {0x4500, 0x45d4},
219 {0x4600, 0x46d4},
220 {0x4f00, 0x461c},
221 {0x7000, 0x7038},
222 {0x7120, 0x7124},
223 {0x7800, 0x7804},
224 {0x7810, 0x7810},
225 {0x7830, 0x7830},
226 {0x7a00, 0x7a7c},
227 {0x7b00, 0x7b04},
228 {0x7e00, 0x7e04},
229 {0x7ffc, 0x7ffc},
230 };
231
232 if (!mt7530_exist(eth))
233 return -EOPNOTSUPP;
234
235 if ((!eth->mac[0] || !of_phy_is_fixed_link(eth->mac[0]->of_node)) &&
236 (!eth->mac[1] || !of_phy_is_fixed_link(eth->mac[1]->of_node))) {
237 seq_puts(m, "no switch found\n");
238 return 0;
239 }
240
241 for (i = 0 ; i < ARRAY_SIZE(ranges) ; i++) {
242 for (offset = ranges[i].start;
243 offset <= ranges[i].end; offset += 4) {
244 data = mt7530_mdio_r32(eth, offset);
245 seq_printf(m, "mt7530 switch reg=0x%08x, data=0x%08x\n",
246 offset, data);
247 }
248 }
249
250 return 0;
251}
252
253static int mtketh_debug_mt7530sw_open(struct inode *inode, struct file *file)
254{
255 return single_open(file, mtketh_mt7530sw_debug_show, inode->i_private);
256}
257
258static const struct file_operations mtketh_debug_mt7530sw_fops = {
developer089e8852022-09-28 14:43:46 +0800259 .owner = THIS_MODULE,
developerfd40db22021-04-29 10:08:25 +0800260 .open = mtketh_debug_mt7530sw_open,
261 .read = seq_read,
262 .llseek = seq_lseek,
263 .release = single_release,
264};
265
266static ssize_t mtketh_mt7530sw_debugfs_write(struct file *file,
267 const char __user *ptr,
268 size_t len, loff_t *off)
269{
270 struct mtk_eth *eth = file->private_data;
271 char buf[32], *token, *p = buf;
developer8b6f2402022-11-28 13:42:34 +0800272 unsigned long reg, value, phy;
developerfd40db22021-04-29 10:08:25 +0800273 int ret;
274
275 if (!mt7530_exist(eth))
276 return -EOPNOTSUPP;
277
278 if (*off != 0)
279 return 0;
280
281 if (len > sizeof(buf) - 1)
282 len = sizeof(buf) - 1;
283
284 ret = strncpy_from_user(buf, ptr, len);
285 if (ret < 0)
286 return ret;
287 buf[len] = '\0';
288
289 token = strsep(&p, " ");
290 if (!token)
291 return -EINVAL;
292 if (kstrtoul(token, 16, (unsigned long *)&phy))
293 return -EINVAL;
294
295 token = strsep(&p, " ");
296 if (!token)
297 return -EINVAL;
298 if (kstrtoul(token, 16, (unsigned long *)&reg))
299 return -EINVAL;
300
301 token = strsep(&p, " ");
302 if (!token)
303 return -EINVAL;
304 if (kstrtoul(token, 16, (unsigned long *)&value))
305 return -EINVAL;
306
307 pr_info("%s:phy=%d, reg=0x%x, val=0x%x\n", __func__,
308 0x1f, reg, value);
309 mt7530_mdio_w32(eth, reg, value);
310 pr_info("%s:phy=%d, reg=0x%x, val=0x%x confirm..\n", __func__,
311 0x1f, reg, mt7530_mdio_r32(eth, reg));
312
313 return len;
314}
315
316static ssize_t mtketh_debugfs_write(struct file *file, const char __user *ptr,
317 size_t len, loff_t *off)
318{
319 struct mtk_eth *eth = file->private_data;
320 char buf[32], *token, *p = buf;
developer8b6f2402022-11-28 13:42:34 +0800321 unsigned long reg, value, phy;
developerfd40db22021-04-29 10:08:25 +0800322 int ret;
323
324 if (*off != 0)
325 return 0;
326
327 if (len > sizeof(buf) - 1)
328 len = sizeof(buf) - 1;
329
330 ret = strncpy_from_user(buf, ptr, len);
331 if (ret < 0)
332 return ret;
333 buf[len] = '\0';
334
335 token = strsep(&p, " ");
336 if (!token)
337 return -EINVAL;
338 if (kstrtoul(token, 16, (unsigned long *)&phy))
339 return -EINVAL;
340
341 token = strsep(&p, " ");
342
343 if (!token)
344 return -EINVAL;
345 if (kstrtoul(token, 16, (unsigned long *)&reg))
346 return -EINVAL;
347
348 token = strsep(&p, " ");
349
350 if (!token)
351 return -EINVAL;
352 if (kstrtoul(token, 16, (unsigned long *)&value))
353 return -EINVAL;
354
355 pr_info("%s:phy=%d, reg=0x%x, val=0x%x\n", __func__,
356 phy, reg, value);
357
358 _mtk_mdio_write(eth, phy, reg, value);
359
360 pr_info("%s:phy=%d, reg=0x%x, val=0x%x confirm..\n", __func__,
361 phy, reg, _mtk_mdio_read(eth, phy, reg));
362
363 return len;
364}
365
366static ssize_t mtketh_debugfs_reset(struct file *file, const char __user *ptr,
367 size_t len, loff_t *off)
368{
369 struct mtk_eth *eth = file->private_data;
developerbd42c172022-07-18 17:51:30 +0800370 char buf[8] = "";
371 int count = len;
372 unsigned long dbg_level = 0;
373
374 len = min(count, sizeof(buf) - 1);
375 if (copy_from_user(buf, ptr, len))
376 return -EFAULT;
377
378 buf[len] = '\0';
379 if (kstrtoul(buf, 0, &dbg_level))
380 return -EINVAL;
developerfd40db22021-04-29 10:08:25 +0800381
developerbd42c172022-07-18 17:51:30 +0800382 switch(dbg_level)
383 {
384 case 0:
developer0baa6962023-01-31 14:25:23 +0800385 atomic_set(&force, 0);
developerbd42c172022-07-18 17:51:30 +0800386 break;
387 case 1:
developer0baa6962023-01-31 14:25:23 +0800388 if (atomic_read(&force) == 1)
developer37482a42022-12-26 13:31:13 +0800389 schedule_work(&eth->pending_work);
developer0baa6962023-01-31 14:25:23 +0800390 else
391 pr_info(" stat:disable\n");
developerbd42c172022-07-18 17:51:30 +0800392 break;
393 case 2:
developer0baa6962023-01-31 14:25:23 +0800394 atomic_set(&force, 1);
developerbd42c172022-07-18 17:51:30 +0800395 break;
developer37482a42022-12-26 13:31:13 +0800396 case 3:
developer0baa6962023-01-31 14:25:23 +0800397 if (atomic_read(&force) == 1) {
developer37482a42022-12-26 13:31:13 +0800398 mtk_reset_flag = MTK_FE_STOP_TRAFFIC;
399 schedule_work(&eth->pending_work);
400 } else
401 pr_info(" device resetting !!!\n");
402 break;
developer7979ddb2023-04-24 17:19:21 +0800403 case 4:
404 dbg_show_level = 1;
405 break;
406 case 5:
407 dbg_show_level = 0;
408 break;
developerbd42c172022-07-18 17:51:30 +0800409 default:
410 pr_info("Usage: echo [level] > /sys/kernel/debug/mtketh/reset\n");
developer37482a42022-12-26 13:31:13 +0800411 pr_info("Commands: [level]\n");
412 pr_info(" 0 disable reset\n");
413 pr_info(" 1 FE and WDMA reset\n");
developerbd42c172022-07-18 17:51:30 +0800414 pr_info(" 2 enable reset\n");
developer37482a42022-12-26 13:31:13 +0800415 pr_info(" 3 FE reset\n");
developer7979ddb2023-04-24 17:19:21 +0800416 pr_info(" 4 enable dump reset info\n");
417 pr_info(" 5 disable dump reset info\n");
developerbd42c172022-07-18 17:51:30 +0800418 break;
419 }
420 return count;
developerfd40db22021-04-29 10:08:25 +0800421}
422
423static const struct file_operations fops_reg_w = {
424 .owner = THIS_MODULE,
425 .open = simple_open,
426 .write = mtketh_debugfs_write,
427 .llseek = noop_llseek,
428};
429
430static const struct file_operations fops_eth_reset = {
431 .owner = THIS_MODULE,
432 .open = simple_open,
433 .write = mtketh_debugfs_reset,
434 .llseek = noop_llseek,
435};
436
437static const struct file_operations fops_mt7530sw_reg_w = {
438 .owner = THIS_MODULE,
439 .open = simple_open,
440 .write = mtketh_mt7530sw_debugfs_write,
441 .llseek = noop_llseek,
442};
443
444void mtketh_debugfs_exit(struct mtk_eth *eth)
445{
446 debugfs_remove_recursive(eth_debug.root);
447}
448
449int mtketh_debugfs_init(struct mtk_eth *eth)
450{
451 int ret = 0;
452
453 eth_debug.root = debugfs_create_dir("mtketh", NULL);
454 if (!eth_debug.root) {
455 dev_notice(eth->dev, "%s:err at %d\n", __func__, __LINE__);
456 ret = -ENOMEM;
457 }
458
459 debugfs_create_file("phy_regs", S_IRUGO,
460 eth_debug.root, eth, &mtketh_debug_fops);
461 debugfs_create_file("phy_reg_w", S_IFREG | S_IWUSR,
462 eth_debug.root, eth, &fops_reg_w);
463 debugfs_create_file("reset", S_IFREG | S_IWUSR,
464 eth_debug.root, eth, &fops_eth_reset);
465 if (mt7530_exist(eth)) {
466 debugfs_create_file("mt7530sw_regs", S_IRUGO,
467 eth_debug.root, eth,
468 &mtketh_debug_mt7530sw_fops);
469 debugfs_create_file("mt7530sw_reg_w", S_IFREG | S_IWUSR,
470 eth_debug.root, eth,
471 &fops_mt7530sw_reg_w);
472 }
473 return ret;
474}
475
476void mii_mgr_read_combine(struct mtk_eth *eth, u32 phy_addr, u32 phy_register,
477 u32 *read_data)
478{
479 if (mt7530_exist(eth) && phy_addr == 31)
480 *read_data = mt7530_mdio_r32(eth, phy_register);
481
482 else
developer089e8852022-09-28 14:43:46 +0800483 *read_data = mdiobus_read(eth->mii_bus, phy_addr, phy_register);
developerfd40db22021-04-29 10:08:25 +0800484}
485
developer3957a912021-05-13 16:44:31 +0800486void mii_mgr_write_combine(struct mtk_eth *eth, u16 phy_addr, u16 phy_register,
developerfd40db22021-04-29 10:08:25 +0800487 u32 write_data)
488{
489 if (mt7530_exist(eth) && phy_addr == 31)
490 mt7530_mdio_w32(eth, phy_register, write_data);
491
492 else
developer089e8852022-09-28 14:43:46 +0800493 mdiobus_write(eth->mii_bus, phy_addr, phy_register, write_data);
developerfd40db22021-04-29 10:08:25 +0800494}
495
developer3957a912021-05-13 16:44:31 +0800496static void mii_mgr_read_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data)
developerfd40db22021-04-29 10:08:25 +0800497{
developer089e8852022-09-28 14:43:46 +0800498 *data = mdiobus_read(eth->mii_bus, port, mdiobus_c45_addr(devad, reg));
developerfd40db22021-04-29 10:08:25 +0800499}
500
developer3957a912021-05-13 16:44:31 +0800501static void mii_mgr_write_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data)
developerfd40db22021-04-29 10:08:25 +0800502{
developer089e8852022-09-28 14:43:46 +0800503 mdiobus_write(eth->mii_bus, port, mdiobus_c45_addr(devad, reg), data);
developerfd40db22021-04-29 10:08:25 +0800504}
505
506int mtk_do_priv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
507{
508 struct mtk_mac *mac = netdev_priv(dev);
509 struct mtk_eth *eth = mac->hw;
510 struct mtk_mii_ioctl_data mii;
511 struct mtk_esw_reg reg;
developerba2d1eb2021-05-25 19:26:45 +0800512 u16 val;
developerfd40db22021-04-29 10:08:25 +0800513
514 switch (cmd) {
515 case MTKETH_MII_READ:
516 if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii)))
517 goto err_copy;
518 mii_mgr_read_combine(eth, mii.phy_id, mii.reg_num,
519 &mii.val_out);
520 if (copy_to_user(ifr->ifr_data, &mii, sizeof(mii)))
521 goto err_copy;
522
523 return 0;
524 case MTKETH_MII_WRITE:
525 if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii)))
526 goto err_copy;
527 mii_mgr_write_combine(eth, mii.phy_id, mii.reg_num,
528 mii.val_in);
developerfd40db22021-04-29 10:08:25 +0800529 return 0;
530 case MTKETH_MII_READ_CL45:
531 if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii)))
532 goto err_copy;
developer3957a912021-05-13 16:44:31 +0800533 mii_mgr_read_cl45(eth,
534 mdio_phy_id_prtad(mii.phy_id),
535 mdio_phy_id_devad(mii.phy_id),
536 mii.reg_num,
developerba2d1eb2021-05-25 19:26:45 +0800537 &val);
538 mii.val_out = val;
developerfd40db22021-04-29 10:08:25 +0800539 if (copy_to_user(ifr->ifr_data, &mii, sizeof(mii)))
540 goto err_copy;
541
542 return 0;
543 case MTKETH_MII_WRITE_CL45:
544 if (copy_from_user(&mii, ifr->ifr_data, sizeof(mii)))
545 goto err_copy;
developerba2d1eb2021-05-25 19:26:45 +0800546 val = mii.val_in;
developer3957a912021-05-13 16:44:31 +0800547 mii_mgr_write_cl45(eth,
548 mdio_phy_id_prtad(mii.phy_id),
549 mdio_phy_id_devad(mii.phy_id),
550 mii.reg_num,
developerba2d1eb2021-05-25 19:26:45 +0800551 val);
developerfd40db22021-04-29 10:08:25 +0800552 return 0;
553 case MTKETH_ESW_REG_READ:
554 if (!mt7530_exist(eth))
555 return -EOPNOTSUPP;
556 if (copy_from_user(&reg, ifr->ifr_data, sizeof(reg)))
557 goto err_copy;
558 if (reg.off > REG_ESW_MAX)
559 return -EINVAL;
560 reg.val = mtk_switch_r32(eth, reg.off);
561
562 if (copy_to_user(ifr->ifr_data, &reg, sizeof(reg)))
563 goto err_copy;
564
565 return 0;
566 case MTKETH_ESW_REG_WRITE:
567 if (!mt7530_exist(eth))
568 return -EOPNOTSUPP;
569 if (copy_from_user(&reg, ifr->ifr_data, sizeof(reg)))
570 goto err_copy;
571 if (reg.off > REG_ESW_MAX)
572 return -EINVAL;
573 mtk_switch_w32(eth, reg.val, reg.off);
574
575 return 0;
576 default:
577 break;
578 }
579
580 return -EOPNOTSUPP;
581err_copy:
582 return -EFAULT;
583}
584
developer089e8852022-09-28 14:43:46 +0800585static void gdm_reg_dump_v3(struct mtk_eth *eth, u32 gdm_id, u32 mib_base)
586{
587 pr_info("| GDMA%d_RX_GBCNT : %010u (Rx Good Bytes) |\n",
588 gdm_id, mtk_r32(eth, mib_base));
589 pr_info("| GDMA%d_RX_GPCNT : %010u (Rx Good Pkts) |\n",
590 gdm_id, mtk_r32(eth, mib_base + 0x08));
591 pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error) |\n",
592 gdm_id, mtk_r32(eth, mib_base + 0x10));
593 pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error) |\n",
594 gdm_id, mtk_r32(eth, mib_base + 0x14));
595 pr_info("| GDMA%d_RX_SERCNT : %010u (too short) |\n",
596 gdm_id, mtk_r32(eth, mib_base + 0x18));
597 pr_info("| GDMA%d_RX_LERCNT : %010u (too long) |\n",
598 gdm_id, mtk_r32(eth, mib_base + 0x1C));
599 pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error) |\n",
600 gdm_id, mtk_r32(eth, mib_base + 0x20));
601 pr_info("| GDMA%d_RX_FCCNT : %010u (flow control) |\n",
602 gdm_id, mtk_r32(eth, mib_base + 0x24));
603 pr_info("| GDMA%d_RX_VDPCNT : %010u (VID drop) |\n",
604 gdm_id, mtk_r32(eth, mib_base + 0x28));
605 pr_info("| GDMA%d_RX_PFCCNT : %010u (priority flow control)\n",
606 gdm_id, mtk_r32(eth, mib_base + 0x2C));
607 pr_info("| GDMA%d_TX_GBCNT : %010u (Tx Good Bytes) |\n",
608 gdm_id, mtk_r32(eth, mib_base + 0x40));
609 pr_info("| GDMA%d_TX_GPCNT : %010u (Tx Good Pkts) |\n",
610 gdm_id, mtk_r32(eth, mib_base + 0x48));
611 pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count) |\n",
612 gdm_id, mtk_r32(eth, mib_base + 0x50));
613 pr_info("| GDMA%d_TX_COLCNT : %010u (collision count)|\n",
614 gdm_id, mtk_r32(eth, mib_base + 0x54));
615 pr_info("| GDMA%d_TX_OERCNT : %010u (overflow error) |\n",
616 gdm_id, mtk_r32(eth, mib_base + 0x58));
617 pr_info("| GDMA%d_TX_FCCNT : %010u (flow control) |\n",
618 gdm_id, mtk_r32(eth, mib_base + 0x60));
619 pr_info("| GDMA%d_TX_PFCCNT : %010u (priority flow control)\n",
620 gdm_id, mtk_r32(eth, mib_base + 0x64));
621 pr_info("| |\n");
622}
623
624static void gdm_reg_dump_v2(struct mtk_eth *eth, u32 gdm_id, u32 mib_base)
625{
626 pr_info("| GDMA%d_RX_GBCNT : %010u (Rx Good Bytes) |\n",
627 gdm_id, mtk_r32(eth, mib_base));
628 pr_info("| GDMA%d_RX_GPCNT : %010u (Rx Good Pkts) |\n",
629 gdm_id, mtk_r32(eth, mib_base + 0x08));
630 pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error) |\n",
631 gdm_id, mtk_r32(eth, mib_base + 0x10));
632 pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error) |\n",
633 gdm_id, mtk_r32(eth, mib_base + 0x14));
634 pr_info("| GDMA%d_RX_SERCNT : %010u (too short) |\n",
635 gdm_id, mtk_r32(eth, mib_base + 0x18));
636 pr_info("| GDMA%d_RX_LERCNT : %010u (too long) |\n",
637 gdm_id, mtk_r32(eth, mib_base + 0x1C));
638 pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error) |\n",
639 gdm_id, mtk_r32(eth, mib_base + 0x20));
640 pr_info("| GDMA%d_RX_FCCNT : %010u (flow control) |\n",
641 gdm_id, mtk_r32(eth, mib_base + 0x24));
642 pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count) |\n",
643 gdm_id, mtk_r32(eth, mib_base + 0x28));
644 pr_info("| GDMA%d_TX_COLCNT : %010u (collision count) |\n",
645 gdm_id, mtk_r32(eth, mib_base + 0x2C));
646 pr_info("| GDMA%d_TX_GBCNT : %010u (Tx Good Bytes) |\n",
647 gdm_id, mtk_r32(eth, mib_base + 0x30));
648 pr_info("| GDMA%d_TX_GPCNT : %010u (Tx Good Pkts) |\n",
649 gdm_id, mtk_r32(eth, mib_base + 0x38));
650 pr_info("| |\n");
651}
652
653static void gdm_cnt_read(struct mtk_eth *eth)
654{
655 u32 i, mib_base;
656
657 pr_info("\n <<CPU>>\n");
658 pr_info(" |\n");
659 pr_info("+-----------------------------------------------+\n");
660 pr_info("| <<PSE>> |\n");
661 pr_info("+-----------------------------------------------+\n");
662 pr_info(" |\n");
663 pr_info("+-----------------------------------------------+\n");
664 pr_info("| <<GDMA>> |\n");
665
666 for (i = 0; i < MTK_MAC_COUNT; i++) {
667 mib_base = MTK_GDM1_TX_GBCNT + MTK_STAT_OFFSET * i;
668
669 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
670 gdm_reg_dump_v3(eth, i + 1, mib_base);
671 else
672 gdm_reg_dump_v2(eth, i + 1, mib_base);
673 }
674
675 pr_info("+-----------------------------------------------+\n");
676}
677
developer9ccff342022-10-13 18:28:54 +0800678void dump_each_port(struct seq_file *seq, struct mtk_eth *eth, u32 base)
679{
680 u32 pkt_cnt = 0;
681 int i = 0;
682
683 for (i = 0; i < 7; i++) {
684 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
685 if ((base == 0x402C) && (i == 6))
686 base = 0x408C;
687 else if ((base == 0x408C) && (i == 6))
688 base = 0x402C;
689 else
690 ;
691 }
692 pkt_cnt = mt7530_mdio_r32(eth, (base) + (i * 0x100));
693 seq_printf(seq, "%8u ", pkt_cnt);
694 }
695 seq_puts(seq, "\n");
696}
697
developerfd40db22021-04-29 10:08:25 +0800698int esw_cnt_read(struct seq_file *seq, void *v)
699{
700 unsigned int pkt_cnt = 0;
701 int i = 0;
702 struct mtk_eth *eth = g_eth;
developerfd40db22021-04-29 10:08:25 +0800703
developer089e8852022-09-28 14:43:46 +0800704 gdm_cnt_read(eth);
developerfd40db22021-04-29 10:08:25 +0800705
706 if (!mt7530_exist(eth))
707 return 0;
708
developer089e8852022-09-28 14:43:46 +0800709 mt798x_iomap();
710
developerfd40db22021-04-29 10:08:25 +0800711 seq_printf(seq, "===================== %8s %8s %8s %8s %8s %8s %8s\n",
712 "Port0", "Port1", "Port2", "Port3", "Port4", "Port5",
713 "Port6");
714 seq_puts(seq, "Tx Drop Packet :");
developer9ccff342022-10-13 18:28:54 +0800715 dump_each_port(seq, eth, 0x4000);
developerfd40db22021-04-29 10:08:25 +0800716 seq_puts(seq, "Tx CRC Error :");
developer9ccff342022-10-13 18:28:54 +0800717 dump_each_port(seq, eth, 0x4004);
developerfd40db22021-04-29 10:08:25 +0800718 seq_puts(seq, "Tx Unicast Packet :");
developer9ccff342022-10-13 18:28:54 +0800719 dump_each_port(seq, eth, 0x4008);
developerfd40db22021-04-29 10:08:25 +0800720 seq_puts(seq, "Tx Multicast Packet :");
developer9ccff342022-10-13 18:28:54 +0800721 dump_each_port(seq, eth, 0x400C);
developerfd40db22021-04-29 10:08:25 +0800722 seq_puts(seq, "Tx Broadcast Packet :");
developer9ccff342022-10-13 18:28:54 +0800723 dump_each_port(seq, eth, 0x4010);
developerfd40db22021-04-29 10:08:25 +0800724 seq_puts(seq, "Tx Collision Event :");
developer9ccff342022-10-13 18:28:54 +0800725 dump_each_port(seq, eth, 0x4014);
developerfd40db22021-04-29 10:08:25 +0800726 seq_puts(seq, "Tx Pause Packet :");
developer9ccff342022-10-13 18:28:54 +0800727 dump_each_port(seq, eth, 0x402C);
developerfd40db22021-04-29 10:08:25 +0800728 seq_puts(seq, "Rx Drop Packet :");
developer9ccff342022-10-13 18:28:54 +0800729 dump_each_port(seq, eth, 0x4060);
developerfd40db22021-04-29 10:08:25 +0800730 seq_puts(seq, "Rx Filtering Packet :");
developer9ccff342022-10-13 18:28:54 +0800731 dump_each_port(seq, eth, 0x4064);
developerfd40db22021-04-29 10:08:25 +0800732 seq_puts(seq, "Rx Unicast Packet :");
developer9ccff342022-10-13 18:28:54 +0800733 dump_each_port(seq, eth, 0x4068);
developerfd40db22021-04-29 10:08:25 +0800734 seq_puts(seq, "Rx Multicast Packet :");
developer9ccff342022-10-13 18:28:54 +0800735 dump_each_port(seq, eth, 0x406C);
developerfd40db22021-04-29 10:08:25 +0800736 seq_puts(seq, "Rx Broadcast Packet :");
developer9ccff342022-10-13 18:28:54 +0800737 dump_each_port(seq, eth, 0x4070);
developerfd40db22021-04-29 10:08:25 +0800738 seq_puts(seq, "Rx Alignment Error :");
developer9ccff342022-10-13 18:28:54 +0800739 dump_each_port(seq, eth, 0x4074);
developerfd40db22021-04-29 10:08:25 +0800740 seq_puts(seq, "Rx CRC Error :");
developer9ccff342022-10-13 18:28:54 +0800741 dump_each_port(seq, eth, 0x4078);
developerfd40db22021-04-29 10:08:25 +0800742 seq_puts(seq, "Rx Undersize Error :");
developer9ccff342022-10-13 18:28:54 +0800743 dump_each_port(seq, eth, 0x407C);
developerfd40db22021-04-29 10:08:25 +0800744 seq_puts(seq, "Rx Fragment Error :");
developer9ccff342022-10-13 18:28:54 +0800745 dump_each_port(seq, eth, 0x4080);
developerfd40db22021-04-29 10:08:25 +0800746 seq_puts(seq, "Rx Oversize Error :");
developer9ccff342022-10-13 18:28:54 +0800747 dump_each_port(seq, eth, 0x4084);
developerfd40db22021-04-29 10:08:25 +0800748 seq_puts(seq, "Rx Jabber Error :");
developer9ccff342022-10-13 18:28:54 +0800749 dump_each_port(seq, eth, 0x4088);
developerfd40db22021-04-29 10:08:25 +0800750 seq_puts(seq, "Rx Pause Packet :");
developer9ccff342022-10-13 18:28:54 +0800751 dump_each_port(seq, eth, 0x408C);
developerfd40db22021-04-29 10:08:25 +0800752 mt7530_mdio_w32(eth, 0x4fe0, 0xf0);
753 mt7530_mdio_w32(eth, 0x4fe0, 0x800000f0);
754
755 seq_puts(seq, "\n");
756
developer089e8852022-09-28 14:43:46 +0800757 mt798x_iounmap();
758
developerfd40db22021-04-29 10:08:25 +0800759 return 0;
760}
761
762static int switch_count_open(struct inode *inode, struct file *file)
763{
764 return single_open(file, esw_cnt_read, 0);
765}
766
767static const struct file_operations switch_count_fops = {
768 .owner = THIS_MODULE,
769 .open = switch_count_open,
770 .read = seq_read,
771 .llseek = seq_lseek,
772 .release = single_release
773};
774
developer621ca6b2023-01-11 11:08:46 +0800775void xfi_mib_dump(struct seq_file *seq, u32 gdm_id)
776{
777 struct mtk_eth *eth = g_eth;
778
779 PRINT_FORMATTED_XFI_MIB(seq, TX_PKT_CNT, GENMASK(31, 0));
780 PRINT_FORMATTED_XFI_MIB(seq, TX_ETH_CNT, GENMASK(31, 0));
781 PRINT_FORMATTED_XFI_MIB(seq, TX_PAUSE_CNT, GENMASK(15, 0));
782 PRINT_FORMATTED_XFI_MIB(seq, TX_BYTE_CNT, GENMASK(31, 0));
783 PRINT_FORMATTED_XFI_MIB64(seq, TX_UC_PKT_CNT);
784 PRINT_FORMATTED_XFI_MIB64(seq, TX_MC_PKT_CNT);
785 PRINT_FORMATTED_XFI_MIB64(seq, TX_BC_PKT_CNT);
786
787 PRINT_FORMATTED_XFI_MIB(seq, RX_PKT_CNT, GENMASK(31, 0));
788 PRINT_FORMATTED_XFI_MIB(seq, RX_ETH_CNT, GENMASK(31, 0));
789 PRINT_FORMATTED_XFI_MIB(seq, RX_PAUSE_CNT, GENMASK(15, 0));
790 PRINT_FORMATTED_XFI_MIB(seq, RX_LEN_ERR_CNT, GENMASK(15, 0));
791 PRINT_FORMATTED_XFI_MIB(seq, RX_CRC_ERR_CNT, GENMASK(15, 0));
792 PRINT_FORMATTED_XFI_MIB64(seq, RX_UC_PKT_CNT);
793 PRINT_FORMATTED_XFI_MIB64(seq, RX_MC_PKT_CNT);
794 PRINT_FORMATTED_XFI_MIB64(seq, RX_BC_PKT_CNT);
795 PRINT_FORMATTED_XFI_MIB(seq, RX_UC_DROP_CNT, GENMASK(31, 0));
796 PRINT_FORMATTED_XFI_MIB(seq, RX_BC_DROP_CNT, GENMASK(31, 0));
797 PRINT_FORMATTED_XFI_MIB(seq, RX_MC_DROP_CNT, GENMASK(31, 0));
798 PRINT_FORMATTED_XFI_MIB(seq, RX_ALL_DROP_CNT, GENMASK(31, 0));
799}
800
801int xfi_cnt_read(struct seq_file *seq, void *v)
802{
803 struct mtk_eth *eth = g_eth;
804 int i;
805
806 seq_puts(seq, "+------------------------------------+\n");
807 seq_puts(seq, "| <<XFI MAC>> |\n");
808
809 for (i = MTK_GMAC2_ID; i < MTK_GMAC_ID_MAX; i++) {
810 xfi_mib_dump(seq, i);
811 mtk_m32(eth, 0x1, 0x1, MTK_XFI_MIB_BASE(i) + MTK_XFI_CNT_CTRL);
812 seq_puts(seq, "| |\n");
813 }
814
815 seq_puts(seq, "+------------------------------------+\n");
816
817 return 0;
818}
819
820static int xfi_count_open(struct inode *inode, struct file *file)
821{
822 return single_open(file, xfi_cnt_read, 0);
823}
824
825static const struct file_operations xfi_count_fops = {
826 .owner = THIS_MODULE,
827 .open = xfi_count_open,
828 .read = seq_read,
829 .llseek = seq_lseek,
830 .release = single_release
831};
832
developer8051e042022-04-08 13:26:36 +0800833static struct proc_dir_entry *proc_tx_ring, *proc_hwtx_ring, *proc_rx_ring;
developerfd40db22021-04-29 10:08:25 +0800834
835int tx_ring_read(struct seq_file *seq, void *v)
836{
developere9356982022-07-04 09:03:20 +0800837 struct mtk_eth *eth = g_eth;
developerfd40db22021-04-29 10:08:25 +0800838 struct mtk_tx_ring *ring = &g_eth->tx_ring;
developere9356982022-07-04 09:03:20 +0800839 struct mtk_tx_dma_v2 *tx_ring;
developerfd40db22021-04-29 10:08:25 +0800840 int i = 0;
841
developerfd40db22021-04-29 10:08:25 +0800842 seq_printf(seq, "free count = %d\n", (int)atomic_read(&ring->free_count));
843 seq_printf(seq, "cpu next free: %d\n", (int)(ring->next_free - ring->dma));
844 seq_printf(seq, "cpu last free: %d\n", (int)(ring->last_free - ring->dma));
845 for (i = 0; i < MTK_DMA_SIZE; i++) {
developer8b6f2402022-11-28 13:42:34 +0800846 dma_addr_t tmp = ring->phys +
847 i * (dma_addr_t)eth->soc->txrx.txd_size;
developere9356982022-07-04 09:03:20 +0800848
849 tx_ring = ring->dma + i * eth->soc->txrx.txd_size;
developerfd40db22021-04-29 10:08:25 +0800850
851 seq_printf(seq, "%d (%pad): %08x %08x %08x %08x", i, &tmp,
developere9356982022-07-04 09:03:20 +0800852 tx_ring->txd1, tx_ring->txd2,
853 tx_ring->txd3, tx_ring->txd4);
854
developer089e8852022-09-28 14:43:46 +0800855 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
856 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developere9356982022-07-04 09:03:20 +0800857 seq_printf(seq, " %08x %08x %08x %08x",
858 tx_ring->txd5, tx_ring->txd6,
859 tx_ring->txd7, tx_ring->txd8);
860 }
861
developerfd40db22021-04-29 10:08:25 +0800862 seq_printf(seq, "\n");
863 }
864
developerfd40db22021-04-29 10:08:25 +0800865 return 0;
866}
867
868static int tx_ring_open(struct inode *inode, struct file *file)
869{
870 return single_open(file, tx_ring_read, NULL);
871}
872
873static const struct file_operations tx_ring_fops = {
874 .owner = THIS_MODULE,
875 .open = tx_ring_open,
876 .read = seq_read,
877 .llseek = seq_lseek,
878 .release = single_release
879};
880
developer8051e042022-04-08 13:26:36 +0800881int hwtx_ring_read(struct seq_file *seq, void *v)
882{
883 struct mtk_eth *eth = g_eth;
developere9356982022-07-04 09:03:20 +0800884 struct mtk_tx_dma_v2 *hwtx_ring;
developer8051e042022-04-08 13:26:36 +0800885 int i = 0;
886
developer8051e042022-04-08 13:26:36 +0800887 for (i = 0; i < MTK_DMA_SIZE; i++) {
developer8b6f2402022-11-28 13:42:34 +0800888 dma_addr_t addr = eth->phy_scratch_ring +
889 i * (dma_addr_t)eth->soc->txrx.txd_size;
developere9356982022-07-04 09:03:20 +0800890
891 hwtx_ring = eth->scratch_ring + i * eth->soc->txrx.txd_size;
developer8051e042022-04-08 13:26:36 +0800892
893 seq_printf(seq, "%d (%pad): %08x %08x %08x %08x", i, &addr,
developere9356982022-07-04 09:03:20 +0800894 hwtx_ring->txd1, hwtx_ring->txd2,
895 hwtx_ring->txd3, hwtx_ring->txd4);
896
developer089e8852022-09-28 14:43:46 +0800897 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
898 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developere9356982022-07-04 09:03:20 +0800899 seq_printf(seq, " %08x %08x %08x %08x",
900 hwtx_ring->txd5, hwtx_ring->txd6,
901 hwtx_ring->txd7, hwtx_ring->txd8);
902 }
903
developer8051e042022-04-08 13:26:36 +0800904 seq_printf(seq, "\n");
905 }
906
developer8051e042022-04-08 13:26:36 +0800907 return 0;
908}
909
910static int hwtx_ring_open(struct inode *inode, struct file *file)
911{
912 return single_open(file, hwtx_ring_read, NULL);
913}
914
915static const struct file_operations hwtx_ring_fops = {
916 .owner = THIS_MODULE,
917 .open = hwtx_ring_open,
918 .read = seq_read,
919 .llseek = seq_lseek,
920 .release = single_release
921};
922
developerfd40db22021-04-29 10:08:25 +0800923int rx_ring_read(struct seq_file *seq, void *v)
924{
developere9356982022-07-04 09:03:20 +0800925 struct mtk_eth *eth = g_eth;
developerfd40db22021-04-29 10:08:25 +0800926 struct mtk_rx_ring *ring = &g_eth->rx_ring[0];
developere9356982022-07-04 09:03:20 +0800927 struct mtk_rx_dma_v2 *rx_ring;
developerfd40db22021-04-29 10:08:25 +0800928 int i = 0;
929
developerfd40db22021-04-29 10:08:25 +0800930 seq_printf(seq, "next to read: %d\n",
931 NEXT_DESP_IDX(ring->calc_idx, MTK_DMA_SIZE));
932 for (i = 0; i < MTK_DMA_SIZE; i++) {
developere9356982022-07-04 09:03:20 +0800933 rx_ring = ring->dma + i * eth->soc->txrx.rxd_size;
934
developerfd40db22021-04-29 10:08:25 +0800935 seq_printf(seq, "%d: %08x %08x %08x %08x", i,
developere9356982022-07-04 09:03:20 +0800936 rx_ring->rxd1, rx_ring->rxd2,
937 rx_ring->rxd3, rx_ring->rxd4);
938
developer8ecd51b2023-03-13 11:28:28 +0800939 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
developere9356982022-07-04 09:03:20 +0800940 seq_printf(seq, " %08x %08x %08x %08x",
941 rx_ring->rxd5, rx_ring->rxd6,
942 rx_ring->rxd7, rx_ring->rxd8);
943 }
944
developerfd40db22021-04-29 10:08:25 +0800945 seq_printf(seq, "\n");
946 }
947
developerfd40db22021-04-29 10:08:25 +0800948 return 0;
949}
950
951static int rx_ring_open(struct inode *inode, struct file *file)
952{
953 return single_open(file, rx_ring_read, NULL);
954}
955
956static const struct file_operations rx_ring_fops = {
957 .owner = THIS_MODULE,
958 .open = rx_ring_open,
959 .read = seq_read,
960 .llseek = seq_lseek,
961 .release = single_release
962};
963
developer77f3fd42021-10-05 15:16:05 +0800964static inline u32 mtk_dbg_r32(u32 reg)
965{
966 void __iomem *virt_reg;
967 u32 val;
968
969 virt_reg = ioremap(reg, 32);
970 val = __raw_readl(virt_reg);
971 iounmap(virt_reg);
972
973 return val;
974}
975
developerfd40db22021-04-29 10:08:25 +0800976int dbg_regs_read(struct seq_file *seq, void *v)
977{
978 struct mtk_eth *eth = g_eth;
979
developer77f3fd42021-10-05 15:16:05 +0800980 seq_puts(seq, " <<DEBUG REG DUMP>>\n");
981
982 seq_printf(seq, "| FE_INT_STA : %08x |\n",
developer8051e042022-04-08 13:26:36 +0800983 mtk_r32(eth, MTK_FE_INT_STATUS));
developer089e8852022-09-28 14:43:46 +0800984 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
985 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
developer77f3fd42021-10-05 15:16:05 +0800986 seq_printf(seq, "| FE_INT_STA2 : %08x |\n",
developer8051e042022-04-08 13:26:36 +0800987 mtk_r32(eth, MTK_FE_INT_STATUS2));
developer77f3fd42021-10-05 15:16:05 +0800988
developerfd40db22021-04-29 10:08:25 +0800989 seq_printf(seq, "| PSE_FQFC_CFG : %08x |\n",
990 mtk_r32(eth, MTK_PSE_FQFC_CFG));
991 seq_printf(seq, "| PSE_IQ_STA1 : %08x |\n",
992 mtk_r32(eth, MTK_PSE_IQ_STA(0)));
993 seq_printf(seq, "| PSE_IQ_STA2 : %08x |\n",
994 mtk_r32(eth, MTK_PSE_IQ_STA(1)));
995
developer089e8852022-09-28 14:43:46 +0800996 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
997 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developerfd40db22021-04-29 10:08:25 +0800998 seq_printf(seq, "| PSE_IQ_STA3 : %08x |\n",
999 mtk_r32(eth, MTK_PSE_IQ_STA(2)));
1000 seq_printf(seq, "| PSE_IQ_STA4 : %08x |\n",
1001 mtk_r32(eth, MTK_PSE_IQ_STA(3)));
developer77f3fd42021-10-05 15:16:05 +08001002 seq_printf(seq, "| PSE_IQ_STA5 : %08x |\n",
1003 mtk_r32(eth, MTK_PSE_IQ_STA(4)));
developer089e8852022-09-28 14:43:46 +08001004 seq_printf(seq, "| PSE_IQ_STA6 : %08x |\n",
1005 mtk_r32(eth, MTK_PSE_IQ_STA(5)));
1006 seq_printf(seq, "| PSE_IQ_STA7 : %08x |\n",
1007 mtk_r32(eth, MTK_PSE_IQ_STA(6)));
1008 seq_printf(seq, "| PSE_IQ_STA8 : %08x |\n",
1009 mtk_r32(eth, MTK_PSE_IQ_STA(7)));
developerfd40db22021-04-29 10:08:25 +08001010 }
1011
1012 seq_printf(seq, "| PSE_OQ_STA1 : %08x |\n",
1013 mtk_r32(eth, MTK_PSE_OQ_STA(0)));
1014 seq_printf(seq, "| PSE_OQ_STA2 : %08x |\n",
1015 mtk_r32(eth, MTK_PSE_OQ_STA(1)));
1016
developer089e8852022-09-28 14:43:46 +08001017 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
1018 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developerfd40db22021-04-29 10:08:25 +08001019 seq_printf(seq, "| PSE_OQ_STA3 : %08x |\n",
1020 mtk_r32(eth, MTK_PSE_OQ_STA(2)));
1021 seq_printf(seq, "| PSE_OQ_STA4 : %08x |\n",
1022 mtk_r32(eth, MTK_PSE_OQ_STA(3)));
developer77f3fd42021-10-05 15:16:05 +08001023 seq_printf(seq, "| PSE_OQ_STA5 : %08x |\n",
1024 mtk_r32(eth, MTK_PSE_OQ_STA(4)));
developer089e8852022-09-28 14:43:46 +08001025 seq_printf(seq, "| PSE_OQ_STA6 : %08x |\n",
1026 mtk_r32(eth, MTK_PSE_OQ_STA(5)));
1027 seq_printf(seq, "| PSE_OQ_STA7 : %08x |\n",
1028 mtk_r32(eth, MTK_PSE_OQ_STA(6)));
1029 seq_printf(seq, "| PSE_OQ_STA8 : %08x |\n",
1030 mtk_r32(eth, MTK_PSE_OQ_STA(7)));
developerfd40db22021-04-29 10:08:25 +08001031 }
1032
developer77f3fd42021-10-05 15:16:05 +08001033 seq_printf(seq, "| PDMA_CRX_IDX : %08x |\n",
1034 mtk_r32(eth, MTK_PRX_CRX_IDX0));
1035 seq_printf(seq, "| PDMA_DRX_IDX : %08x |\n",
1036 mtk_r32(eth, MTK_PRX_DRX_IDX0));
1037 seq_printf(seq, "| QDMA_CTX_IDX : %08x |\n",
1038 mtk_r32(eth, MTK_QTX_CTX_PTR));
1039 seq_printf(seq, "| QDMA_DTX_IDX : %08x |\n",
1040 mtk_r32(eth, MTK_QTX_DTX_PTR));
developerfd40db22021-04-29 10:08:25 +08001041 seq_printf(seq, "| QDMA_FQ_CNT : %08x |\n",
1042 mtk_r32(eth, MTK_QDMA_FQ_CNT));
developer089e8852022-09-28 14:43:46 +08001043 seq_printf(seq, "| QDMA_FWD_CNT : %08x |\n",
1044 mtk_r32(eth, MTK_QDMA_FWD_CNT));
1045 seq_printf(seq, "| QDMA_FSM : %08x |\n",
1046 mtk_r32(eth, MTK_QDMA_FSM));
developerfd40db22021-04-29 10:08:25 +08001047 seq_printf(seq, "| FE_PSE_FREE : %08x |\n",
1048 mtk_r32(eth, MTK_FE_PSE_FREE));
1049 seq_printf(seq, "| FE_DROP_FQ : %08x |\n",
1050 mtk_r32(eth, MTK_FE_DROP_FQ));
1051 seq_printf(seq, "| FE_DROP_FC : %08x |\n",
1052 mtk_r32(eth, MTK_FE_DROP_FC));
1053 seq_printf(seq, "| FE_DROP_PPE : %08x |\n",
1054 mtk_r32(eth, MTK_FE_DROP_PPE));
1055 seq_printf(seq, "| GDM1_IG_CTRL : %08x |\n",
1056 mtk_r32(eth, MTK_GDMA_FWD_CFG(0)));
1057 seq_printf(seq, "| GDM2_IG_CTRL : %08x |\n",
1058 mtk_r32(eth, MTK_GDMA_FWD_CFG(1)));
developer089e8852022-09-28 14:43:46 +08001059 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
1060 seq_printf(seq, "| GDM3_IG_CTRL : %08x |\n",
1061 mtk_r32(eth, MTK_GDMA_FWD_CFG(2)));
1062 }
developerfd40db22021-04-29 10:08:25 +08001063 seq_printf(seq, "| MAC_P1_MCR : %08x |\n",
1064 mtk_r32(eth, MTK_MAC_MCR(0)));
1065 seq_printf(seq, "| MAC_P2_MCR : %08x |\n",
1066 mtk_r32(eth, MTK_MAC_MCR(1)));
developer089e8852022-09-28 14:43:46 +08001067 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
1068 seq_printf(seq, "| MAC_P3_MCR : %08x |\n",
1069 mtk_r32(eth, MTK_MAC_MCR(2)));
1070 }
developer77f3fd42021-10-05 15:16:05 +08001071 seq_printf(seq, "| MAC_P1_FSM : %08x |\n",
1072 mtk_r32(eth, MTK_MAC_FSM(0)));
1073 seq_printf(seq, "| MAC_P2_FSM : %08x |\n",
1074 mtk_r32(eth, MTK_MAC_FSM(1)));
developer089e8852022-09-28 14:43:46 +08001075 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
1076 seq_printf(seq, "| MAC_P3_FSM : %08x |\n",
1077 mtk_r32(eth, MTK_MAC_FSM(2)));
1078 }
developerfd40db22021-04-29 10:08:25 +08001079
developer089e8852022-09-28 14:43:46 +08001080 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
1081 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
developerfd40db22021-04-29 10:08:25 +08001082 seq_printf(seq, "| FE_CDM1_FSM : %08x |\n",
1083 mtk_r32(eth, MTK_FE_CDM1_FSM));
1084 seq_printf(seq, "| FE_CDM2_FSM : %08x |\n",
1085 mtk_r32(eth, MTK_FE_CDM2_FSM));
developer77f3fd42021-10-05 15:16:05 +08001086 seq_printf(seq, "| FE_CDM3_FSM : %08x |\n",
1087 mtk_r32(eth, MTK_FE_CDM3_FSM));
1088 seq_printf(seq, "| FE_CDM4_FSM : %08x |\n",
1089 mtk_r32(eth, MTK_FE_CDM4_FSM));
developer089e8852022-09-28 14:43:46 +08001090 seq_printf(seq, "| FE_CDM5_FSM : %08x |\n",
1091 mtk_r32(eth, MTK_FE_CDM5_FSM));
1092 seq_printf(seq, "| FE_CDM6_FSM : %08x |\n",
1093 mtk_r32(eth, MTK_FE_CDM6_FSM));
developerfd40db22021-04-29 10:08:25 +08001094 seq_printf(seq, "| FE_GDM1_FSM : %08x |\n",
1095 mtk_r32(eth, MTK_FE_GDM1_FSM));
1096 seq_printf(seq, "| FE_GDM2_FSM : %08x |\n",
1097 mtk_r32(eth, MTK_FE_GDM2_FSM));
developer77f3fd42021-10-05 15:16:05 +08001098 seq_printf(seq, "| SGMII_EFUSE : %08x |\n",
1099 mtk_dbg_r32(MTK_SGMII_EFUSE));
1100 seq_printf(seq, "| SGMII0_RX_CNT : %08x |\n",
1101 mtk_dbg_r32(MTK_SGMII_FALSE_CARRIER_CNT(0)));
1102 seq_printf(seq, "| SGMII1_RX_CNT : %08x |\n",
1103 mtk_dbg_r32(MTK_SGMII_FALSE_CARRIER_CNT(1)));
1104 seq_printf(seq, "| WED_RTQM_GLO : %08x |\n",
1105 mtk_dbg_r32(MTK_WED_RTQM_GLO_CFG));
developerfd40db22021-04-29 10:08:25 +08001106 }
1107
developer8051e042022-04-08 13:26:36 +08001108 mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS);
developer089e8852022-09-28 14:43:46 +08001109 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
1110 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
developer8051e042022-04-08 13:26:36 +08001111 mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS2);
developer77f3fd42021-10-05 15:16:05 +08001112
developerfd40db22021-04-29 10:08:25 +08001113 return 0;
1114}
1115
1116static int dbg_regs_open(struct inode *inode, struct file *file)
1117{
1118 return single_open(file, dbg_regs_read, 0);
1119}
1120
1121static const struct file_operations dbg_regs_fops = {
1122 .owner = THIS_MODULE,
1123 .open = dbg_regs_open,
1124 .read = seq_read,
1125 .llseek = seq_lseek,
developer77d03a72021-06-06 00:06:00 +08001126 .release = single_release
1127};
1128
developere3d0de22023-05-30 17:45:00 +08001129ssize_t rss_ctrl_write(struct file *file, const char __user *buffer,
1130 size_t count, loff_t *data)
1131{
1132 char buf[32];
1133 char *p_buf;
1134 char *p_token = NULL;
1135 char *p_delimiter = " \t";
1136 long num = 4;
1137 u32 len = count;
1138 int ret;
1139
1140 if (len >= sizeof(buf)) {
1141 pr_info("Input handling fail!\n");
1142 return -1;
1143 }
1144
1145 if (copy_from_user(buf, buffer, len))
1146 return -EFAULT;
1147
1148 buf[len] = '\0';
1149
1150 p_buf = buf;
1151 p_token = strsep(&p_buf, p_delimiter);
1152 if (!p_token)
1153 num = 4;
1154 else
1155 ret = kstrtol(p_token, 10, &num);
1156
1157 if (!mtk_rss_set_indr_tbl(g_eth, num))
1158 cur_rss_num = num;
1159
1160 return count;
1161}
1162
1163int rss_ctrl_read(struct seq_file *seq, void *v)
1164{
1165 pr_info("ADMA is using %d-RSS.\n", cur_rss_num);
1166 return 0;
1167}
1168
1169static int rss_ctrl_open(struct inode *inode, struct file *file)
1170{
1171 return single_open(file, rss_ctrl_read, 0);
1172}
1173
1174static const struct file_operations rss_ctrl_fops = {
1175 .owner = THIS_MODULE,
1176 .open = rss_ctrl_open,
1177 .read = seq_read,
1178 .llseek = seq_lseek,
1179 .write = rss_ctrl_write,
1180 .release = single_release
1181};
1182
developere9356982022-07-04 09:03:20 +08001183void hw_lro_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd)
developer77d03a72021-06-06 00:06:00 +08001184{
developere9356982022-07-04 09:03:20 +08001185 struct mtk_eth *eth = g_eth;
developer77d03a72021-06-06 00:06:00 +08001186 u32 idx, agg_cnt, agg_size;
1187
developer8ecd51b2023-03-13 11:28:28 +08001188 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
developere9356982022-07-04 09:03:20 +08001189 idx = ring_no - 4;
1190 agg_cnt = RX_DMA_GET_AGG_CNT_V2(rxd->rxd6);
1191 } else {
1192 idx = ring_no - 1;
1193 agg_cnt = RX_DMA_GET_AGG_CNT(rxd->rxd2);
1194 }
developer77d03a72021-06-06 00:06:00 +08001195
developer8b6f2402022-11-28 13:42:34 +08001196 if (idx >= MTK_HW_LRO_RING_NUM)
1197 return;
1198
developer77d03a72021-06-06 00:06:00 +08001199 agg_size = RX_DMA_GET_PLEN0(rxd->rxd2);
1200
1201 hw_lro_agg_size_cnt[idx][agg_size / 5000]++;
1202 hw_lro_agg_num_cnt[idx][agg_cnt]++;
1203 hw_lro_tot_flush_cnt[idx]++;
1204 hw_lro_tot_agg_cnt[idx] += agg_cnt;
1205}
1206
developere9356982022-07-04 09:03:20 +08001207void hw_lro_flush_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd)
developer77d03a72021-06-06 00:06:00 +08001208{
developere9356982022-07-04 09:03:20 +08001209 struct mtk_eth *eth = g_eth;
developer77d03a72021-06-06 00:06:00 +08001210 u32 idx, flush_reason;
1211
developer8ecd51b2023-03-13 11:28:28 +08001212 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
developere9356982022-07-04 09:03:20 +08001213 idx = ring_no - 4;
1214 flush_reason = RX_DMA_GET_FLUSH_RSN_V2(rxd->rxd6);
1215 } else {
1216 idx = ring_no - 1;
1217 flush_reason = RX_DMA_GET_REV(rxd->rxd2);
1218 }
developer77d03a72021-06-06 00:06:00 +08001219
developer8b6f2402022-11-28 13:42:34 +08001220 if (idx >= MTK_HW_LRO_RING_NUM)
1221 return;
1222
developer77d03a72021-06-06 00:06:00 +08001223 if ((flush_reason & 0x7) == MTK_HW_LRO_AGG_FLUSH)
1224 hw_lro_agg_flush_cnt[idx]++;
1225 else if ((flush_reason & 0x7) == MTK_HW_LRO_AGE_FLUSH)
1226 hw_lro_age_flush_cnt[idx]++;
1227 else if ((flush_reason & 0x7) == MTK_HW_LRO_NOT_IN_SEQ_FLUSH)
1228 hw_lro_seq_flush_cnt[idx]++;
1229 else if ((flush_reason & 0x7) == MTK_HW_LRO_TIMESTAMP_FLUSH)
1230 hw_lro_timestamp_flush_cnt[idx]++;
1231 else if ((flush_reason & 0x7) == MTK_HW_LRO_NON_RULE_FLUSH)
1232 hw_lro_norule_flush_cnt[idx]++;
1233}
1234
1235ssize_t hw_lro_stats_write(struct file *file, const char __user *buffer,
1236 size_t count, loff_t *data)
1237{
1238 memset(hw_lro_agg_num_cnt, 0, sizeof(hw_lro_agg_num_cnt));
1239 memset(hw_lro_agg_size_cnt, 0, sizeof(hw_lro_agg_size_cnt));
1240 memset(hw_lro_tot_agg_cnt, 0, sizeof(hw_lro_tot_agg_cnt));
1241 memset(hw_lro_tot_flush_cnt, 0, sizeof(hw_lro_tot_flush_cnt));
1242 memset(hw_lro_agg_flush_cnt, 0, sizeof(hw_lro_agg_flush_cnt));
1243 memset(hw_lro_age_flush_cnt, 0, sizeof(hw_lro_age_flush_cnt));
1244 memset(hw_lro_seq_flush_cnt, 0, sizeof(hw_lro_seq_flush_cnt));
1245 memset(hw_lro_timestamp_flush_cnt, 0,
1246 sizeof(hw_lro_timestamp_flush_cnt));
1247 memset(hw_lro_norule_flush_cnt, 0, sizeof(hw_lro_norule_flush_cnt));
1248
1249 pr_info("clear hw lro cnt table\n");
1250
1251 return count;
1252}
1253
1254int hw_lro_stats_read_v1(struct seq_file *seq, void *v)
1255{
1256 int i;
1257
1258 seq_puts(seq, "HW LRO statistic dump:\n");
1259
1260 /* Agg number count */
1261 seq_puts(seq, "Cnt: RING1 | RING2 | RING3 | Total\n");
1262 for (i = 0; i <= MTK_HW_LRO_MAX_AGG_CNT; i++) {
1263 seq_printf(seq, " %d : %d %d %d %d\n",
1264 i, hw_lro_agg_num_cnt[0][i],
1265 hw_lro_agg_num_cnt[1][i], hw_lro_agg_num_cnt[2][i],
1266 hw_lro_agg_num_cnt[0][i] + hw_lro_agg_num_cnt[1][i] +
1267 hw_lro_agg_num_cnt[2][i]);
1268 }
1269
1270 /* Total agg count */
1271 seq_puts(seq, "Total agg: RING1 | RING2 | RING3 | Total\n");
1272 seq_printf(seq, " %d %d %d %d\n",
1273 hw_lro_tot_agg_cnt[0], hw_lro_tot_agg_cnt[1],
1274 hw_lro_tot_agg_cnt[2],
1275 hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] +
1276 hw_lro_tot_agg_cnt[2]);
1277
1278 /* Total flush count */
1279 seq_puts(seq, "Total flush: RING1 | RING2 | RING3 | Total\n");
1280 seq_printf(seq, " %d %d %d %d\n",
1281 hw_lro_tot_flush_cnt[0], hw_lro_tot_flush_cnt[1],
1282 hw_lro_tot_flush_cnt[2],
1283 hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] +
1284 hw_lro_tot_flush_cnt[2]);
1285
1286 /* Avg agg count */
1287 seq_puts(seq, "Avg agg: RING1 | RING2 | RING3 | Total\n");
1288 seq_printf(seq, " %d %d %d %d\n",
1289 (hw_lro_tot_flush_cnt[0]) ?
1290 hw_lro_tot_agg_cnt[0] / hw_lro_tot_flush_cnt[0] : 0,
1291 (hw_lro_tot_flush_cnt[1]) ?
1292 hw_lro_tot_agg_cnt[1] / hw_lro_tot_flush_cnt[1] : 0,
1293 (hw_lro_tot_flush_cnt[2]) ?
1294 hw_lro_tot_agg_cnt[2] / hw_lro_tot_flush_cnt[2] : 0,
1295 (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] +
1296 hw_lro_tot_flush_cnt[2]) ?
1297 ((hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] +
1298 hw_lro_tot_agg_cnt[2]) / (hw_lro_tot_flush_cnt[0] +
1299 hw_lro_tot_flush_cnt[1] + hw_lro_tot_flush_cnt[2])) : 0);
1300
1301 /* Statistics of aggregation size counts */
1302 seq_puts(seq, "HW LRO flush pkt len:\n");
1303 seq_puts(seq, " Length | RING1 | RING2 | RING3 | Total\n");
1304 for (i = 0; i < 15; i++) {
1305 seq_printf(seq, "%d~%d: %d %d %d %d\n", i * 5000,
1306 (i + 1) * 5000, hw_lro_agg_size_cnt[0][i],
1307 hw_lro_agg_size_cnt[1][i], hw_lro_agg_size_cnt[2][i],
1308 hw_lro_agg_size_cnt[0][i] +
1309 hw_lro_agg_size_cnt[1][i] +
1310 hw_lro_agg_size_cnt[2][i]);
1311 }
1312
1313 seq_puts(seq, "Flush reason: RING1 | RING2 | RING3 | Total\n");
1314 seq_printf(seq, "AGG timeout: %d %d %d %d\n",
1315 hw_lro_agg_flush_cnt[0], hw_lro_agg_flush_cnt[1],
1316 hw_lro_agg_flush_cnt[2],
1317 (hw_lro_agg_flush_cnt[0] + hw_lro_agg_flush_cnt[1] +
1318 hw_lro_agg_flush_cnt[2]));
1319
1320 seq_printf(seq, "AGE timeout: %d %d %d %d\n",
1321 hw_lro_age_flush_cnt[0], hw_lro_age_flush_cnt[1],
1322 hw_lro_age_flush_cnt[2],
1323 (hw_lro_age_flush_cnt[0] + hw_lro_age_flush_cnt[1] +
1324 hw_lro_age_flush_cnt[2]));
1325
1326 seq_printf(seq, "Not in-sequence: %d %d %d %d\n",
1327 hw_lro_seq_flush_cnt[0], hw_lro_seq_flush_cnt[1],
1328 hw_lro_seq_flush_cnt[2],
1329 (hw_lro_seq_flush_cnt[0] + hw_lro_seq_flush_cnt[1] +
1330 hw_lro_seq_flush_cnt[2]));
1331
1332 seq_printf(seq, "Timestamp: %d %d %d %d\n",
1333 hw_lro_timestamp_flush_cnt[0],
1334 hw_lro_timestamp_flush_cnt[1],
1335 hw_lro_timestamp_flush_cnt[2],
1336 (hw_lro_timestamp_flush_cnt[0] +
1337 hw_lro_timestamp_flush_cnt[1] +
1338 hw_lro_timestamp_flush_cnt[2]));
1339
1340 seq_printf(seq, "No LRO rule: %d %d %d %d\n",
1341 hw_lro_norule_flush_cnt[0],
1342 hw_lro_norule_flush_cnt[1],
1343 hw_lro_norule_flush_cnt[2],
1344 (hw_lro_norule_flush_cnt[0] +
1345 hw_lro_norule_flush_cnt[1] +
1346 hw_lro_norule_flush_cnt[2]));
1347
1348 return 0;
1349}
1350
1351int hw_lro_stats_read_v2(struct seq_file *seq, void *v)
1352{
1353 int i;
1354
1355 seq_puts(seq, "HW LRO statistic dump:\n");
1356
1357 /* Agg number count */
1358 seq_puts(seq, "Cnt: RING4 | RING5 | RING6 | RING7 Total\n");
1359 for (i = 0; i <= MTK_HW_LRO_MAX_AGG_CNT; i++) {
1360 seq_printf(seq,
1361 " %d : %d %d %d %d %d\n",
1362 i, hw_lro_agg_num_cnt[0][i], hw_lro_agg_num_cnt[1][i],
1363 hw_lro_agg_num_cnt[2][i], hw_lro_agg_num_cnt[3][i],
1364 hw_lro_agg_num_cnt[0][i] + hw_lro_agg_num_cnt[1][i] +
1365 hw_lro_agg_num_cnt[2][i] + hw_lro_agg_num_cnt[3][i]);
1366 }
1367
1368 /* Total agg count */
1369 seq_puts(seq, "Total agg: RING4 | RING5 | RING6 | RING7 Total\n");
1370 seq_printf(seq, " %d %d %d %d %d\n",
1371 hw_lro_tot_agg_cnt[0], hw_lro_tot_agg_cnt[1],
1372 hw_lro_tot_agg_cnt[2], hw_lro_tot_agg_cnt[3],
1373 hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] +
1374 hw_lro_tot_agg_cnt[2] + hw_lro_tot_agg_cnt[3]);
1375
1376 /* Total flush count */
1377 seq_puts(seq, "Total flush: RING4 | RING5 | RING6 | RING7 Total\n");
1378 seq_printf(seq, " %d %d %d %d %d\n",
1379 hw_lro_tot_flush_cnt[0], hw_lro_tot_flush_cnt[1],
1380 hw_lro_tot_flush_cnt[2], hw_lro_tot_flush_cnt[3],
1381 hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] +
1382 hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3]);
1383
1384 /* Avg agg count */
1385 seq_puts(seq, "Avg agg: RING4 | RING5 | RING6 | RING7 Total\n");
1386 seq_printf(seq, " %d %d %d %d %d\n",
1387 (hw_lro_tot_flush_cnt[0]) ?
1388 hw_lro_tot_agg_cnt[0] / hw_lro_tot_flush_cnt[0] : 0,
1389 (hw_lro_tot_flush_cnt[1]) ?
1390 hw_lro_tot_agg_cnt[1] / hw_lro_tot_flush_cnt[1] : 0,
1391 (hw_lro_tot_flush_cnt[2]) ?
1392 hw_lro_tot_agg_cnt[2] / hw_lro_tot_flush_cnt[2] : 0,
1393 (hw_lro_tot_flush_cnt[3]) ?
1394 hw_lro_tot_agg_cnt[3] / hw_lro_tot_flush_cnt[3] : 0,
1395 (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] +
1396 hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3]) ?
1397 ((hw_lro_tot_agg_cnt[0] + hw_lro_tot_agg_cnt[1] +
1398 hw_lro_tot_agg_cnt[2] + hw_lro_tot_agg_cnt[3]) /
1399 (hw_lro_tot_flush_cnt[0] + hw_lro_tot_flush_cnt[1] +
1400 hw_lro_tot_flush_cnt[2] + hw_lro_tot_flush_cnt[3])) : 0);
1401
1402 /* Statistics of aggregation size counts */
1403 seq_puts(seq, "HW LRO flush pkt len:\n");
1404 seq_puts(seq, " Length | RING4 | RING5 | RING6 | RING7 Total\n");
1405 for (i = 0; i < 15; i++) {
1406 seq_printf(seq, "%d~%d: %d %d %d %d %d\n",
1407 i * 5000, (i + 1) * 5000,
1408 hw_lro_agg_size_cnt[0][i], hw_lro_agg_size_cnt[1][i],
1409 hw_lro_agg_size_cnt[2][i], hw_lro_agg_size_cnt[3][i],
1410 hw_lro_agg_size_cnt[0][i] +
1411 hw_lro_agg_size_cnt[1][i] +
1412 hw_lro_agg_size_cnt[2][i] +
1413 hw_lro_agg_size_cnt[3][i]);
1414 }
1415
1416 seq_puts(seq, "Flush reason: RING4 | RING5 | RING6 | RING7 Total\n");
1417 seq_printf(seq, "AGG timeout: %d %d %d %d %d\n",
1418 hw_lro_agg_flush_cnt[0], hw_lro_agg_flush_cnt[1],
1419 hw_lro_agg_flush_cnt[2], hw_lro_agg_flush_cnt[3],
1420 (hw_lro_agg_flush_cnt[0] + hw_lro_agg_flush_cnt[1] +
1421 hw_lro_agg_flush_cnt[2] + hw_lro_agg_flush_cnt[3]));
1422
1423 seq_printf(seq, "AGE timeout: %d %d %d %d %d\n",
1424 hw_lro_age_flush_cnt[0], hw_lro_age_flush_cnt[1],
1425 hw_lro_age_flush_cnt[2], hw_lro_age_flush_cnt[3],
1426 (hw_lro_age_flush_cnt[0] + hw_lro_age_flush_cnt[1] +
1427 hw_lro_age_flush_cnt[2] + hw_lro_age_flush_cnt[3]));
1428
1429 seq_printf(seq, "Not in-sequence: %d %d %d %d %d\n",
1430 hw_lro_seq_flush_cnt[0], hw_lro_seq_flush_cnt[1],
1431 hw_lro_seq_flush_cnt[2], hw_lro_seq_flush_cnt[3],
1432 (hw_lro_seq_flush_cnt[0] + hw_lro_seq_flush_cnt[1] +
1433 hw_lro_seq_flush_cnt[2] + hw_lro_seq_flush_cnt[3]));
1434
1435 seq_printf(seq, "Timestamp: %d %d %d %d %d\n",
1436 hw_lro_timestamp_flush_cnt[0],
1437 hw_lro_timestamp_flush_cnt[1],
1438 hw_lro_timestamp_flush_cnt[2],
1439 hw_lro_timestamp_flush_cnt[3],
1440 (hw_lro_timestamp_flush_cnt[0] +
1441 hw_lro_timestamp_flush_cnt[1] +
1442 hw_lro_timestamp_flush_cnt[2] +
1443 hw_lro_timestamp_flush_cnt[3]));
1444
1445 seq_printf(seq, "No LRO rule: %d %d %d %d %d\n",
1446 hw_lro_norule_flush_cnt[0],
1447 hw_lro_norule_flush_cnt[1],
1448 hw_lro_norule_flush_cnt[2],
1449 hw_lro_norule_flush_cnt[3],
1450 (hw_lro_norule_flush_cnt[0] +
1451 hw_lro_norule_flush_cnt[1] +
1452 hw_lro_norule_flush_cnt[2] +
1453 hw_lro_norule_flush_cnt[3]));
1454
1455 return 0;
1456}
1457
1458int hw_lro_stats_read_wrapper(struct seq_file *seq, void *v)
1459{
1460 struct mtk_eth *eth = g_eth;
1461
developer8ecd51b2023-03-13 11:28:28 +08001462 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2))
developer77d03a72021-06-06 00:06:00 +08001463 hw_lro_stats_read_v2(seq, v);
1464 else
1465 hw_lro_stats_read_v1(seq, v);
1466
1467 return 0;
1468}
1469
1470static int hw_lro_stats_open(struct inode *inode, struct file *file)
1471{
1472 return single_open(file, hw_lro_stats_read_wrapper, NULL);
1473}
1474
1475static const struct file_operations hw_lro_stats_fops = {
1476 .owner = THIS_MODULE,
1477 .open = hw_lro_stats_open,
1478 .read = seq_read,
1479 .llseek = seq_lseek,
1480 .write = hw_lro_stats_write,
developerfd40db22021-04-29 10:08:25 +08001481 .release = single_release
1482};
1483
developer77d03a72021-06-06 00:06:00 +08001484int hwlro_agg_cnt_ctrl(int cnt)
1485{
1486 int i;
1487
1488 for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
1489 SET_PDMA_RXRING_MAX_AGG_CNT(g_eth, i, cnt);
1490
1491 return 0;
1492}
1493
1494int hwlro_agg_time_ctrl(int time)
1495{
1496 int i;
1497
1498 for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
1499 SET_PDMA_RXRING_AGG_TIME(g_eth, i, time);
1500
1501 return 0;
1502}
1503
1504int hwlro_age_time_ctrl(int time)
1505{
1506 int i;
1507
1508 for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
1509 SET_PDMA_RXRING_AGE_TIME(g_eth, i, time);
1510
1511 return 0;
1512}
1513
1514int hwlro_threshold_ctrl(int bandwidth)
1515{
1516 SET_PDMA_LRO_BW_THRESHOLD(g_eth, bandwidth);
1517
1518 return 0;
1519}
1520
1521int hwlro_ring_enable_ctrl(int enable)
1522{
1523 int i;
1524
1525 pr_info("[%s] %s HW LRO rings\n", __func__, (enable) ? "Enable" : "Disable");
1526
1527 for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++)
1528 SET_PDMA_RXRING_VALID(g_eth, i, enable);
1529
1530 return 0;
1531}
1532
1533int hwlro_stats_enable_ctrl(int enable)
1534{
1535 pr_info("[%s] %s HW LRO statistics\n", __func__, (enable) ? "Enable" : "Disable");
1536 mtk_hwlro_stats_ebl = enable;
1537
1538 return 0;
1539}
1540
1541static const mtk_lro_dbg_func lro_dbg_func[] = {
1542 [0] = hwlro_agg_cnt_ctrl,
1543 [1] = hwlro_agg_time_ctrl,
1544 [2] = hwlro_age_time_ctrl,
1545 [3] = hwlro_threshold_ctrl,
1546 [4] = hwlro_ring_enable_ctrl,
1547 [5] = hwlro_stats_enable_ctrl,
1548};
1549
1550ssize_t hw_lro_auto_tlb_write(struct file *file, const char __user *buffer,
1551 size_t count, loff_t *data)
1552{
1553 char buf[32];
1554 char *p_buf;
1555 char *p_token = NULL;
1556 char *p_delimiter = " \t";
1557 long x = 0, y = 0;
developer4c32b7a2021-11-13 16:46:43 +08001558 u32 len = count;
developer77d03a72021-06-06 00:06:00 +08001559 int ret;
1560
1561 if (len >= sizeof(buf)) {
1562 pr_info("Input handling fail!\n");
developer77d03a72021-06-06 00:06:00 +08001563 return -1;
1564 }
1565
1566 if (copy_from_user(buf, buffer, len))
1567 return -EFAULT;
1568
1569 buf[len] = '\0';
1570
1571 p_buf = buf;
1572 p_token = strsep(&p_buf, p_delimiter);
1573 if (!p_token)
1574 x = 0;
1575 else
1576 ret = kstrtol(p_token, 10, &x);
1577
1578 p_token = strsep(&p_buf, "\t\n ");
1579 if (p_token)
1580 ret = kstrtol(p_token, 10, &y);
1581
1582 if (lro_dbg_func[x] && (ARRAY_SIZE(lro_dbg_func) > x))
1583 (*lro_dbg_func[x]) (y);
1584
1585 return count;
1586}
1587
1588void hw_lro_auto_tlb_dump_v1(struct seq_file *seq, u32 index)
1589{
1590 int i;
1591 struct mtk_lro_alt_v1 alt;
1592 __be32 addr;
1593 u32 tlb_info[9];
1594 u32 dw_len, cnt, priority;
1595 u32 entry;
1596
1597 if (index > 4)
1598 index = index - 1;
1599 entry = (index * 9) + 1;
1600
1601 /* read valid entries of the auto-learn table */
1602 mtk_w32(g_eth, entry, MTK_FE_ALT_CF8);
1603
1604 for (i = 0; i < 9; i++)
1605 tlb_info[i] = mtk_r32(g_eth, MTK_FE_ALT_SEQ_CFC);
1606
1607 memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v1));
1608
1609 dw_len = alt.alt_info7.dw_len;
1610 cnt = alt.alt_info6.cnt;
1611
1612 if (mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE)
1613 priority = cnt; /* packet count */
1614 else
1615 priority = dw_len; /* byte count */
1616
1617 /* dump valid entries of the auto-learn table */
1618 if (index >= 4)
1619 seq_printf(seq, "\n===== TABLE Entry: %d (Act) =====\n", index);
1620 else
1621 seq_printf(seq, "\n===== TABLE Entry: %d (LRU) =====\n", index);
1622
1623 if (alt.alt_info8.ipv4) {
1624 addr = htonl(alt.alt_info1.sip0);
1625 seq_printf(seq, "SIP = %pI4 (IPv4)\n", &addr);
1626 } else {
1627 seq_printf(seq, "SIP = %08X:%08X:%08X:%08X (IPv6)\n",
1628 alt.alt_info4.sip3, alt.alt_info3.sip2,
1629 alt.alt_info2.sip1, alt.alt_info1.sip0);
1630 }
1631
1632 seq_printf(seq, "DIP_ID = %d\n", alt.alt_info8.dip_id);
1633 seq_printf(seq, "TCP SPORT = %d | TCP DPORT = %d\n",
1634 alt.alt_info0.stp, alt.alt_info0.dtp);
1635 seq_printf(seq, "VLAN_VID_VLD = %d\n", alt.alt_info6.vlan_vid_vld);
1636 seq_printf(seq, "VLAN1 = %d | VLAN2 = %d | VLAN3 = %d | VLAN4 =%d\n",
1637 (alt.alt_info5.vlan_vid0 & 0xfff),
1638 ((alt.alt_info5.vlan_vid0 >> 12) & 0xfff),
1639 ((alt.alt_info6.vlan_vid1 << 8) |
1640 ((alt.alt_info5.vlan_vid0 >> 24) & 0xfff)),
1641 ((alt.alt_info6.vlan_vid1 >> 4) & 0xfff));
1642 seq_printf(seq, "TPUT = %d | FREQ = %d\n", dw_len, cnt);
1643 seq_printf(seq, "PRIORITY = %d\n", priority);
1644}
1645
1646void hw_lro_auto_tlb_dump_v2(struct seq_file *seq, u32 index)
1647{
1648 int i;
1649 struct mtk_lro_alt_v2 alt;
1650 u32 score = 0, ipv4 = 0;
1651 u32 ipv6[4] = { 0 };
1652 u32 tlb_info[12];
1653
1654 /* read valid entries of the auto-learn table */
1655 mtk_w32(g_eth, index << MTK_LRO_ALT_INDEX_OFFSET, MTK_LRO_ALT_DBG);
1656
1657 for (i = 0; i < 11; i++)
1658 tlb_info[i] = mtk_r32(g_eth, MTK_LRO_ALT_DBG_DATA);
1659
1660 memcpy(&alt, tlb_info, sizeof(struct mtk_lro_alt_v2));
1661
1662 if (mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW0) & MTK_LRO_ALT_PKT_CNT_MODE)
1663 score = 1; /* packet count */
1664 else
1665 score = 0; /* byte count */
1666
1667 /* dump valid entries of the auto-learn table */
1668 if (alt.alt_info0.valid) {
1669 if (index < 5)
1670 seq_printf(seq,
1671 "\n===== TABLE Entry: %d (onging) =====\n",
1672 index);
1673 else
1674 seq_printf(seq,
1675 "\n===== TABLE Entry: %d (candidate) =====\n",
1676 index);
1677
1678 if (alt.alt_info1.v4_valid) {
1679 ipv4 = (alt.alt_info4.sip0_h << 23) |
1680 alt.alt_info5.sip0_l;
1681 seq_printf(seq, "SIP = 0x%x: (IPv4)\n", ipv4);
1682
1683 ipv4 = (alt.alt_info8.dip0_h << 23) |
1684 alt.alt_info9.dip0_l;
1685 seq_printf(seq, "DIP = 0x%x: (IPv4)\n", ipv4);
1686 } else if (alt.alt_info1.v6_valid) {
1687 ipv6[3] = (alt.alt_info1.sip3_h << 23) |
1688 (alt.alt_info2.sip3_l << 9);
1689 ipv6[2] = (alt.alt_info2.sip2_h << 23) |
1690 (alt.alt_info3.sip2_l << 9);
1691 ipv6[1] = (alt.alt_info3.sip1_h << 23) |
1692 (alt.alt_info4.sip1_l << 9);
1693 ipv6[0] = (alt.alt_info4.sip0_h << 23) |
1694 (alt.alt_info5.sip0_l << 9);
1695 seq_printf(seq, "SIP = 0x%x:0x%x:0x%x:0x%x (IPv6)\n",
1696 ipv6[3], ipv6[2], ipv6[1], ipv6[0]);
1697
1698 ipv6[3] = (alt.alt_info5.dip3_h << 23) |
1699 (alt.alt_info6.dip3_l << 9);
1700 ipv6[2] = (alt.alt_info6.dip2_h << 23) |
1701 (alt.alt_info7.dip2_l << 9);
1702 ipv6[1] = (alt.alt_info7.dip1_h << 23) |
1703 (alt.alt_info8.dip1_l << 9);
1704 ipv6[0] = (alt.alt_info8.dip0_h << 23) |
1705 (alt.alt_info9.dip0_l << 9);
1706 seq_printf(seq, "DIP = 0x%x:0x%x:0x%x:0x%x (IPv6)\n",
1707 ipv6[3], ipv6[2], ipv6[1], ipv6[0]);
1708 }
1709
1710 seq_printf(seq, "TCP SPORT = %d | TCP DPORT = %d\n",
1711 (alt.alt_info9.sp_h << 7) | (alt.alt_info10.sp_l),
1712 alt.alt_info10.dp);
1713 }
1714}
1715
1716int hw_lro_auto_tlb_read(struct seq_file *seq, void *v)
1717{
1718 int i;
1719 u32 reg_val;
1720 u32 reg_op1, reg_op2, reg_op3, reg_op4;
1721 u32 agg_cnt, agg_time, age_time;
1722
1723 seq_puts(seq, "Usage of /proc/mtketh/hw_lro_auto_tlb:\n");
1724 seq_puts(seq, "echo [function] [setting] > /proc/mtketh/hw_lro_auto_tlb\n");
1725 seq_puts(seq, "Functions:\n");
1726 seq_puts(seq, "[0] = hwlro_agg_cnt_ctrl\n");
1727 seq_puts(seq, "[1] = hwlro_agg_time_ctrl\n");
1728 seq_puts(seq, "[2] = hwlro_age_time_ctrl\n");
1729 seq_puts(seq, "[3] = hwlro_threshold_ctrl\n");
1730 seq_puts(seq, "[4] = hwlro_ring_enable_ctrl\n");
1731 seq_puts(seq, "[5] = hwlro_stats_enable_ctrl\n\n");
1732
developer8ecd51b2023-03-13 11:28:28 +08001733 if (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_RX_V2)) {
developer77d03a72021-06-06 00:06:00 +08001734 for (i = 1; i <= 8; i++)
1735 hw_lro_auto_tlb_dump_v2(seq, i);
1736 } else {
1737 /* Read valid entries of the auto-learn table */
1738 mtk_w32(g_eth, 0, MTK_FE_ALT_CF8);
1739 reg_val = mtk_r32(g_eth, MTK_FE_ALT_SEQ_CFC);
1740
1741 seq_printf(seq,
1742 "HW LRO Auto-learn Table: (MTK_FE_ALT_SEQ_CFC=0x%x)\n",
1743 reg_val);
1744
1745 for (i = 7; i >= 0; i--) {
1746 if (reg_val & (1 << i))
1747 hw_lro_auto_tlb_dump_v1(seq, i);
1748 }
1749 }
1750
1751 /* Read the agg_time/age_time/agg_cnt of LRO rings */
1752 seq_puts(seq, "\nHW LRO Ring Settings\n");
1753
1754 for (i = 1; i <= MTK_HW_LRO_RING_NUM; i++) {
1755 reg_op1 = mtk_r32(g_eth, MTK_LRO_CTRL_DW1_CFG(i));
1756 reg_op2 = mtk_r32(g_eth, MTK_LRO_CTRL_DW2_CFG(i));
1757 reg_op3 = mtk_r32(g_eth, MTK_LRO_CTRL_DW3_CFG(i));
1758 reg_op4 = mtk_r32(g_eth, MTK_PDMA_LRO_CTRL_DW2);
1759
1760 agg_cnt =
1761 ((reg_op3 & 0x3) << 6) |
1762 ((reg_op2 >> MTK_LRO_RING_AGG_CNT_L_OFFSET) & 0x3f);
1763 agg_time = (reg_op2 >> MTK_LRO_RING_AGG_TIME_OFFSET) & 0xffff;
1764 age_time =
1765 ((reg_op2 & 0x3f) << 10) |
1766 ((reg_op1 >> MTK_LRO_RING_AGE_TIME_L_OFFSET) & 0x3ff);
1767 seq_printf(seq,
1768 "Ring[%d]: MAX_AGG_CNT=%d, AGG_TIME=%d, AGE_TIME=%d, Threshold=%d\n",
developer8ecd51b2023-03-13 11:28:28 +08001769 (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_RX_V2)) ?
1770 i : i+3,
developer77d03a72021-06-06 00:06:00 +08001771 agg_cnt, agg_time, age_time, reg_op4);
1772 }
1773
1774 seq_puts(seq, "\n");
1775
1776 return 0;
1777}
1778
1779static int hw_lro_auto_tlb_open(struct inode *inode, struct file *file)
1780{
1781 return single_open(file, hw_lro_auto_tlb_read, NULL);
1782}
1783
1784static const struct file_operations hw_lro_auto_tlb_fops = {
1785 .owner = THIS_MODULE,
1786 .open = hw_lro_auto_tlb_open,
1787 .read = seq_read,
1788 .llseek = seq_lseek,
1789 .write = hw_lro_auto_tlb_write,
1790 .release = single_release
1791};
developerfd40db22021-04-29 10:08:25 +08001792
developer8051e042022-04-08 13:26:36 +08001793int reset_event_read(struct seq_file *seq, void *v)
1794{
1795 struct mtk_eth *eth = g_eth;
1796 struct mtk_reset_event reset_event = eth->reset_event;
1797
1798 seq_printf(seq, "[Event] [Count]\n");
1799 seq_printf(seq, " FQ Empty: %d\n",
1800 reset_event.count[MTK_EVENT_FQ_EMPTY]);
1801 seq_printf(seq, " TSO Fail: %d\n",
1802 reset_event.count[MTK_EVENT_TSO_FAIL]);
1803 seq_printf(seq, " TSO Illegal: %d\n",
1804 reset_event.count[MTK_EVENT_TSO_ILLEGAL]);
1805 seq_printf(seq, " TSO Align: %d\n",
1806 reset_event.count[MTK_EVENT_TSO_ALIGN]);
1807 seq_printf(seq, " RFIFO OV: %d\n",
1808 reset_event.count[MTK_EVENT_RFIFO_OV]);
1809 seq_printf(seq, " RFIFO UF: %d\n",
1810 reset_event.count[MTK_EVENT_RFIFO_UF]);
1811 seq_printf(seq, " Force: %d\n",
1812 reset_event.count[MTK_EVENT_FORCE]);
1813 seq_printf(seq, "----------------------------\n");
1814 seq_printf(seq, " Warm Cnt: %d\n",
1815 reset_event.count[MTK_EVENT_WARM_CNT]);
1816 seq_printf(seq, " Cold Cnt: %d\n",
1817 reset_event.count[MTK_EVENT_COLD_CNT]);
1818 seq_printf(seq, " Total Cnt: %d\n",
1819 reset_event.count[MTK_EVENT_TOTAL_CNT]);
1820
1821 return 0;
1822}
1823
1824static int reset_event_open(struct inode *inode, struct file *file)
1825{
1826 return single_open(file, reset_event_read, 0);
1827}
1828
1829ssize_t reset_event_write(struct file *file, const char __user *buffer,
1830 size_t count, loff_t *data)
1831{
1832 struct mtk_eth *eth = g_eth;
1833 struct mtk_reset_event *reset_event = &eth->reset_event;
1834
1835 memset(reset_event, 0, sizeof(struct mtk_reset_event));
1836 pr_info("MTK reset event counter is cleared !\n");
1837
1838 return count;
1839}
1840
1841static const struct file_operations reset_event_fops = {
1842 .owner = THIS_MODULE,
1843 .open = reset_event_open,
1844 .read = seq_read,
1845 .llseek = seq_lseek,
1846 .write = reset_event_write,
1847 .release = single_release
1848};
1849
1850
developerfd40db22021-04-29 10:08:25 +08001851struct proc_dir_entry *proc_reg_dir;
developer621ca6b2023-01-11 11:08:46 +08001852static struct proc_dir_entry *proc_esw_cnt, *proc_xfi_cnt,
1853 *proc_dbg_regs, *proc_reset_event;
developerfd40db22021-04-29 10:08:25 +08001854
1855int debug_proc_init(struct mtk_eth *eth)
1856{
1857 g_eth = eth;
1858
1859 if (!proc_reg_dir)
1860 proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL);
1861
1862 proc_tx_ring =
1863 proc_create(PROCREG_TXRING, 0, proc_reg_dir, &tx_ring_fops);
1864 if (!proc_tx_ring)
1865 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_TXRING);
1866
developer8051e042022-04-08 13:26:36 +08001867 proc_hwtx_ring =
1868 proc_create(PROCREG_HWTXRING, 0, proc_reg_dir, &hwtx_ring_fops);
1869 if (!proc_hwtx_ring)
1870 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_HWTXRING);
1871
developerfd40db22021-04-29 10:08:25 +08001872 proc_rx_ring =
1873 proc_create(PROCREG_RXRING, 0, proc_reg_dir, &rx_ring_fops);
1874 if (!proc_rx_ring)
1875 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_RXRING);
1876
1877 proc_esw_cnt =
1878 proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops);
1879 if (!proc_esw_cnt)
1880 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT);
1881
developer621ca6b2023-01-11 11:08:46 +08001882 if (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V3)) {
1883 proc_xfi_cnt =
1884 proc_create(PROCREG_XFI_CNT, 0,
1885 proc_reg_dir, &xfi_count_fops);
1886 if (!proc_xfi_cnt)
1887 pr_notice("!! FAIL to create %s PROC !!\n",
1888 PROCREG_XFI_CNT);
1889 }
1890
developerfd40db22021-04-29 10:08:25 +08001891 proc_dbg_regs =
1892 proc_create(PROCREG_DBG_REGS, 0, proc_reg_dir, &dbg_regs_fops);
1893 if (!proc_dbg_regs)
1894 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_DBG_REGS);
1895
developere3d0de22023-05-30 17:45:00 +08001896 if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
1897 proc_rss_ctrl =
1898 proc_create(PROCREG_RSS_CTRL, 0, proc_reg_dir,
1899 &rss_ctrl_fops);
1900 if (!proc_rss_ctrl)
1901 pr_info("!! FAIL to create %s PROC !!\n",
1902 PROCREG_RSS_CTRL);
1903
1904 cur_rss_num = g_eth->soc->rss_num;
1905 }
1906
developer77d03a72021-06-06 00:06:00 +08001907 if (g_eth->hwlro) {
1908 proc_hw_lro_stats =
1909 proc_create(PROCREG_HW_LRO_STATS, 0, proc_reg_dir,
1910 &hw_lro_stats_fops);
1911 if (!proc_hw_lro_stats)
1912 pr_info("!! FAIL to create %s PROC !!\n", PROCREG_HW_LRO_STATS);
1913
1914 proc_hw_lro_auto_tlb =
1915 proc_create(PROCREG_HW_LRO_AUTO_TLB, 0, proc_reg_dir,
1916 &hw_lro_auto_tlb_fops);
1917 if (!proc_hw_lro_auto_tlb)
1918 pr_info("!! FAIL to create %s PROC !!\n",
1919 PROCREG_HW_LRO_AUTO_TLB);
1920 }
1921
developer8051e042022-04-08 13:26:36 +08001922 proc_reset_event =
1923 proc_create(PROCREG_RESET_EVENT, 0, proc_reg_dir, &reset_event_fops);
1924 if (!proc_reset_event)
1925 pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_RESET_EVENT);
developer7979ddb2023-04-24 17:19:21 +08001926 dbg_show_level = 1;
developerfd40db22021-04-29 10:08:25 +08001927 return 0;
1928}
1929
1930void debug_proc_exit(void)
1931{
1932 if (proc_tx_ring)
1933 remove_proc_entry(PROCREG_TXRING, proc_reg_dir);
developer8051e042022-04-08 13:26:36 +08001934 if (proc_hwtx_ring)
1935 remove_proc_entry(PROCREG_HWTXRING, proc_reg_dir);
developerfd40db22021-04-29 10:08:25 +08001936 if (proc_rx_ring)
1937 remove_proc_entry(PROCREG_RXRING, proc_reg_dir);
1938
1939 if (proc_esw_cnt)
1940 remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir);
1941
developer621ca6b2023-01-11 11:08:46 +08001942 if (proc_xfi_cnt)
1943 remove_proc_entry(PROCREG_XFI_CNT, proc_reg_dir);
1944
developerfd40db22021-04-29 10:08:25 +08001945 if (proc_reg_dir)
1946 remove_proc_entry(PROCREG_DIR, 0);
1947
1948 if (proc_dbg_regs)
1949 remove_proc_entry(PROCREG_DBG_REGS, proc_reg_dir);
developer77d03a72021-06-06 00:06:00 +08001950
developere3d0de22023-05-30 17:45:00 +08001951 if (proc_rss_ctrl)
1952 remove_proc_entry(PROCREG_RSS_CTRL, proc_reg_dir);
1953
developer77d03a72021-06-06 00:06:00 +08001954 if (g_eth->hwlro) {
1955 if (proc_hw_lro_stats)
1956 remove_proc_entry(PROCREG_HW_LRO_STATS, proc_reg_dir);
1957
1958 if (proc_hw_lro_auto_tlb)
1959 remove_proc_entry(PROCREG_HW_LRO_AUTO_TLB, proc_reg_dir);
1960 }
developer8051e042022-04-08 13:26:36 +08001961
1962 if (proc_reset_event)
1963 remove_proc_entry(PROCREG_RESET_EVENT, proc_reg_dir);
developerfd40db22021-04-29 10:08:25 +08001964}
1965