1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
5 #include <linux/netdevice.h>
10 #include "ionic_debugfs.h"
12 #ifdef CONFIG_DEBUG_FS
14 static struct dentry
*ionic_dir
;
16 void ionic_debugfs_create(void)
18 ionic_dir
= debugfs_create_dir(IONIC_DRV_NAME
, NULL
);
21 void ionic_debugfs_destroy(void)
23 debugfs_remove_recursive(ionic_dir
);
26 void ionic_debugfs_add_dev(struct ionic
*ionic
)
28 ionic
->dentry
= debugfs_create_dir(ionic_bus_info(ionic
), ionic_dir
);
31 void ionic_debugfs_del_dev(struct ionic
*ionic
)
33 debugfs_remove_recursive(ionic
->dentry
);
37 static int identity_show(struct seq_file
*seq
, void *v
)
39 struct ionic
*ionic
= seq
->private;
40 struct ionic_identity
*ident
;
42 ident
= &ionic
->ident
;
44 seq_printf(seq
, "nlifs: %d\n", ident
->dev
.nlifs
);
45 seq_printf(seq
, "nintrs: %d\n", ident
->dev
.nintrs
);
46 seq_printf(seq
, "ndbpgs_per_lif: %d\n", ident
->dev
.ndbpgs_per_lif
);
47 seq_printf(seq
, "intr_coal_mult: %d\n", ident
->dev
.intr_coal_mult
);
48 seq_printf(seq
, "intr_coal_div: %d\n", ident
->dev
.intr_coal_div
);
50 seq_printf(seq
, "max_ucast_filters: %d\n", ident
->lif
.eth
.max_ucast_filters
);
51 seq_printf(seq
, "max_mcast_filters: %d\n", ident
->lif
.eth
.max_mcast_filters
);
55 DEFINE_SHOW_ATTRIBUTE(identity
);
57 void ionic_debugfs_add_ident(struct ionic
*ionic
)
59 debugfs_create_file("identity", 0400, ionic
->dentry
,
60 ionic
, &identity_fops
);
63 void ionic_debugfs_add_sizes(struct ionic
*ionic
)
65 debugfs_create_u32("nlifs", 0400, ionic
->dentry
,
66 (u32
*)&ionic
->ident
.dev
.nlifs
);
67 debugfs_create_u32("nintrs", 0400, ionic
->dentry
, &ionic
->nintrs
);
69 debugfs_create_u32("ntxqs_per_lif", 0400, ionic
->dentry
,
70 (u32
*)&ionic
->ident
.lif
.eth
.config
.queue_count
[IONIC_QTYPE_TXQ
]);
71 debugfs_create_u32("nrxqs_per_lif", 0400, ionic
->dentry
,
72 (u32
*)&ionic
->ident
.lif
.eth
.config
.queue_count
[IONIC_QTYPE_RXQ
]);
75 static int q_tail_show(struct seq_file
*seq
, void *v
)
77 struct ionic_queue
*q
= seq
->private;
79 seq_printf(seq
, "%d\n", q
->tail
->index
);
83 DEFINE_SHOW_ATTRIBUTE(q_tail
);
85 static int q_head_show(struct seq_file
*seq
, void *v
)
87 struct ionic_queue
*q
= seq
->private;
89 seq_printf(seq
, "%d\n", q
->head
->index
);
93 DEFINE_SHOW_ATTRIBUTE(q_head
);
95 static int cq_tail_show(struct seq_file
*seq
, void *v
)
97 struct ionic_cq
*cq
= seq
->private;
99 seq_printf(seq
, "%d\n", cq
->tail
->index
);
103 DEFINE_SHOW_ATTRIBUTE(cq_tail
);
105 static const struct debugfs_reg32 intr_ctrl_regs
[] = {
106 { .name
= "coal_init", .offset
= 0, },
107 { .name
= "mask", .offset
= 4, },
108 { .name
= "credits", .offset
= 8, },
109 { .name
= "mask_on_assert", .offset
= 12, },
110 { .name
= "coal_timer", .offset
= 16, },
113 void ionic_debugfs_add_qcq(struct ionic_lif
*lif
, struct ionic_qcq
*qcq
)
115 struct dentry
*q_dentry
, *cq_dentry
, *intr_dentry
, *stats_dentry
;
116 struct ionic_dev
*idev
= &lif
->ionic
->idev
;
117 struct debugfs_regset32
*intr_ctrl_regset
;
118 struct ionic_intr_info
*intr
= &qcq
->intr
;
119 struct debugfs_blob_wrapper
*desc_blob
;
120 struct device
*dev
= lif
->ionic
->dev
;
121 struct ionic_queue
*q
= &qcq
->q
;
122 struct ionic_cq
*cq
= &qcq
->cq
;
124 qcq
->dentry
= debugfs_create_dir(q
->name
, lif
->dentry
);
126 debugfs_create_x32("total_size", 0400, qcq
->dentry
, &qcq
->total_size
);
127 debugfs_create_x64("base_pa", 0400, qcq
->dentry
, &qcq
->base_pa
);
129 q_dentry
= debugfs_create_dir("q", qcq
->dentry
);
131 debugfs_create_u32("index", 0400, q_dentry
, &q
->index
);
132 debugfs_create_x64("base_pa", 0400, q_dentry
, &q
->base_pa
);
133 if (qcq
->flags
& IONIC_QCQ_F_SG
) {
134 debugfs_create_x64("sg_base_pa", 0400, q_dentry
,
136 debugfs_create_u32("sg_desc_size", 0400, q_dentry
,
139 debugfs_create_u32("num_descs", 0400, q_dentry
, &q
->num_descs
);
140 debugfs_create_u32("desc_size", 0400, q_dentry
, &q
->desc_size
);
141 debugfs_create_u32("pid", 0400, q_dentry
, &q
->pid
);
142 debugfs_create_u32("qid", 0400, q_dentry
, &q
->hw_index
);
143 debugfs_create_u32("qtype", 0400, q_dentry
, &q
->hw_type
);
144 debugfs_create_u64("drop", 0400, q_dentry
, &q
->drop
);
145 debugfs_create_u64("stop", 0400, q_dentry
, &q
->stop
);
146 debugfs_create_u64("wake", 0400, q_dentry
, &q
->wake
);
148 debugfs_create_file("tail", 0400, q_dentry
, q
, &q_tail_fops
);
149 debugfs_create_file("head", 0400, q_dentry
, q
, &q_head_fops
);
151 desc_blob
= devm_kzalloc(dev
, sizeof(*desc_blob
), GFP_KERNEL
);
154 desc_blob
->data
= q
->base
;
155 desc_blob
->size
= (unsigned long)q
->num_descs
* q
->desc_size
;
156 debugfs_create_blob("desc_blob", 0400, q_dentry
, desc_blob
);
158 if (qcq
->flags
& IONIC_QCQ_F_SG
) {
159 desc_blob
= devm_kzalloc(dev
, sizeof(*desc_blob
), GFP_KERNEL
);
162 desc_blob
->data
= q
->sg_base
;
163 desc_blob
->size
= (unsigned long)q
->num_descs
* q
->sg_desc_size
;
164 debugfs_create_blob("sg_desc_blob", 0400, q_dentry
,
168 cq_dentry
= debugfs_create_dir("cq", qcq
->dentry
);
170 debugfs_create_x64("base_pa", 0400, cq_dentry
, &cq
->base_pa
);
171 debugfs_create_u32("num_descs", 0400, cq_dentry
, &cq
->num_descs
);
172 debugfs_create_u32("desc_size", 0400, cq_dentry
, &cq
->desc_size
);
173 debugfs_create_u8("done_color", 0400, cq_dentry
,
174 (u8
*)&cq
->done_color
);
176 debugfs_create_file("tail", 0400, cq_dentry
, cq
, &cq_tail_fops
);
178 desc_blob
= devm_kzalloc(dev
, sizeof(*desc_blob
), GFP_KERNEL
);
181 desc_blob
->data
= cq
->base
;
182 desc_blob
->size
= (unsigned long)cq
->num_descs
* cq
->desc_size
;
183 debugfs_create_blob("desc_blob", 0400, cq_dentry
, desc_blob
);
185 if (qcq
->flags
& IONIC_QCQ_F_INTR
) {
186 intr_dentry
= debugfs_create_dir("intr", qcq
->dentry
);
188 debugfs_create_u32("index", 0400, intr_dentry
,
190 debugfs_create_u32("vector", 0400, intr_dentry
,
193 intr_ctrl_regset
= devm_kzalloc(dev
, sizeof(*intr_ctrl_regset
),
195 if (!intr_ctrl_regset
)
197 intr_ctrl_regset
->regs
= intr_ctrl_regs
;
198 intr_ctrl_regset
->nregs
= ARRAY_SIZE(intr_ctrl_regs
);
199 intr_ctrl_regset
->base
= &idev
->intr_ctrl
[intr
->index
];
201 debugfs_create_regset32("intr_ctrl", 0400, intr_dentry
,
205 if (qcq
->flags
& IONIC_QCQ_F_NOTIFYQ
) {
206 stats_dentry
= debugfs_create_dir("notifyblock", qcq
->dentry
);
208 debugfs_create_u64("eid", 0400, stats_dentry
,
209 (u64
*)&lif
->info
->status
.eid
);
210 debugfs_create_u16("link_status", 0400, stats_dentry
,
211 (u16
*)&lif
->info
->status
.link_status
);
212 debugfs_create_u32("link_speed", 0400, stats_dentry
,
213 (u32
*)&lif
->info
->status
.link_speed
);
214 debugfs_create_u16("link_down_count", 0400, stats_dentry
,
215 (u16
*)&lif
->info
->status
.link_down_count
);
219 static int netdev_show(struct seq_file
*seq
, void *v
)
221 struct net_device
*netdev
= seq
->private;
223 seq_printf(seq
, "%s\n", netdev
->name
);
227 DEFINE_SHOW_ATTRIBUTE(netdev
);
229 void ionic_debugfs_add_lif(struct ionic_lif
*lif
)
231 struct dentry
*lif_dentry
;
233 lif_dentry
= debugfs_create_dir(lif
->name
, lif
->ionic
->dentry
);
234 if (IS_ERR_OR_NULL(lif_dentry
))
236 lif
->dentry
= lif_dentry
;
238 debugfs_create_file("netdev", 0400, lif
->dentry
,
239 lif
->netdev
, &netdev_fops
);
242 void ionic_debugfs_del_lif(struct ionic_lif
*lif
)
244 debugfs_remove_recursive(lif
->dentry
);
248 void ionic_debugfs_del_qcq(struct ionic_qcq
*qcq
)
250 debugfs_remove_recursive(qcq
->dentry
);