lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260127200644.11640-3-mike.marciniszyn@gmail.com>
Date: Tue, 27 Jan 2026 15:06:44 -0500
From: mike.marciniszyn@...il.com
To: Alexander Duyck <alexanderduyck@...com>,
	Jakub Kicinski <kuba@...nel.org>,
	kernel-team@...a.com,
	Andrew Lunn <andrew+netdev@...n.ch>,
	"David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Paolo Abeni <pabeni@...hat.com>
Cc: netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	"Mike Marciniszyn (Meta)" <mike.marciniszyn@...il.com>
Subject: [PATCH net-next 2/2] eth fbnic: Add debugfs hooks for tx/rx rings

From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@...il.com>

Add debugfs hooks to display tx/rx rings for each napi
vector.

Note that the cloning mechanism in fbnic_ethtool.c for configuration
changes protects against concurrency issues with simultaneous config
changes along with debugs ring accesses.

The configuration switch builds up the new configuration offline,
takes the current config down, which removes the debugfs nv files, and
switches to the new configuration.   The new configuration is brought
up which brings the debugfs files back on top of the new configuration
rings.

The interaction with fbnic_queue_stop() and fbnic_queue_start() will
similarly delete and add the files for the indicated vector.

Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@...il.com>
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
---
 drivers/net/ethernet/meta/fbnic/fbnic_csr.h   |  12 +
 .../net/ethernet/meta/fbnic/fbnic_debugfs.c   | 359 ++++++++++++++++++
 drivers/net/ethernet/meta/fbnic/fbnic_pci.c   |   4 +
 drivers/net/ethernet/meta/fbnic/fbnic_txrx.c  |  20 +-
 drivers/net/ethernet/meta/fbnic/fbnic_txrx.h  |   6 +
 5 files changed, 400 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index 422265dc7abd..b717db879cd3 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -1019,6 +1019,9 @@ enum {
 #define FBNIC_QUEUE_TWQ_CTL_ENABLE		CSR_BIT(1)
 #define FBNIC_QUEUE_TWQ0_TAIL		0x002		/* 0x008 */
 #define FBNIC_QUEUE_TWQ1_TAIL		0x003		/* 0x00c */
+#define FBNIC_QUEUE_TWQ0_PTRS		0x004		/* 0x010 */
+#define FBNIC_QUEUE_TWQ1_PTRS		0x005		/* 0x014 */
+#define FBNIC_QUEUE_TWQ_PTRS_HEAD_MASK		CSR_GENMASK(31, 16)

 #define FBNIC_QUEUE_TWQ0_SIZE		0x00a		/* 0x028 */
 #define FBNIC_QUEUE_TWQ1_SIZE		0x00b		/* 0x02c */
@@ -1042,6 +1045,8 @@ enum {
 #define FBNIC_QUEUE_TCQ_CTL_ENABLE		CSR_BIT(1)

 #define FBNIC_QUEUE_TCQ_HEAD		0x081		/* 0x204 */
+#define FBNIC_QUEUE_TCQ_PTRS		0x082		/* 0x208 */
+#define FBNIC_QUEUE_TCQ_PTRS_TAIL_MASK		CSR_GENMASK(31, 16)

 #define FBNIC_QUEUE_TCQ_SIZE		0x084		/* 0x210 */
 #define FBNIC_QUEUE_TCQ_SIZE_MASK		CSR_GENMASK(3, 0)
@@ -1075,6 +1080,9 @@ enum {
 #define FBNIC_QUEUE_RCQ_CTL_ENABLE		CSR_BIT(1)

 #define FBNIC_QUEUE_RCQ_HEAD		0x201		/* 0x804 */
+#define FBNIC_QUEUE_RCQ_PTRS		0x202		/* 0x808 */
+#define FBNIC_QUEUE_RCQ_PTRS_TAIL_MASK		CSR_GENMASK(31, 16)
+#define FBNIC_QUEUE_RCQ_PTRS_HEAD_MASK		CSR_GENMASK(15, 0)

 #define FBNIC_QUEUE_RCQ_SIZE		0x204		/* 0x810 */
 #define FBNIC_QUEUE_RCQ_SIZE_MASK		CSR_GENMASK(3, 0)
@@ -1090,6 +1098,10 @@ enum {

 #define FBNIC_QUEUE_BDQ_HPQ_TAIL	0x241		/* 0x904 */
 #define FBNIC_QUEUE_BDQ_PPQ_TAIL	0x242		/* 0x908 */
+#define FBNIC_QUEUE_BDQ_HPQ_PTRS	0x243		/* 0x90c */
+#define FBNIC_QUEUE_BDQ_PPQ_PTRS	0x244		/* 0x910 */
+#define FBNIC_QUEUE_BDQ_PTRS_HEAD_MASK		CSR_GENMASK(31, 16)
+#define FBNIC_QUEUE_BDQ_PTRS_TAIL_MASK		CSR_GENMASK(15, 0)

 #define FBNIC_QUEUE_BDQ_HPQ_SIZE	0x247		/* 0x91c */
 #define FBNIC_QUEUE_BDQ_PPQ_SIZE	0x248		/* 0x920 */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c b/drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c
index 9cdd03bfec34..08270db2dee8 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c
@@ -7,9 +7,12 @@
 #include <linux/seq_file.h>

 #include "fbnic.h"
+#include "fbnic_txrx.h"

 static struct dentry *fbnic_dbg_root;

+/* Descriptor Seq Functions */
+
 static void fbnic_dbg_desc_break(struct seq_file *s, int i)
 {
 	while (i--)
@@ -18,6 +21,362 @@ static void fbnic_dbg_desc_break(struct seq_file *s, int i)
 	seq_putc(s, '\n');
 }

+static void fbnic_dbg_ring_show(struct seq_file *s)
+{
+	struct fbnic_ring *ring = s->private;
+	unsigned long doorbell_offset;
+	u32 head = 0, tail = 0;
+	u32 __iomem *csr_base;
+
+	csr_base = fbnic_ring_csr_base(ring);
+	doorbell_offset = ring->doorbell - csr_base;
+
+	seq_printf(s, "doorbell CSR: %#05lx q_idx: %d\n",
+		   doorbell_offset, ring->q_idx);
+	seq_printf(s, "size_mask: %#06x size: %zu flags: 0x%02x\n",
+		   ring->size_mask, ring->size, ring->flags);
+	seq_printf(s, "SW: head: %#06x tail: %#06x\n",
+		   ring->head, ring->tail);
+
+	switch (doorbell_offset) {
+	case FBNIC_QUEUE_TWQ0_TAIL:
+		tail = readl(csr_base + FBNIC_QUEUE_TWQ0_PTRS);
+		head = FIELD_GET(FBNIC_QUEUE_TWQ_PTRS_HEAD_MASK, tail);
+		break;
+	case FBNIC_QUEUE_TWQ1_TAIL:
+		tail = readl(csr_base + FBNIC_QUEUE_TWQ1_PTRS);
+		head = FIELD_GET(FBNIC_QUEUE_TWQ_PTRS_HEAD_MASK, tail);
+		break;
+	case FBNIC_QUEUE_TCQ_HEAD:
+		head = readl(csr_base + FBNIC_QUEUE_TCQ_PTRS);
+		tail = FIELD_GET(FBNIC_QUEUE_TCQ_PTRS_TAIL_MASK, head);
+		break;
+	case FBNIC_QUEUE_BDQ_HPQ_TAIL:
+		tail = readl(csr_base + FBNIC_QUEUE_BDQ_HPQ_PTRS);
+		head = FIELD_GET(FBNIC_QUEUE_BDQ_PTRS_HEAD_MASK, tail);
+		break;
+	case FBNIC_QUEUE_BDQ_PPQ_TAIL:
+		tail = readl(csr_base + FBNIC_QUEUE_BDQ_PPQ_PTRS);
+		head = FIELD_GET(FBNIC_QUEUE_BDQ_PTRS_HEAD_MASK, tail);
+		break;
+	case FBNIC_QUEUE_RCQ_HEAD:
+		head = readl(csr_base + FBNIC_QUEUE_RCQ_PTRS);
+		tail = FIELD_GET(FBNIC_QUEUE_RCQ_PTRS_TAIL_MASK, head);
+		break;
+	}
+
+	tail &= FBNIC_QUEUE_BDQ_PTRS_TAIL_MASK;
+	head &= FBNIC_QUEUE_RCQ_PTRS_HEAD_MASK;
+
+	seq_printf(s, "HW: head: %#06x tail: %#06x\n", head, tail);
+
+	seq_puts(s, "\n");
+}
+
+static void fbnic_dbg_twd_desc_seq_show(struct seq_file *s, int i)
+{
+	struct fbnic_ring *ring = s->private;
+	u64 twd = le64_to_cpu(ring->desc[i]);
+
+	switch (FIELD_GET(FBNIC_TWD_TYPE_MASK, twd)) {
+	case FBNIC_TWD_TYPE_META:
+		seq_printf(s, "%04x %#06llx  %llx %llx %llx %llx %llx %#llx %#llx %llx %#04llx %#04llx %llx %#04llx\n",
+			   i, FIELD_GET(FBNIC_TWD_LEN_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_TYPE_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_FLAG_REQ_COMPLETION, twd),
+			   FIELD_GET(FBNIC_TWD_FLAG_REQ_CSO, twd),
+			   FIELD_GET(FBNIC_TWD_FLAG_REQ_LSO, twd),
+			   FIELD_GET(FBNIC_TWD_FLAG_REQ_TS, twd),
+			   FIELD_GET(FBNIC_TWD_L4_HLEN_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_CSUM_OFFSET_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_L4_TYPE_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_L3_IHLEN_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_L3_OHLEN_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_L3_TYPE_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_L2_HLEN_MASK, twd));
+		break;
+	default:
+		seq_printf(s, "%04x %#06llx  %llx %#014llx\n", i,
+			   FIELD_GET(FBNIC_TWD_LEN_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_TYPE_MASK, twd),
+			   FIELD_GET(FBNIC_TWD_ADDR_MASK, twd));
+		break;
+	}
+}
+
+static int fbnic_dbg_twq_desc_seq_show(struct seq_file *s, void *v)
+{
+	struct fbnic_ring *ring = s->private;
+	char hdr[80];
+	int i;
+
+	/* Generate header on first entry */
+	fbnic_dbg_ring_show(s);
+	snprintf(hdr, sizeof(hdr), "%4s %5s %s %s\n",
+		 "DESC", "LEN/MSS", "T", "METADATA/TIMESTAMP/BUFFER_ADDR");
+	seq_puts(s, hdr);
+	fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
+
+	/* Display descriptor */
+	if (!ring->desc) {
+		seq_puts(s, "Descriptor ring not allocated.\n");
+		return 0;
+	}
+
+	for (i = 0; i <= ring->size_mask; i++)
+		fbnic_dbg_twd_desc_seq_show(s, i);
+
+	return 0;
+}
+
+static int fbnic_dbg_tcq_desc_seq_show(struct seq_file *s, void *v)
+{
+	struct fbnic_ring *ring = s->private;
+	char hdr[80];
+	int i;
+
+	/* Generate header on first entry */
+	fbnic_dbg_ring_show(s);
+	snprintf(hdr, sizeof(hdr), "%4s %s %s %s %5s %-16s %-6s %-6s\n",
+		 "DESC", "D", "T", "Q", "STATUS", "TIMESTAMP", "HEAD1", "HEAD0");
+	seq_puts(s, hdr);
+	fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
+
+	/* Display descriptor */
+	if (!ring->desc) {
+		seq_puts(s, "Descriptor ring not allocated.\n");
+		return 0;
+	}
+
+	for (i = 0; i <= ring->size_mask; i++) {
+		u64 tcd = le64_to_cpu(ring->desc[i]);
+
+		switch (FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd)) {
+		case FBNIC_TCD_TYPE_0:
+			seq_printf(s, "%04x %llx %llx %llx %#05llx %-17s %#06llx %#06llx\n",
+				   i, FIELD_GET(FBNIC_TCD_DONE, tcd),
+				   FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd),
+				   FIELD_GET(FBNIC_TCD_TWQ1, tcd),
+				   FIELD_GET(FBNIC_TCD_STATUS_MASK, tcd),
+				   "",
+				   FIELD_GET(FBNIC_TCD_TYPE0_HEAD1_MASK, tcd),
+				   FIELD_GET(FBNIC_TCD_TYPE0_HEAD0_MASK, tcd));
+			break;
+		case FBNIC_TCD_TYPE_1:
+			seq_printf(s, "%04x %llx %llx %llx %#05llx  %#012llx\n",
+				   i, FIELD_GET(FBNIC_TCD_DONE, tcd),
+				   FIELD_GET(FBNIC_TCD_TYPE_MASK, tcd),
+				   FIELD_GET(FBNIC_TCD_TWQ1, tcd),
+				   FIELD_GET(FBNIC_TCD_STATUS_MASK, tcd),
+				   FIELD_GET(FBNIC_TCD_TYPE1_TS_MASK, tcd));
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int fbnic_dbg_bdq_desc_seq_show(struct seq_file *s, void *v)
+{
+	struct fbnic_ring *ring = s->private;
+	char hdr[80];
+	int i;
+
+	/* Generate header on first entry */
+	fbnic_dbg_ring_show(s);
+	snprintf(hdr, sizeof(hdr), "%4s %-4s %s\n",
+		 "DESC", "ID", "BUFFER_ADDR");
+	seq_puts(s, hdr);
+	fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
+
+	/* Display descriptor */
+	if (!ring->desc) {
+		seq_puts(s, "Descriptor ring not allocated.\n");
+		return 0;
+	}
+
+	for (i = 0; i <= ring->size_mask; i++) {
+		u64 bd = le64_to_cpu(ring->desc[i]);
+
+		seq_printf(s, "%04x %#04llx %#014llx\n", i,
+			   FIELD_GET(FBNIC_BD_DESC_ID_MASK, bd),
+			   FIELD_GET(FBNIC_BD_DESC_ADDR_MASK, bd));
+	}
+
+	return 0;
+}
+
+static void fbnic_dbg_rcd_desc_seq_show(struct seq_file *s, int i)
+{
+	struct fbnic_ring *ring = s->private;
+	u64 rcd = le64_to_cpu(ring->desc[i]);
+
+	switch (FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd)) {
+	case FBNIC_RCD_TYPE_HDR_AL:
+	case FBNIC_RCD_TYPE_PAY_AL:
+		seq_printf(s, "%04x %llx %llx %llx %#06llx      %#06llx   %#06llx\n",
+			   i, FIELD_GET(FBNIC_RCD_DONE, rcd),
+			   FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_AL_PAGE_FIN, rcd),
+			   FIELD_GET(FBNIC_RCD_AL_BUFF_OFF_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_AL_BUFF_LEN_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_AL_BUFF_ID_MASK, rcd));
+		break;
+	case FBNIC_RCD_TYPE_OPT_META:
+		seq_printf(s, "%04x %llx %llx %llx %llx %llx      %#06llx   %#012llx\n",
+			   i, FIELD_GET(FBNIC_RCD_DONE, rcd),
+			   FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_OPT_META_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_OPT_META_TS, rcd),
+			   FIELD_GET(FBNIC_RCD_OPT_META_ACTION, rcd),
+			   FIELD_GET(FBNIC_RCD_OPT_META_ACTION_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_OPT_META_TS_MASK, rcd));
+		break;
+	case FBNIC_RCD_TYPE_META:
+		seq_printf(s, "%04x %llx %llx %llx %llx %llx %llx %llx %llx %llx %#06llx   %#010llx\n",
+			   i, FIELD_GET(FBNIC_RCD_DONE, rcd),
+			   FIELD_GET(FBNIC_RCD_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_META_ECN, rcd),
+			   FIELD_GET(FBNIC_RCD_META_L4_CSUM_UNNECESSARY, rcd),
+			   FIELD_GET(FBNIC_RCD_META_ERR_MAC_EOP, rcd),
+			   FIELD_GET(FBNIC_RCD_META_ERR_TRUNCATED_FRAME, rcd),
+			   FIELD_GET(FBNIC_RCD_META_ERR_PARSER, rcd),
+			   FIELD_GET(FBNIC_RCD_META_L4_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_META_L3_TYPE_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_META_L2_CSUM_MASK, rcd),
+			   FIELD_GET(FBNIC_RCD_META_RSS_HASH_MASK, rcd));
+		break;
+	}
+}
+
+static int fbnic_dbg_rcq_desc_seq_show(struct seq_file *s, void *v)
+{
+	struct fbnic_ring *ring = s->private;
+	char hdr[80];
+	int i;
+
+	/* Generate header on first entry */
+	fbnic_dbg_ring_show(s);
+	snprintf(hdr, sizeof(hdr),
+		 "%18s %s %s\n", "OFFSET/", "L", "L");
+	seq_puts(s, hdr);
+	snprintf(hdr, sizeof(hdr),
+		 "%4s %s %s %s %s %s %s %s %s %s %-8s %s\n",
+		 "DESC", "D", "T", "F", "C", "M", "T", "P", "4", "3", "LEN/CSUM", "ID/TS/RSS");
+	seq_puts(s, hdr);
+	fbnic_dbg_desc_break(s, strnlen(hdr, sizeof(hdr)));
+
+	/* Display descriptor */
+	if (!ring->desc) {
+		seq_puts(s, "Descriptor ring not allocated.\n");
+		return 0;
+	}
+
+	for (i = 0; i <= ring->size_mask; i++)
+		fbnic_dbg_rcd_desc_seq_show(s, i);
+
+	return 0;
+}
+
+static int fbnic_dbg_desc_open(struct inode *inode, struct file *file)
+{
+	struct fbnic_ring *ring = inode->i_private;
+	int (*show)(struct seq_file *s, void *v);
+
+	switch (ring->doorbell - fbnic_ring_csr_base(ring)) {
+	case FBNIC_QUEUE_TWQ0_TAIL:
+	case FBNIC_QUEUE_TWQ1_TAIL:
+		show = fbnic_dbg_twq_desc_seq_show;
+		break;
+	case FBNIC_QUEUE_TCQ_HEAD:
+		show = fbnic_dbg_tcq_desc_seq_show;
+		break;
+	case FBNIC_QUEUE_BDQ_HPQ_TAIL:
+	case FBNIC_QUEUE_BDQ_PPQ_TAIL:
+		show = fbnic_dbg_bdq_desc_seq_show;
+		break;
+	case FBNIC_QUEUE_RCQ_HEAD:
+		show = fbnic_dbg_rcq_desc_seq_show;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return single_open(file, show, ring);
+}
+
+static const struct file_operations fbnic_dbg_desc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fbnic_dbg_desc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+void fbnic_dbg_nv_init(struct fbnic_napi_vector *nv)
+{
+	struct fbnic_dev *fbd = nv->fbd;
+	char name[16];
+	int i, j;
+
+	/* Generate a folder for each napi vector */
+	snprintf(name, sizeof(name), "nv.%03d", nv->v_idx);
+
+	nv->dbg_nv = debugfs_create_dir(name, fbd->dbg_fbd);
+
+	/* Generate a file for each Tx ring in the napi vector */
+	for (i = 0; i < nv->txt_count; i++) {
+		struct fbnic_q_triad *qt = &nv->qt[i];
+		unsigned int hw_idx;
+
+		hw_idx = fbnic_ring_csr_base(&qt->cmpl) -
+			  &fbd->uc_addr0[FBNIC_QUEUE(0)];
+		hw_idx /= FBNIC_QUEUE_STRIDE;
+
+		snprintf(name, sizeof(name), "twq0.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub0,
+				    &fbnic_dbg_desc_fops);
+
+		snprintf(name, sizeof(name), "twq1.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub1,
+				    &fbnic_dbg_desc_fops);
+
+		snprintf(name, sizeof(name), "tcq.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->cmpl,
+				    &fbnic_dbg_desc_fops);
+	}
+
+	/* Generate a file for each Rx ring in the napi vector */
+	for (j = 0; j < nv->rxt_count; j++, i++) {
+		struct fbnic_q_triad *qt = &nv->qt[i];
+		unsigned int hw_idx;
+
+		hw_idx = fbnic_ring_csr_base(&qt->cmpl) -
+			  &fbd->uc_addr0[FBNIC_QUEUE(0)];
+		hw_idx /= FBNIC_QUEUE_STRIDE;
+
+		snprintf(name, sizeof(name), "hpq.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub0,
+				    &fbnic_dbg_desc_fops);
+
+		snprintf(name, sizeof(name), "ppq.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->sub1,
+				    &fbnic_dbg_desc_fops);
+
+		snprintf(name, sizeof(name), "rcq.%03d", hw_idx);
+		debugfs_create_file(name, 0400, nv->dbg_nv, &qt->cmpl,
+				    &fbnic_dbg_desc_fops);
+	}
+}
+
+void fbnic_dbg_nv_exit(struct fbnic_napi_vector *nv)
+{
+	debugfs_remove_recursive(nv->dbg_nv);
+	nv->dbg_nv = NULL;
+}
+
 static int fbnic_dbg_mac_addr_show(struct seq_file *s, void *v)
 {
 	struct fbnic_dev *fbd = s->private;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 9240673c7533..6f9389748a7d 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -142,10 +142,14 @@ void fbnic_up(struct fbnic_net *fbn)
 	netif_tx_start_all_queues(fbn->netdev);

 	fbnic_service_task_start(fbn);
+
+	fbnic_dbg_up(fbn);
 }

 void fbnic_down_noidle(struct fbnic_net *fbn)
 {
+	fbnic_dbg_down(fbn);
+
 	fbnic_service_task_stop(fbn);

 	/* Disable Tx/Rx Processing */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index e36ed25462b4..e29959241ff3 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -39,7 +39,7 @@ struct fbnic_xmit_cb {

 #define FBNIC_XMIT_NOUNMAP	((void *)1)

-static u32 __iomem *fbnic_ring_csr_base(const struct fbnic_ring *ring)
+u32 __iomem *fbnic_ring_csr_base(const struct fbnic_ring *ring)
 {
 	unsigned long csr_base = (unsigned long)ring->doorbell;

@@ -2255,6 +2255,22 @@ fbnic_nv_disable(struct fbnic_net *fbn, struct fbnic_napi_vector *nv)
 	fbnic_wrfl(fbn->fbd);
 }

+void fbnic_dbg_down(struct fbnic_net *fbn)
+{
+	int i;
+
+	for (i = 0; i < fbn->num_napi; i++)
+		fbnic_dbg_nv_exit(fbn->napi[i]);
+}
+
+void fbnic_dbg_up(struct fbnic_net *fbn)
+{
+	int i;
+
+	for (i = 0; i < fbn->num_napi; i++)
+		fbnic_dbg_nv_init(fbn->napi[i]);
+}
+
 void fbnic_disable(struct fbnic_net *fbn)
 {
 	struct fbnic_dev *fbd = fbn->fbd;
@@ -2861,6 +2877,7 @@ static void __fbnic_nv_restart(struct fbnic_net *fbn,

 	for (i = 0; i < nv->txt_count; i++)
 		netif_wake_subqueue(fbn->netdev, nv->qt[i].sub0.q_idx);
+	fbnic_dbg_nv_init(nv);
 }

 static int fbnic_queue_start(struct net_device *dev,
@@ -2895,6 +2912,7 @@ static int fbnic_queue_stop(struct net_device *dev, void *qmem, int idx)

 	real = container_of(fbn->rx[idx], struct fbnic_q_triad, cmpl);
 	nv = fbn->napi[idx % fbn->num_napi];
+	fbnic_dbg_nv_exit(nv);

 	napi_disable_locked(&nv->napi);
 	fbnic_nv_irq_disable(nv);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
index 27776e844e29..b9560103ab86 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
@@ -151,6 +151,7 @@ struct fbnic_napi_vector {
 	struct napi_struct napi;
 	struct device *dev;		/* Device for DMA unmapping */
 	struct fbnic_dev *fbd;
+	struct dentry *dbg_nv;

 	u16 v_idx;
 	u8 txt_count;
@@ -187,9 +188,12 @@ void fbnic_napi_disable(struct fbnic_net *fbn);
 void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause);
 void fbnic_enable(struct fbnic_net *fbn);
 void fbnic_disable(struct fbnic_net *fbn);
+void fbnic_dbg_up(struct fbnic_net *fbn);
+void fbnic_dbg_down(struct fbnic_net *fbn);
 void fbnic_flush(struct fbnic_net *fbn);
 void fbnic_fill(struct fbnic_net *fbn);

+u32 __iomem *fbnic_ring_csr_base(const struct fbnic_ring *ring);
 void fbnic_napi_depletion_check(struct net_device *netdev);
 int fbnic_wait_all_queues_idle(struct fbnic_dev *fbd, bool may_fail);

@@ -198,4 +202,6 @@ static inline int fbnic_napi_idx(const struct fbnic_napi_vector *nv)
 	return nv->v_idx - FBNIC_NON_NAPI_VECTORS;
 }

+void fbnic_dbg_nv_init(struct fbnic_napi_vector *nv);
+void fbnic_dbg_nv_exit(struct fbnic_napi_vector *nv);
 #endif /* _FBNIC_TXRX_H_ */
--
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