Merge tag 'gcc-plugins-v5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / net / ethernet / marvell / mvpp2 / mvpp2_cls.c
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 }