Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

eth: fbnic: Add support to dump registers

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>

authored by

Mohsin Bashir and committed by
Paolo Abeni
3d12862b a71c69f5

+186 -1
+2 -1
drivers/net/ethernet/meta/fbnic/Makefile
··· 7 7 8 8 obj-$(CONFIG_FBNIC) += fbnic.o 9 9 10 - fbnic-y := fbnic_devlink.o \ 10 + fbnic-y := fbnic_csr.o \ 11 + fbnic_devlink.o \ 11 12 fbnic_ethtool.o \ 12 13 fbnic_fw.o \ 13 14 fbnic_hw_stats.o \
+3
drivers/net/ethernet/meta/fbnic/fbnic.h
··· 156 156 void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version, 157 157 const size_t str_sz); 158 158 159 + void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version); 160 + int fbnic_csr_regs_len(struct fbnic_dev *fbd); 161 + 159 162 enum fbnic_boards { 160 163 fbnic_board_asic 161 164 };
+148
drivers/net/ethernet/meta/fbnic/fbnic_csr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include "fbnic.h" 5 + 6 + #define FBNIC_BOUNDS(section) { \ 7 + .start = FBNIC_CSR_START_##section, \ 8 + .end = FBNIC_CSR_END_##section + 1, \ 9 + } 10 + 11 + struct fbnic_csr_bounds { 12 + u32 start; 13 + u32 end; 14 + }; 15 + 16 + static const struct fbnic_csr_bounds fbnic_csr_sects[] = { 17 + FBNIC_BOUNDS(INTR), 18 + FBNIC_BOUNDS(INTR_CQ), 19 + FBNIC_BOUNDS(QM_TX), 20 + FBNIC_BOUNDS(QM_RX), 21 + FBNIC_BOUNDS(TCE), 22 + FBNIC_BOUNDS(TCE_RAM), 23 + FBNIC_BOUNDS(TMI), 24 + FBNIC_BOUNDS(PTP), 25 + FBNIC_BOUNDS(RXB), 26 + FBNIC_BOUNDS(RPC), 27 + FBNIC_BOUNDS(FAB), 28 + FBNIC_BOUNDS(MASTER), 29 + FBNIC_BOUNDS(PCS), 30 + FBNIC_BOUNDS(RSFEC), 31 + FBNIC_BOUNDS(MAC_MAC), 32 + FBNIC_BOUNDS(SIG), 33 + FBNIC_BOUNDS(PUL_USER), 34 + FBNIC_BOUNDS(QUEUE), 35 + FBNIC_BOUNDS(RPC_RAM), 36 + }; 37 + 38 + #define FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY 14 39 + #define FBNIC_RPC_TCAM_ACT_NUM_ENTRIES 64 40 + 41 + #define FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY 4 42 + #define FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES 32 43 + 44 + #define FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY 9 45 + #define FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES 8 46 + 47 + #define FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY 9 48 + #define FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES 8 49 + 50 + #define FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY 9 51 + #define FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES 8 52 + 53 + #define FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY 9 54 + #define FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES 8 55 + 56 + #define FBNIC_RPC_RSS_TBL_DW_PER_ENTRY 2 57 + #define FBNIC_RPC_RSS_TBL_NUM_ENTRIES 256 58 + 59 + static void fbnic_csr_get_regs_rpc_ram(struct fbnic_dev *fbd, u32 **data_p) 60 + { 61 + u32 start = FBNIC_CSR_START_RPC_RAM; 62 + u32 end = FBNIC_CSR_END_RPC_RAM; 63 + u32 *data = *data_p; 64 + u32 i, j; 65 + 66 + *(data++) = start; 67 + *(data++) = end - 1; 68 + 69 + /* FBNIC_RPC_TCAM_ACT */ 70 + for (i = 0; i < FBNIC_RPC_TCAM_ACT_NUM_ENTRIES; i++) { 71 + for (j = 0; j < FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY; j++) 72 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_ACT(i, j)); 73 + } 74 + 75 + /* FBNIC_RPC_TCAM_MACDA */ 76 + for (i = 0; i < FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES; i++) { 77 + for (j = 0; j < FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY; j++) 78 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_MACDA(i, j)); 79 + } 80 + 81 + /* FBNIC_RPC_TCAM_OUTER_IPSRC */ 82 + for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES; i++) { 83 + for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY; j++) 84 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(i, j)); 85 + } 86 + 87 + /* FBNIC_RPC_TCAM_OUTER_IPDST */ 88 + for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES; i++) { 89 + for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY; j++) 90 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(i, j)); 91 + } 92 + 93 + /* FBNIC_RPC_TCAM_IPSRC */ 94 + for (i = 0; i < FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES; i++) { 95 + for (j = 0; j < FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY; j++) 96 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPSRC(i, j)); 97 + } 98 + 99 + /* FBNIC_RPC_TCAM_IPDST */ 100 + for (i = 0; i < FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES; i++) { 101 + for (j = 0; j < FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY; j++) 102 + *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPDST(i, j)); 103 + } 104 + 105 + /* FBNIC_RPC_RSS_TBL */ 106 + for (i = 0; i < FBNIC_RPC_RSS_TBL_NUM_ENTRIES; i++) { 107 + for (j = 0; j < FBNIC_RPC_RSS_TBL_DW_PER_ENTRY; j++) 108 + *(data++) = rd32(fbd, FBNIC_RPC_RSS_TBL(i, j)); 109 + } 110 + 111 + *data_p = data; 112 + } 113 + 114 + void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version) 115 + { 116 + const struct fbnic_csr_bounds *bound; 117 + u32 *start = data; 118 + int i, j; 119 + 120 + *regs_version = 1u; 121 + 122 + /* Skip RPC_RAM section which cannot be dumped linearly */ 123 + for (i = 0, bound = fbnic_csr_sects; 124 + i < ARRAY_SIZE(fbnic_csr_sects) - 1; i++, ++bound) { 125 + *(data++) = bound->start; 126 + *(data++) = bound->end - 1; 127 + for (j = bound->start; j < bound->end; j++) 128 + *(data++) = rd32(fbd, j); 129 + } 130 + 131 + /* Dump the RPC_RAM as special case registers */ 132 + fbnic_csr_get_regs_rpc_ram(fbd, &data); 133 + 134 + WARN_ON(data - start != fbnic_csr_regs_len(fbd)); 135 + } 136 + 137 + int fbnic_csr_regs_len(struct fbnic_dev *fbd) 138 + { 139 + int i, len = 0; 140 + 141 + /* Dump includes start and end information of each section 142 + * which results in an offset of 2 143 + */ 144 + for (i = 0; i < ARRAY_SIZE(fbnic_csr_sects); i++) 145 + len += fbnic_csr_sects[i].end - fbnic_csr_sects[i].start + 2; 146 + 147 + return len; 148 + }
+16
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
··· 665 665 #define FBNIC_RPC_TCAM_MACDA_VALUE CSR_GENMASK(15, 0) 666 666 #define FBNIC_RPC_TCAM_MACDA_MASK CSR_GENMASK(31, 16) 667 667 668 + #define FBNIC_RPC_TCAM_OUTER_IPSRC(m, n)\ 669 + (0x08c00 + 0x08 * (n) + (m)) /* 0x023000 + 32*n + 4*m */ 670 + #define FBNIC_RPC_TCAM_OUTER_IPDST(m, n)\ 671 + (0x08c48 + 0x08 * (n) + (m)) /* 0x023120 + 32*n + 4*m */ 672 + #define FBNIC_RPC_TCAM_IPSRC(m, n)\ 673 + (0x08c90 + 0x08 * (n) + (m)) /* 0x023240 + 32*n + 4*m */ 674 + #define FBNIC_RPC_TCAM_IPDST(m, n)\ 675 + (0x08cd8 + 0x08 * (n) + (m)) /* 0x023360 + 32*n + 4*m */ 676 + 668 677 #define FBNIC_RPC_RSS_TBL(n, m) \ 669 678 (0x08d20 + 0x100 * (n) + (m)) /* 0x023480 + 1024*n + 4*m */ 670 679 #define FBNIC_RPC_RSS_TBL_COUNT 2 ··· 691 682 #define FBNIC_CSR_START_MASTER 0x0C400 /* CSR section delimiter */ 692 683 #define FBNIC_MASTER_SPARE_0 0x0C41B /* 0x3106c */ 693 684 #define FBNIC_CSR_END_MASTER 0x0C452 /* CSR section delimiter */ 685 + 686 + /* MAC PCS registers */ 687 + #define FBNIC_CSR_START_PCS 0x10000 /* CSR section delimiter */ 688 + #define FBNIC_CSR_END_PCS 0x10668 /* CSR section delimiter */ 689 + 690 + #define FBNIC_CSR_START_RSFEC 0x10800 /* CSR section delimiter */ 691 + #define FBNIC_CSR_END_RSFEC 0x108c8 /* CSR section delimiter */ 694 692 695 693 /* MAC MAC registers (ASIC only) */ 696 694 #define FBNIC_CSR_START_MAC_MAC 0x11000 /* CSR section delimiter */
+17
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
··· 116 116 } 117 117 } 118 118 119 + static void fbnic_get_regs(struct net_device *netdev, 120 + struct ethtool_regs *regs, void *data) 121 + { 122 + struct fbnic_net *fbn = netdev_priv(netdev); 123 + 124 + fbnic_csr_get_regs(fbn->fbd, data, &regs->version); 125 + } 126 + 127 + static int fbnic_get_regs_len(struct net_device *netdev) 128 + { 129 + struct fbnic_net *fbn = netdev_priv(netdev); 130 + 131 + return fbnic_csr_regs_len(fbn->fbd) * sizeof(u32); 132 + } 133 + 119 134 static const struct ethtool_ops fbnic_ethtool_ops = { 120 135 .get_drvinfo = fbnic_get_drvinfo, 136 + .get_regs_len = fbnic_get_regs_len, 137 + .get_regs = fbnic_get_regs, 121 138 .get_ts_info = fbnic_get_ts_info, 122 139 .get_ts_stats = fbnic_get_ts_stats, 123 140 .get_eth_mac_stats = fbnic_get_eth_mac_stats,