]> www.infradead.org Git - users/hch/misc.git/commitdiff
eth: fbnic: Add support to dump registers
authorMohsin Bashir <mohsin.bashr@gmail.com>
Tue, 12 Nov 2024 22:26:05 +0000 (14:26 -0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 14 Nov 2024 14:28:49 +0000 (15:28 +0100)
Add support for the 'ethtool -d <dev>' command to retrieve and print
a register dump for fbnic. The dump defaults to version 1 and consists
of two parts: all the register sections that can be dumped linearly, and
an RPC RAM section that is structured in an interleaved fashion and
requires special handling. For each register section, the dump also
contains the start and end boundary information which can simplify parsing.

Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Link: https://patch.msgid.link/20241112222605.3303211-1-mohsin.bashr@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/meta/fbnic/Makefile
drivers/net/ethernet/meta/fbnic/fbnic.h
drivers/net/ethernet/meta/fbnic/fbnic_csr.c [new file with mode: 0644]
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c

index cadd4dac66201b16bb949743c6448cd8e53030f6..425e8b8012657b97653857c896399709632d66eb 100644 (file)
@@ -7,7 +7,8 @@
 
 obj-$(CONFIG_FBNIC) += fbnic.o
 
-fbnic-y := fbnic_devlink.o \
+fbnic-y := fbnic_csr.o \
+          fbnic_devlink.o \
           fbnic_ethtool.o \
           fbnic_fw.o \
           fbnic_hw_stats.o \
index 9f9cb9b3e74e8a1f68f263ba6f1e18de4f17207d..98870cb2b6892417535bc008710570d386f95237 100644 (file)
@@ -156,6 +156,9 @@ int fbnic_alloc_irqs(struct fbnic_dev *fbd);
 void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version,
                                 const size_t str_sz);
 
