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(PCIE_SS_COMPHY),
34 FBNIC_BOUNDS(PUL_USER),
35 FBNIC_BOUNDS(QUEUE),
36 FBNIC_BOUNDS(RPC_RAM),
37 };
38
39 #define FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY 14
40 #define FBNIC_RPC_TCAM_ACT_NUM_ENTRIES 64
41
42 #define FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY 4
43 #define FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES 32
44
45 #define FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY 9
46 #define FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES 8
47
48 #define FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY 9
49 #define FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES 8
50
51 #define FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY 9
52 #define FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES 8
53
54 #define FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY 9
55 #define FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES 8
56
57 #define FBNIC_RPC_RSS_TBL_DW_PER_ENTRY 2
58 #define FBNIC_RPC_RSS_TBL_NUM_ENTRIES 256
59
fbnic_csr_get_regs_rpc_ram(struct fbnic_dev * fbd,u32 ** data_p)60 static void fbnic_csr_get_regs_rpc_ram(struct fbnic_dev *fbd, u32 **data_p)
61 {
62 u32 start = FBNIC_CSR_START_RPC_RAM;
63 u32 end = FBNIC_CSR_END_RPC_RAM;
64 u32 *data = *data_p;
65 u32 i, j;
66
67 *(data++) = start;
68 *(data++) = end;
69
70 /* FBNIC_RPC_TCAM_ACT */
71 for (i = 0; i < FBNIC_RPC_TCAM_ACT_NUM_ENTRIES; i++) {
72 for (j = 0; j < FBNIC_RPC_TCAM_ACT_DW_PER_ENTRY; j++)
73 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_ACT(i, j));
74 }
75
76 /* FBNIC_RPC_TCAM_MACDA */
77 for (i = 0; i < FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES; i++) {
78 for (j = 0; j < FBNIC_RPC_TCAM_MACDA_DW_PER_ENTRY; j++)
79 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_MACDA(i, j));
80 }
81
82 /* FBNIC_RPC_TCAM_OUTER_IPSRC */
83 for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPSRC_NUM_ENTRIES; i++) {
84 for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPSRC_DW_PER_ENTRY; j++)
85 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPSRC(i, j));
86 }
87
88 /* FBNIC_RPC_TCAM_OUTER_IPDST */
89 for (i = 0; i < FBNIC_RPC_TCAM_OUTER_IPDST_NUM_ENTRIES; i++) {
90 for (j = 0; j < FBNIC_RPC_TCAM_OUTER_IPDST_DW_PER_ENTRY; j++)
91 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_OUTER_IPDST(i, j));
92 }
93
94 /* FBNIC_RPC_TCAM_IPSRC */
95 for (i = 0; i < FBNIC_RPC_TCAM_IPSRC_NUM_ENTRIES; i++) {
96 for (j = 0; j < FBNIC_RPC_TCAM_IPSRC_DW_PER_ENTRY; j++)
97 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPSRC(i, j));
98 }
99
100 /* FBNIC_RPC_TCAM_IPDST */
101 for (i = 0; i < FBNIC_RPC_TCAM_IPDST_NUM_ENTRIES; i++) {
102 for (j = 0; j < FBNIC_RPC_TCAM_IPDST_DW_PER_ENTRY; j++)
103 *(data++) = rd32(fbd, FBNIC_RPC_TCAM_IPDST(i, j));
104 }
105
106 /* FBNIC_RPC_RSS_TBL */
107 for (i = 0; i < FBNIC_RPC_RSS_TBL_NUM_ENTRIES; i++) {
108 for (j = 0; j < FBNIC_RPC_RSS_TBL_DW_PER_ENTRY; j++)
109 *(data++) = rd32(fbd, FBNIC_RPC_RSS_TBL(i, j));
110 }
111
112 *data_p = data;
113 }
114
fbnic_csr_get_regs(struct fbnic_dev * fbd,u32 * data,u32 * regs_version)115 void fbnic_csr_get_regs(struct fbnic_dev *fbd, u32 *data, u32 *regs_version)
116 {
117 const struct fbnic_csr_bounds *bound;
118 u32 *start = data;
119 int i, j;
120
121 *regs_version = 1u;
122
123 /* Skip RPC_RAM section which cannot be dumped linearly */
124 for (i = 0, bound = fbnic_csr_sects;
125 i < ARRAY_SIZE(fbnic_csr_sects) - 1; i++, ++bound) {
126 *(data++) = bound->start;
127 *(data++) = bound->end - 1;
128 for (j = bound->start; j < bound->end; j++)
129 *(data++) = rd32(fbd, j);
130 }
131
132 /* Dump the RPC_RAM as special case registers */
133 fbnic_csr_get_regs_rpc_ram(fbd, &data);
134
135 WARN_ON(data - start != fbnic_csr_regs_len(fbd));
136 }
137
fbnic_csr_regs_len(struct fbnic_dev * fbd)138 int fbnic_csr_regs_len(struct fbnic_dev *fbd)
139 {
140 int i, len = 0;
141
142 /* Dump includes start and end information of each section
143 * which results in an offset of 2
144 */
145 for (i = 0; i < ARRAY_SIZE(fbnic_csr_sects); i++)
146 len += fbnic_csr_sects[i].end - fbnic_csr_sects[i].start + 2;
147
148 return len;
149 }
150