1 | /* Broadcom NetXtreme-C/E network driver. |
2 | * |
3 | * Copyright (c) 2017-2018 Broadcom Limited |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. |
8 | */ |
9 | |
10 | #include <linux/debugfs.h> |
11 | #include <linux/module.h> |
12 | #include <linux/pci.h> |
13 | #include "bnxt_hsi.h" |
14 | #include <linux/dim.h> |
15 | #include "bnxt.h" |
16 | #include "bnxt_debugfs.h" |
17 | |
18 | static struct dentry *bnxt_debug_mnt; |
19 | |
20 | static ssize_t debugfs_dim_read(struct file *filep, |
21 | char __user *buffer, |
22 | size_t count, loff_t *ppos) |
23 | { |
24 | struct dim *dim = filep->private_data; |
25 | int len; |
26 | char *buf; |
27 | |
28 | if (*ppos) |
29 | return 0; |
30 | if (!dim) |
31 | return -ENODEV; |
32 | buf = kasprintf(GFP_KERNEL, |
33 | fmt: "state = %d\n" \ |
34 | "profile_ix = %d\n" \ |
35 | "mode = %d\n" \ |
36 | "tune_state = %d\n" \ |
37 | "steps_right = %d\n" \ |
38 | "steps_left = %d\n" \ |
39 | "tired = %d\n" , |
40 | dim->state, |
41 | dim->profile_ix, |
42 | dim->mode, |
43 | dim->tune_state, |
44 | dim->steps_right, |
45 | dim->steps_left, |
46 | dim->tired); |
47 | if (!buf) |
48 | return -ENOMEM; |
49 | if (count < strlen(buf)) { |
50 | kfree(objp: buf); |
51 | return -ENOSPC; |
52 | } |
53 | len = simple_read_from_buffer(to: buffer, count, ppos, from: buf, strlen(buf)); |
54 | kfree(objp: buf); |
55 | return len; |
56 | } |
57 | |
58 | static const struct file_operations debugfs_dim_fops = { |
59 | .owner = THIS_MODULE, |
60 | .open = simple_open, |
61 | .read = debugfs_dim_read, |
62 | }; |
63 | |
64 | static void debugfs_dim_ring_init(struct dim *dim, int ring_idx, |
65 | struct dentry *dd) |
66 | { |
67 | static char qname[16]; |
68 | |
69 | snprintf(buf: qname, size: 10, fmt: "%d" , ring_idx); |
70 | debugfs_create_file(name: qname, mode: 0600, parent: dd, data: dim, fops: &debugfs_dim_fops); |
71 | } |
72 | |
73 | void bnxt_debug_dev_init(struct bnxt *bp) |
74 | { |
75 | const char *pname = pci_name(pdev: bp->pdev); |
76 | struct dentry *dir; |
77 | int i; |
78 | |
79 | bp->debugfs_pdev = debugfs_create_dir(name: pname, parent: bnxt_debug_mnt); |
80 | dir = debugfs_create_dir(name: "dim" , parent: bp->debugfs_pdev); |
81 | |
82 | /* create files for each rx ring */ |
83 | for (i = 0; i < bp->cp_nr_rings; i++) { |
84 | struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; |
85 | |
86 | if (cpr && bp->bnapi[i]->rx_ring) |
87 | debugfs_dim_ring_init(dim: &cpr->dim, ring_idx: i, dd: dir); |
88 | } |
89 | } |
90 | |
91 | void bnxt_debug_dev_exit(struct bnxt *bp) |
92 | { |
93 | if (bp) { |
94 | debugfs_remove_recursive(dentry: bp->debugfs_pdev); |
95 | bp->debugfs_pdev = NULL; |
96 | } |
97 | } |
98 | |
99 | void bnxt_debug_init(void) |
100 | { |
101 | bnxt_debug_mnt = debugfs_create_dir(name: "bnxt_en" , NULL); |
102 | } |
103 | |
104 | void bnxt_debug_exit(void) |
105 | { |
106 | debugfs_remove_recursive(dentry: bnxt_debug_mnt); |
107 | } |
108 | |