0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/module.h>
0020 #include <linux/kernel.h>
0021 #include <linux/debugfs.h>
0022 #include <linux/seq_file.h>
0023 #include <linux/uaccess.h>
0024
0025 #include "card_base.h"
0026 #include "card_ddcb.h"
0027
0028 static void dbg_uidn_show(struct seq_file *s, struct genwqe_reg *regs,
0029 int entries)
0030 {
0031 unsigned int i;
0032 u32 v_hi, v_lo;
0033
0034 for (i = 0; i < entries; i++) {
0035 v_hi = (regs[i].val >> 32) & 0xffffffff;
0036 v_lo = (regs[i].val) & 0xffffffff;
0037
0038 seq_printf(s, " 0x%08x 0x%08x 0x%08x 0x%08x EXT_ERR_REC\n",
0039 regs[i].addr, regs[i].idx, v_hi, v_lo);
0040 }
0041 }
0042
0043 static int curr_dbg_uidn_show(struct seq_file *s, void *unused, int uid)
0044 {
0045 struct genwqe_dev *cd = s->private;
0046 int entries;
0047 struct genwqe_reg *regs;
0048
0049 entries = genwqe_ffdc_buff_size(cd, uid);
0050 if (entries < 0)
0051 return -EINVAL;
0052
0053 if (entries == 0)
0054 return 0;
0055
0056 regs = kcalloc(entries, sizeof(*regs), GFP_KERNEL);
0057 if (regs == NULL)
0058 return -ENOMEM;
0059
0060 genwqe_stop_traps(cd);
0061 genwqe_ffdc_buff_read(cd, uid, regs, entries);
0062 genwqe_start_traps(cd);
0063
0064 dbg_uidn_show(s, regs, entries);
0065 kfree(regs);
0066 return 0;
0067 }
0068
0069 static int curr_dbg_uid0_show(struct seq_file *s, void *unused)
0070 {
0071 return curr_dbg_uidn_show(s, unused, 0);
0072 }
0073
0074 DEFINE_SHOW_ATTRIBUTE(curr_dbg_uid0);
0075
0076 static int curr_dbg_uid1_show(struct seq_file *s, void *unused)
0077 {
0078 return curr_dbg_uidn_show(s, unused, 1);
0079 }
0080
0081 DEFINE_SHOW_ATTRIBUTE(curr_dbg_uid1);
0082
0083 static int curr_dbg_uid2_show(struct seq_file *s, void *unused)
0084 {
0085 return curr_dbg_uidn_show(s, unused, 2);
0086 }
0087
0088 DEFINE_SHOW_ATTRIBUTE(curr_dbg_uid2);
0089
0090 static int prev_dbg_uidn_show(struct seq_file *s, void *unused, int uid)
0091 {
0092 struct genwqe_dev *cd = s->private;
0093
0094 dbg_uidn_show(s, cd->ffdc[uid].regs, cd->ffdc[uid].entries);
0095 return 0;
0096 }
0097
0098 static int prev_dbg_uid0_show(struct seq_file *s, void *unused)
0099 {
0100 return prev_dbg_uidn_show(s, unused, 0);
0101 }
0102
0103 DEFINE_SHOW_ATTRIBUTE(prev_dbg_uid0);
0104
0105 static int prev_dbg_uid1_show(struct seq_file *s, void *unused)
0106 {
0107 return prev_dbg_uidn_show(s, unused, 1);
0108 }
0109
0110 DEFINE_SHOW_ATTRIBUTE(prev_dbg_uid1);
0111
0112 static int prev_dbg_uid2_show(struct seq_file *s, void *unused)
0113 {
0114 return prev_dbg_uidn_show(s, unused, 2);
0115 }
0116
0117 DEFINE_SHOW_ATTRIBUTE(prev_dbg_uid2);
0118
0119 static int curr_regs_show(struct seq_file *s, void *unused)
0120 {
0121 struct genwqe_dev *cd = s->private;
0122 unsigned int i;
0123 struct genwqe_reg *regs;
0124
0125 regs = kcalloc(GENWQE_FFDC_REGS, sizeof(*regs), GFP_KERNEL);
0126 if (regs == NULL)
0127 return -ENOMEM;
0128
0129 genwqe_stop_traps(cd);
0130 genwqe_read_ffdc_regs(cd, regs, GENWQE_FFDC_REGS, 1);
0131 genwqe_start_traps(cd);
0132
0133 for (i = 0; i < GENWQE_FFDC_REGS; i++) {
0134 if (regs[i].addr == 0xffffffff)
0135 break;
0136
0137 if (regs[i].val == 0x0ull)
0138 continue;
0139
0140 seq_printf(s, " 0x%08x 0x%016llx\n",
0141 regs[i].addr, regs[i].val);
0142 }
0143 return 0;
0144 }
0145
0146 DEFINE_SHOW_ATTRIBUTE(curr_regs);
0147
0148 static int prev_regs_show(struct seq_file *s, void *unused)
0149 {
0150 struct genwqe_dev *cd = s->private;
0151 unsigned int i;
0152 struct genwqe_reg *regs = cd->ffdc[GENWQE_DBG_REGS].regs;
0153
0154 if (regs == NULL)
0155 return -EINVAL;
0156
0157 for (i = 0; i < GENWQE_FFDC_REGS; i++) {
0158 if (regs[i].addr == 0xffffffff)
0159 break;
0160
0161 if (regs[i].val == 0x0ull)
0162 continue;
0163
0164 seq_printf(s, " 0x%08x 0x%016llx\n",
0165 regs[i].addr, regs[i].val);
0166 }
0167 return 0;
0168 }
0169
0170 DEFINE_SHOW_ATTRIBUTE(prev_regs);
0171
0172 static int jtimer_show(struct seq_file *s, void *unused)
0173 {
0174 struct genwqe_dev *cd = s->private;
0175 unsigned int vf_num;
0176 u64 jtimer;
0177
0178 jtimer = genwqe_read_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, 0);
0179 seq_printf(s, " PF 0x%016llx %d msec\n", jtimer,
0180 GENWQE_PF_JOBTIMEOUT_MSEC);
0181
0182 for (vf_num = 0; vf_num < cd->num_vfs; vf_num++) {
0183 jtimer = genwqe_read_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT,
0184 vf_num + 1);
0185 seq_printf(s, " VF%-2d 0x%016llx %d msec\n", vf_num, jtimer,
0186 cd->vf_jobtimeout_msec[vf_num]);
0187 }
0188 return 0;
0189 }
0190
0191 DEFINE_SHOW_ATTRIBUTE(jtimer);
0192
0193 static int queue_working_time_show(struct seq_file *s, void *unused)
0194 {
0195 struct genwqe_dev *cd = s->private;
0196 unsigned int vf_num;
0197 u64 t;
0198
0199 t = genwqe_read_vreg(cd, IO_SLC_VF_QUEUE_WTIME, 0);
0200 seq_printf(s, " PF 0x%016llx\n", t);
0201
0202 for (vf_num = 0; vf_num < cd->num_vfs; vf_num++) {
0203 t = genwqe_read_vreg(cd, IO_SLC_VF_QUEUE_WTIME, vf_num + 1);
0204 seq_printf(s, " VF%-2d 0x%016llx\n", vf_num, t);
0205 }
0206 return 0;
0207 }
0208
0209 DEFINE_SHOW_ATTRIBUTE(queue_working_time);
0210
0211 static int ddcb_info_show(struct seq_file *s, void *unused)
0212 {
0213 struct genwqe_dev *cd = s->private;
0214 unsigned int i;
0215 struct ddcb_queue *queue;
0216 struct ddcb *pddcb;
0217
0218 queue = &cd->queue;
0219 seq_puts(s, "DDCB QUEUE:\n");
0220 seq_printf(s, " ddcb_max: %d\n"
0221 " ddcb_daddr: %016llx - %016llx\n"
0222 " ddcb_vaddr: %p\n"
0223 " ddcbs_in_flight: %u\n"
0224 " ddcbs_max_in_flight: %u\n"
0225 " ddcbs_completed: %u\n"
0226 " return_on_busy: %u\n"
0227 " wait_on_busy: %u\n"
0228 " irqs_processed: %u\n",
0229 queue->ddcb_max, (long long)queue->ddcb_daddr,
0230 (long long)queue->ddcb_daddr +
0231 (queue->ddcb_max * DDCB_LENGTH),
0232 queue->ddcb_vaddr, queue->ddcbs_in_flight,
0233 queue->ddcbs_max_in_flight, queue->ddcbs_completed,
0234 queue->return_on_busy, queue->wait_on_busy,
0235 cd->irqs_processed);
0236
0237
0238 seq_printf(s, " 0x%08x 0x%016llx IO_QUEUE_CONFIG\n"
0239 " 0x%08x 0x%016llx IO_QUEUE_STATUS\n"
0240 " 0x%08x 0x%016llx IO_QUEUE_SEGMENT\n"
0241 " 0x%08x 0x%016llx IO_QUEUE_INITSQN\n"
0242 " 0x%08x 0x%016llx IO_QUEUE_WRAP\n"
0243 " 0x%08x 0x%016llx IO_QUEUE_OFFSET\n"
0244 " 0x%08x 0x%016llx IO_QUEUE_WTIME\n"
0245 " 0x%08x 0x%016llx IO_QUEUE_ERRCNTS\n"
0246 " 0x%08x 0x%016llx IO_QUEUE_LRW\n",
0247 queue->IO_QUEUE_CONFIG,
0248 __genwqe_readq(cd, queue->IO_QUEUE_CONFIG),
0249 queue->IO_QUEUE_STATUS,
0250 __genwqe_readq(cd, queue->IO_QUEUE_STATUS),
0251 queue->IO_QUEUE_SEGMENT,
0252 __genwqe_readq(cd, queue->IO_QUEUE_SEGMENT),
0253 queue->IO_QUEUE_INITSQN,
0254 __genwqe_readq(cd, queue->IO_QUEUE_INITSQN),
0255 queue->IO_QUEUE_WRAP,
0256 __genwqe_readq(cd, queue->IO_QUEUE_WRAP),
0257 queue->IO_QUEUE_OFFSET,
0258 __genwqe_readq(cd, queue->IO_QUEUE_OFFSET),
0259 queue->IO_QUEUE_WTIME,
0260 __genwqe_readq(cd, queue->IO_QUEUE_WTIME),
0261 queue->IO_QUEUE_ERRCNTS,
0262 __genwqe_readq(cd, queue->IO_QUEUE_ERRCNTS),
0263 queue->IO_QUEUE_LRW,
0264 __genwqe_readq(cd, queue->IO_QUEUE_LRW));
0265
0266 seq_printf(s, "DDCB list (ddcb_act=%d/ddcb_next=%d):\n",
0267 queue->ddcb_act, queue->ddcb_next);
0268
0269 pddcb = queue->ddcb_vaddr;
0270 for (i = 0; i < queue->ddcb_max; i++) {
0271 seq_printf(s, " %-3d: RETC=%03x SEQ=%04x HSI/SHI=%02x/%02x ",
0272 i, be16_to_cpu(pddcb->retc_16),
0273 be16_to_cpu(pddcb->seqnum_16),
0274 pddcb->hsi, pddcb->shi);
0275 seq_printf(s, "PRIV=%06llx CMD=%02x\n",
0276 be64_to_cpu(pddcb->priv_64), pddcb->cmd);
0277 pddcb++;
0278 }
0279 return 0;
0280 }
0281
0282 DEFINE_SHOW_ATTRIBUTE(ddcb_info);
0283
0284 static int info_show(struct seq_file *s, void *unused)
0285 {
0286 struct genwqe_dev *cd = s->private;
0287 u64 app_id, slu_id, bitstream = -1;
0288 struct pci_dev *pci_dev = cd->pci_dev;
0289
0290 slu_id = __genwqe_readq(cd, IO_SLU_UNITCFG);
0291 app_id = __genwqe_readq(cd, IO_APP_UNITCFG);
0292
0293 if (genwqe_is_privileged(cd))
0294 bitstream = __genwqe_readq(cd, IO_SLU_BITSTREAM);
0295
0296 seq_printf(s, "%s driver version: %s\n"
0297 " Device Name/Type: %s %s CardIdx: %d\n"
0298 " SLU/APP Config : 0x%016llx/0x%016llx\n"
0299 " Build Date : %u/%x/%u\n"
0300 " Base Clock : %u MHz\n"
0301 " Arch/SVN Release: %u/%llx\n"
0302 " Bitstream : %llx\n",
0303 GENWQE_DEVNAME, DRV_VERSION, dev_name(&pci_dev->dev),
0304 genwqe_is_privileged(cd) ?
0305 "Physical" : "Virtual or no SR-IOV",
0306 cd->card_idx, slu_id, app_id,
0307 (u16)((slu_id >> 12) & 0x0fLLU),
0308 (u16)((slu_id >> 4) & 0xffLLU),
0309 (u16)((slu_id >> 16) & 0x0fLLU) + 2010,
0310 genwqe_base_clock_frequency(cd),
0311 (u16)((slu_id >> 32) & 0xffLLU), slu_id >> 40,
0312 bitstream);
0313
0314 return 0;
0315 }
0316
0317 DEFINE_SHOW_ATTRIBUTE(info);
0318
0319 void genwqe_init_debugfs(struct genwqe_dev *cd)
0320 {
0321 struct dentry *root;
0322 char card_name[64];
0323 char name[64];
0324 unsigned int i;
0325
0326 sprintf(card_name, "%s%d_card", GENWQE_DEVNAME, cd->card_idx);
0327
0328 root = debugfs_create_dir(card_name, cd->debugfs_genwqe);
0329
0330
0331 debugfs_create_file("ddcb_info", S_IRUGO, root, cd, &ddcb_info_fops);
0332 debugfs_create_file("info", S_IRUGO, root, cd, &info_fops);
0333 debugfs_create_x64("err_inject", 0666, root, &cd->err_inject);
0334 debugfs_create_u32("ddcb_software_timeout", 0666, root,
0335 &cd->ddcb_software_timeout);
0336 debugfs_create_u32("kill_timeout", 0666, root, &cd->kill_timeout);
0337
0338
0339 if (!genwqe_is_privileged(cd)) {
0340 cd->debugfs_root = root;
0341 return;
0342 }
0343
0344 debugfs_create_file("curr_regs", S_IRUGO, root, cd, &curr_regs_fops);
0345 debugfs_create_file("curr_dbg_uid0", S_IRUGO, root, cd,
0346 &curr_dbg_uid0_fops);
0347 debugfs_create_file("curr_dbg_uid1", S_IRUGO, root, cd,
0348 &curr_dbg_uid1_fops);
0349 debugfs_create_file("curr_dbg_uid2", S_IRUGO, root, cd,
0350 &curr_dbg_uid2_fops);
0351 debugfs_create_file("prev_regs", S_IRUGO, root, cd, &prev_regs_fops);
0352 debugfs_create_file("prev_dbg_uid0", S_IRUGO, root, cd,
0353 &prev_dbg_uid0_fops);
0354 debugfs_create_file("prev_dbg_uid1", S_IRUGO, root, cd,
0355 &prev_dbg_uid1_fops);
0356 debugfs_create_file("prev_dbg_uid2", S_IRUGO, root, cd,
0357 &prev_dbg_uid2_fops);
0358
0359 for (i = 0; i < GENWQE_MAX_VFS; i++) {
0360 sprintf(name, "vf%u_jobtimeout_msec", i);
0361 debugfs_create_u32(name, 0666, root,
0362 &cd->vf_jobtimeout_msec[i]);
0363 }
0364
0365 debugfs_create_file("jobtimer", S_IRUGO, root, cd, &jtimer_fops);
0366 debugfs_create_file("queue_working_time", S_IRUGO, root, cd,
0367 &queue_working_time_fops);
0368 debugfs_create_u32("skip_recovery", 0666, root, &cd->skip_recovery);
0369 debugfs_create_u32("use_platform_recovery", 0666, root,
0370 &cd->use_platform_recovery);
0371
0372 cd->debugfs_root = root;
0373 }
0374
0375 void genqwe_exit_debugfs(struct genwqe_dev *cd)
0376 {
0377 debugfs_remove_recursive(cd->debugfs_root);
0378 }