1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2015 Freescale Semiconductor Inc.
3 * Copyright 2018-2019 NXP
5 #include <linux/module.h>
6 #include <linux/debugfs.h>
8 #include "dpaa2-eth-debugfs.h"
10 #define DPAA2_ETH_DBG_ROOT "dpaa2-eth"
12 static struct dentry
*dpaa2_dbg_root
;
14 static int dpaa2_dbg_cpu_show(struct seq_file
*file
, void *offset
)
16 struct dpaa2_eth_priv
*priv
= (struct dpaa2_eth_priv
*)file
->private;
17 struct rtnl_link_stats64
*stats
;
18 struct dpaa2_eth_drv_stats
*extras
;
21 seq_printf(file
, "Per-CPU stats for %s\n", priv
->net_dev
->name
);
22 seq_printf(file
, "%s%16s%16s%16s%16s%16s%16s%16s%16s%16s\n",
23 "CPU", "Rx", "Rx Err", "Rx SG", "Tx", "Tx Err", "Tx conf",
24 "Tx SG", "Tx converted to SG", "Enq busy");
26 for_each_online_cpu(i
) {
27 stats
= per_cpu_ptr(priv
->percpu_stats
, i
);
28 extras
= per_cpu_ptr(priv
->percpu_extras
, i
);
29 seq_printf(file
, "%3d%16llu%16llu%16llu%16llu%16llu%16llu%16llu%16llu%16llu\n",
36 extras
->tx_conf_frames
,
38 extras
->tx_converted_sg_frames
,
39 extras
->tx_portal_busy
);
45 DEFINE_SHOW_ATTRIBUTE(dpaa2_dbg_cpu
);
47 static char *fq_type_to_str(struct dpaa2_eth_fq
*fq
)
52 case DPAA2_TX_CONF_FQ
:
59 static int dpaa2_dbg_fqs_show(struct seq_file
*file
, void *offset
)
61 struct dpaa2_eth_priv
*priv
= (struct dpaa2_eth_priv
*)file
->private;
62 struct dpaa2_eth_fq
*fq
;
66 seq_printf(file
, "FQ stats for %s:\n", priv
->net_dev
->name
);
67 seq_printf(file
, "%s%16s%16s%16s%16s%16s\n",
68 "VFQID", "CPU", "TC", "Type", "Frames", "Pending frames");
70 for (i
= 0; i
< priv
->num_fqs
; i
++) {
72 err
= dpaa2_io_query_fq_count(NULL
, fq
->fqid
, &fcnt
, &bcnt
);
76 /* Skip FQs with no traffic */
77 if (!fq
->stats
.frames
&& !fcnt
)
80 seq_printf(file
, "%5d%16d%16d%16s%16llu%16u\n",
92 DEFINE_SHOW_ATTRIBUTE(dpaa2_dbg_fqs
);
94 static int dpaa2_dbg_ch_show(struct seq_file
*file
, void *offset
)
96 struct dpaa2_eth_priv
*priv
= (struct dpaa2_eth_priv
*)file
->private;
97 struct dpaa2_eth_channel
*ch
;
100 seq_printf(file
, "Channel stats for %s:\n", priv
->net_dev
->name
);
101 seq_printf(file
, "%s%16s%16s%16s%16s%16s%16s\n",
102 "CHID", "CPU", "Deq busy", "Frames", "CDANs",
103 "Avg Frm/CDAN", "Buf count");
105 for (i
= 0; i
< priv
->num_channels
; i
++) {
106 ch
= priv
->channel
[i
];
107 seq_printf(file
, "%4d%16d%16llu%16llu%16llu%16llu%16d\n",
109 ch
->nctx
.desired_cpu
,
110 ch
->stats
.dequeue_portal_busy
,
113 div64_u64(ch
->stats
.frames
, ch
->stats
.cdan
),
120 DEFINE_SHOW_ATTRIBUTE(dpaa2_dbg_ch
);
122 void dpaa2_dbg_add(struct dpaa2_eth_priv
*priv
)
126 /* Create a directory for the interface */
127 dir
= debugfs_create_dir(priv
->net_dev
->name
, dpaa2_dbg_root
);
130 /* per-cpu stats file */
131 debugfs_create_file("cpu_stats", 0444, dir
, priv
, &dpaa2_dbg_cpu_fops
);
133 /* per-fq stats file */
134 debugfs_create_file("fq_stats", 0444, dir
, priv
, &dpaa2_dbg_fqs_fops
);
136 /* per-fq stats file */
137 debugfs_create_file("ch_stats", 0444, dir
, priv
, &dpaa2_dbg_ch_fops
);
140 void dpaa2_dbg_remove(struct dpaa2_eth_priv
*priv
)
142 debugfs_remove_recursive(priv
->dbg
.dir
);
145 void dpaa2_eth_dbg_init(void)
147 dpaa2_dbg_root
= debugfs_create_dir(DPAA2_ETH_DBG_ROOT
, NULL
);
148 pr_debug("DPAA2-ETH: debugfs created\n");
151 void dpaa2_eth_dbg_exit(void)
153 debugfs_remove(dpaa2_dbg_root
);