]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
nfp: separate data path information from the reset of adapter structure
[mirror_ubuntu-artful-kernel.git] / drivers / net / ethernet / netronome / nfp / nfp_net_debugfs.c
CommitLineData
4c352362 1/*
6f1cd5ca 2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
4c352362
JK
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33#include <linux/debugfs.h>
34#include <linux/module.h>
35#include <linux/rtnetlink.h>
36
37#include "nfp_net.h"
38
39static struct dentry *nfp_dir;
40
41static int nfp_net_debugfs_rx_q_read(struct seq_file *file, void *data)
42{
4c352362 43 int fl_rd_p, fl_wr_p, rx_rd_p, rx_wr_p, rxd_cnt;
73725d9d
JK
44 struct nfp_net_r_vector *r_vec = file->private;
45 struct nfp_net_rx_ring *rx_ring;
4c352362 46 struct nfp_net_rx_desc *rxd;
4c352362 47 struct nfp_net *nn;
c0f031bc 48 void *frag;
4c352362
JK
49 int i;
50
51 rtnl_lock();
52
73725d9d 53 if (!r_vec->nfp_net || !r_vec->rx_ring)
4c352362 54 goto out;
73725d9d
JK
55 nn = r_vec->nfp_net;
56 rx_ring = r_vec->rx_ring;
79c12a75 57 if (!netif_running(nn->dp.netdev))
4c352362
JK
58 goto out;
59
60 rxd_cnt = rx_ring->cnt;
61
62 fl_rd_p = nfp_qcp_rd_ptr_read(rx_ring->qcp_fl);
63 fl_wr_p = nfp_qcp_wr_ptr_read(rx_ring->qcp_fl);
64 rx_rd_p = nfp_qcp_rd_ptr_read(rx_ring->qcp_rx);
65 rx_wr_p = nfp_qcp_wr_ptr_read(rx_ring->qcp_rx);
66
43860c12
JK
67 seq_printf(file, "RX[%02d,%02d,%02d]: cnt=%d dma=%pad host=%p H_RD=%d H_WR=%d FL_RD=%d FL_WR=%d RX_RD=%d RX_WR=%d\n",
68 rx_ring->idx, rx_ring->fl_qcidx, rx_ring->rx_qcidx,
69 rx_ring->cnt, &rx_ring->dma, rx_ring->rxds,
70 rx_ring->rd_p, rx_ring->wr_p,
4c352362
JK
71 fl_rd_p, fl_wr_p, rx_rd_p, rx_wr_p);
72
73 for (i = 0; i < rxd_cnt; i++) {
74 rxd = &rx_ring->rxds[i];
75 seq_printf(file, "%04d: 0x%08x 0x%08x", i,
76 rxd->vals[0], rxd->vals[1]);
77
c0f031bc
JK
78 frag = READ_ONCE(rx_ring->rxbufs[i].frag);
79 if (frag)
80 seq_printf(file, " frag=%p", frag);
4c352362
JK
81
82 if (rx_ring->rxbufs[i].dma_addr)
83 seq_printf(file, " dma_addr=%pad",
84 &rx_ring->rxbufs[i].dma_addr);
85
86 if (i == rx_ring->rd_p % rxd_cnt)
87 seq_puts(file, " H_RD ");
88 if (i == rx_ring->wr_p % rxd_cnt)
89 seq_puts(file, " H_WR ");
90 if (i == fl_rd_p % rxd_cnt)
91 seq_puts(file, " FL_RD");
92 if (i == fl_wr_p % rxd_cnt)
93 seq_puts(file, " FL_WR");
94 if (i == rx_rd_p % rxd_cnt)
95 seq_puts(file, " RX_RD");
96 if (i == rx_wr_p % rxd_cnt)
97 seq_puts(file, " RX_WR");
98
99 seq_putc(file, '\n');
100 }
101out:
102 rtnl_unlock();
103 return 0;
104}
105
106static int nfp_net_debugfs_rx_q_open(struct inode *inode, struct file *f)
107{
108 return single_open(f, nfp_net_debugfs_rx_q_read, inode->i_private);
109}
110
111static const struct file_operations nfp_rx_q_fops = {
112 .owner = THIS_MODULE,
113 .open = nfp_net_debugfs_rx_q_open,
114 .release = single_release,
115 .read = seq_read,
116 .llseek = seq_lseek
117};
118
ecd63a02
JK
119static int nfp_net_debugfs_tx_q_open(struct inode *inode, struct file *f);
120
121static const struct file_operations nfp_tx_q_fops = {
122 .owner = THIS_MODULE,
123 .open = nfp_net_debugfs_tx_q_open,
124 .release = single_release,
125 .read = seq_read,
126 .llseek = seq_lseek
127};
128
4c352362
JK
129static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data)
130{
73725d9d
JK
131 struct nfp_net_r_vector *r_vec = file->private;
132 struct nfp_net_tx_ring *tx_ring;
4c352362
JK
133 struct nfp_net_tx_desc *txd;
134 int d_rd_p, d_wr_p, txd_cnt;
135 struct sk_buff *skb;
136 struct nfp_net *nn;
137 int i;
138
139 rtnl_lock();
140
ecd63a02
JK
141 if (debugfs_real_fops(file->file) == &nfp_tx_q_fops)
142 tx_ring = r_vec->tx_ring;
143 else
144 tx_ring = r_vec->xdp_ring;
145 if (!r_vec->nfp_net || !tx_ring)
4c352362 146 goto out;
73725d9d 147 nn = r_vec->nfp_net;
79c12a75 148 if (!netif_running(nn->dp.netdev))
4c352362
JK
149 goto out;
150
151 txd_cnt = tx_ring->cnt;
152
153 d_rd_p = nfp_qcp_rd_ptr_read(tx_ring->qcp_q);
154 d_wr_p = nfp_qcp_wr_ptr_read(tx_ring->qcp_q);
155
43860c12
JK
156 seq_printf(file, "TX[%02d,%02d%s]: cnt=%d dma=%pad host=%p H_RD=%d H_WR=%d D_RD=%d D_WR=%d\n",
157 tx_ring->idx, tx_ring->qcidx,
158 tx_ring == r_vec->tx_ring ? "" : "xdp",
159 tx_ring->cnt, &tx_ring->dma, tx_ring->txds,
160 tx_ring->rd_p, tx_ring->wr_p, d_rd_p, d_wr_p);
4c352362
JK
161
162 for (i = 0; i < txd_cnt; i++) {
163 txd = &tx_ring->txds[i];
164 seq_printf(file, "%04d: 0x%08x 0x%08x 0x%08x 0x%08x", i,
165 txd->vals[0], txd->vals[1],
166 txd->vals[2], txd->vals[3]);
167
168 skb = READ_ONCE(tx_ring->txbufs[i].skb);
ecd63a02
JK
169 if (skb) {
170 if (tx_ring == r_vec->tx_ring)
171 seq_printf(file, " skb->head=%p skb->data=%p",
172 skb->head, skb->data);
173 else
174 seq_printf(file, " frag=%p", skb);
175 }
176
4c352362
JK
177 if (tx_ring->txbufs[i].dma_addr)
178 seq_printf(file, " dma_addr=%pad",
179 &tx_ring->txbufs[i].dma_addr);
180
181 if (i == tx_ring->rd_p % txd_cnt)
182 seq_puts(file, " H_RD");
183 if (i == tx_ring->wr_p % txd_cnt)
184 seq_puts(file, " H_WR");
185 if (i == d_rd_p % txd_cnt)
186 seq_puts(file, " D_RD");
187 if (i == d_wr_p % txd_cnt)
188 seq_puts(file, " D_WR");
189
190 seq_putc(file, '\n');
191 }
192out:
193 rtnl_unlock();
194 return 0;
195}
196
197static int nfp_net_debugfs_tx_q_open(struct inode *inode, struct file *f)
198{
199 return single_open(f, nfp_net_debugfs_tx_q_read, inode->i_private);
200}
201
ecd63a02 202static const struct file_operations nfp_xdp_q_fops = {
4c352362
JK
203 .owner = THIS_MODULE,
204 .open = nfp_net_debugfs_tx_q_open,
205 .release = single_release,
206 .read = seq_read,
207 .llseek = seq_lseek
208};
209
6f1cd5ca 210void nfp_net_debugfs_port_add(struct nfp_net *nn, struct dentry *ddir, int id)
4c352362 211{
ecd63a02 212 struct dentry *queues, *tx, *rx, *xdp;
6f1cd5ca 213 char name[20];
4c352362
JK
214 int i;
215
216 if (IS_ERR_OR_NULL(nfp_dir))
217 return;
218
6f1cd5ca
JK
219 sprintf(name, "port%d", id);
220 nn->debugfs_dir = debugfs_create_dir(name, ddir);
4c352362
JK
221 if (IS_ERR_OR_NULL(nn->debugfs_dir))
222 return;
223
224 /* Create queue debugging sub-tree */
225 queues = debugfs_create_dir("queue", nn->debugfs_dir);
5b161096 226 if (IS_ERR_OR_NULL(queues))
4c352362
JK
227 return;
228
229 rx = debugfs_create_dir("rx", queues);
230 tx = debugfs_create_dir("tx", queues);
ecd63a02
JK
231 xdp = debugfs_create_dir("xdp", queues);
232 if (IS_ERR_OR_NULL(rx) || IS_ERR_OR_NULL(tx) || IS_ERR_OR_NULL(xdp))
4c352362
JK
233 return;
234
164d1e9e 235 for (i = 0; i < min(nn->max_rx_rings, nn->max_r_vecs); i++) {
6f1cd5ca
JK
236 sprintf(name, "%d", i);
237 debugfs_create_file(name, S_IRUSR, rx,
73725d9d 238 &nn->r_vecs[i], &nfp_rx_q_fops);
6f1cd5ca 239 debugfs_create_file(name, S_IRUSR, xdp,
ecd63a02 240 &nn->r_vecs[i], &nfp_xdp_q_fops);
4c352362
JK
241 }
242
164d1e9e 243 for (i = 0; i < min(nn->max_tx_rings, nn->max_r_vecs); i++) {
6f1cd5ca
JK
244 sprintf(name, "%d", i);
245 debugfs_create_file(name, S_IRUSR, tx,
73725d9d 246 &nn->r_vecs[i], &nfp_tx_q_fops);
4c352362
JK
247 }
248}
249
6f1cd5ca 250struct dentry *nfp_net_debugfs_device_add(struct pci_dev *pdev)
4c352362 251{
6f1cd5ca
JK
252 struct dentry *dev_dir;
253
254 if (IS_ERR_OR_NULL(nfp_dir))
255 return NULL;
256
257 dev_dir = debugfs_create_dir(pci_name(pdev), nfp_dir);
258 if (IS_ERR_OR_NULL(dev_dir))
259 return NULL;
260
261 return dev_dir;
262}
263
264void nfp_net_debugfs_dir_clean(struct dentry **dir)
265{
266 debugfs_remove_recursive(*dir);
267 *dir = NULL;
4c352362
JK
268}
269
270void nfp_net_debugfs_create(void)
271{
272 nfp_dir = debugfs_create_dir("nfp_net", NULL);
273}
274
275void nfp_net_debugfs_destroy(void)
276{
277 debugfs_remove_recursive(nfp_dir);
278 nfp_dir = NULL;
279}