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
fbnic_csr_get_regs_rpc_ram(struct fbnic_dev * fbd,u32 ** data_p)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;
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
fbnic_csr_get_regs(struct fbnic_dev * fbd,u32 * data,u32 * regs_version)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
fbnic_csr_regs_len(struct fbnic_dev * fbd)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 }
149