1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * RSS and Classifier definitions for Marvell PPv2 Network Controller |
4 | * |
5 | * Copyright (C) 2014 Marvell |
6 | * |
7 | * Marcin Wojtas <mw@semihalf.com> |
8 | */ |
9 | |
10 | #ifndef _MVPP2_CLS_H_ |
11 | #define _MVPP2_CLS_H_ |
12 | |
13 | #include "mvpp2.h" |
14 | #include "mvpp2_prs.h" |
15 | |
16 | /* Classifier constants */ |
17 | #define MVPP2_CLS_FLOWS_TBL_SIZE 512 |
18 | #define MVPP2_CLS_FLOWS_TBL_DATA_WORDS 3 |
19 | #define MVPP2_CLS_LKP_TBL_SIZE 64 |
20 | #define MVPP2_CLS_RX_QUEUES 256 |
21 | |
22 | /* Classifier flow constants */ |
23 | |
24 | #define MVPP2_FLOW_N_FIELDS 4 |
25 | |
26 | enum mvpp2_cls_engine { |
27 | MVPP22_CLS_ENGINE_C2 = 1, |
28 | MVPP22_CLS_ENGINE_C3A, |
29 | MVPP22_CLS_ENGINE_C3B, |
30 | MVPP22_CLS_ENGINE_C4, |
31 | MVPP22_CLS_ENGINE_C3HA = 6, |
32 | MVPP22_CLS_ENGINE_C3HB = 7, |
33 | }; |
34 | |
35 | #define MVPP22_CLS_HEK_OPT_MAC_DA BIT(0) |
36 | #define MVPP22_CLS_HEK_OPT_VLAN_PRI BIT(1) |
37 | #define MVPP22_CLS_HEK_OPT_VLAN BIT(2) |
38 | #define MVPP22_CLS_HEK_OPT_L3_PROTO BIT(3) |
39 | #define MVPP22_CLS_HEK_OPT_IP4SA BIT(4) |
40 | #define MVPP22_CLS_HEK_OPT_IP4DA BIT(5) |
41 | #define MVPP22_CLS_HEK_OPT_IP6SA BIT(6) |
42 | #define MVPP22_CLS_HEK_OPT_IP6DA BIT(7) |
43 | #define MVPP22_CLS_HEK_OPT_L4SIP BIT(8) |
44 | #define MVPP22_CLS_HEK_OPT_L4DIP BIT(9) |
45 | #define MVPP22_CLS_HEK_N_FIELDS 10 |
46 | |
47 | #define MVPP22_CLS_HEK_L4_OPTS (MVPP22_CLS_HEK_OPT_L4SIP | \ |
48 | MVPP22_CLS_HEK_OPT_L4DIP) |
49 | |
50 | #define MVPP22_CLS_HEK_IP4_2T (MVPP22_CLS_HEK_OPT_IP4SA | \ |
51 | MVPP22_CLS_HEK_OPT_IP4DA) |
52 | |
53 | #define MVPP22_CLS_HEK_IP6_2T (MVPP22_CLS_HEK_OPT_IP6SA | \ |
54 | MVPP22_CLS_HEK_OPT_IP6DA) |
55 | |
56 | /* The fifth tuple in "5T" is the L4_Info field */ |
57 | #define MVPP22_CLS_HEK_IP4_5T (MVPP22_CLS_HEK_IP4_2T | \ |
58 | MVPP22_CLS_HEK_L4_OPTS) |
59 | |
60 | #define MVPP22_CLS_HEK_IP6_5T (MVPP22_CLS_HEK_IP6_2T | \ |
61 | MVPP22_CLS_HEK_L4_OPTS) |
62 | |
63 | #define MVPP22_CLS_HEK_TAGGED (MVPP22_CLS_HEK_OPT_VLAN | \ |
64 | MVPP22_CLS_HEK_OPT_VLAN_PRI) |
65 | |
66 | enum mvpp2_cls_field_id { |
67 | MVPP22_CLS_FIELD_MAC_DA = 0x03, |
68 | MVPP22_CLS_FIELD_VLAN_PRI = 0x05, |
69 | MVPP22_CLS_FIELD_VLAN = 0x06, |
70 | MVPP22_CLS_FIELD_L3_PROTO = 0x0f, |
71 | MVPP22_CLS_FIELD_IP4SA = 0x10, |
72 | MVPP22_CLS_FIELD_IP4DA = 0x11, |
73 | MVPP22_CLS_FIELD_IP6SA = 0x17, |
74 | MVPP22_CLS_FIELD_IP6DA = 0x1a, |
75 | MVPP22_CLS_FIELD_L4SIP = 0x1d, |
76 | MVPP22_CLS_FIELD_L4DIP = 0x1e, |
77 | }; |
78 | |
79 | /* Classifier C2 engine constants */ |
80 | #define MVPP22_CLS_C2_TCAM_EN(data) ((data) << 16) |
81 | |
82 | enum mvpp22_cls_c2_action { |
83 | MVPP22_C2_NO_UPD = 0, |
84 | MVPP22_C2_NO_UPD_LOCK, |
85 | MVPP22_C2_UPD, |
86 | MVPP22_C2_UPD_LOCK, |
87 | }; |
88 | |
89 | enum mvpp22_cls_c2_fwd_action { |
90 | MVPP22_C2_FWD_NO_UPD = 0, |
91 | MVPP22_C2_FWD_NO_UPD_LOCK, |
92 | MVPP22_C2_FWD_SW, |
93 | MVPP22_C2_FWD_SW_LOCK, |
94 | MVPP22_C2_FWD_HW, |
95 | MVPP22_C2_FWD_HW_LOCK, |
96 | MVPP22_C2_FWD_HW_LOW_LAT, |
97 | MVPP22_C2_FWD_HW_LOW_LAT_LOCK, |
98 | }; |
99 | |
100 | enum mvpp22_cls_c2_color_action { |
101 | MVPP22_C2_COL_NO_UPD = 0, |
102 | MVPP22_C2_COL_NO_UPD_LOCK, |
103 | MVPP22_C2_COL_GREEN, |
104 | MVPP22_C2_COL_GREEN_LOCK, |
105 | MVPP22_C2_COL_YELLOW, |
106 | MVPP22_C2_COL_YELLOW_LOCK, |
107 | MVPP22_C2_COL_RED, /* Drop */ |
108 | MVPP22_C2_COL_RED_LOCK, /* Drop */ |
109 | }; |
110 | |
111 | #define MVPP2_CLS_C2_TCAM_WORDS 5 |
112 | #define MVPP2_CLS_C2_ATTR_WORDS 5 |
113 | |
114 | struct mvpp2_cls_c2_entry { |
115 | u32 index; |
116 | /* TCAM lookup key */ |
117 | u32 tcam[MVPP2_CLS_C2_TCAM_WORDS]; |
118 | /* Actions to perform upon TCAM match */ |
119 | u32 act; |
120 | /* Attributes relative to the actions to perform */ |
121 | u32 attr[MVPP2_CLS_C2_ATTR_WORDS]; |
122 | /* Entry validity */ |
123 | u8 valid; |
124 | }; |
125 | |
126 | #define MVPP22_FLOW_ETHER_BIT BIT(0) |
127 | #define MVPP22_FLOW_IP4_BIT BIT(1) |
128 | #define MVPP22_FLOW_IP6_BIT BIT(2) |
129 | #define MVPP22_FLOW_TCP_BIT BIT(3) |
130 | #define MVPP22_FLOW_UDP_BIT BIT(4) |
131 | |
132 | #define MVPP22_FLOW_TCP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_TCP_BIT) |
133 | #define MVPP22_FLOW_TCP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_TCP_BIT) |
134 | #define MVPP22_FLOW_UDP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_UDP_BIT) |
135 | #define MVPP22_FLOW_UDP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_UDP_BIT) |
136 | #define MVPP22_FLOW_IP4 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT) |
137 | #define MVPP22_FLOW_IP6 (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT) |
138 | #define MVPP22_FLOW_ETHERNET (MVPP22_FLOW_ETHER_BIT) |
139 | |
140 | /* Classifier C2 engine entries */ |
141 | #define MVPP22_CLS_C2_N_ENTRIES 256 |
142 | |
143 | /* Number of per-port dedicated entries in the C2 TCAM */ |
144 | #define MVPP22_CLS_C2_PORT_N_FLOWS MVPP2_N_RFS_ENTRIES_PER_FLOW |
145 | |
146 | /* Each port has one range per flow type + one entry controlling the global RSS |
147 | * setting and the default rx queue |
148 | */ |
149 | #define MVPP22_CLS_C2_PORT_RANGE (MVPP22_CLS_C2_PORT_N_FLOWS + 1) |
150 | #define MVPP22_CLS_C2_PORT_FIRST(p) ((p) * MVPP22_CLS_C2_PORT_RANGE) |
151 | #define (p) (MVPP22_CLS_C2_PORT_FIRST((p) + 1) - 1) |
152 | |
153 | #define MVPP22_CLS_C2_PORT_FLOW_FIRST(p) (MVPP22_CLS_C2_PORT_FIRST(p)) |
154 | |
155 | #define MVPP22_CLS_C2_RFS_LOC(p, loc) (MVPP22_CLS_C2_PORT_FLOW_FIRST(p) + (loc)) |
156 | |
157 | /* Packet flow ID */ |
158 | enum mvpp2_prs_flow { |
159 | MVPP2_FL_START = 8, |
160 | MVPP2_FL_IP4_TCP_NF_UNTAG = MVPP2_FL_START, |
161 | MVPP2_FL_IP4_UDP_NF_UNTAG, |
162 | MVPP2_FL_IP4_TCP_NF_TAG, |
163 | MVPP2_FL_IP4_UDP_NF_TAG, |
164 | MVPP2_FL_IP6_TCP_NF_UNTAG, |
165 | MVPP2_FL_IP6_UDP_NF_UNTAG, |
166 | MVPP2_FL_IP6_TCP_NF_TAG, |
167 | MVPP2_FL_IP6_UDP_NF_TAG, |
168 | MVPP2_FL_IP4_TCP_FRAG_UNTAG, |
169 | MVPP2_FL_IP4_UDP_FRAG_UNTAG, |
170 | MVPP2_FL_IP4_TCP_FRAG_TAG, |
171 | MVPP2_FL_IP4_UDP_FRAG_TAG, |
172 | MVPP2_FL_IP6_TCP_FRAG_UNTAG, |
173 | MVPP2_FL_IP6_UDP_FRAG_UNTAG, |
174 | MVPP2_FL_IP6_TCP_FRAG_TAG, |
175 | MVPP2_FL_IP6_UDP_FRAG_TAG, |
176 | MVPP2_FL_IP4_UNTAG, /* non-TCP, non-UDP, same for below */ |
177 | MVPP2_FL_IP4_TAG, |
178 | MVPP2_FL_IP6_UNTAG, |
179 | MVPP2_FL_IP6_TAG, |
180 | MVPP2_FL_NON_IP_UNTAG, |
181 | MVPP2_FL_NON_IP_TAG, |
182 | MVPP2_FL_LAST, |
183 | }; |
184 | |
185 | /* LU Type defined for all engines, and specified in the flow table */ |
186 | #define MVPP2_CLS_LU_TYPE_MASK 0x3f |
187 | |
188 | enum mvpp2_cls_lu_type { |
189 | /* rule->loc is used as a lu-type for the entries 0 - 62. */ |
190 | MVPP22_CLS_LU_TYPE_ALL = 63, |
191 | }; |
192 | |
193 | #define MVPP2_N_FLOWS (MVPP2_FL_LAST - MVPP2_FL_START) |
194 | |
195 | struct mvpp2_cls_flow { |
196 | /* The L2-L4 traffic flow type */ |
197 | int flow_type; |
198 | |
199 | /* The first id in the flow table for this flow */ |
200 | u16 flow_id; |
201 | |
202 | /* The supported HEK fields for this flow */ |
203 | u16 supported_hash_opts; |
204 | |
205 | /* The Header Parser result_info that matches this flow */ |
206 | struct mvpp2_prs_result_info prs_ri; |
207 | }; |
208 | |
209 | #define MVPP2_CLS_FLT_ENTRIES_PER_FLOW (MVPP2_MAX_PORTS + 1 + 16) |
210 | #define MVPP2_CLS_FLT_FIRST(id) (((id) - MVPP2_FL_START) * \ |
211 | MVPP2_CLS_FLT_ENTRIES_PER_FLOW) |
212 | |
213 | #define MVPP2_CLS_FLT_C2_RFS(port, id, rfs_n) (MVPP2_CLS_FLT_FIRST(id) + \ |
214 | ((port) * MVPP2_MAX_PORTS) + \ |
215 | (rfs_n)) |
216 | |
217 | #define (id) (MVPP2_CLS_FLT_C2_RFS(MVPP2_MAX_PORTS, id, 0)) |
218 | #define MVPP2_CLS_FLT_HASH_ENTRY(port, id) (MVPP2_CLS_FLT_C2_RSS_ENTRY(id) + 1 + (port)) |
219 | #define MVPP2_CLS_FLT_LAST(id) (MVPP2_CLS_FLT_FIRST(id) + \ |
220 | MVPP2_CLS_FLT_ENTRIES_PER_FLOW - 1) |
221 | |
222 | /* Iterate on each classifier flow id. Sets 'i' to be the index of the first |
223 | * entry in the cls_flows table for each different flow_id. |
224 | * This relies on entries having the same flow_id in the cls_flows table being |
225 | * contiguous. |
226 | */ |
227 | #define for_each_cls_flow_id(i) \ |
228 | for ((i) = 0; (i) < MVPP2_N_PRS_FLOWS; (i)++) \ |
229 | if ((i) > 0 && \ |
230 | cls_flows[(i)].flow_id == cls_flows[(i) - 1].flow_id) \ |
231 | continue; \ |
232 | else |
233 | |
234 | /* Iterate on each classifier flow that has a given flow_type. Sets 'i' to be |
235 | * the index of the first entry in the cls_flow table for each different flow_id |
236 | * that has the given flow_type. This allows to operate on all flows that |
237 | * matches a given ethtool flow type. |
238 | */ |
239 | #define for_each_cls_flow_id_with_type(i, type) \ |
240 | for_each_cls_flow_id((i)) \ |
241 | if (cls_flows[(i)].flow_type != (type)) \ |
242 | continue; \ |
243 | else |
244 | |
245 | #define for_each_cls_flow_id_containing_type(i, type) \ |
246 | for_each_cls_flow_id((i)) \ |
247 | if ((cls_flows[(i)].flow_type & (type)) != (type)) \ |
248 | continue; \ |
249 | else |
250 | |
251 | struct mvpp2_cls_flow_entry { |
252 | u32 index; |
253 | u32 data[MVPP2_CLS_FLOWS_TBL_DATA_WORDS]; |
254 | }; |
255 | |
256 | struct mvpp2_cls_lookup_entry { |
257 | u32 lkpid; |
258 | u32 way; |
259 | u32 data; |
260 | }; |
261 | |
262 | int (struct mvpp2_port *port); |
263 | |
264 | int (struct mvpp2_port *port); |
265 | int (struct mvpp2_port *port); |
266 | |
267 | int (struct mvpp2_port *port, u32 *); |
268 | int (struct mvpp2_port *port, u32 ); |
269 | |
270 | int (struct mvpp2_port *port, u32 , |
271 | const u32 *indir); |
272 | int (struct mvpp2_port *port, u32 , |
273 | u32 *indir); |
274 | |
275 | int mvpp2_ethtool_rxfh_get(struct mvpp2_port *port, struct ethtool_rxnfc *info); |
276 | int mvpp2_ethtool_rxfh_set(struct mvpp2_port *port, struct ethtool_rxnfc *info); |
277 | |
278 | void mvpp2_cls_init(struct mvpp2 *priv); |
279 | |
280 | void mvpp2_cls_port_config(struct mvpp2_port *port); |
281 | |
282 | void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port); |
283 | |
284 | int mvpp2_cls_flow_eng_get(struct mvpp2_cls_flow_entry *fe); |
285 | |
286 | u16 mvpp2_flow_get_hek_fields(struct mvpp2_cls_flow_entry *fe); |
287 | |
288 | const struct mvpp2_cls_flow *mvpp2_cls_flow_get(int flow); |
289 | |
290 | u32 mvpp2_cls_flow_hits(struct mvpp2 *priv, int index); |
291 | |
292 | void mvpp2_cls_flow_read(struct mvpp2 *priv, int index, |
293 | struct mvpp2_cls_flow_entry *fe); |
294 | |
295 | u32 mvpp2_cls_lookup_hits(struct mvpp2 *priv, int index); |
296 | |
297 | void mvpp2_cls_lookup_read(struct mvpp2 *priv, int lkpid, int way, |
298 | struct mvpp2_cls_lookup_entry *le); |
299 | |
300 | u32 mvpp2_cls_c2_hit_count(struct mvpp2 *priv, int c2_index); |
301 | |
302 | void mvpp2_cls_c2_read(struct mvpp2 *priv, int index, |
303 | struct mvpp2_cls_c2_entry *c2); |
304 | |
305 | int mvpp2_ethtool_cls_rule_get(struct mvpp2_port *port, |
306 | struct ethtool_rxnfc *rxnfc); |
307 | |
308 | int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port, |
309 | struct ethtool_rxnfc *info); |
310 | |
311 | int mvpp2_ethtool_cls_rule_del(struct mvpp2_port *port, |
312 | struct ethtool_rxnfc *info); |
313 | |
314 | #endif |
315 | |