1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2015-2019 Netronome Systems, Inc. */
3 #include <linux/debugfs.h>
4 #include <linux/module.h>
5 #include <linux/rtnetlink.h>
8 #include "nfp_net_dp.h"
10 static struct dentry
*nfp_dir
;
12 static int nfp_rx_q_show(struct seq_file
*file
, void *data
)
14 struct nfp_net_r_vector
*r_vec
= file
->private;
15 struct nfp_net_rx_ring
*rx_ring
;
16 int fl_rd_p
, fl_wr_p
, rxd_cnt
;
17 struct nfp_net_rx_desc
*rxd
;
24 if (!r_vec
->nfp_net
|| !r_vec
->rx_ring
)
27 rx_ring
= r_vec
->rx_ring
;
28 if (!nfp_net_running(nn
))
31 rxd_cnt
= rx_ring
->cnt
;
33 fl_rd_p
= nfp_qcp_rd_ptr_read(rx_ring
->qcp_fl
);
34 fl_wr_p
= nfp_qcp_wr_ptr_read(rx_ring
->qcp_fl
);
36 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",
37 rx_ring
->idx
, rx_ring
->fl_qcidx
,
38 rx_ring
->cnt
, &rx_ring
->dma
, rx_ring
->rxds
,
39 rx_ring
->rd_p
, rx_ring
->wr_p
, fl_rd_p
, fl_wr_p
);
41 for (i
= 0; i
< rxd_cnt
; i
++) {
42 rxd
= &rx_ring
->rxds
[i
];
43 seq_printf(file
, "%04d: 0x%08x 0x%08x", i
,
44 rxd
->vals
[0], rxd
->vals
[1]);
46 if (!r_vec
->xsk_pool
) {
47 frag
= READ_ONCE(rx_ring
->rxbufs
[i
].frag
);
49 seq_printf(file
, " frag=%p", frag
);
51 if (rx_ring
->rxbufs
[i
].dma_addr
)
52 seq_printf(file
, " dma_addr=%pad",
53 &rx_ring
->rxbufs
[i
].dma_addr
);
55 if (rx_ring
->xsk_rxbufs
[i
].dma_addr
)
56 seq_printf(file
, " dma_addr=%pad",
57 &rx_ring
->xsk_rxbufs
[i
].dma_addr
);
60 if (i
== rx_ring
->rd_p
% rxd_cnt
)
61 seq_puts(file
, " H_RD ");
62 if (i
== rx_ring
->wr_p
% rxd_cnt
)
63 seq_puts(file
, " H_WR ");
64 if (i
== fl_rd_p
% rxd_cnt
)
65 seq_puts(file
, " FL_RD");
66 if (i
== fl_wr_p
% rxd_cnt
)
67 seq_puts(file
, " FL_WR");
75 DEFINE_SHOW_ATTRIBUTE(nfp_rx_q
);
77 static int nfp_tx_q_show(struct seq_file
*file
, void *data
);
78 DEFINE_SHOW_ATTRIBUTE(nfp_tx_q
);
80 static int nfp_tx_q_show(struct seq_file
*file
, void *data
)
82 struct nfp_net_r_vector
*r_vec
= file
->private;
83 struct nfp_net_tx_ring
*tx_ring
;
89 if (debugfs_real_fops(file
->file
) == &nfp_tx_q_fops
)
90 tx_ring
= r_vec
->tx_ring
;
92 tx_ring
= r_vec
->xdp_ring
;
93 if (!r_vec
->nfp_net
|| !tx_ring
)
96 if (!nfp_net_running(nn
))
99 d_rd_p
= nfp_qcp_rd_ptr_read(tx_ring
->qcp_q
);
100 d_wr_p
= nfp_qcp_wr_ptr_read(tx_ring
->qcp_q
);
102 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",
103 tx_ring
->idx
, tx_ring
->qcidx
,
104 tx_ring
== r_vec
->tx_ring
? "" : "xdp",
105 tx_ring
->cnt
, &tx_ring
->dma
, tx_ring
->txds
,
106 tx_ring
->rd_p
, tx_ring
->wr_p
, d_rd_p
, d_wr_p
);
108 seq_printf(file
, " TXRWB=%llu", *tx_ring
->txrwb
);
109 seq_putc(file
, '\n');
111 nfp_net_debugfs_print_tx_descs(file
, &nn
->dp
, r_vec
, tx_ring
,
118 static int nfp_xdp_q_show(struct seq_file
*file
, void *data
)
120 return nfp_tx_q_show(file
, data
);
122 DEFINE_SHOW_ATTRIBUTE(nfp_xdp_q
);
124 void nfp_net_debugfs_vnic_add(struct nfp_net
*nn
, struct dentry
*ddir
)
126 struct dentry
*queues
, *tx
, *rx
, *xdp
;
130 if (IS_ERR_OR_NULL(nfp_dir
))
133 if (nfp_net_is_data_vnic(nn
))
134 sprintf(name
, "vnic%d", nn
->id
);
136 strcpy(name
, "ctrl-vnic");
137 nn
->debugfs_dir
= debugfs_create_dir(name
, ddir
);
139 /* Create queue debugging sub-tree */
140 queues
= debugfs_create_dir("queue", nn
->debugfs_dir
);
142 rx
= debugfs_create_dir("rx", queues
);
143 tx
= debugfs_create_dir("tx", queues
);
144 xdp
= debugfs_create_dir("xdp", queues
);
146 for (i
= 0; i
< min(nn
->max_rx_rings
, nn
->max_r_vecs
); i
++) {
147 sprintf(name
, "%d", i
);
148 debugfs_create_file(name
, 0400, rx
,
149 &nn
->r_vecs
[i
], &nfp_rx_q_fops
);
150 debugfs_create_file(name
, 0400, xdp
,
151 &nn
->r_vecs
[i
], &nfp_xdp_q_fops
);
154 for (i
= 0; i
< min(nn
->max_tx_rings
, nn
->max_r_vecs
); i
++) {
155 sprintf(name
, "%d", i
);
156 debugfs_create_file(name
, 0400, tx
,
157 &nn
->r_vecs
[i
], &nfp_tx_q_fops
);
161 struct dentry
*nfp_net_debugfs_device_add(struct pci_dev
*pdev
)
163 return debugfs_create_dir(pci_name(pdev
), nfp_dir
);
166 void nfp_net_debugfs_dir_clean(struct dentry
**dir
)
168 debugfs_remove_recursive(*dir
);
172 void nfp_net_debugfs_create(void)
174 nfp_dir
= debugfs_create_dir("nfp_net", NULL
);
177 void nfp_net_debugfs_destroy(void)
179 debugfs_remove_recursive(nfp_dir
);