nfp: fix print format for ring pointers in ring dumps
[linux-2.6/btrfs-unstable.git] / drivers / net / ethernet / netronome / nfp / nfp_net_debugfs.c
blob8c52c0e8379c37faf7a90e905b186105cb1ad95a
1 /*
2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
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.
9 * The BSD 2-Clause License:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
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.
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.
33 #include <linux/debugfs.h>
34 #include <linux/module.h>
35 #include <linux/rtnetlink.h>
37 #include "nfp_net.h"
39 static struct dentry *nfp_dir;
41 static int nfp_net_debugfs_rx_q_read(struct seq_file *file, void *data)
43 struct nfp_net_r_vector *r_vec = file->private;
44 struct nfp_net_rx_ring *rx_ring;
45 int fl_rd_p, fl_wr_p, rxd_cnt;
46 struct nfp_net_rx_desc *rxd;
47 struct nfp_net *nn;
48 void *frag;
49 int i;
51 rtnl_lock();
53 if (!r_vec->nfp_net || !r_vec->rx_ring)
54 goto out;
55 nn = r_vec->nfp_net;
56 rx_ring = r_vec->rx_ring;
57 if (!netif_running(nn->dp.netdev))
58 goto out;
60 rxd_cnt = rx_ring->cnt;
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);
65 seq_printf(file, "RX[%02d,%02d]: cnt=%u dma=%pad host=%p H_RD=%u H_WR=%u FL_RD=%u FL_WR=%u\n",
66 rx_ring->idx, rx_ring->fl_qcidx,
67 rx_ring->cnt, &rx_ring->dma, rx_ring->rxds,
68 rx_ring->rd_p, rx_ring->wr_p, fl_rd_p, fl_wr_p);
70 for (i = 0; i < rxd_cnt; i++) {
71 rxd = &rx_ring->rxds[i];
72 seq_printf(file, "%04d: 0x%08x 0x%08x", i,
73 rxd->vals[0], rxd->vals[1]);
75 frag = READ_ONCE(rx_ring->rxbufs[i].frag);
76 if (frag)
77 seq_printf(file, " frag=%p", frag);
79 if (rx_ring->rxbufs[i].dma_addr)
80 seq_printf(file, " dma_addr=%pad",
81 &rx_ring->rxbufs[i].dma_addr);
83 if (i == rx_ring->rd_p % rxd_cnt)
84 seq_puts(file, " H_RD ");
85 if (i == rx_ring->wr_p % rxd_cnt)
86 seq_puts(file, " H_WR ");
87 if (i == fl_rd_p % rxd_cnt)
88 seq_puts(file, " FL_RD");
89 if (i == fl_wr_p % rxd_cnt)
90 seq_puts(file, " FL_WR");
92 seq_putc(file, '\n');
94 out:
95 rtnl_unlock();
96 return 0;
99 static int nfp_net_debugfs_rx_q_open(struct inode *inode, struct file *f)
101 return single_open(f, nfp_net_debugfs_rx_q_read, inode->i_private);
104 static const struct file_operations nfp_rx_q_fops = {
105 .owner = THIS_MODULE,
106 .open = nfp_net_debugfs_rx_q_open,
107 .release = single_release,
108 .read = seq_read,
109 .llseek = seq_lseek
112 static int nfp_net_debugfs_tx_q_open(struct inode *inode, struct file *f);
114 static const struct file_operations nfp_tx_q_fops = {
115 .owner = THIS_MODULE,
116 .open = nfp_net_debugfs_tx_q_open,
117 .release = single_release,
118 .read = seq_read,
119 .llseek = seq_lseek
122 static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data)
124 struct nfp_net_r_vector *r_vec = file->private;
125 struct nfp_net_tx_ring *tx_ring;
126 struct nfp_net_tx_desc *txd;
127 int d_rd_p, d_wr_p, txd_cnt;
128 struct sk_buff *skb;
129 struct nfp_net *nn;
130 int i;
132 rtnl_lock();
134 if (debugfs_real_fops(file->file) == &nfp_tx_q_fops)
135 tx_ring = r_vec->tx_ring;
136 else
137 tx_ring = r_vec->xdp_ring;
138 if (!r_vec->nfp_net || !tx_ring)
139 goto out;
140 nn = r_vec->nfp_net;
141 if (!netif_running(nn->dp.netdev))
142 goto out;
144 txd_cnt = tx_ring->cnt;
146 d_rd_p = nfp_qcp_rd_ptr_read(tx_ring->qcp_q);
147 d_wr_p = nfp_qcp_wr_ptr_read(tx_ring->qcp_q);
149 seq_printf(file, "TX[%02d,%02d%s]: cnt=%u dma=%pad host=%p H_RD=%u H_WR=%u D_RD=%u D_WR=%u\n",
150 tx_ring->idx, tx_ring->qcidx,
151 tx_ring == r_vec->tx_ring ? "" : "xdp",
152 tx_ring->cnt, &tx_ring->dma, tx_ring->txds,
153 tx_ring->rd_p, tx_ring->wr_p, d_rd_p, d_wr_p);
155 for (i = 0; i < txd_cnt; i++) {
156 txd = &tx_ring->txds[i];
157 seq_printf(file, "%04d: 0x%08x 0x%08x 0x%08x 0x%08x", i,
158 txd->vals[0], txd->vals[1],
159 txd->vals[2], txd->vals[3]);
161 skb = READ_ONCE(tx_ring->txbufs[i].skb);
162 if (skb) {
163 if (tx_ring == r_vec->tx_ring)
164 seq_printf(file, " skb->head=%p skb->data=%p",
165 skb->head, skb->data);
166 else
167 seq_printf(file, " frag=%p", skb);
170 if (tx_ring->txbufs[i].dma_addr)
171 seq_printf(file, " dma_addr=%pad",
172 &tx_ring->txbufs[i].dma_addr);
174 if (i == tx_ring->rd_p % txd_cnt)
175 seq_puts(file, " H_RD");
176 if (i == tx_ring->wr_p % txd_cnt)
177 seq_puts(file, " H_WR");
178 if (i == d_rd_p % txd_cnt)
179 seq_puts(file, " D_RD");
180 if (i == d_wr_p % txd_cnt)
181 seq_puts(file, " D_WR");
183 seq_putc(file, '\n');
185 out:
186 rtnl_unlock();
187 return 0;
190 static int nfp_net_debugfs_tx_q_open(struct inode *inode, struct file *f)
192 return single_open(f, nfp_net_debugfs_tx_q_read, inode->i_private);
195 static const struct file_operations nfp_xdp_q_fops = {
196 .owner = THIS_MODULE,
197 .open = nfp_net_debugfs_tx_q_open,
198 .release = single_release,
199 .read = seq_read,
200 .llseek = seq_lseek
203 void nfp_net_debugfs_vnic_add(struct nfp_net *nn, struct dentry *ddir, int id)
205 struct dentry *queues, *tx, *rx, *xdp;
206 char name[20];
207 int i;
209 if (IS_ERR_OR_NULL(nfp_dir))
210 return;
212 sprintf(name, "vnic%d", id);
213 nn->debugfs_dir = debugfs_create_dir(name, ddir);
214 if (IS_ERR_OR_NULL(nn->debugfs_dir))
215 return;
217 /* Create queue debugging sub-tree */
218 queues = debugfs_create_dir("queue", nn->debugfs_dir);
219 if (IS_ERR_OR_NULL(queues))
220 return;
222 rx = debugfs_create_dir("rx", queues);
223 tx = debugfs_create_dir("tx", queues);
224 xdp = debugfs_create_dir("xdp", queues);
225 if (IS_ERR_OR_NULL(rx) || IS_ERR_OR_NULL(tx) || IS_ERR_OR_NULL(xdp))
226 return;
228 for (i = 0; i < min(nn->max_rx_rings, nn->max_r_vecs); i++) {
229 sprintf(name, "%d", i);
230 debugfs_create_file(name, S_IRUSR, rx,
231 &nn->r_vecs[i], &nfp_rx_q_fops);
232 debugfs_create_file(name, S_IRUSR, xdp,
233 &nn->r_vecs[i], &nfp_xdp_q_fops);
236 for (i = 0; i < min(nn->max_tx_rings, nn->max_r_vecs); i++) {
237 sprintf(name, "%d", i);
238 debugfs_create_file(name, S_IRUSR, tx,
239 &nn->r_vecs[i], &nfp_tx_q_fops);
243 struct dentry *nfp_net_debugfs_device_add(struct pci_dev *pdev)
245 struct dentry *dev_dir;
247 if (IS_ERR_OR_NULL(nfp_dir))
248 return NULL;
250 dev_dir = debugfs_create_dir(pci_name(pdev), nfp_dir);
251 if (IS_ERR_OR_NULL(dev_dir))
252 return NULL;
254 return dev_dir;
257 void nfp_net_debugfs_dir_clean(struct dentry **dir)
259 debugfs_remove_recursive(*dir);
260 *dir = NULL;
263 void nfp_net_debugfs_create(void)
265 nfp_dir = debugfs_create_dir("nfp_net", NULL);
268 void nfp_net_debugfs_destroy(void)
270 debugfs_remove_recursive(nfp_dir);
271 nfp_dir = NULL;