xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_csr.c (revision 1623bc27a85a93e82194c8d077eccc464efa67db)
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;
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 }
149