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 10 void pdsc_debugfs_create(void) 11 { 12 pdsc_dir = debugfs_create_dir(PDS_CORE_DRV_NAME, NULL); 13 } 14 15 void pdsc_debugfs_destroy(void) 16 { 17 debugfs_remove_recursive(pdsc_dir); 18 } 19 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 27 void pdsc_debugfs_del_dev(struct pdsc *pdsc) 28 { 29 debugfs_remove_recursive(pdsc->dentry); 30 pdsc->dentry = NULL; 31 } 32 33 static int identity_show(struct seq_file *seq, void *v) 34 { 35 struct pdsc *pdsc = seq->private; 36 struct pds_core_dev_identity *ident; 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 65 void pdsc_debugfs_add_ident(struct pdsc *pdsc) 66 { 67 debugfs_create_file("identity", 0400, pdsc->dentry, 68 pdsc, &identity_fops); 69 } 70 71 static int viftype_show(struct seq_file *seq, void *v) 72 { 73 struct pdsc *pdsc = seq->private; 74 int vt; 75 76 for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++) { 77 if (!pdsc->viftype_status[vt].name) 78 continue; 79 80 seq_printf(seq, "%s\t%d supported %d enabled\n", 81 pdsc->viftype_status[vt].name, 82 pdsc->viftype_status[vt].supported, 83 pdsc->viftype_status[vt].enabled); 84 } 85 return 0; 86 } 87 DEFINE_SHOW_ATTRIBUTE(viftype); 88 89 void pdsc_debugfs_add_viftype(struct pdsc *pdsc) 90 { 91 debugfs_create_file("viftypes", 0400, pdsc->dentry, 92 pdsc, &viftype_fops); 93 } 94 95 static const struct debugfs_reg32 intr_ctrl_regs[] = { 96 { .name = "coal_init", .offset = 0, }, 97 { .name = "mask", .offset = 4, }, 98 { .name = "credits", .offset = 8, }, 99 { .name = "mask_on_assert", .offset = 12, }, 100 { .name = "coal_timer", .offset = 16, }, 101 }; 102 103 void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq) 104 { 105 struct dentry *qcq_dentry, *q_dentry, *cq_dentry; 106 struct dentry *intr_dentry; 107 struct debugfs_regset32 *intr_ctrl_regset; 108 struct pdsc_intr_info *intr = &pdsc->intr_info[qcq->intx]; 109 struct pdsc_queue *q = &qcq->q; 110 struct pdsc_cq *cq = &qcq->cq; 111 112 qcq_dentry = debugfs_create_dir(q->name, pdsc->dentry); 113 if (IS_ERR_OR_NULL(qcq_dentry)) 114 return; 115 qcq->dentry = qcq_dentry; 116 117 debugfs_create_x64("q_base_pa", 0400, qcq_dentry, &qcq->q_base_pa); 118 debugfs_create_x32("q_size", 0400, qcq_dentry, &qcq->q_size); 119 debugfs_create_x64("cq_base_pa", 0400, qcq_dentry, &qcq->cq_base_pa); 120 debugfs_create_x32("cq_size", 0400, qcq_dentry, &qcq->cq_size); 121 debugfs_create_x32("accum_work", 0400, qcq_dentry, &qcq->accum_work); 122 123 q_dentry = debugfs_create_dir("q", qcq->dentry); 124 if (IS_ERR_OR_NULL(q_dentry)) 125 return; 126 127 debugfs_create_u32("index", 0400, q_dentry, &q->index); 128 debugfs_create_u32("num_descs", 0400, q_dentry, &q->num_descs); 129 debugfs_create_u32("desc_size", 0400, q_dentry, &q->desc_size); 130 debugfs_create_u32("pid", 0400, q_dentry, &q->pid); 131 132 debugfs_create_u16("tail", 0400, q_dentry, &q->tail_idx); 133 debugfs_create_u16("head", 0400, q_dentry, &q->head_idx); 134 135 cq_dentry = debugfs_create_dir("cq", qcq->dentry); 136 if (IS_ERR_OR_NULL(cq_dentry)) 137 return; 138 139 debugfs_create_x64("base_pa", 0400, cq_dentry, &cq->base_pa); 140 debugfs_create_u32("num_descs", 0400, cq_dentry, &cq->num_descs); 141 debugfs_create_u32("desc_size", 0400, cq_dentry, &cq->desc_size); 142 debugfs_create_bool("done_color", 0400, cq_dentry, &cq->done_color); 143 debugfs_create_u16("tail", 0400, cq_dentry, &cq->tail_idx); 144 145 if (qcq->flags & PDS_CORE_QCQ_F_INTR) { 146 intr_dentry = debugfs_create_dir("intr", qcq->dentry); 147 if (IS_ERR_OR_NULL(intr_dentry)) 148 return; 149 150 debugfs_create_u32("index", 0400, intr_dentry, &intr->index); 151 debugfs_create_u32("vector", 0400, intr_dentry, &intr->vector); 152 153 intr_ctrl_regset = kzalloc(sizeof(*intr_ctrl_regset), 154 GFP_KERNEL); 155 if (!intr_ctrl_regset) 156 return; 157 intr_ctrl_regset->regs = intr_ctrl_regs; 158 intr_ctrl_regset->nregs = ARRAY_SIZE(intr_ctrl_regs); 159 intr_ctrl_regset->base = &pdsc->intr_ctrl[intr->index]; 160 161 debugfs_create_regset32("intr_ctrl", 0400, intr_dentry, 162 intr_ctrl_regset); 163 } 164 }; 165 166 void pdsc_debugfs_del_qcq(struct pdsc_qcq *qcq) 167 { 168 debugfs_remove_recursive(qcq->dentry); 169 qcq->dentry = NULL; 170 } 171