blob: 7fe9dd885746e68100da0d1e3db965ff2127bbbe [file] [log] [blame]
Mike Marciniszyn77241052015-07-30 15:17:43 -04001#ifdef CONFIG_DEBUG_FS
2/*
Jubin John05d6ac12016-02-14 20:22:17 -08003 * Copyright(c) 2015, 2016 Intel Corporation.
Mike Marciniszyn77241052015-07-30 15:17:43 -04004 *
5 * This file is provided under a dual BSD/GPLv2 license. When using or
6 * redistributing this file, you may do so under either license.
7 *
8 * GPL LICENSE SUMMARY
9 *
Mike Marciniszyn77241052015-07-30 15:17:43 -040010 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * BSD LICENSE
20 *
Mike Marciniszyn77241052015-07-30 15:17:43 -040021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 *
25 * - Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * - Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in
29 * the documentation and/or other materials provided with the
30 * distribution.
31 * - Neither the name of Intel Corporation nor the names of its
32 * contributors may be used to endorse or promote products derived
33 * from this software without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 *
47 */
48#include <linux/debugfs.h>
49#include <linux/seq_file.h>
50#include <linux/kernel.h>
51#include <linux/export.h>
Dean Luickae993e72016-03-05 08:50:27 -080052#include <linux/module.h>
Michael J. Ruhl1bb0d7b2017-02-08 05:28:31 -080053#include <linux/string.h>
Mike Marciniszyn77241052015-07-30 15:17:43 -040054
55#include "hfi.h"
56#include "debugfs.h"
57#include "device.h"
58#include "qp.h"
59#include "sdma.h"
60
61static struct dentry *hfi1_dbg_root;
62
Mike Marciniszyn16170d92016-08-31 07:24:46 -070063/* wrappers to enforce srcu in seq file */
64static ssize_t hfi1_seq_read(
65 struct file *file,
66 char __user *buf,
67 size_t size,
68 loff_t *ppos)
69{
70 struct dentry *d = file->f_path.dentry;
71 int srcu_idx;
72 ssize_t r;
73
74 r = debugfs_use_file_start(d, &srcu_idx);
75 if (likely(!r))
76 r = seq_read(file, buf, size, ppos);
77 debugfs_use_file_finish(srcu_idx);
78 return r;
79}
80
81static loff_t hfi1_seq_lseek(
82 struct file *file,
83 loff_t offset,
84 int whence)
85{
86 struct dentry *d = file->f_path.dentry;
87 int srcu_idx;
88 loff_t r;
89
90 r = debugfs_use_file_start(d, &srcu_idx);
91 if (likely(!r))
92 r = seq_lseek(file, offset, whence);
93 debugfs_use_file_finish(srcu_idx);
94 return r;
95}
96
Mike Marciniszyn77241052015-07-30 15:17:43 -040097#define private2dd(file) (file_inode(file)->i_private)
98#define private2ppd(file) (file_inode(file)->i_private)
99
100#define DEBUGFS_SEQ_FILE_OPS(name) \
101static const struct seq_operations _##name##_seq_ops = { \
102 .start = _##name##_seq_start, \
103 .next = _##name##_seq_next, \
104 .stop = _##name##_seq_stop, \
105 .show = _##name##_seq_show \
106}
Jubin Johnf4d507c2016-02-14 20:20:25 -0800107
Mike Marciniszyn77241052015-07-30 15:17:43 -0400108#define DEBUGFS_SEQ_FILE_OPEN(name) \
109static int _##name##_open(struct inode *inode, struct file *s) \
110{ \
111 struct seq_file *seq; \
112 int ret; \
113 ret = seq_open(s, &_##name##_seq_ops); \
114 if (ret) \
115 return ret; \
116 seq = s->private_data; \
117 seq->private = inode->i_private; \
118 return 0; \
119}
120
121#define DEBUGFS_FILE_OPS(name) \
122static const struct file_operations _##name##_file_ops = { \
123 .owner = THIS_MODULE, \
124 .open = _##name##_open, \
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700125 .read = hfi1_seq_read, \
126 .llseek = hfi1_seq_lseek, \
Mike Marciniszyn77241052015-07-30 15:17:43 -0400127 .release = seq_release \
128}
129
130#define DEBUGFS_FILE_CREATE(name, parent, data, ops, mode) \
131do { \
132 struct dentry *ent; \
133 ent = debugfs_create_file(name, mode, parent, \
134 data, ops); \
135 if (!ent) \
136 pr_warn("create of %s failed\n", name); \
137} while (0)
138
Mike Marciniszyn77241052015-07-30 15:17:43 -0400139#define DEBUGFS_SEQ_FILE_CREATE(name, parent, data) \
140 DEBUGFS_FILE_CREATE(#name, parent, data, &_##name##_file_ops, S_IRUGO)
141
142static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400143{
144 struct hfi1_opcode_stats_perctx *opstats;
145
Mike Marciniszyn77241052015-07-30 15:17:43 -0400146 if (*pos >= ARRAY_SIZE(opstats->stats))
147 return NULL;
148 return pos;
149}
150
151static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
152{
153 struct hfi1_opcode_stats_perctx *opstats;
154
155 ++*pos;
156 if (*pos >= ARRAY_SIZE(opstats->stats))
157 return NULL;
158 return pos;
159}
160
Mike Marciniszyn77241052015-07-30 15:17:43 -0400161static void _opcode_stats_seq_stop(struct seq_file *s, void *v)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400162{
Mike Marciniszyn77241052015-07-30 15:17:43 -0400163}
164
165static int _opcode_stats_seq_show(struct seq_file *s, void *v)
166{
167 loff_t *spos = v;
168 loff_t i = *spos, j;
169 u64 n_packets = 0, n_bytes = 0;
170 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
171 struct hfi1_devdata *dd = dd_from_dev(ibd);
172
173 for (j = 0; j < dd->first_user_ctxt; j++) {
174 if (!dd->rcd[j])
175 continue;
176 n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
177 n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
178 }
179 if (!n_packets && !n_bytes)
180 return SEQ_SKIP;
181 seq_printf(s, "%02llx %llu/%llu\n", i,
Jubin John17fb4f22016-02-14 20:21:52 -0800182 (unsigned long long)n_packets,
183 (unsigned long long)n_bytes);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400184
185 return 0;
186}
187
188DEBUGFS_SEQ_FILE_OPS(opcode_stats);
189DEBUGFS_SEQ_FILE_OPEN(opcode_stats)
190DEBUGFS_FILE_OPS(opcode_stats);
191
192static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos)
193{
194 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
195 struct hfi1_devdata *dd = dd_from_dev(ibd);
196
197 if (!*pos)
198 return SEQ_START_TOKEN;
199 if (*pos >= dd->first_user_ctxt)
200 return NULL;
201 return pos;
202}
203
204static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
205{
206 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
207 struct hfi1_devdata *dd = dd_from_dev(ibd);
208
209 if (v == SEQ_START_TOKEN)
210 return pos;
211
212 ++*pos;
213 if (*pos >= dd->first_user_ctxt)
214 return NULL;
215 return pos;
216}
217
218static void _ctx_stats_seq_stop(struct seq_file *s, void *v)
219{
220 /* nothing allocated */
221}
222
223static int _ctx_stats_seq_show(struct seq_file *s, void *v)
224{
225 loff_t *spos;
226 loff_t i, j;
227 u64 n_packets = 0;
228 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
229 struct hfi1_devdata *dd = dd_from_dev(ibd);
230
231 if (v == SEQ_START_TOKEN) {
232 seq_puts(s, "Ctx:npkts\n");
233 return 0;
234 }
235
236 spos = v;
237 i = *spos;
238
239 if (!dd->rcd[i])
240 return SEQ_SKIP;
241
242 for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++)
243 n_packets += dd->rcd[i]->opstats->stats[j].n_packets;
244
245 if (!n_packets)
246 return SEQ_SKIP;
247
248 seq_printf(s, " %llu:%llu\n", i, n_packets);
249 return 0;
250}
251
252DEBUGFS_SEQ_FILE_OPS(ctx_stats);
253DEBUGFS_SEQ_FILE_OPEN(ctx_stats)
254DEBUGFS_FILE_OPS(ctx_stats);
255
256static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
Mike Marciniszync62fb262016-08-12 11:17:37 -0400257 __acquires(RCU)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400258{
259 struct qp_iter *iter;
260 loff_t n = *pos;
261
Mike Marciniszyn77241052015-07-30 15:17:43 -0400262 iter = qp_iter_init(s->private);
Mike Marciniszync62fb262016-08-12 11:17:37 -0400263
264 /* stop calls rcu_read_unlock */
265 rcu_read_lock();
266
Mike Marciniszyn77241052015-07-30 15:17:43 -0400267 if (!iter)
268 return NULL;
269
Mike Marciniszync62fb262016-08-12 11:17:37 -0400270 do {
Mike Marciniszyn77241052015-07-30 15:17:43 -0400271 if (qp_iter_next(iter)) {
272 kfree(iter);
273 return NULL;
274 }
Mike Marciniszync62fb262016-08-12 11:17:37 -0400275 } while (n--);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400276
277 return iter;
278}
279
280static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
Jubin John17fb4f22016-02-14 20:21:52 -0800281 loff_t *pos)
Mike Marciniszync62fb262016-08-12 11:17:37 -0400282 __must_hold(RCU)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400283{
284 struct qp_iter *iter = iter_ptr;
285
286 (*pos)++;
287
288 if (qp_iter_next(iter)) {
289 kfree(iter);
290 return NULL;
291 }
292
293 return iter;
294}
295
296static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
Mike Marciniszync62fb262016-08-12 11:17:37 -0400297 __releases(RCU)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400298{
299 rcu_read_unlock();
300}
301
302static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
303{
304 struct qp_iter *iter = iter_ptr;
305
306 if (!iter)
307 return 0;
308
309 qp_iter_print(s, iter);
310
311 return 0;
312}
313
314DEBUGFS_SEQ_FILE_OPS(qp_stats);
315DEBUGFS_SEQ_FILE_OPEN(qp_stats)
316DEBUGFS_FILE_OPS(qp_stats);
317
318static void *_sdes_seq_start(struct seq_file *s, loff_t *pos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400319{
320 struct hfi1_ibdev *ibd;
321 struct hfi1_devdata *dd;
322
Mike Marciniszyn77241052015-07-30 15:17:43 -0400323 ibd = (struct hfi1_ibdev *)s->private;
324 dd = dd_from_dev(ibd);
325 if (!dd->per_sdma || *pos >= dd->num_sdma)
326 return NULL;
327 return pos;
328}
329
330static void *_sdes_seq_next(struct seq_file *s, void *v, loff_t *pos)
331{
332 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
333 struct hfi1_devdata *dd = dd_from_dev(ibd);
334
335 ++*pos;
336 if (!dd->per_sdma || *pos >= dd->num_sdma)
337 return NULL;
338 return pos;
339}
340
Mike Marciniszyn77241052015-07-30 15:17:43 -0400341static void _sdes_seq_stop(struct seq_file *s, void *v)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400342{
Mike Marciniszyn77241052015-07-30 15:17:43 -0400343}
344
345static int _sdes_seq_show(struct seq_file *s, void *v)
346{
347 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
348 struct hfi1_devdata *dd = dd_from_dev(ibd);
349 loff_t *spos = v;
350 loff_t i = *spos;
351
352 sdma_seqfile_dump_sde(s, &dd->per_sdma[i]);
353 return 0;
354}
355
356DEBUGFS_SEQ_FILE_OPS(sdes);
357DEBUGFS_SEQ_FILE_OPEN(sdes)
358DEBUGFS_FILE_OPS(sdes);
359
360/* read the per-device counters */
361static ssize_t dev_counters_read(struct file *file, char __user *buf,
362 size_t count, loff_t *ppos)
363{
364 u64 *counters;
365 size_t avail;
366 struct hfi1_devdata *dd;
367 ssize_t rval;
368
Mike Marciniszyn77241052015-07-30 15:17:43 -0400369 dd = private2dd(file);
Dean Luick582e05c2016-02-18 11:13:01 -0800370 avail = hfi1_read_cntrs(dd, NULL, &counters);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400371 rval = simple_read_from_buffer(buf, count, ppos, counters, avail);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400372 return rval;
373}
374
375/* read the per-device counters */
376static ssize_t dev_names_read(struct file *file, char __user *buf,
377 size_t count, loff_t *ppos)
378{
379 char *names;
380 size_t avail;
381 struct hfi1_devdata *dd;
382 ssize_t rval;
383
Mike Marciniszyn77241052015-07-30 15:17:43 -0400384 dd = private2dd(file);
Dean Luick582e05c2016-02-18 11:13:01 -0800385 avail = hfi1_read_cntrs(dd, &names, NULL);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400386 rval = simple_read_from_buffer(buf, count, ppos, names, avail);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400387 return rval;
388}
389
390struct counter_info {
391 char *name;
392 const struct file_operations ops;
393};
394
395/*
396 * Could use file_inode(file)->i_ino to figure out which file,
397 * instead of separate routine for each, but for now, this works...
398 */
399
400/* read the per-port names (same for each port) */
401static ssize_t portnames_read(struct file *file, char __user *buf,
402 size_t count, loff_t *ppos)
403{
404 char *names;
405 size_t avail;
406 struct hfi1_devdata *dd;
407 ssize_t rval;
408
Mike Marciniszyn77241052015-07-30 15:17:43 -0400409 dd = private2dd(file);
Dean Luick582e05c2016-02-18 11:13:01 -0800410 avail = hfi1_read_portcntrs(dd->pport, &names, NULL);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400411 rval = simple_read_from_buffer(buf, count, ppos, names, avail);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400412 return rval;
413}
414
415/* read the per-port counters */
416static ssize_t portcntrs_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800417 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400418{
419 u64 *counters;
420 size_t avail;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400421 struct hfi1_pportdata *ppd;
422 ssize_t rval;
423
Mike Marciniszyn77241052015-07-30 15:17:43 -0400424 ppd = private2ppd(file);
Dean Luick582e05c2016-02-18 11:13:01 -0800425 avail = hfi1_read_portcntrs(ppd, NULL, &counters);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400426 rval = simple_read_from_buffer(buf, count, ppos, counters, avail);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400427 return rval;
428}
429
Dean Luickc9c8ea32016-03-05 08:50:33 -0800430static void check_dyn_flag(u64 scratch0, char *p, int size, int *used,
431 int this_hfi, int hfi, u32 flag, const char *what)
432{
433 u32 mask;
434
435 mask = flag << (hfi ? CR_DYN_SHIFT : 0);
436 if (scratch0 & mask) {
437 *used += scnprintf(p + *used, size - *used,
438 " 0x%08x - HFI%d %s in use, %s device\n",
439 mask, hfi, what,
440 this_hfi == hfi ? "this" : "other");
441 }
442}
443
444static ssize_t asic_flags_read(struct file *file, char __user *buf,
445 size_t count, loff_t *ppos)
446{
447 struct hfi1_pportdata *ppd;
448 struct hfi1_devdata *dd;
449 u64 scratch0;
450 char *tmp;
451 int ret = 0;
452 int size;
453 int used;
454 int i;
455
Dean Luickc9c8ea32016-03-05 08:50:33 -0800456 ppd = private2ppd(file);
457 dd = ppd->dd;
458 size = PAGE_SIZE;
459 used = 0;
460 tmp = kmalloc(size, GFP_KERNEL);
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700461 if (!tmp)
Dean Luickc9c8ea32016-03-05 08:50:33 -0800462 return -ENOMEM;
Dean Luickc9c8ea32016-03-05 08:50:33 -0800463
464 scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
465 used += scnprintf(tmp + used, size - used,
466 "Resource flags: 0x%016llx\n", scratch0);
467
468 /* check permanent flag */
469 if (scratch0 & CR_THERM_INIT) {
470 used += scnprintf(tmp + used, size - used,
471 " 0x%08x - thermal monitoring initialized\n",
472 (u32)CR_THERM_INIT);
473 }
474
475 /* check each dynamic flag on each HFI */
476 for (i = 0; i < 2; i++) {
477 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
478 CR_SBUS, "SBus");
479 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
480 CR_EPROM, "EPROM");
481 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
482 CR_I2C1, "i2c chain 1");
483 check_dyn_flag(scratch0, tmp, size, &used, dd->hfi1_id, i,
484 CR_I2C2, "i2c chain 2");
485 }
486 used += scnprintf(tmp + used, size - used, "Write bits to clear\n");
487
488 ret = simple_read_from_buffer(buf, count, ppos, tmp, used);
Dean Luickc9c8ea32016-03-05 08:50:33 -0800489 kfree(tmp);
490 return ret;
491}
492
493static ssize_t asic_flags_write(struct file *file, const char __user *buf,
494 size_t count, loff_t *ppos)
495{
496 struct hfi1_pportdata *ppd;
497 struct hfi1_devdata *dd;
498 char *buff;
499 int ret;
500 unsigned long long value;
501 u64 scratch0;
502 u64 clear;
503
Dean Luickc9c8ea32016-03-05 08:50:33 -0800504 ppd = private2ppd(file);
505 dd = ppd->dd;
506
Dean Luickc9c8ea32016-03-05 08:50:33 -0800507 /* zero terminate and read the expected integer */
Michael J. Ruhl1bb0d7b2017-02-08 05:28:31 -0800508 buff = memdup_user_nul(buf, count);
509 if (IS_ERR(buff))
510 return PTR_ERR(buff);
511
Dean Luickc9c8ea32016-03-05 08:50:33 -0800512 ret = kstrtoull(buff, 0, &value);
513 if (ret)
514 goto do_free;
515 clear = value;
516
517 /* obtain exclusive access */
518 mutex_lock(&dd->asic_data->asic_resource_mutex);
519 acquire_hw_mutex(dd);
520
521 scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
522 scratch0 &= ~clear;
523 write_csr(dd, ASIC_CFG_SCRATCH, scratch0);
524 /* force write to be visible to other HFI on another OS */
525 (void)read_csr(dd, ASIC_CFG_SCRATCH);
526
527 release_hw_mutex(dd);
528 mutex_unlock(&dd->asic_data->asic_resource_mutex);
529
530 /* return the number of bytes written */
531 ret = count;
532
533 do_free:
534 kfree(buff);
Dean Luickc9c8ea32016-03-05 08:50:33 -0800535 return ret;
536}
537
Dean Luick1b9e7742016-12-07 19:32:34 -0800538/* read the dc8051 memory */
539static ssize_t dc8051_memory_read(struct file *file, char __user *buf,
540 size_t count, loff_t *ppos)
541{
542 struct hfi1_pportdata *ppd = private2ppd(file);
543 ssize_t rval;
544 void *tmp;
545 loff_t start, end;
546
547 /* the checks below expect the position to be positive */
548 if (*ppos < 0)
549 return -EINVAL;
550
551 tmp = kzalloc(DC8051_DATA_MEM_SIZE, GFP_KERNEL);
552 if (!tmp)
553 return -ENOMEM;
554
555 /*
556 * Fill in the requested portion of the temporary buffer from the
557 * 8051 memory. The 8051 memory read is done in terms of 8 bytes.
558 * Adjust start and end to fit. Skip reading anything if out of
559 * range.
560 */
561 start = *ppos & ~0x7; /* round down */
562 if (start < DC8051_DATA_MEM_SIZE) {
563 end = (*ppos + count + 7) & ~0x7; /* round up */
564 if (end > DC8051_DATA_MEM_SIZE)
565 end = DC8051_DATA_MEM_SIZE;
566 rval = read_8051_data(ppd->dd, start, end - start,
567 (u64 *)(tmp + start));
568 if (rval)
569 goto done;
570 }
571
572 rval = simple_read_from_buffer(buf, count, ppos, tmp,
573 DC8051_DATA_MEM_SIZE);
574done:
575 kfree(tmp);
576 return rval;
577}
578
579static ssize_t debugfs_lcb_read(struct file *file, char __user *buf,
580 size_t count, loff_t *ppos)
581{
582 struct hfi1_pportdata *ppd = private2ppd(file);
583 struct hfi1_devdata *dd = ppd->dd;
584 unsigned long total, csr_off;
585 u64 data;
586
587 if (*ppos < 0)
588 return -EINVAL;
589 /* only read 8 byte quantities */
590 if ((count % 8) != 0)
591 return -EINVAL;
592 /* offset must be 8-byte aligned */
593 if ((*ppos % 8) != 0)
594 return -EINVAL;
595 /* do nothing if out of range or zero count */
596 if (*ppos >= (LCB_END - LCB_START) || !count)
597 return 0;
598 /* reduce count if needed */
599 if (*ppos + count > LCB_END - LCB_START)
600 count = (LCB_END - LCB_START) - *ppos;
601
602 csr_off = LCB_START + *ppos;
603 for (total = 0; total < count; total += 8, csr_off += 8) {
604 if (read_lcb_csr(dd, csr_off, (u64 *)&data))
605 break; /* failed */
606 if (put_user(data, (unsigned long __user *)(buf + total)))
607 break;
608 }
609 *ppos += total;
610 return total;
611}
612
613static ssize_t debugfs_lcb_write(struct file *file, const char __user *buf,
614 size_t count, loff_t *ppos)
615{
616 struct hfi1_pportdata *ppd = private2ppd(file);
617 struct hfi1_devdata *dd = ppd->dd;
618 unsigned long total, csr_off, data;
619
620 if (*ppos < 0)
621 return -EINVAL;
622 /* only write 8 byte quantities */
623 if ((count % 8) != 0)
624 return -EINVAL;
625 /* offset must be 8-byte aligned */
626 if ((*ppos % 8) != 0)
627 return -EINVAL;
628 /* do nothing if out of range or zero count */
629 if (*ppos >= (LCB_END - LCB_START) || !count)
630 return 0;
631 /* reduce count if needed */
632 if (*ppos + count > LCB_END - LCB_START)
633 count = (LCB_END - LCB_START) - *ppos;
634
635 csr_off = LCB_START + *ppos;
636 for (total = 0; total < count; total += 8, csr_off += 8) {
637 if (get_user(data, (unsigned long __user *)(buf + total)))
638 break;
639 if (write_lcb_csr(dd, csr_off, data))
640 break; /* failed */
641 }
642 *ppos += total;
643 return total;
644}
645
Mike Marciniszyn77241052015-07-30 15:17:43 -0400646/*
647 * read the per-port QSFP data for ppd
648 */
649static ssize_t qsfp_debugfs_dump(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800650 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400651{
652 struct hfi1_pportdata *ppd;
653 char *tmp;
654 int ret;
655
Mike Marciniszyn77241052015-07-30 15:17:43 -0400656 ppd = private2ppd(file);
657 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL);
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700658 if (!tmp)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400659 return -ENOMEM;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400660
661 ret = qsfp_dump(ppd, tmp, PAGE_SIZE);
662 if (ret > 0)
663 ret = simple_read_from_buffer(buf, count, ppos, tmp, ret);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400664 kfree(tmp);
665 return ret;
666}
667
668/* Do an i2c write operation on the chain for the given HFI. */
669static ssize_t __i2c_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800670 size_t count, loff_t *ppos, u32 target)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400671{
672 struct hfi1_pportdata *ppd;
673 char *buff;
674 int ret;
675 int i2c_addr;
676 int offset;
677 int total_written;
678
Mike Marciniszyn77241052015-07-30 15:17:43 -0400679 ppd = private2ppd(file);
680
Dean Luick7b476222016-02-18 11:12:51 -0800681 /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */
682 i2c_addr = (*ppos >> 16) & 0xffff;
683 offset = *ppos & 0xffff;
684
685 /* explicitly reject invalid address 0 to catch cp and cat */
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700686 if (i2c_addr == 0)
687 return -EINVAL;
Dean Luick7b476222016-02-18 11:12:51 -0800688
Michael J. Ruhl1bb0d7b2017-02-08 05:28:31 -0800689 buff = memdup_user(buf, count);
690 if (IS_ERR(buff))
691 return PTR_ERR(buff);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400692
Mike Marciniszyn77241052015-07-30 15:17:43 -0400693 total_written = i2c_write(ppd, target, i2c_addr, offset, buff, count);
694 if (total_written < 0) {
695 ret = total_written;
Dean Luickae993e72016-03-05 08:50:27 -0800696 goto _free;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400697 }
698
699 *ppos += total_written;
700
701 ret = total_written;
702
703 _free:
704 kfree(buff);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400705 return ret;
706}
707
708/* Do an i2c write operation on chain for HFI 0. */
709static ssize_t i2c1_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800710 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400711{
712 return __i2c_debugfs_write(file, buf, count, ppos, 0);
713}
714
715/* Do an i2c write operation on chain for HFI 1. */
716static ssize_t i2c2_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800717 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400718{
719 return __i2c_debugfs_write(file, buf, count, ppos, 1);
720}
721
722/* Do an i2c read operation on the chain for the given HFI. */
723static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800724 size_t count, loff_t *ppos, u32 target)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400725{
726 struct hfi1_pportdata *ppd;
727 char *buff;
728 int ret;
729 int i2c_addr;
730 int offset;
731 int total_read;
732
Mike Marciniszyn77241052015-07-30 15:17:43 -0400733 ppd = private2ppd(file);
734
Dean Luick7b476222016-02-18 11:12:51 -0800735 /* byte offset format: [offsetSize][i2cAddr][offsetHigh][offsetLow] */
736 i2c_addr = (*ppos >> 16) & 0xffff;
737 offset = *ppos & 0xffff;
738
739 /* explicitly reject invalid address 0 to catch cp and cat */
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700740 if (i2c_addr == 0)
741 return -EINVAL;
Dean Luick7b476222016-02-18 11:12:51 -0800742
Mike Marciniszyn77241052015-07-30 15:17:43 -0400743 buff = kmalloc(count, GFP_KERNEL);
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700744 if (!buff)
745 return -ENOMEM;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400746
Mike Marciniszyn77241052015-07-30 15:17:43 -0400747 total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count);
748 if (total_read < 0) {
749 ret = total_read;
Dean Luickae993e72016-03-05 08:50:27 -0800750 goto _free;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400751 }
752
753 *ppos += total_read;
754
755 ret = copy_to_user(buf, buff, total_read);
756 if (ret > 0) {
757 ret = -EFAULT;
Dean Luickae993e72016-03-05 08:50:27 -0800758 goto _free;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400759 }
760
761 ret = total_read;
762
763 _free:
764 kfree(buff);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400765 return ret;
766}
767
768/* Do an i2c read operation on chain for HFI 0. */
769static ssize_t i2c1_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800770 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400771{
772 return __i2c_debugfs_read(file, buf, count, ppos, 0);
773}
774
775/* Do an i2c read operation on chain for HFI 1. */
776static ssize_t i2c2_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800777 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400778{
779 return __i2c_debugfs_read(file, buf, count, ppos, 1);
780}
781
782/* Do a QSFP write operation on the i2c chain for the given HFI. */
783static ssize_t __qsfp_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800784 size_t count, loff_t *ppos, u32 target)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400785{
786 struct hfi1_pportdata *ppd;
787 char *buff;
788 int ret;
789 int total_written;
790
Mike Marciniszyn16170d92016-08-31 07:24:46 -0700791 if (*ppos + count > QSFP_PAGESIZE * 4) /* base page + page00-page03 */
792 return -EINVAL;
Mike Marciniszyn77241052015-07-30 15:17:43 -0400793
794 ppd = private2ppd(file);
795
Michael J. Ruhl1bb0d7b2017-02-08 05:28:31 -0800796 buff = memdup_user(buf, count);
797 if (IS_ERR(buff))
798 return PTR_ERR(buff);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400799
Dean Luickae993e72016-03-05 08:50:27 -0800800 total_written = qsfp_write(ppd, target, *ppos, buff, count);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400801 if (total_written < 0) {
802 ret = total_written;
803 goto _free;
804 }
805
806 *ppos += total_written;
807
808 ret = total_written;
809
810 _free:
811 kfree(buff);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400812 return ret;
813}
814
815/* Do a QSFP write operation on i2c chain for HFI 0. */
816static ssize_t qsfp1_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800817 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400818{
819 return __qsfp_debugfs_write(file, buf, count, ppos, 0);
820}
821
822/* Do a QSFP write operation on i2c chain for HFI 1. */
823static ssize_t qsfp2_debugfs_write(struct file *file, const char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800824 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400825{
826 return __qsfp_debugfs_write(file, buf, count, ppos, 1);
827}
828
829/* Do a QSFP read operation on the i2c chain for the given HFI. */
830static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800831 size_t count, loff_t *ppos, u32 target)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400832{
833 struct hfi1_pportdata *ppd;
834 char *buff;
835 int ret;
836 int total_read;
837
Mike Marciniszyn77241052015-07-30 15:17:43 -0400838 if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */
839 ret = -EINVAL;
840 goto _return;
841 }
842
843 ppd = private2ppd(file);
844
845 buff = kmalloc(count, GFP_KERNEL);
846 if (!buff) {
847 ret = -ENOMEM;
848 goto _return;
849 }
850
Dean Luickae993e72016-03-05 08:50:27 -0800851 total_read = qsfp_read(ppd, target, *ppos, buff, count);
Mike Marciniszyn77241052015-07-30 15:17:43 -0400852 if (total_read < 0) {
853 ret = total_read;
854 goto _free;
855 }
856
857 *ppos += total_read;
858
859 ret = copy_to_user(buf, buff, total_read);
860 if (ret > 0) {
861 ret = -EFAULT;
862 goto _free;
863 }
864
865 ret = total_read;
866
867 _free:
868 kfree(buff);
869 _return:
Mike Marciniszyn77241052015-07-30 15:17:43 -0400870 return ret;
871}
872
873/* Do a QSFP read operation on i2c chain for HFI 0. */
874static ssize_t qsfp1_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800875 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400876{
877 return __qsfp_debugfs_read(file, buf, count, ppos, 0);
878}
879
880/* Do a QSFP read operation on i2c chain for HFI 1. */
881static ssize_t qsfp2_debugfs_read(struct file *file, char __user *buf,
Jubin John17fb4f22016-02-14 20:21:52 -0800882 size_t count, loff_t *ppos)
Mike Marciniszyn77241052015-07-30 15:17:43 -0400883{
884 return __qsfp_debugfs_read(file, buf, count, ppos, 1);
885}
886
Dean Luickae993e72016-03-05 08:50:27 -0800887static int __i2c_debugfs_open(struct inode *in, struct file *fp, u32 target)
888{
889 struct hfi1_pportdata *ppd;
890 int ret;
891
892 if (!try_module_get(THIS_MODULE))
893 return -ENODEV;
894
895 ppd = private2ppd(fp);
896
897 ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0);
898 if (ret) /* failed - release the module */
899 module_put(THIS_MODULE);
900
901 return ret;
902}
903
904static int i2c1_debugfs_open(struct inode *in, struct file *fp)
905{
906 return __i2c_debugfs_open(in, fp, 0);
907}
908
909static int i2c2_debugfs_open(struct inode *in, struct file *fp)
910{
911 return __i2c_debugfs_open(in, fp, 1);
912}
913
914static int __i2c_debugfs_release(struct inode *in, struct file *fp, u32 target)
915{
916 struct hfi1_pportdata *ppd;
917
918 ppd = private2ppd(fp);
919
920 release_chip_resource(ppd->dd, i2c_target(target));
921 module_put(THIS_MODULE);
922
923 return 0;
924}
925
926static int i2c1_debugfs_release(struct inode *in, struct file *fp)
927{
928 return __i2c_debugfs_release(in, fp, 0);
929}
930
931static int i2c2_debugfs_release(struct inode *in, struct file *fp)
932{
933 return __i2c_debugfs_release(in, fp, 1);
934}
935
936static int __qsfp_debugfs_open(struct inode *in, struct file *fp, u32 target)
937{
938 struct hfi1_pportdata *ppd;
939 int ret;
940
941 if (!try_module_get(THIS_MODULE))
942 return -ENODEV;
943
944 ppd = private2ppd(fp);
945
946 ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0);
947 if (ret) /* failed - release the module */
948 module_put(THIS_MODULE);
949
950 return ret;
951}
952
953static int qsfp1_debugfs_open(struct inode *in, struct file *fp)
954{
955 return __qsfp_debugfs_open(in, fp, 0);
956}
957
958static int qsfp2_debugfs_open(struct inode *in, struct file *fp)
959{
960 return __qsfp_debugfs_open(in, fp, 1);
961}
962
963static int __qsfp_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 module_put(THIS_MODULE);
971
972 return 0;
973}
974
975static int qsfp1_debugfs_release(struct inode *in, struct file *fp)
976{
977 return __qsfp_debugfs_release(in, fp, 0);
978}
979
980static int qsfp2_debugfs_release(struct inode *in, struct file *fp)
981{
982 return __qsfp_debugfs_release(in, fp, 1);
983}
984
Mike Marciniszyn77241052015-07-30 15:17:43 -0400985#define DEBUGFS_OPS(nm, readroutine, writeroutine) \
986{ \
987 .name = nm, \
988 .ops = { \
989 .read = readroutine, \
990 .write = writeroutine, \
991 .llseek = generic_file_llseek, \
992 }, \
993}
994
Dean Luickae993e72016-03-05 08:50:27 -0800995#define DEBUGFS_XOPS(nm, readf, writef, openf, releasef) \
996{ \
997 .name = nm, \
998 .ops = { \
999 .read = readf, \
1000 .write = writef, \
1001 .llseek = generic_file_llseek, \
1002 .open = openf, \
1003 .release = releasef \
1004 }, \
1005}
1006
Mike Marciniszyn77241052015-07-30 15:17:43 -04001007static const struct counter_info cntr_ops[] = {
1008 DEBUGFS_OPS("counter_names", dev_names_read, NULL),
1009 DEBUGFS_OPS("counters", dev_counters_read, NULL),
1010 DEBUGFS_OPS("portcounter_names", portnames_read, NULL),
1011};
1012
1013static const struct counter_info port_cntr_ops[] = {
1014 DEBUGFS_OPS("port%dcounters", portcntrs_debugfs_read, NULL),
Dean Luickae993e72016-03-05 08:50:27 -08001015 DEBUGFS_XOPS("i2c1", i2c1_debugfs_read, i2c1_debugfs_write,
1016 i2c1_debugfs_open, i2c1_debugfs_release),
1017 DEBUGFS_XOPS("i2c2", i2c2_debugfs_read, i2c2_debugfs_write,
1018 i2c2_debugfs_open, i2c2_debugfs_release),
Mike Marciniszyn77241052015-07-30 15:17:43 -04001019 DEBUGFS_OPS("qsfp_dump%d", qsfp_debugfs_dump, NULL),
Dean Luickae993e72016-03-05 08:50:27 -08001020 DEBUGFS_XOPS("qsfp1", qsfp1_debugfs_read, qsfp1_debugfs_write,
1021 qsfp1_debugfs_open, qsfp1_debugfs_release),
1022 DEBUGFS_XOPS("qsfp2", qsfp2_debugfs_read, qsfp2_debugfs_write,
1023 qsfp2_debugfs_open, qsfp2_debugfs_release),
Dean Luickc9c8ea32016-03-05 08:50:33 -08001024 DEBUGFS_OPS("asic_flags", asic_flags_read, asic_flags_write),
Dean Luick1b9e7742016-12-07 19:32:34 -08001025 DEBUGFS_OPS("dc8051_memory", dc8051_memory_read, NULL),
1026 DEBUGFS_OPS("lcb", debugfs_lcb_read, debugfs_lcb_write),
Mike Marciniszyn77241052015-07-30 15:17:43 -04001027};
1028
Tadeusz Strukaf3674d2016-09-25 07:44:44 -07001029static void *_sdma_cpu_list_seq_start(struct seq_file *s, loff_t *pos)
1030{
1031 if (*pos >= num_online_cpus())
1032 return NULL;
1033
1034 return pos;
1035}
1036
1037static void *_sdma_cpu_list_seq_next(struct seq_file *s, void *v, loff_t *pos)
1038{
1039 ++*pos;
1040 if (*pos >= num_online_cpus())
1041 return NULL;
1042
1043 return pos;
1044}
1045
1046static void _sdma_cpu_list_seq_stop(struct seq_file *s, void *v)
1047{
1048 /* nothing allocated */
1049}
1050
1051static int _sdma_cpu_list_seq_show(struct seq_file *s, void *v)
1052{
1053 struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
1054 struct hfi1_devdata *dd = dd_from_dev(ibd);
1055 loff_t *spos = v;
1056 loff_t i = *spos;
1057
1058 sdma_seqfile_dump_cpu_list(s, dd, (unsigned long)i);
1059 return 0;
1060}
1061
1062DEBUGFS_SEQ_FILE_OPS(sdma_cpu_list);
1063DEBUGFS_SEQ_FILE_OPEN(sdma_cpu_list)
1064DEBUGFS_FILE_OPS(sdma_cpu_list);
1065
Mike Marciniszyn77241052015-07-30 15:17:43 -04001066void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd)
1067{
1068 char name[sizeof("port0counters") + 1];
1069 char link[10];
1070 struct hfi1_devdata *dd = dd_from_dev(ibd);
1071 struct hfi1_pportdata *ppd;
1072 int unit = dd->unit;
1073 int i, j;
1074
1075 if (!hfi1_dbg_root)
1076 return;
1077 snprintf(name, sizeof(name), "%s_%d", class_name(), unit);
1078 snprintf(link, sizeof(link), "%d", unit);
1079 ibd->hfi1_ibdev_dbg = debugfs_create_dir(name, hfi1_dbg_root);
1080 if (!ibd->hfi1_ibdev_dbg) {
1081 pr_warn("create of %s failed\n", name);
1082 return;
1083 }
1084 ibd->hfi1_ibdev_link =
1085 debugfs_create_symlink(link, hfi1_dbg_root, name);
1086 if (!ibd->hfi1_ibdev_link) {
1087 pr_warn("create of %s symlink failed\n", name);
1088 return;
1089 }
1090 DEBUGFS_SEQ_FILE_CREATE(opcode_stats, ibd->hfi1_ibdev_dbg, ibd);
1091 DEBUGFS_SEQ_FILE_CREATE(ctx_stats, ibd->hfi1_ibdev_dbg, ibd);
1092 DEBUGFS_SEQ_FILE_CREATE(qp_stats, ibd->hfi1_ibdev_dbg, ibd);
1093 DEBUGFS_SEQ_FILE_CREATE(sdes, ibd->hfi1_ibdev_dbg, ibd);
Tadeusz Strukaf3674d2016-09-25 07:44:44 -07001094 DEBUGFS_SEQ_FILE_CREATE(sdma_cpu_list, ibd->hfi1_ibdev_dbg, ibd);
Mike Marciniszyn77241052015-07-30 15:17:43 -04001095 /* dev counter files */
1096 for (i = 0; i < ARRAY_SIZE(cntr_ops); i++)
1097 DEBUGFS_FILE_CREATE(cntr_ops[i].name,
1098 ibd->hfi1_ibdev_dbg,
1099 dd,
1100 &cntr_ops[i].ops, S_IRUGO);
1101 /* per port files */
1102 for (ppd = dd->pport, j = 0; j < dd->num_pports; j++, ppd++)
1103 for (i = 0; i < ARRAY_SIZE(port_cntr_ops); i++) {
1104 snprintf(name,
1105 sizeof(name),
1106 port_cntr_ops[i].name,
1107 j + 1);
1108 DEBUGFS_FILE_CREATE(name,
1109 ibd->hfi1_ibdev_dbg,
1110 ppd,
1111 &port_cntr_ops[i].ops,
Jubin Johnd125a6c2016-02-14 20:19:49 -08001112 !port_cntr_ops[i].ops.write ?
Jubin John8638b772016-02-14 20:19:24 -08001113 S_IRUGO : S_IRUGO | S_IWUSR);
Mike Marciniszyn77241052015-07-30 15:17:43 -04001114 }
1115}
1116
1117void hfi1_dbg_ibdev_exit(struct hfi1_ibdev *ibd)
1118{
1119 if (!hfi1_dbg_root)
1120 goto out;
1121 debugfs_remove(ibd->hfi1_ibdev_link);
1122 debugfs_remove_recursive(ibd->hfi1_ibdev_dbg);
1123out:
1124 ibd->hfi1_ibdev_dbg = NULL;
Mike Marciniszyn77241052015-07-30 15:17:43 -04001125}
1126
1127/*
1128 * driver stats field names, one line per stat, single string. Used by
1129 * programs like hfistats to print the stats in a way which works for
1130 * different versions of drivers, without changing program source.
1131 * if hfi1_ib_stats changes, this needs to change. Names need to be
1132 * 12 chars or less (w/o newline), for proper display by hfistats utility.
1133 */
1134static const char * const hfi1_statnames[] = {
1135 /* must be element 0*/
1136 "KernIntr",
1137 "ErrorIntr",
1138 "Tx_Errs",
1139 "Rcv_Errs",
1140 "H/W_Errs",
1141 "NoPIOBufs",
1142 "CtxtsOpen",
1143 "RcvLen_Errs",
1144 "EgrBufFull",
1145 "EgrHdrFull"
1146};
1147
1148static void *_driver_stats_names_seq_start(struct seq_file *s, loff_t *pos)
Mike Marciniszyn77241052015-07-30 15:17:43 -04001149{
Mike Marciniszyn77241052015-07-30 15:17:43 -04001150 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1151 return NULL;
1152 return pos;
1153}
1154
1155static void *_driver_stats_names_seq_next(
1156 struct seq_file *s,
1157 void *v,
1158 loff_t *pos)
1159{
1160 ++*pos;
1161 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1162 return NULL;
1163 return pos;
1164}
1165
1166static void _driver_stats_names_seq_stop(struct seq_file *s, void *v)
Mike Marciniszyn77241052015-07-30 15:17:43 -04001167{
Mike Marciniszyn77241052015-07-30 15:17:43 -04001168}
1169
1170static int _driver_stats_names_seq_show(struct seq_file *s, void *v)
1171{
1172 loff_t *spos = v;
1173
1174 seq_printf(s, "%s\n", hfi1_statnames[*spos]);
1175 return 0;
1176}
1177
1178DEBUGFS_SEQ_FILE_OPS(driver_stats_names);
1179DEBUGFS_SEQ_FILE_OPEN(driver_stats_names)
1180DEBUGFS_FILE_OPS(driver_stats_names);
1181
1182static void *_driver_stats_seq_start(struct seq_file *s, loff_t *pos)
Mike Marciniszyn77241052015-07-30 15:17:43 -04001183{
Mike Marciniszyn77241052015-07-30 15:17:43 -04001184 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1185 return NULL;
1186 return pos;
1187}
1188
1189static void *_driver_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
1190{
1191 ++*pos;
1192 if (*pos >= ARRAY_SIZE(hfi1_statnames))
1193 return NULL;
1194 return pos;
1195}
1196
1197static void _driver_stats_seq_stop(struct seq_file *s, void *v)
Mike Marciniszyn77241052015-07-30 15:17:43 -04001198{
Mike Marciniszyn77241052015-07-30 15:17:43 -04001199}
1200
1201static u64 hfi1_sps_ints(void)
1202{
1203 unsigned long flags;
1204 struct hfi1_devdata *dd;
1205 u64 sps_ints = 0;
1206
1207 spin_lock_irqsave(&hfi1_devs_lock, flags);
1208 list_for_each_entry(dd, &hfi1_dev_list, list) {
1209 sps_ints += get_all_cpu_total(dd->int_counter);
1210 }
1211 spin_unlock_irqrestore(&hfi1_devs_lock, flags);
1212 return sps_ints;
1213}
1214
1215static int _driver_stats_seq_show(struct seq_file *s, void *v)
1216{
1217 loff_t *spos = v;
1218 char *buffer;
1219 u64 *stats = (u64 *)&hfi1_stats;
1220 size_t sz = seq_get_buf(s, &buffer);
1221
1222 if (sz < sizeof(u64))
1223 return SEQ_SKIP;
1224 /* special case for interrupts */
1225 if (*spos == 0)
1226 *(u64 *)buffer = hfi1_sps_ints();
1227 else
1228 *(u64 *)buffer = stats[*spos];
1229 seq_commit(s, sizeof(u64));
1230 return 0;
1231}
1232
1233DEBUGFS_SEQ_FILE_OPS(driver_stats);
1234DEBUGFS_SEQ_FILE_OPEN(driver_stats)
1235DEBUGFS_FILE_OPS(driver_stats);
1236
1237void hfi1_dbg_init(void)
1238{
1239 hfi1_dbg_root = debugfs_create_dir(DRIVER_NAME, NULL);
1240 if (!hfi1_dbg_root)
1241 pr_warn("init of debugfs failed\n");
1242 DEBUGFS_SEQ_FILE_CREATE(driver_stats_names, hfi1_dbg_root, NULL);
1243 DEBUGFS_SEQ_FILE_CREATE(driver_stats, hfi1_dbg_root, NULL);
1244}
1245
1246void hfi1_dbg_exit(void)
1247{
1248 debugfs_remove_recursive(hfi1_dbg_root);
1249 hfi1_dbg_root = NULL;
1250}
1251
1252#endif