1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
3
4 #include <linux/pci.h>
5
6 #include "core.h"
7
8 static struct dentry *pdsc_dir;
9
pdsc_debugfs_create(void)10 void pdsc_debugfs_create(void)
11 {
12 pdsc_dir = debugfs_create_dir(PDS_CORE_DRV_NAME, NULL);
13 }
14
pdsc_debugfs_destroy(void)15 void pdsc_debugfs_destroy(void)
16 {
17 debugfs_remove_recursive(pdsc_dir);
18 }
19
pdsc_debugfs_add_dev(struct pdsc * pdsc)20 void pdsc_debugfs_add_dev(struct pdsc *pdsc)
21 {
22 pdsc->dentry = debugfs_create_dir(pci_name(pdsc->pdev), pdsc_dir);
23
24 debugfs_create_ulong("state", 0400, pdsc->dentry, &pdsc->state);
25 }
26
pdsc_debugfs_del_dev(struct pdsc * pdsc)27 void pdsc_debugfs_del_dev(struct pdsc *pdsc)
28 {
29 debugfs_remove_recursive(pdsc->dentry);
30 pdsc->dentry = NULL;
31 }
32
identity_show(struct seq_file * seq,void * v)33 static int identity_show(struct seq_file *seq, void *v)
34 {
35 struct pds_core_dev_identity *ident;
36 struct pdsc *pdsc = seq->private;
37 int vt;
38
39 ident = &pdsc->dev_ident;
40
41 seq_printf(seq, "fw_heartbeat: 0x%x\n",
42 ioread32(&pdsc->info_regs->fw_heartbeat));
43
44 seq_printf(seq, "nlifs: %d\n",
45 le32_to_cpu(ident->nlifs));
46 seq_printf(seq, "nintrs: %d\n",
47 le32_to_cpu(ident->nintrs));
48 seq_printf(seq, "ndbpgs_per_lif: %d\n",
49 le32_to_cpu(ident->ndbpgs_per_lif));
50 seq_printf(seq, "intr_coal_mult: %d\n",
51 le32_to_cpu(ident->intr_coal_mult));
52 seq_printf(seq, "intr_coal_div: %d\n",
53 le32_to_cpu(ident->intr_coal_div));
54
55 seq_puts(seq, "vif_types: ");
56 for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++)
57 seq_printf(seq, "%d ",
58 le16_to_cpu(pdsc->dev_ident.vif_types[vt]));
59 seq_puts(seq, "\n");
60
61 return 0;
62 }
63 DEFINE_SHOW_ATTRIBUTE(identity);
64
pdsc_debugfs_add_ident(struct pdsc * pdsc)65 void pdsc_debugfs_add_ident(struct pdsc *pdsc)
66 {
67 /* This file will already exist in the reset flow */
68 if (debugfs_lookup("identity", pdsc->dentry))
69 return;
70
71 debugfs_create_file("identity", 0400, pdsc->dentry,
72 pdsc, &identity_fops);
73 }
74
viftype_show(struct seq_file * seq,void * v)75 static int viftype_show(struct seq_file *seq, void *v)
76 {
77 struct pdsc *pdsc = seq->private;
78 int vt;
79
80 for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++) {
81 if (!pdsc->viftype_status[vt].name)
82 continue;
83
84 seq_printf(seq, "%s\t%d supported %d enabled\n",
85 pdsc->viftype_status[vt].name,
86 pdsc->viftype_status[vt].supported,
87 pdsc->viftype_status[vt].enabled);
88 }
89 return 0;
90 }
91 DEFINE_SHOW_ATTRIBUTE(viftype);
92
pdsc_debugfs_add_viftype(struct pdsc * pdsc)93 void pdsc_debugfs_add_viftype(struct pdsc *pdsc)
94 {
95 debugfs_create_file("viftypes", 0400, pdsc->dentry,
96 pdsc, &viftype_fops);
97 }
98
99 static const struct debugfs_reg32 intr_ctrl_regs[] = {
100 { .name = "coal_init", .offset = 0, },
101 { .name = "mask", .offset = 4, },
102 { .name = "credits", .offset = 8, },
103 { .name = "mask_on_assert", .offset = 12, },
104 { .name = "coal_timer", .offset = 16, },
105 };
106
pdsc_debugfs_add_qcq(struct pdsc * pdsc,struct pdsc_qcq * qcq)107 void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq)
108 {
109 struct dentry *qcq_dentry, *q_dentry, *cq_dentry, *intr_dentry;
110 struct debugfs_regset32 *intr_ctrl_regset;
111 struct pdsc_queue *q = &qcq->q;
112 struct pdsc_cq *cq = &qcq->cq;
113
114 qcq_dentry = debugfs_create_dir(q->name, pdsc->dentry);
115 if (IS_ERR(qcq_dentry))
116 return;
117 qcq->dentry = qcq_dentry;
118
119 debugfs_create_x64("q_base_pa", 0400, qcq_dentry, &qcq->q_base_pa);
120 debugfs_create_x32("q_size", 0400, qcq_dentry, &qcq->q_size);
121 debugfs_create_x64("cq_base_pa", 0400, qcq_dentry, &qcq->cq_base_pa);
122 debugfs_create_x32("cq_size", 0400, qcq_dentry, &qcq->cq_size);
123 debugfs_create_x32("accum_work", 0400, qcq_dentry, &qcq->accum_work);
124
125 q_dentry = debugfs_create_dir("q", qcq->dentry);
126 if (IS_ERR(q_dentry))
127 return;
128
129 debugfs_create_u32("index", 0400, q_dentry, &q->index);
130 debugfs_create_u32("num_descs", 0400, q_dentry, &q->num_descs);
131 debugfs_create_u32("desc_size", 0400, q_dentry, &q->desc_size);
132 debugfs_create_u32("pid", 0400, q_dentry, &q->pid);
133
134 debugfs_create_u16("tail", 0400, q_dentry, &q->tail_idx);
135 debugfs_create_u16("head", 0400, q_dentry, &q->head_idx);
136
137 cq_dentry = debugfs_create_dir("cq", qcq->dentry);
138 if (IS_ERR(cq_dentry))
139 return;
140
141 debugfs_create_x64("base_pa", 0400, cq_dentry, &cq->base_pa);
142 debugfs_create_u32("num_descs", 0400, cq_dentry, &cq->num_descs);
143 debugfs_create_u32("desc_size", 0400, cq_dentry, &cq->desc_size);
144 debugfs_create_bool("done_color", 0400, cq_dentry, &cq->done_color);
145 debugfs_create_u16("tail", 0400, cq_dentry, &cq->tail_idx);
146
147 if (qcq->flags & PDS_CORE_QCQ_F_INTR) {
148 struct pdsc_intr_info *intr = &pdsc->intr_info[qcq->intx];
149
150 intr_dentry = debugfs_create_dir("intr", qcq->dentry);
151 if (IS_ERR(intr_dentry))
152 return;
153
154 debugfs_create_u32("index", 0400, intr_dentry, &intr->index);
155 debugfs_create_u32("vector", 0400, intr_dentry, &intr->vector);
156
157 intr_ctrl_regset = kzalloc(sizeof(*intr_ctrl_regset),
158 GFP_KERNEL);
159 if (!intr_ctrl_regset)
160 return;
161 intr_ctrl_regset->regs = intr_ctrl_regs;
162 intr_ctrl_regset->nregs = ARRAY_SIZE(intr_ctrl_regs);
163 intr_ctrl_regset->base = &pdsc->intr_ctrl[intr->index];
164
165 debugfs_create_regset32("intr_ctrl", 0400, intr_dentry,
166 intr_ctrl_regset);
167 }
168 };
169
pdsc_debugfs_del_qcq(struct pdsc_qcq * qcq)170 void pdsc_debugfs_del_qcq(struct pdsc_qcq *qcq)
171 {
172 debugfs_remove_recursive(qcq->dentry);
173 qcq->dentry = NULL;
174 }
175