1 // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
2 /*
3 * Copyright(c) 2015-2018 Intel Corporation.
4 */
5
6 #include <linux/debugfs.h>
7 #include <linux/seq_file.h>
8 #include <linux/kernel.h>
9 #include <linux/export.h>
10 #include <linux/module.h>
11 #include <linux/string.h>
12 #include <linux/types.h>
13 #include <linux/ratelimit.h>
14 #include <linux/fault-inject.h>
15
16 #include "hfi.h"
17 #include "trace.h"
18 #include "debugfs.h"
19 #include "device.h"
20 #include "qp.h"
21 #include "sdma.h"
22 #include "fault.h"
23
24 static struct dentry *hfi1_dbg_root;
25
26 /* wrappers to enforce srcu in seq file */
hfi1_seq_read(struct file * file,char __user * buf,size_t size,loff_t * ppos)27 ssize_t hfi1_seq_read(struct file *file, char __user *buf, size_t size,
28 loff_t *ppos)
29 {
30 struct dentry *d = file->f_path.dentry;
31 ssize_t r;
32
33 r = debugfs_file_get(d);
34 if (unlikely(r))
35 return r;
36 r = seq_read(file, buf, size, ppos);
37 debugfs_file_put(d);
38 return r;
39 }
40
hfi1_seq_lseek(struct file * file,loff_t offset,int whence)41 loff_t hfi1_seq_lseek(struct file *file, loff_t offset, int whence)
42 {
43 struct dentry *d = file->f_path.dentry;
44 loff_t r;
45
46 r = debugfs_file_get(d);
47 if (unlikely(r))
48 return r;
49 r = seq_lseek(file, offset, whence);
50 debugfs_file_put(d);
51 return r;
52 }
53
54 #define private2dd(file) (file_inode(file)->i_private)
55 #define private2ppd(file) (file_inode(file)->i_private)
56
_opcode_stats_seq_start(struct seq_file * s,loff_t * pos)57 static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
58 {
59 struct hfi1_opcode_stats_perctx *opstats;
60
61 if (*pos >= ARRAY_SIZE(opstats->stats))
62 return NULL;
63 return pos;
64 }
65
_opcode_stats_seq_next(struct seq_file * s,void * v,loff_t * pos)66 static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
67 {
68 struct hfi1_opcode_stats_perctx *opstats;
69
70 ++*pos;
71 if (*pos >= ARRAY_SIZE(opstats->stats))
72 return NULL;
73 return pos;
74 }
75
_opcode_stats_seq_stop(struct seq_file * s,void * v)76 static void _opcode_stats_seq_stop(struct seq_file *s, void *v)
77 {
78 }
79
opcode_stats_show(struct seq_file * s,u8 i,u64 packets,u64 bytes)80 static int opcode_stats_show(struct seq_file *s, u8 i, u64 packets, u64 bytes)
81 {
82 if (!packets && !bytes)
83 return SEQ_SKIP;
84 seq_printf(s, "%02x %llu/%llu\n", i,
85 (unsigned long long)packets,
86 (unsigned long long)bytes);
87
88 return 0;
89 }
90
_opcode_stats_seq_show(struct seq_file * s,void * v)91 static int _opcode_stats_seq_show(struct seq_file *s, void *v)
92 {
93 loff_t *spos = v;
94 loff_t i = *spos, j;
95 u64 n_packets = 0, n_bytes = 0;
96 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
97 struct hfi1_devdata *dd = dd_from_dev(ibd);
98 struct hfi1_ctxtdata *rcd;
99
100 for (j = 0; j < dd->first_dyn_alloc_ctxt; j++) {
101 rcd = hfi1_rcd_get_by_index(dd, j);
102 if (rcd) {
103 n_packets += rcd->opstats->stats[i].n_packets;
104 n_bytes += rcd->opstats->stats[i].n_bytes;
105 }
106 hfi1_rcd_put(rcd);
107 }
108 return opcode_stats_show(s, i, n_packets, n_bytes);
109 }
110
111 DEBUGFS_SEQ_FILE_OPS(opcode_stats);
112 DEBUGFS_SEQ_FILE_OPEN(opcode_stats)
113 DEBUGFS_FILE_OPS(opcode_stats);
114
_tx_opcode_stats_seq_start(struct seq_file * s,loff_t * pos)115 static void *_tx_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
116 {
117 return _opcode_stats_seq_start(s, pos);
118 }
119
_tx_opcode_stats_seq_next(struct seq_file * s,void * v,loff_t * pos)120 static void *_tx_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
121 {
122 return _opcode_stats_seq_next(s, v, pos);
123 }
124
_tx_opcode_stats_seq_stop(struct seq_file * s,void * v)125 static void _tx_opcode_stats_seq_stop(struct seq_file *s, void *v)
126 {
127 }
128
_tx_opcode_stats_seq_show(struct seq_file * s,void * v)129 static int _tx_opcode_stats_seq_show(struct seq_file *s, void *v)
130 {
131 loff_t *spos = v;
132 loff_t i = *spos;
133 int j;
134 u64 n_packets = 0, n_bytes = 0;
135 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
136 struct hfi1_devdata *dd = dd_from_dev(ibd);
137
138 for_each_possible_cpu(j) {
139 struct hfi1_opcode_stats_perctx *s =
140 per_cpu_ptr(dd->tx_opstats, j);
141 n_packets += s->stats[i].n_packets;
142 n_bytes += s->stats[i].n_bytes;
143 }
144 return opcode_stats_show(s, i, n_packets, n_bytes);
145 }
146
147 DEBUGFS_SEQ_FILE_OPS(tx_opcode_stats);
148 DEBUGFS_SEQ_FILE_OPEN(tx_opcode_stats)
149 DEBUGFS_FILE_OPS(tx_opcode_stats);
150
_ctx_stats_seq_start(struct seq_file * s,loff_t * pos)151 static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos)
152 {
153 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
154 struct hfi1_devdata *dd = dd_from_dev(ibd);
155
156 if (!*pos)
157 return SEQ_START_TOKEN;
158 if (*pos >= dd->first_dyn_alloc_ctxt)
159 return NULL;
160 return pos;
161 }
162
_ctx_stats_seq_next(struct seq_file * s,void * v,loff_t * pos)163 static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
164 {
165 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
166 struct hfi1_devdata *dd = dd_from_dev(ibd);
167
168 if (v == SEQ_START_TOKEN)
169 return pos;
170
171 ++*pos;
172 if (*pos >= dd->first_dyn_alloc_ctxt)
173 return NULL;
174 return pos;
175 }
176
_ctx_stats_seq_stop(struct seq_file * s,void * v)177 static void _ctx_stats_seq_stop(struct seq_file *s, void *v)
178 {
179 /* nothing allocated */
180 }
181
_ctx_stats_seq_show(struct seq_file * s,void * v)182 static int _ctx_stats_seq_show(struct seq_file *s, void *v)
183 {
184 loff_t *spos;
185 loff_t i, j;
186 u64 n_packets = 0;
187 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
188 struct hfi1_devdata *dd = dd_from_dev(ibd);
189 struct hfi1_ctxtdata *rcd;
190
191 if (v == SEQ_START_TOKEN) {
192 seq_puts(s, "Ctx:npkts\n");
193 return 0;
194 }
195
196 spos = v;
197 i = *spos;
198
199 rcd = hfi1_rcd_get_by_index_safe(dd, i);
200 if (!rcd)
201 return SEQ_SKIP;
202
203 for (j = 0; j < ARRAY_SIZE(rcd->opstats->stats); j++)
204 n_packets += rcd->opstats->stats[j].n_packets;
205
206 hfi1_rcd_put(rcd);
207
208 if (!n_packets)
209 return SEQ_SKIP;
210
211 seq_printf(s, " %llu:%llu\n", i, n_packets);
212 return 0;
213 }
214
215 DEBUGFS_SEQ_FILE_OPS(ctx_stats);
216 DEBUGFS_SEQ_FILE_OPEN(ctx_stats)
217 DEBUGFS_FILE_OPS(ctx_stats);
218
_qp_stats_seq_start(struct seq_file * s,loff_t * pos)219 static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
220 __acquires(RCU)
221 {
222 struct rvt_qp_iter *iter;
223 loff_t n = *pos;
224
225 iter = rvt_qp_iter_init(s->private, 0, NULL);
226
227 /* stop calls rcu_read_unlock */
228 rcu_read_lock();
229
230 if (!iter)
231 return NULL;
232
233 do {
234 if (rvt_qp_iter_next(iter)) {
235 kfree(iter);
236 return NULL;
237 }
238 } while (n--);
239
240 return iter;
241 }
242
_qp_stats_seq_next(struct seq_file * s,void * iter_ptr,loff_t * pos)243 static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
244 loff_t *pos)
245 __must_hold(RCU)
246 {
247 struct rvt_qp_iter *iter = iter_ptr;
248
249 (*pos)++;
250
251 if (rvt_qp_iter_next(iter)) {
252 kfree(iter);
253 return NULL;
254 }
255
256 return iter;
257 }
258
_qp_stats_seq_stop(struct seq_file * s,void * iter_ptr)259 static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
260 __releases(RCU)
261 {
262 rcu_read_unlock();
263 }
264
_qp_stats_seq_show(struct seq_file * s,void * iter_ptr)265 static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
266 {
267 struct rvt_qp_iter *iter = iter_ptr;
268
269 if (!iter)
270 return 0;
271
272 qp_iter_print(s, iter);
273
274 return 0;
275 }
276
277 DEBUGFS_SEQ_FILE_OPS(qp_stats);
278 DEBUGFS_SEQ_FILE_OPEN(qp_stats)
279 DEBUGFS_FILE_OPS(qp_stats);
280
_sdes_seq_start(struct seq_file * s,loff_t * pos)281 static void *_sdes_seq_start(struct seq_file *s, loff_t *pos)
282 {
283 struct hfi1_ibdev *ibd;
284 struct hfi1_devdata *dd;
285
286 ibd = (struct hfi1_ibdev *)s->private;
287 dd = dd_from_dev(ibd);
288 if (!dd->per_sdma || *pos >= dd->num_sdma)
289 return NULL;
290 return pos;
291 }
292
_sdes_seq_next(struct seq_file * s,void * v,loff_t * pos)293 static void *_sdes_seq_next(struct seq_file *s, void *v, loff_t *pos)
294 {
295 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
296 struct hfi1_devdata *dd = dd_from_dev(ibd);
297
298 ++*pos;
299 if (!dd->per_sdma || *pos >= dd->num_sdma)
300 return NULL;
301 return pos;
302 }
303
_sdes_seq_stop(struct seq_file * s,void * v)304 static void _sdes_seq_stop(struct seq_file *s, void *v)
305 {
306 }
307
_sdes_seq_show(struct seq_file * s,void * v)308 static int _sdes_seq_show(struct seq_file *s, void *v)
309 {
310 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
311 struct hfi1_devdata *dd = dd_from_dev(ibd);
312 loff_t *spos = v;
313 loff_t i = *spos;
314
315 sdma_seqfile_dump_sde(s, &dd->per_sdma[i]);
316 return 0;
317 }
318
319 DEBUGFS_SEQ_FILE_OPS(sdes);
320 DEBUGFS_SEQ_FILE_OPEN(sdes)
321 DEBUGFS_FILE_OPS(sdes);
322
_rcds_seq_start(struct seq_file * s,loff_t * pos)323 static void *_rcds_seq_start(struct seq_file *s, loff_t *pos)
324 {
325 struct hfi1_ibdev *ibd;
326 struct hfi1_devdata *dd;
327
328 ibd = (struct hfi1_ibdev *)s->private;
329 dd = dd_from_dev(ibd);
330 if (!dd->rcd || *pos >= dd->n_krcv_queues)
331 return NULL;
332 return pos;
333 }
334
_rcds_seq_next(struct seq_file * s,void * v,loff_t * pos)335 static void *_rcds_seq_next(struct seq_file *s, void *v, loff_t *pos)
336 {
337 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
338 struct hfi1_devdata *dd = dd_from_dev(ibd);
339
340 ++*pos;
341 if (!dd->rcd || *pos >= dd->num_rcv_contexts)
342 return NULL;
343 return pos;
344 }
345
_rcds_seq_stop(struct seq_file * s,void * v)346 static void _rcds_seq_stop(struct seq_file *s, void *v)
347 {
348 }
349
_rcds_seq_show(struct seq_file * s,void * v)350 static int _rcds_seq_show(struct seq_file *s, void *v)
351 {
352 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
353 struct hfi1_devdata *dd = dd_from_dev(ibd);
354 struct hfi1_ctxtdata *rcd;
355 loff_t *spos = v;
356 loff_t i = *spos;
357
358 rcd = hfi1_rcd_get_by_index_safe(dd, i);
359 if (rcd)
360 seqfile_dump_rcd(s, rcd);
361 hfi1_rcd_put(rcd);
362 return 0;
363 }
364
365 DEBUGFS_SEQ_FILE_OPS(rcds);
366 DEBUGFS_SEQ_FILE_OPEN(rcds)
367 DEBUGFS_FILE_OPS(rcds);
368
_pios_seq_start(struct seq_file * s,loff_t * pos)369 static void *_pios_seq_start(struct seq_file *s, loff_t *pos)
370 {
371 struct hfi1_ibdev *ibd;
372 struct hfi1_devdata *dd;
373
374 ibd = (struct hfi1_ibdev *)s->private;
375 dd = dd_from_dev(ibd);
376 if (!dd->send_contexts || *pos >= dd->num_send_contexts)
377 return NULL;
378 return pos;
379 }
380
_pios_seq_next(struct seq_file * s,void * v,loff_t * pos)381 static void *_pios_seq_next(struct seq_file *s, void *v, loff_t *pos)
382 {
383 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
384 struct hfi1_devdata *dd = dd_from_dev(ibd);
385
386 ++*pos;
387 if (!dd->send_contexts || *pos >= dd->num_send_contexts)
388 return NULL;
389 return pos;
390 }
391
_pios_seq_stop(struct seq_file * s,void * v)392 static void _pios_seq_stop(struct seq_file *s, void *v)
393 {
394 }
395
_pios_seq_show(struct seq_file * s,void * v)396 static int _pios_seq_show(struct seq_file *s, void *v)
397 {
398 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
399 struct hfi1_devdata *dd = dd_from_dev(ibd);
400 struct send_context_info *sci;
401 loff_t *spos = v;
402 loff_t i = *spos;
403 unsigned long flags;
404
405 spin_lock_irqsave(&dd->sc_lock, flags);
406 sci = &dd->send_contexts[i];
407 if (sci && sci->type != SC_USER && sci->allocated && sci->sc)
408 seqfile_dump_sci(s, i, sci);
409 spin_unlock_irqrestore(&dd->sc_lock, flags);
410 return 0;
411 }
412
413 DEBUGFS_SEQ_FILE_OPS(pios);
414 DEBUGFS_SEQ_FILE_OPEN(pios)
415 DEBUGFS_FILE_OPS(pios);
416
417 /* read the per-device counters */
dev_counters_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)418 static ssize_t dev_counters_read(struct file *file, char __user *buf,
419 size_t count, loff_t *ppos)
420 {
421 u64 *counters;
422 size_t avail;
423 struct hfi1_devdata *dd;
424 ssize_t rval;
425
426 dd = private2dd(file);
427 avail = hfi1_read_cntrs(dd, NULL, &counters);
428 rval = simple_read_from_buffer(buf, count, ppos, counters, avail);
429 return rval;
430 }
431
432 /* read the per-device counters */
dev_names_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)433 static ssize_t dev_names_read(struct file *file, char __user *buf,
434 size_t count, loff_t *ppos)
435 {
436 char *names;
437 size_t avail;
438 struct hfi1_devdata *dd;
439 ssize_t rval;
440
441 dd = private2dd(file);
442 avail = hfi1_read_cntrs(dd, &names, NULL);
443 rval = simple_read_from_buffer(buf, count, ppos, names, avail);
444 return rval;
445 }
446
447 struct counter_info {
448 char *name;
449 const struct file_operations ops;
450 };
451
452 /*
453 * Could use file_inode(file)->i_ino to figure out which file,
454 * instead of separate routine for each, but for now, this works...
455 */
456
457 /* read the per-port names (same for each port) */
portnames_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)458 static ssize_t portnames_read(struct file *file, char __user *buf,
459 size_t count, loff_t *ppos)
460 {
461 char *names;
462 size_t avail;
463 struct hfi1_devdata *dd;
464 ssize_t rval;
465
466 dd = private2dd(file);
467 avail = hfi1_read_portcntrs(dd->pport, &names, NULL);
468 rval = simple_read_from_buffer(buf, count, ppos, names, avail);
469 return rval;
470 }
471
472 /* read the per-port counters */
portcntrs_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)473 static ssize_t portcntrs_debugfs_read(struct file *file, char __user *buf,
474 size_t count, loff_t *ppos)
475 {
476 u64 *counters;
477 size_t avail;
478 struct hfi1_pportdata *ppd;
479 ssize_t rval;
480
481 ppd = private2ppd(file);
482 avail = hfi1_read_portcntrs(ppd, NULL, &counters);
483 rval = simple_read_from_buffer(buf, count, ppos, counters, avail);
484 return rval;
485 }
486
check_dyn_flag(u64 scratch0,char * p,int size,int * used,int this_hfi,int hfi,u32 flag,const char * what)487 static void check_dyn_flag(u64 scratch0, char *p, int size, int *used,
488 int this_hfi, int hfi, u32 flag, const char *what)
489 {
490 u32 mask;
491
492 mask = flag << (hfi ? CR_DYN_SHIFT : 0);
493 if (scratch0 & mask) {
494 *used += scnprintf(p + *used, size - *used,
495 " 0x%08x - HFI%d %s in use, %s device\n",
496 mask, hfi, what,
497 this_hfi == hfi ? "this" : "other");
498 }
499 }
500
asic_flags_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)501 static ssize_t asic_flags_read(struct file *file, char __user *buf,
502 size_t count, loff_t *ppos)
503 {
504 struct hfi1_pportdata *ppd;
505 struct hfi1_devdata *dd;
506 u64 scratch0;
507 char *tmp;
508 int ret = 0;
509 int size;
510 int used;
511 int i;
512
513 ppd = private2ppd(file);
514 dd = ppd->dd;
515 size = PAGE_SIZE;
516 used = 0;
517 tmp = kmalloc(size, GFP_KERNEL);
518 if (!tmp)
519 return -ENOMEM;
520
521 scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
522 used += scnprintf(tmp + used, size - used,
523 "Resource flags: 0x%016llx\n", scratch0);
524
525 /* check permanent flag */
526 if (scratch0 & CR_THERM_INIT) {
527 used += scnprintf(tmp + used, size - used,
528 " 0x%08x - thermal monitoring initialized\n",
529 (u32)CR_THERM_INIT);
530 }
531
532 /* check each dynamic flag on each HFI */
533 for (i = 0; i < 2; i++) {
534 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
535 CR_SBUS, "SBus");
536 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
537 CR_EPROM, "EPROM");
538 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
539 CR_I2C1, "i2c chain 1");
540 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
541 CR_I2C2, "i2c chain 2");
542 }
543 used += scnprintf(tmp + used, size - used, "Write bits to clear\n");
544
545 ret = simple_read_from_buffer(buf, count, ppos, tmp, used);
546 kfree(tmp);
547 return ret;
548 }
549
asic_flags_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)550 static ssize_t asic_flags_write(struct file *file, const char __user *buf,
551 size_t count, loff_t *ppos)
552 {
553 struct hfi1_pportdata *ppd;
554 struct hfi1_devdata *dd;
555 char *buff;
556 int ret;
557 unsigned long long value;
558 u64 scratch0;
559 u64 clear;
560
561 ppd = private2ppd(file);
562 dd = ppd->dd;
563
564 /* zero terminate and read the expected integer */
565 buff = memdup_user_nul(buf, count);
566 if (IS_ERR(buff))
567 return PTR_ERR(buff);
568
569 ret = kstrtoull(buff, 0, &value);
570 if (ret)
571 goto do_free;
572 clear = value;
573
574 /* obtain exclusive access */
575 mutex_lock(&dd->asic_data->asic_resource_mutex);
576 acquire_hw_mutex(dd);
577
578 scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
579 scratch0 &= ~clear;
580 write_csr(dd, ASIC_CFG_SCRATCH, scratch0);
581 /* force write to be visible to other HFI on another OS */
582 (void)read_csr(dd, ASIC_CFG_SCRATCH);
583
584 release_hw_mutex(dd);
585 mutex_unlock(&dd->asic_data->asic_resource_mutex);
586
587 /* return the number of bytes written */
588 ret = count;
589
590 do_free:
591 kfree(buff);
592 return ret;
593 }
594
595 /* read the dc8051 memory */
dc8051_memory_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)596 static ssize_t dc8051_memory_read(struct file *file, char __user *buf,
597 size_t count, loff_t *ppos)
598 {
599 struct hfi1_pportdata *ppd = private2ppd(file);
600 ssize_t rval;
601 void *tmp;
602 loff_t start, end;
603
604 /* the checks below expect the position to be positive */
605 if (*ppos < 0)
606 return -EINVAL;
607
608 tmp = kzalloc(DC8051_DATA_MEM_SIZE, GFP_KERNEL);
609 if (!tmp)
610 return -ENOMEM;
611
612 /*
613 * Fill in the requested portion of the temporary buffer from the
614 * 8051 memory. The 8051 memory read is done in terms of 8 bytes.
615 * Adjust start and end to fit. Skip reading anything if out of
616 * range.
617 */
618 start = *ppos & ~0x7; /* round down */
619 if (start < DC8051_DATA_MEM_SIZE) {
620 end = (*ppos + count + 7) & ~0x7; /* round up */
621 if (end > DC8051_DATA_MEM_SIZE)
622 end = DC8051_DATA_MEM_SIZE;
623 rval = read_8051_data(ppd->dd, start, end - start,
624 (u64 *)(tmp + start));
625 if (rval)
626 goto done;
627 }
628
629 rval = simple_read_from_buffer(buf, count, ppos, tmp,
630 DC8051_DATA_MEM_SIZE);
631 done:
632 kfree(tmp);
633 return rval;
634 }
635
debugfs_lcb_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)636 static ssize_t debugfs_lcb_read(struct file *file, char __user *buf,
637 size_t count, loff_t *ppos)
638 {
639 struct hfi1_pportdata *ppd = private2ppd(file);
640 struct hfi1_devdata *dd = ppd->dd;
641 unsigned long total, csr_off;
642 u64 data;
643
644 if (*ppos < 0)
645 return -EINVAL;
646 /* only read 8 byte quantities */
647 if ((count % 8) != 0)
648 return -EINVAL;
649 /* offset must be 8-byte aligned */
650 if ((*ppos % 8) != 0)
651 return -EINVAL;
652 /* do nothing if out of range or zero count */
653 if (*ppos >= (LCB_END - LCB_START) || !count)
654 return 0;
655 /* reduce count if needed */
656 if (*ppos + count > LCB_END - LCB_START)
657 count = (LCB_END - LCB_START) - *ppos;
658
659 csr_off = LCB_START + *ppos;
660 for (total = 0; total < count; total += 8, csr_off += 8) {
661 if (read_lcb_csr(dd, csr_off, (u64 *)&data))
662 break; /* failed */
663 if (put_user(data, (unsigned long __user *)(buf + total)))
664 break;
665 }
666 *ppos += total;
667 return total;
668 }
669
debugfs_lcb_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)670 static ssize_t debugfs_lcb_write(struct file *file, const char __user *buf,
671 size_t count, loff_t *ppos)
672 {
673 struct hfi1_pportdata *ppd = private2ppd(file);
674 struct hfi1_devdata *dd = ppd->dd;
675 unsigned long total, csr_off, data;
676
677 if (*ppos < 0)
678 return -EINVAL;
679 /* only write 8 byte quantities */
680 if ((count % 8) != 0)
681 return -EINVAL;
682 /* offset must be 8-byte aligned */
683 if ((*ppos % 8) != 0)
684 return -EINVAL;
685 /* do nothing if out of range or zero count */
686 if (*ppos >= (LCB_END - LCB_START) || !count)
687 return 0;
688 /* reduce count if needed */
689 if (*ppos + count > LCB_END - LCB_START)
690 count = (LCB_END - LCB_START) - *ppos;
691
692 csr_off = LCB_START + *ppos;
693 for (total = 0; total < count; total += 8, csr_off += 8) {
694 if (get_user(data, (unsigned long __user *)(buf + total)))
695 break;
696 if (write_lcb_csr(dd, csr_off, data))
697 break; /* failed */
698 }
699 *ppos += total;
700 return total;
701 }
702
703 /*
704 * read the per-port QSFP data for ppd
705 */
qsfp_debugfs_dump(struct file * file,char __user * buf,size_t count,loff_t * ppos)706 static ssize_t qsfp_debugfs_dump(struct file *file, char __user *buf,
707 size_t count, loff_t *ppos)
708 {
709 struct hfi1_pportdata *ppd;
710 char *tmp;
711 int ret;
712
713 ppd = private2ppd(file);
714 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL);
715 if (!tmp)
716 return -ENOMEM;
717
718 ret = qsfp_dump(ppd, tmp, PAGE_SIZE);
719 if (ret > 0)
720 ret = simple_read_from_buffer(buf, count, ppos, tmp, ret);
721 kfree(tmp);
722 return ret;
723 }
724
725 /* Do an i2c write operation on the chain for the given HFI. */
__i2c_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos,u32 target)726 static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf,
727 size_t count, loff_t *ppos, u32 target)
728 {
729 struct hfi1_pportdata *ppd;
730 char *buff;
731 int ret;
732 int i2c_addr;
733 int offset;
734 int total_written;
735
736 ppd = private2ppd(file);
737
738 /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */
739 i2c_addr = (*ppos >> 16) & 0xffff;
740 offset = *ppos & 0xffff;
741
742 /* explicitly reject invalid address 0 to catch cp and cat */
743 if (i2c_addr == 0)
744 return -EINVAL;
745
746 buff = memdup_user(buf, count);
747 if (IS_ERR(buff))
748 return PTR_ERR(buff);
749
750 total_written = i2c_write(ppd, target, i2c_addr, offset, buff, count);
751 if (total_written < 0) {
752 ret = total_written;
753 goto _free;
754 }
755
756 *ppos += total_written;
757
758 ret = total_written;
759
760 _free:
761 kfree(buff);
762 return ret;
763 }
764
765 /* Do an i2c write operation on chain for HFI 0. */
i2c1_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)766 static ssize_t i2c1_debugfs_write(struct file *file, const char __user *buf,
767 size_t count, loff_t *ppos)
768 {
769 return __i2c_debugfs_write(file, buf, count, ppos, 0);
770 }
771
772 /* Do an i2c write operation on chain for HFI 1. */
i2c2_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)773 static ssize_t i2c2_debugfs_write(struct file *file, const char __user *buf,
774 size_t count, loff_t *ppos)
775 {
776 return __i2c_debugfs_write(file, buf, count, ppos, 1);
777 }
778
779 /* Do an i2c read operation on the chain for the given HFI. */
__i2c_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos,u32 target)780 static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf,
781 size_t count, loff_t *ppos, u32 target)
782 {
783 struct hfi1_pportdata *ppd;
784 char *buff;
785 int ret;
786 int i2c_addr;
787 int offset;
788 int total_read;
789
790 ppd = private2ppd(file);
791
792 /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */
793 i2c_addr = (*ppos >> 16) & 0xffff;
794 offset = *ppos & 0xffff;
795
796 /* explicitly reject invalid address 0 to catch cp and cat */
797 if (i2c_addr == 0)
798 return -EINVAL;
799
800 buff = kmalloc(count, GFP_KERNEL);
801 if (!buff)
802 return -ENOMEM;
803
804 total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count);
805 if (total_read < 0) {
806 ret = total_read;
807 goto _free;
808 }
809
810 *ppos += total_read;
811
812 ret = copy_to_user(buf, buff, total_read);
813 if (ret > 0) {
814 ret = -EFAULT;
815 goto _free;
816 }
817
818 ret = total_read;
819
820 _free:
821 kfree(buff);
822 return ret;
823 }
824
825 /* Do an i2c read operation on chain for HFI 0. */
i2c1_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)826 static ssize_t i2c1_debugfs_read(struct file *file, char __user *buf,
827 size_t count, loff_t *ppos)
828 {
829 return __i2c_debugfs_read(file, buf, count, ppos, 0);
830 }
831
832 /* Do an i2c read operation on chain for HFI 1. */
i2c2_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)833 static ssize_t i2c2_debugfs_read(struct file *file, char __user *buf,
834 size_t count, loff_t *ppos)
835 {
836 return __i2c_debugfs_read(file, buf, count, ppos, 1);
837 }
838
839 /* Do a QSFP write operation on the i2c chain for the given HFI. */
__qsfp_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos,u32 target)840 static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf,
841 size_t count, loff_t *ppos, u32 target)
842 {
843 struct hfi1_pportdata *ppd;
844 char *buff;
845 int ret;
846 int total_written;
847
848 if (*ppos + count > QSFP_PAGESIZE * 4) /* base page + page00-page03 */
849 return -EINVAL;
850
851 ppd = private2ppd(file);
852
853 buff = memdup_user(buf, count);
854 if (IS_ERR(buff))
855 return PTR_ERR(buff);
856
857 total_written = qsfp_write(ppd, target, *ppos, buff, count);
858 if (total_written < 0) {
859 ret = total_written;
860 goto _free;
861 }
862
863 *ppos += total_written;
864
865 ret = total_written;
866
867 _free:
868 kfree(buff);
869 return ret;
870 }
871
872 /* Do a QSFP write operation on i2c chain for HFI 0. */
qsfp1_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)873 static ssize_t qsfp1_debugfs_write(struct file *file, const char __user *buf,
874 size_t count, loff_t *ppos)
875 {
876 return __qsfp_debugfs_write(file, buf, count, ppos, 0);
877 }
878
879 /* Do a QSFP write operation on i2c chain for HFI 1. */
qsfp2_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)880 static ssize_t qsfp2_debugfs_write(struct file *file, const char __user *buf,
881 size_t count, loff_t *ppos)
882 {
883 return __qsfp_debugfs_write(file, buf, count, ppos, 1);
884 }
885
886 /* Do a QSFP read operation on the i2c chain for the given HFI. */
__qsfp_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos,u32 target)887 static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf,
888 size_t count, loff_t *ppos, u32 target)
889 {
890 struct hfi1_pportdata *ppd;
891 char *buff;
892 int ret;
893 int total_read;
894
895 if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */
896 ret = -EINVAL;
897 goto _return;
898 }
899
900 ppd = private2ppd(file);
901
902 buff = kmalloc(count, GFP_KERNEL);
903 if (!buff) {
904 ret = -ENOMEM;
905 goto _return;
906 }
907
908 total_read = qsfp_read(ppd, target, *ppos, buff, count);
909 if (total_read < 0) {
910 ret = total_read;
911 goto _free;
912 }
913
914 *ppos += total_read;
915
916 ret = copy_to_user(buf, buff, total_read);
917 if (ret > 0) {
918 ret = -EFAULT;
919 goto _free;
920 }
921
922 ret = total_read;
923
924 _free:
925 kfree(buff);
926 _return:
927 return ret;
928 }
929
930 /* Do a QSFP read operation on i2c chain for HFI 0. */
qsfp1_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)931 static ssize_t qsfp1_debugfs_read(struct file *file, char __user *buf,
932 size_t count, loff_t *ppos)
933 {
934 return __qsfp_debugfs_read(file, buf, count, ppos, 0);
935 }
936
937 /* Do a QSFP read operation on i2c chain for HFI 1. */
qsfp2_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)938 static ssize_t qsfp2_debugfs_read(struct file *file, char __user *buf,
939 size_t count, loff_t *ppos)
940 {
941 return __qsfp_debugfs_read(file, buf, count, ppos, 1);
942 }
943
__i2c_debugfs_open(struct inode * in,struct file * fp,u32 target)944 static int __i2c_debugfs_open(struct inode *in, struct file *fp, u32 target)
945 {
946 struct hfi1_pportdata *ppd;
947
948 ppd = private2ppd(fp);
949
950 return acquire_chip_resource(ppd->dd, i2c_target(target), 0);
951 }
952
i2c1_debugfs_open(struct inode * in,struct file * fp)953 static int i2c1_debugfs_open(struct inode *in, struct file *fp)
954 {
955 return __i2c_debugfs_open(in, fp, 0);
956 }
957
i2c2_debugfs_open(struct inode * in,struct file * fp)958 static int i2c2_debugfs_open(struct inode *in, struct file *fp)
959 {
960 return __i2c_debugfs_open(in, fp, 1);
961 }
962
__i2c_debugfs_release(struct inode * in,struct file * fp,u32 target)963 static int __i2c_debugfs_release(struct inode *in, struct file *fp, u32 target)
964 {
965 struct hfi1_pportdata *ppd;
966
967 ppd = private2ppd(fp);
968
969 release_chip_resource(ppd->dd, i2c_target(target));
970
971 return 0;
972 }
973
i2c1_debugfs_release(struct inode * in,struct file * fp)974 static int i2c1_debugfs_release(struct inode *in, struct file *fp)
975 {
976 return __i2c_debugfs_release(in, fp, 0);
977 }
978
i2c2_debugfs_release(struct inode * in,struct file * fp)979 static int i2c2_debugfs_release(struct inode *in, struct file *fp)
980 {
981 return __i2c_debugfs_release(in, fp, 1);
982 }
983
__qsfp_debugfs_open(struct inode * in,struct file * fp,u32 target)984 static int __qsfp_debugfs_open(struct inode *in, struct file *fp, u32 target)
985 {
986 struct hfi1_pportdata *ppd;
987
988 ppd = private2ppd(fp);
989
990 return acquire_chip_resource(ppd->dd, i2c_target(target), 0);
991 }
992
qsfp1_debugfs_open(struct inode * in,struct file * fp)993 static int qsfp1_debugfs_open(struct inode *in, struct file *fp)
994 {
995 return __qsfp_debugfs_open(in, fp, 0);
996 }
997
qsfp2_debugfs_open(struct inode * in,struct file * fp)998 static int qsfp2_debugfs_open(struct inode *in, struct file *fp)
999 {
1000 return __qsfp_debugfs_open(in, fp, 1);
1001 }
1002
__qsfp_debugfs_release(struct inode * in,struct file * fp,u32 target)1003 static int __qsfp_debugfs_release(struct inode *in, struct file *fp, u32 target)
1004 {
1005 struct hfi1_pportdata *ppd;
1006
1007 ppd = private2ppd(fp);
1008
1009 release_chip_resource(ppd->dd, i2c_target(target));
1010
1011 return 0;
1012 }
1013
qsfp1_debugfs_release(struct inode * in,struct file * fp)1014 static int qsfp1_debugfs_release(struct inode *in, struct file *fp)
1015 {
1016 return __qsfp_debugfs_release(in, fp, 0);
1017 }
1018
qsfp2_debugfs_release(struct inode * in,struct file * fp)1019 static int qsfp2_debugfs_release(struct inode *in, struct file *fp)
1020 {
1021 return __qsfp_debugfs_release(in, fp, 1);
1022 }
1023
1024 #define EXPROM_WRITE_ENABLE BIT_ULL(14)
1025
1026 static bool exprom_wp_disabled;
1027
exprom_wp_set(struct hfi1_devdata * dd,bool disable)1028 static int exprom_wp_set(struct hfi1_devdata *dd, bool disable)
1029 {
1030 u64 gpio_val = 0;
1031
1032 if (disable) {
1033 gpio_val = EXPROM_WRITE_ENABLE;
1034 exprom_wp_disabled = true;
1035 dd_dev_info(dd, "Disable Expansion ROM Write Protection\n");
1036 } else {
1037 exprom_wp_disabled = false;
1038 dd_dev_info(dd, "Enable Expansion ROM Write Protection\n");
1039 }
1040
1041 write_csr(dd, ASIC_GPIO_OUT, gpio_val);
1042 write_csr(dd, ASIC_GPIO_OE, gpio_val);
1043
1044 return 0;
1045 }
1046
exprom_wp_debugfs_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)1047 static ssize_t exprom_wp_debugfs_read(struct file *file, char __user *buf,
1048 size_t count, loff_t *ppos)
1049 {
1050 return 0;
1051 }
1052
exprom_wp_debugfs_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)1053 static ssize_t exprom_wp_debugfs_write(struct file *file,
1054 const char __user *buf, size_t count,
1055 loff_t *ppos)
1056 {
1057 struct hfi1_pportdata *ppd = private2ppd(file);
1058 char cdata;
1059
1060 if (count != 1)
1061 return -EINVAL;
1062 if (get_user(cdata, buf))
1063 return -EFAULT;
1064 if (cdata == '0')
1065 exprom_wp_set(ppd->dd, false);
1066 else if (cdata == '1')
1067 exprom_wp_set(ppd->dd, true);
1068 else
1069 return -EINVAL;
1070
1071 return 1;
1072 }
1073
1074 static unsigned long exprom_in_use;
1075
exprom_wp_debugfs_open(struct inode * in,struct file * fp)1076 static int exprom_wp_debugfs_open(struct inode *in, struct file *fp)
1077 {
1078 if (test_and_set_bit(0, &exprom_in_use))
1079 return -EBUSY;
1080
1081 return 0;
1082 }
1083
exprom_wp_debugfs_release(struct inode * in,struct file * fp)1084 static int exprom_wp_debugfs_release(struct inode *in, struct file *fp)
1085 {
1086 struct hfi1_pportdata *ppd = private2ppd(fp);
1087
1088 if (exprom_wp_disabled)
1089 exprom_wp_set(ppd->dd, false);
1090 clear_bit(0, &exprom_in_use);
1091
1092 return 0;
1093 }
1094
1095 #define DEBUGFS_OPS(nm, readroutine, writeroutine) \
1096 { \
1097 .name = nm, \
1098 .ops = { \
1099 .owner = THIS_MODULE, \
1100 .read = readroutine, \
1101 .write = writeroutine, \
1102 .llseek = generic_file_llseek, \
1103 }, \
1104 }
1105
1106 #define DEBUGFS_XOPS(nm, readf, writef, openf, releasef) \
1107 { \
1108 .name = nm, \
1109 .ops = { \
1110 .owner = THIS_MODULE, \
1111 .read = readf, \
1112 .write = writef, \
1113 .llseek = generic_file_llseek, \
1114 .open = openf, \
1115 .release = releasef \
1116 }, \
1117 }
1118
1119 static const struct counter_info cntr_ops[] = {
1120 DEBUGFS_OPS("counter_names", dev_names_read, NULL),
1121 DEBUGFS_OPS("counters", dev_counters_read, NULL),
1122 DEBUGFS_OPS("portcounter_names", portnames_read, NULL),
1123 };
1124
1125 static const struct counter_info port_cntr_ops[] = {
1126 DEBUGFS_OPS("port%dcounters", portcntrs_debugfs_read, NULL),
1127 DEBUGFS_XOPS("i2c1", i2c1_debugfs_read, i2c1_debugfs_write,
1128 i2c1_debugfs_open, i2c1_debugfs_release),
1129 DEBUGFS_XOPS("i2c2", i2c2_debugfs_read, i2c2_debugfs_write,
1130 i2c2_debugfs_open, i2c2_debugfs_release),
1131 DEBUGFS_OPS("qsfp_dump%d", qsfp_debugfs_dump, NULL),
1132 DEBUGFS_XOPS("qsfp1", qsfp1_debugfs_read, qsfp1_debugfs_write,
1133 qsfp1_debugfs_open, qsfp1_debugfs_release),
1134 DEBUGFS_XOPS("qsfp2", qsfp2_debugfs_read, qsfp2_debugfs_write,
1135 qsfp2_debugfs_open, qsfp2_debugfs_release),
1136 DEBUGFS_XOPS("exprom_wp", exprom_wp_debugfs_read,
1137 exprom_wp_debugfs_write, exprom_wp_debugfs_open,
1138 exprom_wp_debugfs_release),
1139 DEBUGFS_OPS("asic_flags", asic_flags_read, asic_flags_write),
1140 DEBUGFS_OPS("dc8051_memory", dc8051_memory_read, NULL),
1141 DEBUGFS_OPS("lcb", debugfs_lcb_read, debugfs_lcb_write),
1142 };
1143
_sdma_cpu_list_seq_start(struct seq_file * s,loff_t * pos)1144 static void *_sdma_cpu_list_seq_start(struct seq_file *s, loff_t *pos)
1145 {
1146 if (*pos >= num_online_cpus())
1147 return NULL;
1148
1149 return pos;
1150 }
1151
_sdma_cpu_list_seq_next(struct seq_file * s,void * v,loff_t * pos)1152 static void *_sdma_cpu_list_seq_next(struct seq_file *s, void *v, loff_t *pos)
1153 {
1154 ++*pos;
1155 if (*pos >= num_online_cpus())
1156 return NULL;
1157
1158 return pos;
1159 }
1160
_sdma_cpu_list_seq_stop(struct seq_file * s,void * v)1161 static void _sdma_cpu_list_seq_stop(struct seq_file *s, void *v)
1162 {
1163 /* nothing allocated */
1164 }
1165
_sdma_cpu_list_seq_show(struct seq_file * s,void * v)1166 static int _sdma_cpu_list_seq_show(struct seq_file *s, void *v)
1167 {
1168 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
1169 struct hfi1_devdata *dd = dd_from_dev(ibd);
1170 loff_t *spos = v;
1171 loff_t i = *spos;
1172
1173 sdma_seqfile_dump_cpu_list(s, dd, (unsigned long)i);
1174 return 0;
1175 }
1176
1177 DEBUGFS_SEQ_FILE_OPS(sdma_cpu_list);
1178 DEBUGFS_SEQ_FILE_OPEN(sdma_cpu_list)
1179 DEBUGFS_FILE_OPS(sdma_cpu_list);
1180
hfi1_dbg_ibdev_init(struct hfi1_ibdev * ibd)1181 void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd)
1182 {
1183 char name[sizeof("port0counters") + 1];
1184 char link[10];
1185 struct hfi1_devdata *dd = dd_from_dev(ibd);
1186 struct hfi1_pportdata *ppd;
1187 struct dentry *root;
1188 int unit = dd->unit;
1189 int i, j;
1190
1191 if (!hfi1_dbg_root)
1192 return;
1193 snprintf(name, sizeof(name), "%s_%d", class_name(), unit);
1194 snprintf(link, sizeof(link), "%d", unit);
1195 root = debugfs_create_dir(name, hfi1_dbg_root);
1196 ibd->hfi1_ibdev_dbg = root;
1197
1198 ibd->hfi1_ibdev_link =
1199 debugfs_create_symlink(link, hfi1_dbg_root, name);
1200
1201 debugfs_create_file("opcode_stats", 0444, root, ibd,
1202 &_opcode_stats_file_ops);
1203 debugfs_create_file("tx_opcode_stats", 0444, root, ibd,
1204 &_tx_opcode_stats_file_ops);
1205 debugfs_create_file("ctx_stats", 0444, root, ibd, &_ctx_stats_file_ops);
1206 debugfs_create_file("qp_stats", 0444, root, ibd, &_qp_stats_file_ops);
1207 debugfs_create_file("sdes", 0444, root, ibd, &_sdes_file_ops);
1208 debugfs_create_file("rcds", 0444, root, ibd, &_rcds_file_ops);
1209 debugfs_create_file("pios", 0444, root, ibd, &_pios_file_ops);
1210 debugfs_create_file("sdma_cpu_list", 0444, root, ibd,
1211 &_sdma_cpu_list_file_ops);
1212
1213 /* dev counter files */
1214 for (i = 0; i < ARRAY_SIZE(cntr_ops); i++)
1215 debugfs_create_file(cntr_ops[i].name, 0444, root, dd,
1216 &cntr_ops[i].ops);
1217
1218 /* per port files */
1219 for (ppd = dd->pport, j = 0; j < dd->num_pports; j++, ppd++)
1220 for (i = 0; i < ARRAY_SIZE(port_cntr_ops); i++) {
1221 snprintf(name,
1222 sizeof(name),
1223 port_cntr_ops[i].name,
1224 j + 1);
1225 debugfs_create_file(name,
1226 !port_cntr_ops[i].ops.write ?
1227 S_IRUGO :
1228 S_IRUGO | S_IWUSR,
1229 root, ppd, &port_cntr_ops[i].ops);
1230 }
1231
1232 hfi1_fault_init_debugfs(ibd);
1233 }
1234
hfi1_dbg_ibdev_exit(struct hfi1_ibdev * ibd)1235 void hfi1_dbg_ibdev_exit(struct hfi1_ibdev *ibd)
1236 {
1237 if (!hfi1_dbg_root)
1238 goto out;
1239 hfi1_fault_exit_debugfs(ibd);
1240 debugfs_remove(ibd->hfi1_ibdev_link);
1241 debugfs_remove_recursive(ibd->hfi1_ibdev_dbg);
1242 out:
1243 ibd->hfi1_ibdev_dbg = NULL;
1244 }
1245
1246 /*
1247 * driver stats field names, one line per stat, single string. Used by
1248 * programs like hfistats to print the stats in a way which works for
1249 * different versions of drivers, without changing program source.
1250 * if hfi1_ib_stats changes, this needs to change. Names need to be
1251 * 12 chars or less (w/o newline), for proper display by hfistats utility.
1252 */
1253 static const char * const hfi1_statnames[] = {
1254 /* must be element 0*/
1255 "KernIntr",
1256 "ErrorIntr",
1257 "Tx_Errs",
1258 "Rcv_Errs",
1259 "H/W_Errs",
1260 "NoPIOBufs",
1261 "CtxtsOpen",
1262 "RcvLen_Errs",
1263 "EgrBufFull",
1264 "EgrHdrFull"
1265 };
1266
_driver_stats_names_seq_start(struct seq_file * s,loff_t * pos)1267 static void *_driver_stats_names_seq_start(struct seq_file *s, loff_t *pos)
1268 {
1269 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1270 return NULL;
1271 return pos;
1272 }
1273
_driver_stats_names_seq_next(struct seq_file * s,void * v,loff_t * pos)1274 static void *_driver_stats_names_seq_next(
1275 struct seq_file *s,
1276 void *v,
1277 loff_t *pos)
1278 {
1279 ++*pos;
1280 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1281 return NULL;
1282 return pos;
1283 }
1284
_driver_stats_names_seq_stop(struct seq_file * s,void * v)1285 static void _driver_stats_names_seq_stop(struct seq_file *s, void *v)
1286 {
1287 }
1288
_driver_stats_names_seq_show(struct seq_file * s,void * v)1289 static int _driver_stats_names_seq_show(struct seq_file *s, void *v)
1290 {
1291 loff_t *spos = v;
1292
1293 seq_printf(s, "%s\n", hfi1_statnames[*spos]);
1294 return 0;
1295 }
1296
1297 DEBUGFS_SEQ_FILE_OPS(driver_stats_names);
1298 DEBUGFS_SEQ_FILE_OPEN(driver_stats_names)
1299 DEBUGFS_FILE_OPS(driver_stats_names);
1300
_driver_stats_seq_start(struct seq_file * s,loff_t * pos)1301 static void *_driver_stats_seq_start(struct seq_file *s, loff_t *pos)
1302 {
1303 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1304 return NULL;
1305 return pos;
1306 }
1307
_driver_stats_seq_next(struct seq_file * s,void * v,loff_t * pos)1308 static void *_driver_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
1309 {
1310 ++*pos;
1311 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1312 return NULL;
1313 return pos;
1314 }
1315
_driver_stats_seq_stop(struct seq_file * s,void * v)1316 static void _driver_stats_seq_stop(struct seq_file *s, void *v)
1317 {
1318 }
1319
hfi1_sps_show_ints(struct seq_file * s)1320 static void hfi1_sps_show_ints(struct seq_file *s)
1321 {
1322 unsigned long index, flags;
1323 struct hfi1_devdata *dd;
1324 u64 sps_ints = 0;
1325
1326 xa_lock_irqsave(&hfi1_dev_table, flags);
1327 xa_for_each(&hfi1_dev_table, index, dd) {
1328 sps_ints += get_all_cpu_total(dd->int_counter);
1329 }
1330 xa_unlock_irqrestore(&hfi1_dev_table, flags);
1331 seq_write(s, &sps_ints, sizeof(u64));
1332 }
1333
_driver_stats_seq_show(struct seq_file * s,void * v)1334 static int _driver_stats_seq_show(struct seq_file *s, void *v)
1335 {
1336 loff_t *spos = v;
1337 u64 *stats = (u64 *)&hfi1_stats;
1338
1339 /* special case for interrupts */
1340 if (*spos == 0)
1341 hfi1_sps_show_ints(s);
1342 else
1343 seq_write(s, stats + *spos, sizeof(u64));
1344 return 0;
1345 }
1346
1347 DEBUGFS_SEQ_FILE_OPS(driver_stats);
1348 DEBUGFS_SEQ_FILE_OPEN(driver_stats)
1349 DEBUGFS_FILE_OPS(driver_stats);
1350
hfi1_dbg_init(void)1351 void hfi1_dbg_init(void)
1352 {
1353 hfi1_dbg_root = debugfs_create_dir(DRIVER_NAME, NULL);
1354 debugfs_create_file("driver_stats_names", 0444, hfi1_dbg_root, NULL,
1355 &_driver_stats_names_file_ops);
1356 debugfs_create_file("driver_stats", 0444, hfi1_dbg_root, NULL,
1357 &_driver_stats_file_ops);
1358 }
1359
hfi1_dbg_exit(void)1360 void hfi1_dbg_exit(void)
1361 {
1362 debugfs_remove_recursive(hfi1_dbg_root);
1363 hfi1_dbg_root = NULL;
1364 }
1365