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