+void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version);
+int fbnic_csr_regs_len(struct fbnic_dev *fbd);
+
 enum fbnic_boards {
        fbnic_board_asic
 };
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.c b/drivers/net/ethernet/meta/fbnic/fbnic_csr.c
new file mode 100644 (file)
index 0000000..2118901
--- /dev/null
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) Meta Platforms, Inc. and affiliates. */
+
+#include "fbnic.h"
+
+#define FBNIC_BOUNDS(section) { \
+       .start = FBNIC_CSR_START_##section, \
+       .end = FBNIC_CSR_END_##section + 1, \
+}
+
+struct fbnic_csr_bounds {
+       u32     start;
+       u32     end;
+};
+
+static const struct fbnic_csr_bounds fbnic_csr_sects[] = {
+       FBNIC_BOUNDS(INTR),
+       FBNIC_BOUNDS(INTR_CQ),
+       FBNIC_BOUNDS(QM_TX),
+       FBNIC_BOUNDS(QM_RX),
+       FBNIC_BOUNDS(TCE),
+       FBNIC_BOUNDS(TCE_RAM),
+       FBNIC_BOUNDS(TMI),
+       FBNIC_BOUNDS(PTP),
+       FBNIC_BOUNDS(RXB),
+       FBNIC_BOUNDS(RPC),
+       FBNIC_BOUNDS(FAB),
+       FBNIC_BOUNDS(MASTER),
+       FBNIC_BOUNDS(PCS),
+       FBNIC_BOUNDS(RSFEC),
+       FBNIC_BOUNDS(MAC_MAC),
+       FBNIC_BOUNDS(SIG),
+       FBNIC_BOUNDS(PUL_USER),
+       FBNIC_BOUNDS(QUEUE),
+       FBNIC_BOUNDS(RPC_RAM),
+};
+
+#define FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY                        14
+#define FBNIC_RPC_TCAM_ACT_NUM_ENTRIES                 64
+
+#define FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY              4
+#define FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES               32
+
+#define FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY                9
+#define FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES         8
+
+#define FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY                9
+#define FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES         8
+
+#define FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY              9
+#define FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES               8
+
+#define FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY              9
+#define FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES               8
+
+#define FBNIC_RPC_RSS_TBL_DW_PER_ENTRY                 2
+#define FBNIC_RPC_RSS_TBL_NUM_ENTRIES                  256
+
+static void fbnic_csr_get_regs_rpc_ram(struct fbnic_dev *fbd, u32 **data_p)
+{
+       u32 start = FBNIC_CSR_START_RPC_RAM;
+       u32 end = FBNIC_CSR_END_RPC_RAM;
+       u32 *data = *data_p;
+       u32 i, j;
+
+       *(data++) = start;
+       *(data++) = end - 1;
+
+       /* FBNIC_RPC_TCAM_ACT */
+       for (i = 0; i < FBNIC_RPC_TCAM_ACT_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_ACT(i, j));
+       }
+
+       /* FBNIC_RPC_TCAM_MACDA */
+       for (i = 0; i < FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_MACDA(i, j));
+       }
+
+       /* FBNIC_RPC_TCAM_OUTER_IPSRC */
+       for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(i, j));
+       }
+
+       /* FBNIC_RPC_TCAM_OUTER_IPDST */
+       for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(i, j));
+       }
+
+       /* FBNIC_RPC_TCAM_IPSRC */
+       for (i = 0; i < FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPSRC(i, j));
+       }
+
+       /* FBNIC_RPC_TCAM_IPDST */
+       for (i = 0; i < FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPDST(i, j));
+       }
+
+       /* FBNIC_RPC_RSS_TBL */
+       for (i = 0; i < FBNIC_RPC_RSS_TBL_NUM_ENTRIES; i++) {
+               for (j = 0; j < FBNIC_RPC_RSS_TBL_DW_PER_ENTRY; j++)
+                       *(data++) = rd32(fbd, FBNIC_RPC_RSS_TBL(i, j));
+       }
+
+       *data_p = data;
+}
+
+void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version)
+{
+       const struct fbnic_csr_bounds *bound;
+       u32 *start = data;
+       int i, j;
+
+       *regs_version = 1u;
+
+       /* Skip RPC_RAM section which cannot be dumped linearly */
+       for (i = 0, bound = fbnic_csr_sects;
+            i < ARRAY_SIZE(fbnic_csr_sects) - 1; i++, ++bound) {
+               *(data++) = bound->start;
+               *(data++) = bound->end - 1;
+               for (j = bound->start; j < bound->end; j++)
+                       *(data++) = rd32(fbd, j);
+       }
+
+       /* Dump the RPC_RAM as special case registers */
+       fbnic_csr_get_regs_rpc_ram(fbd, &data);
+
+       WARN_ON(data - start != fbnic_csr_regs_len(fbd));
+}
+
+int fbnic_csr_regs_len(struct fbnic_dev *fbd)
+{
+       int i, len = 0;
+
+       /* Dump includes start and end information of each section
+        * which results in an offset of 2
+        */
+       for (i = 0; i < ARRAY_SIZE(fbnic_csr_sects); i++)
+               len += fbnic_csr_sects[i].end - fbnic_csr_sects[i].start + 2;
+
+       return len;
+}
index dd407089ca47baf4e234c6dcd93b943ca7b8dfc2..f9a531ce9e179e36eca03e7041d2f9457edcb683 100644 (file)
@@ -665,6 +665,15 @@ enum {
 #define FBNIC_RPC_TCAM_MACDA_VALUE             CSR_GENMASK(15, 0)
 #define FBNIC_RPC_TCAM_MACDA_MASK              CSR_GENMASK(31, 16)
 
+#define FBNIC_RPC_TCAM_OUTER_IPSRC(m, n)\
+       (0x08c00 + 0x08 * (n) + (m))            /* 0x023000 + 32*n + 4*m */
+#define FBNIC_RPC_TCAM_OUTER_IPDST(m, n)\
+       (0x08c48 + 0x08 * (n) + (m))            /* 0x023120 + 32*n + 4*m */
+#define FBNIC_RPC_TCAM_IPSRC(m, n)\
+       (0x08c90 + 0x08 * (n) + (m))            /* 0x023240 + 32*n + 4*m */
+#define FBNIC_RPC_TCAM_IPDST(m, n)\
+       (0x08cd8 + 0x08 * (n) + (m))            /* 0x023360 + 32*n + 4*m */
+
 #define FBNIC_RPC_RSS_TBL(n, m) \
        (0x08d20 + 0x100 * (n) + (m))           /* 0x023480 + 1024*n + 4*m */
 #define FBNIC_RPC_RSS_TBL_COUNT                        2
@@ -683,6 +692,13 @@ enum {
 #define FBNIC_MASTER_SPARE_0           0x0C41B         /* 0x3106c */
 #define FBNIC_CSR_END_MASTER           0x0C452 /* CSR section delimiter */
 
+/* MAC PCS registers */
+#define FBNIC_CSR_START_PCS            0x10000 /* CSR section delimiter */
+#define FBNIC_CSR_END_PCS              0x10668 /* CSR section delimiter */
+
+#define FBNIC_CSR_START_RSFEC          0x10800 /* CSR section delimiter */
+#define FBNIC_CSR_END_RSFEC            0x108c8 /* CSR section delimiter */
+
 /* MAC MAC registers (ASIC only) */
 #define FBNIC_CSR_START_MAC_MAC                0x11000 /* CSR section delimiter */
 #define FBNIC_MAC_COMMAND_CONFIG       0x11002         /* 0x44008 */
index 1117d5a32867c5e475dfe5eea71e61fd4c82104c..354b5397815fcc87a9a0aa56ebb7f3760146beb1 100644 (file)
@@ -116,8 +116,25 @@ static void fbnic_get_ts_stats(struct net_device *netdev,
        }
 }
 
+static void fbnic_get_regs(struct net_device *netdev,
+                          struct ethtool_regs *regs, void *data)
+{
+       struct fbnic_net *fbn = netdev_priv(netdev);
+
+       fbnic_csr_get_regs(fbn->fbd, data, &regs->version);
+}
+
+static int fbnic_get_regs_len(struct net_device *netdev)
+{
+       struct fbnic_net *fbn = netdev_priv(netdev);
+
+       return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32);
+}
+
 static const struct ethtool_ops fbnic_ethtool_ops = {
        .get_drvinfo            = fbnic_get_drvinfo,
+       .get_regs_len           = fbnic_get_regs_len,
+       .get_regs               = fbnic_get_regs,
        .get_ts_info            = fbnic_get_ts_info,
        .get_ts_stats           = fbnic_get_ts_stats,
        .get_eth_mac_stats      = fbnic_get_eth_mac_stats,