1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * RSS and Classifier helpers for Marvell PPv2 Network Controller
4  *
5  * Copyright (C) 2014 Marvell
6  *
7  * Marcin Wojtas <mw@semihalf.com>
8  */
9 
10 #include "mvpp2.h"
11 #include "mvpp2_cls.h"
12 #include "mvpp2_prs.h"
13 
14 #define MVPP2_DEF_FLOW(_type, _id, _opts, _ri, _ri_mask)	\
15 {								\
16 	.flow_type = _type,					\
17 	.flow_id = _id,						\
18 	.supported_hash_opts = _opts,				\
19 	.prs_ri = {						\
20 		.ri = _ri,					\
21 		.ri_mask = _ri_mask				\
22 	}							\
23 }
24 
25 static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
26 	/* TCP over IPv4 flows, Not fragmented, no vlan tag */
27 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_UNTAG,
28 		       MVPP22_CLS_HEK_IP4_5T,
29 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
30 		       MVPP2_PRS_RI_L4_TCP,
31 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
32 
33 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_UNTAG,
34 		       MVPP22_CLS_HEK_IP4_5T,
35 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
36 		       MVPP2_PRS_RI_L4_TCP,
37 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
38 
39 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_UNTAG,
40 		       MVPP22_CLS_HEK_IP4_5T,
41 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
42 		       MVPP2_PRS_RI_L4_TCP,
43 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
44 
45 	/* TCP over IPv4 flows, Not fragmented, with vlan tag */
46 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG,
47 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
48 		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,
49 		       MVPP2_PRS_IP_MASK),
50 
51 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG,
52 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
53 		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,
54 		       MVPP2_PRS_IP_MASK),
55 
56 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG,
57 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
58 		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,
59 		       MVPP2_PRS_IP_MASK),
60 
61 	/* TCP over IPv4 flows, fragmented, no vlan tag */
62 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
63 		       MVPP22_CLS_HEK_IP4_2T,
64 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
65 		       MVPP2_PRS_RI_L4_TCP,
66 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
67 
68 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
69 		       MVPP22_CLS_HEK_IP4_2T,
70 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
71 		       MVPP2_PRS_RI_L4_TCP,
72 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
73 
74 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
75 		       MVPP22_CLS_HEK_IP4_2T,
76 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
77 		       MVPP2_PRS_RI_L4_TCP,
78 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
79 
80 	/* TCP over IPv4 flows, fragmented, with vlan tag */
81 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
82 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
83 		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,
84 		       MVPP2_PRS_IP_MASK),
85 
86 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
87 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
88 		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,
89 		       MVPP2_PRS_IP_MASK),
90 
91 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
92 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
93 		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,
94 		       MVPP2_PRS_IP_MASK),
95 
96 	/* UDP over IPv4 flows, Not fragmented, no vlan tag */
97 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_UNTAG,
98 		       MVPP22_CLS_HEK_IP4_5T,
99 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
100 		       MVPP2_PRS_RI_L4_UDP,
101 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
102 
103 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_UNTAG,
104 		       MVPP22_CLS_HEK_IP4_5T,
105 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
106 		       MVPP2_PRS_RI_L4_UDP,
107 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
108 
109 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_UNTAG,
110 		       MVPP22_CLS_HEK_IP4_5T,
111 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
112 		       MVPP2_PRS_RI_L4_UDP,
113 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
114 
115 	/* UDP over IPv4 flows, Not fragmented, with vlan tag */
116 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG,
117 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
118 		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,
119 		       MVPP2_PRS_IP_MASK),
120 
121 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG,
122 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
123 		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,
124 		       MVPP2_PRS_IP_MASK),
125 
126 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG,
127 		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN,
128 		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,
129 		       MVPP2_PRS_IP_MASK),
130 
131 	/* UDP over IPv4 flows, fragmented, no vlan tag */
132 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
133 		       MVPP22_CLS_HEK_IP4_2T,
134 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
135 		       MVPP2_PRS_RI_L4_UDP,
136 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
137 
138 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
139 		       MVPP22_CLS_HEK_IP4_2T,
140 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
141 		       MVPP2_PRS_RI_L4_UDP,
142 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
143 
144 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
145 		       MVPP22_CLS_HEK_IP4_2T,
146 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
147 		       MVPP2_PRS_RI_L4_UDP,
148 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
149 
150 	/* UDP over IPv4 flows, fragmented, with vlan tag */
151 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
152 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
153 		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,
154 		       MVPP2_PRS_IP_MASK),
155 
156 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
157 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
158 		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,
159 		       MVPP2_PRS_IP_MASK),
160 
161 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
162 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
163 		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,
164 		       MVPP2_PRS_IP_MASK),
165 
166 	/* TCP over IPv6 flows, not fragmented, no vlan tag */
167 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_UNTAG,
168 		       MVPP22_CLS_HEK_IP6_5T,
169 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6 |
170 		       MVPP2_PRS_RI_L4_TCP,
171 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
172 
173 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_UNTAG,
174 		       MVPP22_CLS_HEK_IP6_5T,
175 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6_EXT |
176 		       MVPP2_PRS_RI_L4_TCP,
177 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
178 
179 	/* TCP over IPv6 flows, not fragmented, with vlan tag */
180 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_TAG,
181 		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN,
182 		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_L4_TCP,
183 		       MVPP2_PRS_IP_MASK),
184 
185 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_TAG,
186 		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN,
187 		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_L4_TCP,
188 		       MVPP2_PRS_IP_MASK),
189 
190 	/* TCP over IPv6 flows, fragmented, no vlan tag */
191 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_UNTAG,
192 		       MVPP22_CLS_HEK_IP6_2T,
193 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6 |
194 		       MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
195 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
196 
197 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_UNTAG,
198 		       MVPP22_CLS_HEK_IP6_2T,
199 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6_EXT |
200 		       MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
201 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
202 
203 	/* TCP over IPv6 flows, fragmented, with vlan tag */
204 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_TAG,
205 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
206 		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_IP_FRAG_TRUE |
207 		       MVPP2_PRS_RI_L4_TCP,
208 		       MVPP2_PRS_IP_MASK),
209 
210 	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_TAG,
211 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
212 		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_IP_FRAG_TRUE |
213 		       MVPP2_PRS_RI_L4_TCP,
214 		       MVPP2_PRS_IP_MASK),
215 
216 	/* UDP over IPv6 flows, not fragmented, no vlan tag */
217 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_UNTAG,
218 		       MVPP22_CLS_HEK_IP6_5T,
219 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6 |
220 		       MVPP2_PRS_RI_L4_UDP,
221 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
222 
223 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_UNTAG,
224 		       MVPP22_CLS_HEK_IP6_5T,
225 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6_EXT |
226 		       MVPP2_PRS_RI_L4_UDP,
227 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
228 
229 	/* UDP over IPv6 flows, not fragmented, with vlan tag */
230 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_TAG,
231 		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN,
232 		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_L4_UDP,
233 		       MVPP2_PRS_IP_MASK),
234 
235 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_TAG,
236 		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN,
237 		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_L4_UDP,
238 		       MVPP2_PRS_IP_MASK),
239 
240 	/* UDP over IPv6 flows, fragmented, no vlan tag */
241 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_UNTAG,
242 		       MVPP22_CLS_HEK_IP6_2T,
243 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6 |
244 		       MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
245 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
246 
247 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_UNTAG,
248 		       MVPP22_CLS_HEK_IP6_2T,
249 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6_EXT |
250 		       MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
251 		       MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
252 
253 	/* UDP over IPv6 flows, fragmented, with vlan tag */
254 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_TAG,
255 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
256 		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_IP_FRAG_TRUE |
257 		       MVPP2_PRS_RI_L4_UDP,
258 		       MVPP2_PRS_IP_MASK),
259 
260 	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_TAG,
261 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
262 		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_IP_FRAG_TRUE |
263 		       MVPP2_PRS_RI_L4_UDP,
264 		       MVPP2_PRS_IP_MASK),
265 
266 	/* IPv4 flows, no vlan tag */
267 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_UNTAG,
268 		       MVPP22_CLS_HEK_IP4_2T,
269 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4,
270 		       MVPP2_PRS_RI_VLAN_MASK | MVPP2_PRS_RI_L3_PROTO_MASK),
271 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_UNTAG,
272 		       MVPP22_CLS_HEK_IP4_2T,
273 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT,
274 		       MVPP2_PRS_RI_VLAN_MASK | MVPP2_PRS_RI_L3_PROTO_MASK),
275 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_UNTAG,
276 		       MVPP22_CLS_HEK_IP4_2T,
277 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER,
278 		       MVPP2_PRS_RI_VLAN_MASK | MVPP2_PRS_RI_L3_PROTO_MASK),
279 
280 	/* IPv4 flows, with vlan tag */
281 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG,
282 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
283 		       MVPP2_PRS_RI_L3_IP4,
284 		       MVPP2_PRS_RI_L3_PROTO_MASK),
285 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG,
286 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
287 		       MVPP2_PRS_RI_L3_IP4_OPT,
288 		       MVPP2_PRS_RI_L3_PROTO_MASK),
289 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG,
290 		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN,
291 		       MVPP2_PRS_RI_L3_IP4_OTHER,
292 		       MVPP2_PRS_RI_L3_PROTO_MASK),
293 
294 	/* IPv6 flows, no vlan tag */
295 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_UNTAG,
296 		       MVPP22_CLS_HEK_IP6_2T,
297 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6,
298 		       MVPP2_PRS_RI_VLAN_MASK | MVPP2_PRS_RI_L3_PROTO_MASK),
299 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_UNTAG,
300 		       MVPP22_CLS_HEK_IP6_2T,
301 		       MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP6,
302 		       MVPP2_PRS_RI_VLAN_MASK | MVPP2_PRS_RI_L3_PROTO_MASK),
303 
304 	/* IPv6 flows, with vlan tag */
305 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_TAG,
306 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
307 		       MVPP2_PRS_RI_L3_IP6,
308 		       MVPP2_PRS_RI_L3_PROTO_MASK),
309 	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_TAG,
310 		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN,
311 		       MVPP2_PRS_RI_L3_IP6,
312 		       MVPP2_PRS_RI_L3_PROTO_MASK),
313 
314 	/* Non IP flow, no vlan tag */
315 	MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_UNTAG,
316 		       0,
317 		       MVPP2_PRS_RI_VLAN_NONE,
318 		       MVPP2_PRS_RI_VLAN_MASK),
319 	/* Non IP flow, with vlan tag */
320 	MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG,
321 		       MVPP22_CLS_HEK_OPT_VLAN,
322 		       0, 0),
323 };
324 
325 u32 mvpp2_cls_flow_hits(struct mvpp2 *priv, int index)
326 {
327 	mvpp2_write(priv, MVPP2_CTRS_IDX, index);
328 
329 	return mvpp2_read(priv, MVPP2_CLS_FLOW_TBL_HIT_CTR);
330 }
331 
332 void mvpp2_cls_flow_read(struct mvpp2 *priv, int index,
333 			 struct mvpp2_cls_flow_entry *fe)
334 {
335 	fe->index = index;
336 	mvpp2_write(priv, MVPP2_CLS_FLOW_INDEX_REG, index);
337 	fe->data[0] = mvpp2_read(priv, MVPP2_CLS_FLOW_TBL0_REG);
338 	fe->data[1] = mvpp2_read(priv, MVPP2_CLS_FLOW_TBL1_REG);
339 	fe->data[2] = mvpp2_read(priv, MVPP2_CLS_FLOW_TBL2_REG);
340 }
341 
342 /* Update classification flow table registers */
343 static void mvpp2_cls_flow_write(struct mvpp2 *priv,
344 				 struct mvpp2_cls_flow_entry *fe)
345 {
346 	mvpp2_write(priv, MVPP2_CLS_FLOW_INDEX_REG, fe->index);
347 	mvpp2_write(priv, MVPP2_CLS_FLOW_TBL0_REG, fe->data[0]);
348 	mvpp2_write(priv, MVPP2_CLS_FLOW_TBL1_REG, fe->data[1]);
349 	mvpp2_write(priv, MVPP2_CLS_FLOW_TBL2_REG, fe->data[2]);
350 }
351 
352 u32 mvpp2_cls_lookup_hits(struct mvpp2 *priv, int index)
353 {
354 	mvpp2_write(priv, MVPP2_CTRS_IDX, index);
355 
356 	return mvpp2_read(priv, MVPP2_CLS_DEC_TBL_HIT_CTR);
357 }
358 
359 void mvpp2_cls_lookup_read(struct mvpp2 *priv, int lkpid, int way,
360 			   struct mvpp2_cls_lookup_entry *le)
361 {
362 	u32 val;
363 
364 	val = (way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | lkpid;
365 	mvpp2_write(priv, MVPP2_CLS_LKP_INDEX_REG, val);
366 	le->way = way;
367 	le->lkpid = lkpid;
368 	le->data = mvpp2_read(priv, MVPP2_CLS_LKP_TBL_REG);
369 }
370 
371 /* Update classification lookup table register */
372 static void mvpp2_cls_lookup_write(struct mvpp2 *priv,
373 				   struct mvpp2_cls_lookup_entry *le)
374 {
375 	u32 val;
376 
377 	val = (le->way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | le->lkpid;
378 	mvpp2_write(priv, MVPP2_CLS_LKP_INDEX_REG, val);
379 	mvpp2_write(priv, MVPP2_CLS_LKP_TBL_REG, le->data);
380 }
381 
382 /* Operations on flow entry */
383 static int mvpp2_cls_flow_hek_num_get(struct mvpp2_cls_flow_entry *fe)
384 {
385 	return fe->data[1] & MVPP2_CLS_FLOW_TBL1_N_FIELDS_MASK;
386 }
387 
388 static void mvpp2_cls_flow_hek_num_set(struct mvpp2_cls_flow_entry *fe,
389 				       int num_of_fields)
390 {
391 	fe->data[1] &= ~MVPP2_CLS_FLOW_TBL1_N_FIELDS_MASK;
392 	fe->data[1] |= MVPP2_CLS_FLOW_TBL1_N_FIELDS(num_of_fields);
393 }
394 
395 static int mvpp2_cls_flow_hek_get(struct mvpp2_cls_flow_entry *fe,
396 				  int field_index)
397 {
398 	return (fe->data[2] >> MVPP2_CLS_FLOW_TBL2_FLD_OFFS(field_index)) &
399 		MVPP2_CLS_FLOW_TBL2_FLD_MASK;
400 }
401 
402 static void mvpp2_cls_flow_hek_set(struct mvpp2_cls_flow_entry *fe,
403 				   int field_index, int field_id)
404 {
405 	fe->data[2] &= ~MVPP2_CLS_FLOW_TBL2_FLD(field_index,
406 						MVPP2_CLS_FLOW_TBL2_FLD_MASK);
407 	fe->data[2] |= MVPP2_CLS_FLOW_TBL2_FLD(field_index, field_id);
408 }
409 
410 static void mvpp2_cls_flow_eng_set(struct mvpp2_cls_flow_entry *fe,
411 				   int engine)
412 {
413 	fe->data[0] &= ~MVPP2_CLS_FLOW_TBL0_ENG(MVPP2_CLS_FLOW_TBL0_ENG_MASK);
414 	fe->data[0] |= MVPP2_CLS_FLOW_TBL0_ENG(engine);
415 }
416 
417 int mvpp2_cls_flow_eng_get(struct mvpp2_cls_flow_entry *fe)
418 {
419 	return (fe->data[0] >> MVPP2_CLS_FLOW_TBL0_OFFS) &
420 		MVPP2_CLS_FLOW_TBL0_ENG_MASK;
421 }
422 
423 static void mvpp2_cls_flow_port_id_sel(struct mvpp2_cls_flow_entry *fe,
424 				       bool from_packet)
425 {
426 	if (from_packet)
427 		fe->data[0] |= MVPP2_CLS_FLOW_TBL0_PORT_ID_SEL;
428 	else
429 		fe->data[0] &= ~MVPP2_CLS_FLOW_TBL0_PORT_ID_SEL;
430 }
431 
432 static void mvpp2_cls_flow_last_set(struct mvpp2_cls_flow_entry *fe,
433 				    bool is_last)
434 {
435 	fe->data[0] &= ~MVPP2_CLS_FLOW_TBL0_LAST;
436 	fe->data[0] |= !!is_last;
437 }
438 
439 static void mvpp2_cls_flow_pri_set(struct mvpp2_cls_flow_entry *fe, int prio)
440 {
441 	fe->data[1] &= ~MVPP2_CLS_FLOW_TBL1_PRIO(MVPP2_CLS_FLOW_TBL1_PRIO_MASK);
442 	fe->data[1] |= MVPP2_CLS_FLOW_TBL1_PRIO(prio);
443 }
444 
445 static void mvpp2_cls_flow_port_add(struct mvpp2_cls_flow_entry *fe,
446 				    u32 port)
447 {
448 	fe->data[0] |= MVPP2_CLS_FLOW_TBL0_PORT_ID(port);
449 }
450 
451 static void mvpp2_cls_flow_port_remove(struct mvpp2_cls_flow_entry *fe,
452 				       u32 port)
453 {
454 	fe->data[0] &= ~MVPP2_CLS_FLOW_TBL0_PORT_ID(port);
455 }
456 
457 static void mvpp2_cls_flow_lu_type_set(struct mvpp2_cls_flow_entry *fe,
458 				       u8 lu_type)
459 {
460 	fe->data[1] &= ~MVPP2_CLS_FLOW_TBL1_LU_TYPE(MVPP2_CLS_LU_TYPE_MASK);
461 	fe->data[1] |= MVPP2_CLS_FLOW_TBL1_LU_TYPE(lu_type);
462 }
463 
464 /* Initialize the parser entry for the given flow */
465 static void mvpp2_cls_flow_prs_init(struct mvpp2 *priv,
466 				    const struct mvpp2_cls_flow *flow)
467 {
468 	mvpp2_prs_add_flow(priv, flow->flow_id, flow->prs_ri.ri,
469 			   flow->prs_ri.ri_mask);
470 }
471 
472 /* Initialize the Lookup Id table entry for the given flow */
473 static void mvpp2_cls_flow_lkp_init(struct mvpp2 *priv,
474 				    const struct mvpp2_cls_flow *flow)
475 {
476 	struct mvpp2_cls_lookup_entry le;
477 
478 	le.way = 0;
479 	le.lkpid = flow->flow_id;
480 
481 	/* The default RxQ for this port is set in the C2 lookup */
482 	le.data = 0;
483 
484 	/* We point on the first lookup in the sequence for the flow, that is
485 	 * the C2 lookup.
486 	 */
487 	le.data |= MVPP2_CLS_LKP_FLOW_PTR(MVPP2_CLS_FLT_FIRST(flow->flow_id));
488 
489 	/* CLS is always enabled, RSS is enabled/disabled in C2 lookup */
490 	le.data |= MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK;
491 
492 	mvpp2_cls_lookup_write(priv, &le);
493 }
494 
495 static void mvpp2_cls_c2_write(struct mvpp2 *priv,
496 			       struct mvpp2_cls_c2_entry *c2)
497 {
498 	u32 val;
499 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_IDX, c2->index);
500 
501 	val = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_INV);
502 	if (c2->valid)
503 		val &= ~MVPP22_CLS_C2_TCAM_INV_BIT;
504 	else
505 		val |= MVPP22_CLS_C2_TCAM_INV_BIT;
506 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_INV, val);
507 
508 	mvpp2_write(priv, MVPP22_CLS_C2_ACT, c2->act);
509 
510 	mvpp2_write(priv, MVPP22_CLS_C2_ATTR0, c2->attr[0]);
511 	mvpp2_write(priv, MVPP22_CLS_C2_ATTR1, c2->attr[1]);
512 	mvpp2_write(priv, MVPP22_CLS_C2_ATTR2, c2->attr[2]);
513 	mvpp2_write(priv, MVPP22_CLS_C2_ATTR3, c2->attr[3]);
514 
515 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_DATA0, c2->tcam[0]);
516 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_DATA1, c2->tcam[1]);
517 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_DATA2, c2->tcam[2]);
518 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_DATA3, c2->tcam[3]);
519 	/* Writing TCAM_DATA4 flushes writes to TCAM_DATA0-4 and INV to HW */
520 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_DATA4, c2->tcam[4]);
521 }
522 
523 void mvpp2_cls_c2_read(struct mvpp2 *priv, int index,
524 		       struct mvpp2_cls_c2_entry *c2)
525 {
526 	u32 val;
527 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_IDX, index);
528 
529 	c2->index = index;
530 
531 	c2->tcam[0] = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_DATA0);
532 	c2->tcam[1] = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_DATA1);
533 	c2->tcam[2] = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_DATA2);
534 	c2->tcam[3] = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_DATA3);
535 	c2->tcam[4] = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_DATA4);
536 
537 	c2->act = mvpp2_read(priv, MVPP22_CLS_C2_ACT);
538 
539 	c2->attr[0] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR0);
540 	c2->attr[1] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR1);
541 	c2->attr[2] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR2);
542 	c2->attr[3] = mvpp2_read(priv, MVPP22_CLS_C2_ATTR3);
543 
544 	val = mvpp2_read(priv, MVPP22_CLS_C2_TCAM_INV);
545 	c2->valid = !(val & MVPP22_CLS_C2_TCAM_INV_BIT);
546 }
547 
548 static int mvpp2_cls_ethtool_flow_to_type(int flow_type)
549 {
550 	switch (flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
551 	case TCP_V4_FLOW:
552 		return MVPP22_FLOW_TCP4;
553 	case TCP_V6_FLOW:
554 		return MVPP22_FLOW_TCP6;
555 	case UDP_V4_FLOW:
556 		return MVPP22_FLOW_UDP4;
557 	case UDP_V6_FLOW:
558 		return MVPP22_FLOW_UDP6;
559 	case IPV4_FLOW:
560 		return MVPP22_FLOW_IP4;
561 	case IPV6_FLOW:
562 		return MVPP22_FLOW_IP6;
563 	default:
564 		return -EOPNOTSUPP;
565 	}
566 }
567 
568 static int mvpp2_cls_c2_port_flow_index(struct mvpp2_port *port, int loc)
569 {
570 	return MVPP22_CLS_C2_RFS_LOC(port->id, loc);
571 }
572 
573 /* Initialize the flow table entries for the given flow */
574 static void mvpp2_cls_flow_init(struct mvpp2 *priv,
575 				const struct mvpp2_cls_flow *flow)
576 {
577 	struct mvpp2_cls_flow_entry fe;
578 	int i, pri = 0;
579 
580 	/* Assign default values to all entries in the flow */
581 	for (i = MVPP2_CLS_FLT_FIRST(flow->flow_id);
582 	     i <= MVPP2_CLS_FLT_LAST(flow->flow_id); i++) {
583 		memset(&fe, 0, sizeof(fe));
584 		fe.index = i;
585 		mvpp2_cls_flow_pri_set(&fe, pri++);
586 
587 		if (i == MVPP2_CLS_FLT_LAST(flow->flow_id))
588 			mvpp2_cls_flow_last_set(&fe, 1);
589 
590 		mvpp2_cls_flow_write(priv, &fe);
591 	}
592 
593 	/* RSS config C2 lookup */
594 	mvpp2_cls_flow_read(priv, MVPP2_CLS_FLT_C2_RSS_ENTRY(flow->flow_id),
595 			    &fe);
596 
597 	mvpp2_cls_flow_eng_set(&fe, MVPP22_CLS_ENGINE_C2);
598 	mvpp2_cls_flow_port_id_sel(&fe, true);
599 	mvpp2_cls_flow_lu_type_set(&fe, MVPP22_FLOW_ETHERNET);
600 
601 	/* Add all ports */
602 	for (i = 0; i < MVPP2_MAX_PORTS; i++)
603 		mvpp2_cls_flow_port_add(&fe, BIT(i));
604 
605 	mvpp2_cls_flow_write(priv, &fe);
606 
607 	/* C3Hx lookups */
608 	for (i = 0; i < MVPP2_MAX_PORTS; i++) {
609 		mvpp2_cls_flow_read(priv,
610 				    MVPP2_CLS_FLT_HASH_ENTRY(i, flow->flow_id),
611 				    &fe);
612 
613 		/* Set a default engine. Will be overwritten when setting the
614 		 * real HEK parameters
615 		 */
616 		mvpp2_cls_flow_eng_set(&fe, MVPP22_CLS_ENGINE_C3HA);
617 		mvpp2_cls_flow_port_id_sel(&fe, true);
618 		mvpp2_cls_flow_port_add(&fe, BIT(i));
619 
620 		mvpp2_cls_flow_write(priv, &fe);
621 	}
622 }
623 
624 /* Adds a field to the Header Extracted Key generation parameters*/
625 static int mvpp2_flow_add_hek_field(struct mvpp2_cls_flow_entry *fe,
626 				    u32 field_id)
627 {
628 	int nb_fields = mvpp2_cls_flow_hek_num_get(fe);
629 
630 	if (nb_fields == MVPP2_FLOW_N_FIELDS)
631 		return -EINVAL;
632 
633 	mvpp2_cls_flow_hek_set(fe, nb_fields, field_id);
634 
635 	mvpp2_cls_flow_hek_num_set(fe, nb_fields + 1);
636 
637 	return 0;
638 }
639 
640 static int mvpp2_flow_set_hek_fields(struct mvpp2_cls_flow_entry *fe,
641 				     unsigned long hash_opts)
642 {
643 	u32 field_id;
644 	int i;
645 
646 	/* Clear old fields */
647 	mvpp2_cls_flow_hek_num_set(fe, 0);
648 	fe->data[2] = 0;
649 
650 	for_each_set_bit(i, &hash_opts, MVPP22_CLS_HEK_N_FIELDS) {
651 		switch (BIT(i)) {
652 		case MVPP22_CLS_HEK_OPT_MAC_DA:
653 			field_id = MVPP22_CLS_FIELD_MAC_DA;
654 			break;
655 		case MVPP22_CLS_HEK_OPT_VLAN:
656 			field_id = MVPP22_CLS_FIELD_VLAN;
657 			break;
658 		case MVPP22_CLS_HEK_OPT_IP4SA:
659 			field_id = MVPP22_CLS_FIELD_IP4SA;
660 			break;
661 		case MVPP22_CLS_HEK_OPT_IP4DA:
662 			field_id = MVPP22_CLS_FIELD_IP4DA;
663 			break;
664 		case MVPP22_CLS_HEK_OPT_IP6SA:
665 			field_id = MVPP22_CLS_FIELD_IP6SA;
666 			break;
667 		case MVPP22_CLS_HEK_OPT_IP6DA:
668 			field_id = MVPP22_CLS_FIELD_IP6DA;
669 			break;
670 		case MVPP22_CLS_HEK_OPT_L4SIP:
671 			field_id = MVPP22_CLS_FIELD_L4SIP;
672 			break;
673 		case MVPP22_CLS_HEK_OPT_L4DIP:
674 			field_id = MVPP22_CLS_FIELD_L4DIP;
675 			break;
676 		default:
677 			return -EINVAL;
678 		}
679 		if (mvpp2_flow_add_hek_field(fe, field_id))
680 			return -EINVAL;
681 	}
682 
683 	return 0;
684 }
685 
686 /* Returns the size, in bits, of the corresponding HEK field */
687 static int mvpp2_cls_hek_field_size(u32 field)
688 {
689 	switch (field) {
690 	case MVPP22_CLS_HEK_OPT_MAC_DA:
691 		return 48;
692 	case MVPP22_CLS_HEK_OPT_IP4SA:
693 	case MVPP22_CLS_HEK_OPT_IP4DA:
694 		return 32;
695 	case MVPP22_CLS_HEK_OPT_IP6SA:
696 	case MVPP22_CLS_HEK_OPT_IP6DA:
697 		return 128;
698 	case MVPP22_CLS_HEK_OPT_L4SIP:
699 	case MVPP22_CLS_HEK_OPT_L4DIP:
700 		return 16;
701 	default:
702 		return -1;
703 	}
704 }
705 
706 const struct mvpp2_cls_flow *mvpp2_cls_flow_get(int flow)
707 {
708 	if (flow >= MVPP2_N_PRS_FLOWS)
709 		return NULL;
710 
711 	return &cls_flows[flow];
712 }
713 
714 /* Set the hash generation options for the given traffic flow.
715  * One traffic flow (in the ethtool sense) has multiple classification flows,
716  * to handle specific cases such as fragmentation, or the presence of a
717  * VLAN / DSA Tag.
718  *
719  * Each of these individual flows has different constraints, for example we
720  * can't hash fragmented packets on L4 data (else we would risk having packet
721  * re-ordering), so each classification flows masks the options with their
722  * supported ones.
723  *
724  */
725 static int mvpp2_port_rss_hash_opts_set(struct mvpp2_port *port, int flow_type,
726 					u16 requested_opts)
727 {
728 	const struct mvpp2_cls_flow *flow;
729 	struct mvpp2_cls_flow_entry fe;
730 	int i, engine, flow_index;
731 	u16 hash_opts;
732 
733 	for_each_cls_flow_id_with_type(i, flow_type) {
734 		flow = mvpp2_cls_flow_get(i);
735 		if (!flow)
736 			return -EINVAL;
737 
738 		flow_index = MVPP2_CLS_FLT_HASH_ENTRY(port->id, flow->flow_id);
739 
740 		mvpp2_cls_flow_read(port->priv, flow_index, &fe);
741 
742 		hash_opts = flow->supported_hash_opts & requested_opts;
743 
744 		/* Use C3HB engine to access L4 infos. This adds L4 infos to the
745 		 * hash parameters
746 		 */
747 		if (hash_opts & MVPP22_CLS_HEK_L4_OPTS)
748 			engine = MVPP22_CLS_ENGINE_C3HB;
749 		else
750 			engine = MVPP22_CLS_ENGINE_C3HA;
751 
752 		if (mvpp2_flow_set_hek_fields(&fe, hash_opts))
753 			return -EINVAL;
754 
755 		mvpp2_cls_flow_eng_set(&fe, engine);
756 
757 		mvpp2_cls_flow_write(port->priv, &fe);
758 	}
759 
760 	return 0;
761 }
762 
763 u16 mvpp2_flow_get_hek_fields(struct mvpp2_cls_flow_entry *fe)
764 {
765 	u16 hash_opts = 0;
766 	int n_fields, i, field;
767 
768 	n_fields = mvpp2_cls_flow_hek_num_get(fe);
769 
770 	for (i = 0; i < n_fields; i++) {
771 		field = mvpp2_cls_flow_hek_get(fe, i);
772 
773 		switch (field) {
774 		case MVPP22_CLS_FIELD_MAC_DA:
775 			hash_opts |= MVPP22_CLS_HEK_OPT_MAC_DA;
776 			break;
777 		case MVPP22_CLS_FIELD_VLAN:
778 			hash_opts |= MVPP22_CLS_HEK_OPT_VLAN;
779 			break;
780 		case MVPP22_CLS_FIELD_L3_PROTO:
781 			hash_opts |= MVPP22_CLS_HEK_OPT_L3_PROTO;
782 			break;
783 		case MVPP22_CLS_FIELD_IP4SA:
784 			hash_opts |= MVPP22_CLS_HEK_OPT_IP4SA;
785 			break;
786 		case MVPP22_CLS_FIELD_IP4DA:
787 			hash_opts |= MVPP22_CLS_HEK_OPT_IP4DA;
788 			break;
789 		case MVPP22_CLS_FIELD_IP6SA:
790 			hash_opts |= MVPP22_CLS_HEK_OPT_IP6SA;
791 			break;
792 		case MVPP22_CLS_FIELD_IP6DA:
793 			hash_opts |= MVPP22_CLS_HEK_OPT_IP6DA;
794 			break;
795 		case MVPP22_CLS_FIELD_L4SIP:
796 			hash_opts |= MVPP22_CLS_HEK_OPT_L4SIP;
797 			break;
798 		case MVPP22_CLS_FIELD_L4DIP:
799 			hash_opts |= MVPP22_CLS_HEK_OPT_L4DIP;
800 			break;
801 		default:
802 			break;
803 		}
804 	}
805 	return hash_opts;
806 }
807 
808 /* Returns the hash opts for this flow. There are several classifier flows
809  * for one traffic flow, this returns an aggregation of all configurations.
810  */
811 static u16 mvpp2_port_rss_hash_opts_get(struct mvpp2_port *port, int flow_type)
812 {
813 	const struct mvpp2_cls_flow *flow;
814 	struct mvpp2_cls_flow_entry fe;
815 	int i, flow_index;
816 	u16 hash_opts = 0;
817 
818 	for_each_cls_flow_id_with_type(i, flow_type) {
819 		flow = mvpp2_cls_flow_get(i);
820 		if (!flow)
821 			return 0;
822 
823 		flow_index = MVPP2_CLS_FLT_HASH_ENTRY(port->id, flow->flow_id);
824 
825 		mvpp2_cls_flow_read(port->priv, flow_index, &fe);
826 
827 		hash_opts |= mvpp2_flow_get_hek_fields(&fe);
828 	}
829 
830 	return hash_opts;
831 }
832 
833 static void mvpp2_cls_port_init_flows(struct mvpp2 *priv)
834 {
835 	const struct mvpp2_cls_flow *flow;
836 	int i;
837 
838 	for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) {
839 		flow = mvpp2_cls_flow_get(i);
840 		if (!flow)
841 			break;
842 
843 		mvpp2_cls_flow_prs_init(priv, flow);
844 		mvpp2_cls_flow_lkp_init(priv, flow);
845 		mvpp2_cls_flow_init(priv, flow);
846 	}
847 }
848 
849 static void mvpp2_port_c2_cls_init(struct mvpp2_port *port)
850 {
851 	struct mvpp2_cls_c2_entry c2;
852 	u8 qh, ql, pmap;
853 
854 	memset(&c2, 0, sizeof(c2));
855 
856 	c2.index = MVPP22_CLS_C2_RSS_ENTRY(port->id);
857 
858 	pmap = BIT(port->id);
859 	c2.tcam[4] = MVPP22_CLS_C2_PORT_ID(pmap);
860 	c2.tcam[4] |= MVPP22_CLS_C2_TCAM_EN(MVPP22_CLS_C2_PORT_ID(pmap));
861 
862 	/* Match on Lookup Type */
863 	c2.tcam[4] |= MVPP22_CLS_C2_TCAM_EN(MVPP22_CLS_C2_LU_TYPE(MVPP2_CLS_LU_TYPE_MASK));
864 	c2.tcam[4] |= MVPP22_CLS_C2_LU_TYPE(MVPP22_FLOW_ETHERNET);
865 
866 	/* Update RSS status after matching this entry */
867 	c2.act = MVPP22_CLS_C2_ACT_RSS_EN(MVPP22_C2_UPD_LOCK);
868 
869 	/* Mark packet as "forwarded to software", needed for RSS */
870 	c2.act |= MVPP22_CLS_C2_ACT_FWD(MVPP22_C2_FWD_SW_LOCK);
871 
872 	/* Configure the default rx queue : Update Queue Low and Queue High, but
873 	 * don't lock, since the rx queue selection might be overridden by RSS
874 	 */
875 	c2.act |= MVPP22_CLS_C2_ACT_QHIGH(MVPP22_C2_UPD) |
876 		   MVPP22_CLS_C2_ACT_QLOW(MVPP22_C2_UPD);
877 
878 	qh = (port->first_rxq >> 3) & MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
879 	ql = port->first_rxq & MVPP22_CLS_C2_ATTR0_QLOW_MASK;
880 
881 	c2.attr[0] = MVPP22_CLS_C2_ATTR0_QHIGH(qh) |
882 		      MVPP22_CLS_C2_ATTR0_QLOW(ql);
883 
884 	c2.valid = true;
885 
886 	mvpp2_cls_c2_write(port->priv, &c2);
887 }
888 
889 /* Classifier default initialization */
890 void mvpp2_cls_init(struct mvpp2 *priv)
891 {
892 	struct mvpp2_cls_lookup_entry le;
893 	struct mvpp2_cls_flow_entry fe;
894 	struct mvpp2_cls_c2_entry c2;
895 	int index;
896 
897 	/* Enable classifier */
898 	mvpp2_write(priv, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK);
899 
900 	/* Clear classifier flow table */
901 	memset(&fe.data, 0, sizeof(fe.data));
902 	for (index = 0; index < MVPP2_CLS_FLOWS_TBL_SIZE; index++) {
903 		fe.index = index;
904 		mvpp2_cls_flow_write(priv, &fe);
905 	}
906 
907 	/* Clear classifier lookup table */
908 	le.data = 0;
909 	for (index = 0; index < MVPP2_CLS_LKP_TBL_SIZE; index++) {
910 		le.lkpid = index;
911 		le.way = 0;
912 		mvpp2_cls_lookup_write(priv, &le);
913 
914 		le.way = 1;
915 		mvpp2_cls_lookup_write(priv, &le);
916 	}
917 
918 	/* Clear C2 TCAM engine table */
919 	memset(&c2, 0, sizeof(c2));
920 	c2.valid = false;
921 	for (index = 0; index < MVPP22_CLS_C2_N_ENTRIES; index++) {
922 		c2.index = index;
923 		mvpp2_cls_c2_write(priv, &c2);
924 	}
925 
926 	mvpp2_cls_port_init_flows(priv);
927 }
928 
929 void mvpp2_cls_port_config(struct mvpp2_port *port)
930 {
931 	struct mvpp2_cls_lookup_entry le;
932 	u32 val;
933 
934 	/* Set way for the port */
935 	val = mvpp2_read(port->priv, MVPP2_CLS_PORT_WAY_REG);
936 	val &= ~MVPP2_CLS_PORT_WAY_MASK(port->id);
937 	mvpp2_write(port->priv, MVPP2_CLS_PORT_WAY_REG, val);
938 
939 	/* Pick the entry to be accessed in lookup ID decoding table
940 	 * according to the way and lkpid.
941 	 */
942 	le.lkpid = port->id;
943 	le.way = 0;
944 	le.data = 0;
945 
946 	/* Set initial CPU queue for receiving packets */
947 	le.data &= ~MVPP2_CLS_LKP_TBL_RXQ_MASK;
948 	le.data |= port->first_rxq;
949 
950 	/* Disable classification engines */
951 	le.data &= ~MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK;
952 
953 	/* Update lookup ID table entry */
954 	mvpp2_cls_lookup_write(port->priv, &le);
955 
956 	mvpp2_port_c2_cls_init(port);
957 }
958 
959 u32 mvpp2_cls_c2_hit_count(struct mvpp2 *priv, int c2_index)
960 {
961 	mvpp2_write(priv, MVPP22_CLS_C2_TCAM_IDX, c2_index);
962 
963 	return mvpp2_read(priv, MVPP22_CLS_C2_HIT_CTR);
964 }
965 
966 static void mvpp2_rss_port_c2_enable(struct mvpp2_port *port)
967 {
968 	struct mvpp2_cls_c2_entry c2;
969 
970 	mvpp2_cls_c2_read(port->priv, MVPP22_CLS_C2_RSS_ENTRY(port->id), &c2);
971 
972 	c2.attr[2] |= MVPP22_CLS_C2_ATTR2_RSS_EN;
973 
974 	mvpp2_cls_c2_write(port->priv, &c2);
975 }
976 
977 static void mvpp2_rss_port_c2_disable(struct mvpp2_port *port)
978 {
979 	struct mvpp2_cls_c2_entry c2;
980 
981 	mvpp2_cls_c2_read(port->priv, MVPP22_CLS_C2_RSS_ENTRY(port->id), &c2);
982 
983 	c2.attr[2] &= ~MVPP22_CLS_C2_ATTR2_RSS_EN;
984 
985 	mvpp2_cls_c2_write(port->priv, &c2);
986 }
987 
988 void mvpp22_port_rss_enable(struct mvpp2_port *port)
989 {
990 	mvpp2_rss_port_c2_enable(port);
991 }
992 
993 void mvpp22_port_rss_disable(struct mvpp2_port *port)
994 {
995 	mvpp2_rss_port_c2_disable(port);
996 }
997 
998 static void mvpp22_port_c2_lookup_disable(struct mvpp2_port *port, int entry)
999 {
1000 	struct mvpp2_cls_c2_entry c2;
1001 
1002 	mvpp2_cls_c2_read(port->priv, entry, &c2);
1003 
1004 	/* Clear the port map so that the entry doesn't match anymore */
1005 	c2.tcam[4] &= ~(MVPP22_CLS_C2_PORT_ID(BIT(port->id)));
1006 
1007 	mvpp2_cls_c2_write(port->priv, &c2);
1008 }
1009 
1010 /* Set CPU queue number for oversize packets */
1011 void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port)
1012 {
1013 	u32 val;
1014 
1015 	mvpp2_write(port->priv, MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port->id),
1016 		    port->first_rxq & MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK);
1017 
1018 	mvpp2_write(port->priv, MVPP2_CLS_SWFWD_P2HQ_REG(port->id),
1019 		    (port->first_rxq >> MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS));
1020 
1021 	val = mvpp2_read(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG);
1022 	val |= MVPP2_CLS_SWFWD_PCTRL_MASK(port->id);
1023 	mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val);
1024 }
1025 
1026 static int mvpp2_port_c2_tcam_rule_add(struct mvpp2_port *port,
1027 				       struct mvpp2_rfs_rule *rule)
1028 {
1029 	struct flow_action_entry *act;
1030 	struct mvpp2_cls_c2_entry c2;
1031 	u8 qh, ql, pmap;
1032 	int index;
1033 
1034 	memset(&c2, 0, sizeof(c2));
1035 
1036 	index = mvpp2_cls_c2_port_flow_index(port, rule->loc);
1037 	if (index < 0)
1038 		return -EINVAL;
1039 	c2.index = index;
1040 
1041 	act = &rule->flow->action.entries[0];
1042 
1043 	rule->c2_index = c2.index;
1044 
1045 	c2.tcam[0] = (rule->c2_tcam & 0xffff) |
1046 		     ((rule->c2_tcam_mask & 0xffff) << 16);
1047 	c2.tcam[1] = ((rule->c2_tcam >> 16) & 0xffff) |
1048 		     (((rule->c2_tcam_mask >> 16) & 0xffff) << 16);
1049 	c2.tcam[2] = ((rule->c2_tcam >> 32) & 0xffff) |
1050 		     (((rule->c2_tcam_mask >> 32) & 0xffff) << 16);
1051 	c2.tcam[3] = ((rule->c2_tcam >> 48) & 0xffff) |
1052 		     (((rule->c2_tcam_mask >> 48) & 0xffff) << 16);
1053 
1054 	pmap = BIT(port->id);
1055 	c2.tcam[4] = MVPP22_CLS_C2_PORT_ID(pmap);
1056 	c2.tcam[4] |= MVPP22_CLS_C2_TCAM_EN(MVPP22_CLS_C2_PORT_ID(pmap));
1057 
1058 	/* Match on Lookup Type */
1059 	c2.tcam[4] |= MVPP22_CLS_C2_TCAM_EN(MVPP22_CLS_C2_LU_TYPE(MVPP2_CLS_LU_TYPE_MASK));
1060 	c2.tcam[4] |= MVPP22_CLS_C2_LU_TYPE(rule->loc);
1061 
1062 	if (act->id == FLOW_ACTION_DROP) {
1063 		c2.act = MVPP22_CLS_C2_ACT_COLOR(MVPP22_C2_COL_RED_LOCK);
1064 	} else {
1065 		/* We want to keep the default color derived from the Header
1066 		 * Parser drop entries, for VLAN and MAC filtering. This will
1067 		 * assign a default color of Green or Red, and we want matches
1068 		 * with a non-drop action to keep that color.
1069 		 */
1070 		c2.act = MVPP22_CLS_C2_ACT_COLOR(MVPP22_C2_COL_NO_UPD_LOCK);
1071 
1072 		/* Mark packet as "forwarded to software", needed for RSS */
1073 		c2.act |= MVPP22_CLS_C2_ACT_FWD(MVPP22_C2_FWD_SW_LOCK);
1074 
1075 		c2.act |= MVPP22_CLS_C2_ACT_QHIGH(MVPP22_C2_UPD_LOCK) |
1076 			   MVPP22_CLS_C2_ACT_QLOW(MVPP22_C2_UPD_LOCK);
1077 
1078 		qh = ((act->queue.index + port->first_rxq) >> 3) & MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
1079 		ql = (act->queue.index + port->first_rxq) & MVPP22_CLS_C2_ATTR0_QLOW_MASK;
1080 
1081 		c2.attr[0] = MVPP22_CLS_C2_ATTR0_QHIGH(qh) |
1082 			      MVPP22_CLS_C2_ATTR0_QLOW(ql);
1083 	}
1084 
1085 	c2.valid = true;
1086 
1087 	mvpp2_cls_c2_write(port->priv, &c2);
1088 
1089 	return 0;
1090 }
1091 
1092 static int mvpp2_port_c2_rfs_rule_insert(struct mvpp2_port *port,
1093 					 struct mvpp2_rfs_rule *rule)
1094 {
1095 	return mvpp2_port_c2_tcam_rule_add(port, rule);
1096 }
1097 
1098 static int mvpp2_port_cls_rfs_rule_remove(struct mvpp2_port *port,
1099 					  struct mvpp2_rfs_rule *rule)
1100 {
1101 	const struct mvpp2_cls_flow *flow;
1102 	struct mvpp2_cls_flow_entry fe;
1103 	int index, i;
1104 
1105 	for_each_cls_flow_id_containing_type(i, rule->flow_type) {
1106 		flow = mvpp2_cls_flow_get(i);
1107 		if (!flow)
1108 			return 0;
1109 
1110 		index = MVPP2_CLS_FLT_C2_RFS(port->id, flow->flow_id, rule->loc);
1111 
1112 		mvpp2_cls_flow_read(port->priv, index, &fe);
1113 		mvpp2_cls_flow_port_remove(&fe, BIT(port->id));
1114 		mvpp2_cls_flow_write(port->priv, &fe);
1115 	}
1116 
1117 	if (rule->c2_index >= 0)
1118 		mvpp22_port_c2_lookup_disable(port, rule->c2_index);
1119 
1120 	return 0;
1121 }
1122 
1123 static int mvpp2_port_flt_rfs_rule_insert(struct mvpp2_port *port,
1124 					  struct mvpp2_rfs_rule *rule)
1125 {
1126 	const struct mvpp2_cls_flow *flow;
1127 	struct mvpp2 *priv = port->priv;
1128 	struct mvpp2_cls_flow_entry fe;
1129 	int index, ret, i;
1130 
1131 	if (rule->engine != MVPP22_CLS_ENGINE_C2)
1132 		return -EOPNOTSUPP;
1133 
1134 	ret = mvpp2_port_c2_rfs_rule_insert(port, rule);
1135 	if (ret)
1136 		return ret;
1137 
1138 	for_each_cls_flow_id_containing_type(i, rule->flow_type) {
1139 		flow = mvpp2_cls_flow_get(i);
1140 		if (!flow)
1141 			return 0;
1142 
1143 		index = MVPP2_CLS_FLT_C2_RFS(port->id, flow->flow_id, rule->loc);
1144 
1145 		mvpp2_cls_flow_read(priv, index, &fe);
1146 		mvpp2_cls_flow_eng_set(&fe, rule->engine);
1147 		mvpp2_cls_flow_port_id_sel(&fe, true);
1148 		mvpp2_flow_set_hek_fields(&fe, rule->hek_fields);
1149 		mvpp2_cls_flow_lu_type_set(&fe, rule->loc);
1150 		mvpp2_cls_flow_port_add(&fe, 0xf);
1151 
1152 		mvpp2_cls_flow_write(priv, &fe);
1153 	}
1154 
1155 	return 0;
1156 }
1157 
1158 static int mvpp2_cls_c2_build_match(struct mvpp2_rfs_rule *rule)
1159 {
1160 	struct flow_rule *flow = rule->flow;
1161 	int offs = 64;
1162 
1163 	if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_PORTS)) {
1164 		struct flow_match_ports match;
1165 
1166 		flow_rule_match_ports(flow, &match);
1167 		if (match.mask->src) {
1168 			rule->hek_fields |= MVPP22_CLS_HEK_OPT_L4SIP;
1169 			offs -= mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4SIP);
1170 
1171 			rule->c2_tcam |= ((u64)ntohs(match.key->src)) << offs;
1172 			rule->c2_tcam_mask |= ((u64)ntohs(match.mask->src)) << offs;
1173 		}
1174 
1175 		if (match.mask->dst) {
1176 			rule->hek_fields |= MVPP22_CLS_HEK_OPT_L4DIP;
1177 			offs -= mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4DIP);
1178 
1179 			rule->c2_tcam |= ((u64)ntohs(match.key->dst)) << offs;
1180 			rule->c2_tcam_mask |= ((u64)ntohs(match.mask->dst)) << offs;
1181 		}
1182 	}
1183 
1184 	if (hweight16(rule->hek_fields) > MVPP2_FLOW_N_FIELDS)
1185 		return -EOPNOTSUPP;
1186 
1187 	return 0;
1188 }
1189 
1190 static int mvpp2_cls_rfs_parse_rule(struct mvpp2_rfs_rule *rule)
1191 {
1192 	struct flow_rule *flow = rule->flow;
1193 	struct flow_action_entry *act;
1194 
1195 	act = &flow->action.entries[0];
1196 	if (act->id != FLOW_ACTION_QUEUE && act->id != FLOW_ACTION_DROP)
1197 		return -EOPNOTSUPP;
1198 
1199 	/* For now, only use the C2 engine which has a HEK size limited to 64
1200 	 * bits for TCAM matching.
1201 	 */
1202 	rule->engine = MVPP22_CLS_ENGINE_C2;
1203 
1204 	if (mvpp2_cls_c2_build_match(rule))
1205 		return -EINVAL;
1206 
1207 	return 0;
1208 }
1209 
1210 int mvpp2_ethtool_cls_rule_get(struct mvpp2_port *port,
1211 			       struct ethtool_rxnfc *rxnfc)
1212 {
1213 	struct mvpp2_ethtool_fs *efs;
1214 
1215 	if (rxnfc->fs.location >= MVPP2_N_RFS_RULES)
1216 		return -EINVAL;
1217 
1218 	efs = port->rfs_rules[rxnfc->fs.location];
1219 	if (!efs)
1220 		return -ENOENT;
1221 
1222 	memcpy(rxnfc, &efs->rxnfc, sizeof(efs->rxnfc));
1223 
1224 	return 0;
1225 }
1226 
1227 int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port,
1228 			       struct ethtool_rxnfc *info)
1229 {
1230 	struct ethtool_rx_flow_spec_input input = {};
1231 	struct ethtool_rx_flow_rule *ethtool_rule;
1232 	struct mvpp2_ethtool_fs *efs, *old_efs;
1233 	int ret = 0;
1234 
1235 	if (info->fs.location >= 4 ||
1236 	    info->fs.location < 0)
1237 		return -EINVAL;
1238 
1239 	efs = kzalloc(sizeof(*efs), GFP_KERNEL);
1240 	if (!efs)
1241 		return -ENOMEM;
1242 
1243 	input.fs = &info->fs;
1244 
1245 	ethtool_rule = ethtool_rx_flow_rule_create(&input);
1246 	if (IS_ERR(ethtool_rule)) {
1247 		ret = PTR_ERR(ethtool_rule);
1248 		goto clean_rule;
1249 	}
1250 
1251 	efs->rule.flow = ethtool_rule->rule;
1252 	efs->rule.flow_type = mvpp2_cls_ethtool_flow_to_type(info->fs.flow_type);
1253 
1254 	ret = mvpp2_cls_rfs_parse_rule(&efs->rule);
1255 	if (ret)
1256 		goto clean_eth_rule;
1257 
1258 	efs->rule.loc = info->fs.location;
1259 
1260 	/* Replace an already existing rule */
1261 	if (port->rfs_rules[efs->rule.loc]) {
1262 		old_efs = port->rfs_rules[efs->rule.loc];
1263 		ret = mvpp2_port_cls_rfs_rule_remove(port, &old_efs->rule);
1264 		if (ret)
1265 			goto clean_eth_rule;
1266 		kfree(old_efs);
1267 		port->n_rfs_rules--;
1268 	}
1269 
1270 	ret = mvpp2_port_flt_rfs_rule_insert(port, &efs->rule);
1271 	if (ret)
1272 		goto clean_eth_rule;
1273 
1274 	ethtool_rx_flow_rule_destroy(ethtool_rule);
1275 	efs->rule.flow = NULL;
1276 
1277 	memcpy(&efs->rxnfc, info, sizeof(*info));
1278 	port->rfs_rules[efs->rule.loc] = efs;
1279 	port->n_rfs_rules++;
1280 
1281 	return ret;
1282 
1283 clean_eth_rule:
1284 	ethtool_rx_flow_rule_destroy(ethtool_rule);
1285 clean_rule:
1286 	kfree(efs);
1287 	return ret;
1288 }
1289 
1290 int mvpp2_ethtool_cls_rule_del(struct mvpp2_port *port,
1291 			       struct ethtool_rxnfc *info)
1292 {
1293 	struct mvpp2_ethtool_fs *efs;
1294 	int ret;
1295 
1296 	efs = port->rfs_rules[info->fs.location];
1297 	if (!efs)
1298 		return -EINVAL;
1299 
1300 	/* Remove the rule from the engines. */
1301 	ret = mvpp2_port_cls_rfs_rule_remove(port, &efs->rule);
1302 	if (ret)
1303 		return ret;
1304 
1305 	port->n_rfs_rules--;
1306 	port->rfs_rules[info->fs.location] = NULL;
1307 	kfree(efs);
1308 
1309 	return 0;
1310 }
1311 
1312 static inline u32 mvpp22_rxfh_indir(struct mvpp2_port *port, u32 rxq)
1313 {
1314 	int nrxqs, cpu, cpus = num_possible_cpus();
1315 
1316 	/* Number of RXQs per CPU */
1317 	nrxqs = port->nrxqs / cpus;
1318 
1319 	/* CPU that will handle this rx queue */
1320 	cpu = rxq / nrxqs;
1321 
1322 	if (!cpu_online(cpu))
1323 		return port->first_rxq;
1324 
1325 	/* Indirection to better distribute the paquets on the CPUs when
1326 	 * configuring the RSS queues.
1327 	 */
1328 	return port->first_rxq + ((rxq * nrxqs + rxq / cpus) % port->nrxqs);
1329 }
1330 
1331 void mvpp22_rss_fill_table(struct mvpp2_port *port, u32 table)
1332 {
1333 	struct mvpp2 *priv = port->priv;
1334 	int i;
1335 
1336 	for (i = 0; i < MVPP22_RSS_TABLE_ENTRIES; i++) {
1337 		u32 sel = MVPP22_RSS_INDEX_TABLE(table) |
1338 			  MVPP22_RSS_INDEX_TABLE_ENTRY(i);
1339 		mvpp2_write(priv, MVPP22_RSS_INDEX, sel);
1340 
1341 		mvpp2_write(priv, MVPP22_RSS_TABLE_ENTRY,
1342 			    mvpp22_rxfh_indir(port, port->indir[i]));
1343 	}
1344 }
1345 
1346 int mvpp2_ethtool_rxfh_set(struct mvpp2_port *port, struct ethtool_rxnfc *info)
1347 {
1348 	u16 hash_opts = 0;
1349 	u32 flow_type;
1350 
1351 	flow_type = mvpp2_cls_ethtool_flow_to_type(info->flow_type);
1352 
1353 	switch (flow_type) {
1354 	case MVPP22_FLOW_TCP4:
1355 	case MVPP22_FLOW_UDP4:
1356 	case MVPP22_FLOW_TCP6:
1357 	case MVPP22_FLOW_UDP6:
1358 		if (info->data & RXH_L4_B_0_1)
1359 			hash_opts |= MVPP22_CLS_HEK_OPT_L4SIP;
1360 		if (info->data & RXH_L4_B_2_3)
1361 			hash_opts |= MVPP22_CLS_HEK_OPT_L4DIP;
1362 		/* Fallthrough */
1363 	case MVPP22_FLOW_IP4:
1364 	case MVPP22_FLOW_IP6:
1365 		if (info->data & RXH_L2DA)
1366 			hash_opts |= MVPP22_CLS_HEK_OPT_MAC_DA;
1367 		if (info->data & RXH_VLAN)
1368 			hash_opts |= MVPP22_CLS_HEK_OPT_VLAN;
1369 		if (info->data & RXH_L3_PROTO)
1370 			hash_opts |= MVPP22_CLS_HEK_OPT_L3_PROTO;
1371 		if (info->data & RXH_IP_SRC)
1372 			hash_opts |= (MVPP22_CLS_HEK_OPT_IP4SA |
1373 				     MVPP22_CLS_HEK_OPT_IP6SA);
1374 		if (info->data & RXH_IP_DST)
1375 			hash_opts |= (MVPP22_CLS_HEK_OPT_IP4DA |
1376 				     MVPP22_CLS_HEK_OPT_IP6DA);
1377 		break;
1378 	default: return -EOPNOTSUPP;
1379 	}
1380 
1381 	return mvpp2_port_rss_hash_opts_set(port, flow_type, hash_opts);
1382 }
1383 
1384 int mvpp2_ethtool_rxfh_get(struct mvpp2_port *port, struct ethtool_rxnfc *info)
1385 {
1386 	unsigned long hash_opts;
1387 	u32 flow_type;
1388 	int i;
1389 
1390 	flow_type = mvpp2_cls_ethtool_flow_to_type(info->flow_type);
1391 
1392 	hash_opts = mvpp2_port_rss_hash_opts_get(port, flow_type);
1393 	info->data = 0;
1394 
1395 	for_each_set_bit(i, &hash_opts, MVPP22_CLS_HEK_N_FIELDS) {
1396 		switch (BIT(i)) {
1397 		case MVPP22_CLS_HEK_OPT_MAC_DA:
1398 			info->data |= RXH_L2DA;
1399 			break;
1400 		case MVPP22_CLS_HEK_OPT_VLAN:
1401 			info->data |= RXH_VLAN;
1402 			break;
1403 		case MVPP22_CLS_HEK_OPT_L3_PROTO:
1404 			info->data |= RXH_L3_PROTO;
1405 			break;
1406 		case MVPP22_CLS_HEK_OPT_IP4SA:
1407 		case MVPP22_CLS_HEK_OPT_IP6SA:
1408 			info->data |= RXH_IP_SRC;
1409 			break;
1410 		case MVPP22_CLS_HEK_OPT_IP4DA:
1411 		case MVPP22_CLS_HEK_OPT_IP6DA:
1412 			info->data |= RXH_IP_DST;
1413 			break;
1414 		case MVPP22_CLS_HEK_OPT_L4SIP:
1415 			info->data |= RXH_L4_B_0_1;
1416 			break;
1417 		case MVPP22_CLS_HEK_OPT_L4DIP:
1418 			info->data |= RXH_L4_B_2_3;
1419 			break;
1420 		default:
1421 			return -EINVAL;
1422 		}
1423 	}
1424 	return 0;
1425 }
1426 
1427 void mvpp22_port_rss_init(struct mvpp2_port *port)
1428 {
1429 	struct mvpp2 *priv = port->priv;
1430 	int i;
1431 
1432 	/* Set the table width: replace the whole classifier Rx queue number
1433 	 * with the ones configured in RSS table entries.
1434 	 */
1435 	mvpp2_write(priv, MVPP22_RSS_INDEX, MVPP22_RSS_INDEX_TABLE(port->id));
1436 	mvpp2_write(priv, MVPP22_RSS_WIDTH, 8);
1437 
1438 	/* The default RxQ is used as a key to select the RSS table to use.
1439 	 * We use one RSS table per port.
1440 	 */
1441 	mvpp2_write(priv, MVPP22_RSS_INDEX,
1442 		    MVPP22_RSS_INDEX_QUEUE(port->first_rxq));
1443 	mvpp2_write(priv, MVPP22_RXQ2RSS_TABLE,
1444 		    MVPP22_RSS_TABLE_POINTER(port->id));
1445 
1446 	/* Configure the first table to evenly distribute the packets across
1447 	 * real Rx Queues. The table entries map a hash to a port Rx Queue.
1448 	 */
1449 	for (i = 0; i < MVPP22_RSS_TABLE_ENTRIES; i++)
1450 		port->indir[i] = ethtool_rxfh_indir_default(i, port->nrxqs);
1451 
1452 	mvpp22_rss_fill_table(port, port->id);
1453 
1454 	/* Configure default flows */
1455 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_IP4, MVPP22_CLS_HEK_IP4_2T);
1456 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_IP6, MVPP22_CLS_HEK_IP6_2T);
1457 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_TCP4, MVPP22_CLS_HEK_IP4_5T);
1458 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_TCP6, MVPP22_CLS_HEK_IP6_5T);
1459 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_UDP4, MVPP22_CLS_HEK_IP4_5T);
1460 	mvpp2_port_rss_hash_opts_set(port, MVPP22_FLOW_UDP6, MVPP22_CLS_HEK_IP6_5T);
1461 }
1462