Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2018-2022 NXP
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : : #include <sys/mman.h>
13 : :
14 : : #include <rte_ethdev.h>
15 : : #include <rte_log.h>
16 : : #include <rte_malloc.h>
17 : : #include <rte_flow_driver.h>
18 : : #include <rte_tailq.h>
19 : :
20 : : #include <fsl_dpni.h>
21 : : #include <fsl_dpkg.h>
22 : :
23 : : #include <dpaa2_ethdev.h>
24 : : #include <dpaa2_pmd_logs.h>
25 : :
26 : : static char *dpaa2_flow_control_log;
27 : : static uint16_t dpaa2_flow_miss_flow_id; /* Default miss flow id is 0. */
28 : : static int dpaa2_sp_loaded = -1;
29 : :
30 : : enum dpaa2_flow_entry_size {
31 : : DPAA2_FLOW_ENTRY_MIN_SIZE = (DPNI_MAX_KEY_SIZE / 2),
32 : : DPAA2_FLOW_ENTRY_MAX_SIZE = DPNI_MAX_KEY_SIZE
33 : : };
34 : :
35 : : enum dpaa2_flow_dist_type {
36 : : DPAA2_FLOW_QOS_TYPE = 1 << 0,
37 : : DPAA2_FLOW_FS_TYPE = 1 << 1
38 : : };
39 : :
40 : : #define DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT 16
41 : : #define DPAA2_FLOW_MAX_KEY_SIZE 16
42 : : #define DPAA2_PROT_FIELD_STRING_SIZE 16
43 : : #define VXLAN_HF_VNI 0x08
44 : :
45 : : struct dpaa2_dev_flow {
46 : : LIST_ENTRY(dpaa2_dev_flow) next;
47 : : struct dpni_rule_cfg qos_rule;
48 : : uint8_t *qos_key_addr;
49 : : uint8_t *qos_mask_addr;
50 : : uint16_t qos_rule_size;
51 : : struct dpni_rule_cfg fs_rule;
52 : : uint8_t qos_real_key_size;
53 : : uint8_t fs_real_key_size;
54 : : uint8_t *fs_key_addr;
55 : : uint8_t *fs_mask_addr;
56 : : uint16_t fs_rule_size;
57 : : uint8_t tc_id; /** Traffic Class ID. */
58 : : uint8_t tc_index; /** index within this Traffic Class. */
59 : : enum rte_flow_action_type action_type;
60 : : struct dpni_fs_action_cfg fs_action_cfg;
61 : : };
62 : :
63 : : struct rte_dpaa2_flow_item {
64 : : struct rte_flow_item generic_item;
65 : : int in_tunnel;
66 : : };
67 : :
68 : : static const
69 : : enum rte_flow_item_type dpaa2_hp_supported_pattern_type[] = {
70 : : RTE_FLOW_ITEM_TYPE_END,
71 : : RTE_FLOW_ITEM_TYPE_ETH,
72 : : RTE_FLOW_ITEM_TYPE_VLAN,
73 : : RTE_FLOW_ITEM_TYPE_IPV4,
74 : : RTE_FLOW_ITEM_TYPE_IPV6,
75 : : RTE_FLOW_ITEM_TYPE_ICMP,
76 : : RTE_FLOW_ITEM_TYPE_UDP,
77 : : RTE_FLOW_ITEM_TYPE_TCP,
78 : : RTE_FLOW_ITEM_TYPE_SCTP,
79 : : RTE_FLOW_ITEM_TYPE_GRE,
80 : : RTE_FLOW_ITEM_TYPE_GTP,
81 : : RTE_FLOW_ITEM_TYPE_ESP,
82 : : RTE_FLOW_ITEM_TYPE_AH,
83 : : RTE_FLOW_ITEM_TYPE_RAW
84 : : };
85 : :
86 : : static const
87 : : enum rte_flow_item_type dpaa2_sp_supported_pattern_type[] = {
88 : : RTE_FLOW_ITEM_TYPE_VXLAN,
89 : : RTE_FLOW_ITEM_TYPE_ECPRI
90 : : };
91 : :
92 : : static const
93 : : enum rte_flow_action_type dpaa2_supported_action_type[] = {
94 : : RTE_FLOW_ACTION_TYPE_END,
95 : : RTE_FLOW_ACTION_TYPE_QUEUE,
96 : : RTE_FLOW_ACTION_TYPE_PORT_ID,
97 : : RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
98 : : RTE_FLOW_ACTION_TYPE_RSS
99 : : };
100 : :
101 : : #ifndef __cplusplus
102 : : static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = {
103 : : .hdr.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
104 : : .hdr.src_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
105 : : .hdr.ether_type = RTE_BE16(0xffff),
106 : : };
107 : :
108 : : static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = {
109 : : .hdr.vlan_tci = RTE_BE16(0xffff),
110 : : };
111 : :
112 : : static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = {
113 : : .hdr.src_addr = RTE_BE32(0xffffffff),
114 : : .hdr.dst_addr = RTE_BE32(0xffffffff),
115 : : .hdr.next_proto_id = 0xff,
116 : : };
117 : :
118 : : static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = {
119 : : .hdr = {
120 : : .src_addr = RTE_IPV6_MASK_FULL,
121 : : .dst_addr = RTE_IPV6_MASK_FULL,
122 : : .proto = 0xff
123 : : },
124 : : };
125 : :
126 : : static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = {
127 : : .hdr.icmp_type = 0xff,
128 : : .hdr.icmp_code = 0xff,
129 : : };
130 : :
131 : : static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = {
132 : : .hdr = {
133 : : .src_port = RTE_BE16(0xffff),
134 : : .dst_port = RTE_BE16(0xffff),
135 : : },
136 : : };
137 : :
138 : : static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = {
139 : : .hdr = {
140 : : .src_port = RTE_BE16(0xffff),
141 : : .dst_port = RTE_BE16(0xffff),
142 : : },
143 : : };
144 : :
145 : : static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = {
146 : : .hdr = {
147 : : .src_port = RTE_BE16(0xffff),
148 : : .dst_port = RTE_BE16(0xffff),
149 : : },
150 : : };
151 : :
152 : : static const struct rte_flow_item_esp dpaa2_flow_item_esp_mask = {
153 : : .hdr = {
154 : : .spi = RTE_BE32(0xffffffff),
155 : : .seq = RTE_BE32(0xffffffff),
156 : : },
157 : : };
158 : :
159 : : static const struct rte_flow_item_ah dpaa2_flow_item_ah_mask = {
160 : : .spi = RTE_BE32(0xffffffff),
161 : : };
162 : :
163 : : static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = {
164 : : .protocol = RTE_BE16(0xffff),
165 : : };
166 : :
167 : : static const struct rte_flow_item_vxlan dpaa2_flow_item_vxlan_mask = {
168 : : .flags = 0xff,
169 : : .vni = { 0xff, 0xff, 0xff },
170 : : };
171 : :
172 : : static const struct rte_flow_item_ecpri dpaa2_flow_item_ecpri_mask = {
173 : : .hdr.common.type = 0xff,
174 : : .hdr.dummy[0] = RTE_BE32(0xffffffff),
175 : : .hdr.dummy[1] = RTE_BE32(0xffffffff),
176 : : .hdr.dummy[2] = RTE_BE32(0xffffffff),
177 : : };
178 : :
179 : : static const struct rte_flow_item_gtp dpaa2_flow_item_gtp_mask = {
180 : : .teid = RTE_BE32(0xffffffff),
181 : : };
182 : :
183 : : #endif
184 : :
185 : : #define DPAA2_FLOW_DUMP printf
186 : :
187 : : static inline void
188 : 0 : dpaa2_prot_field_string(uint32_t prot, uint32_t field,
189 : : char *string)
190 : : {
191 [ # # ]: 0 : if (!dpaa2_flow_control_log)
192 : : return;
193 : :
194 : : if (prot == NET_PROT_ETH) {
195 : : strcpy(string, "eth");
196 [ # # ]: 0 : if (field == NH_FLD_ETH_DA)
197 : : strcat(string, ".dst");
198 [ # # ]: 0 : else if (field == NH_FLD_ETH_SA)
199 : : strcat(string, ".src");
200 [ # # ]: 0 : else if (field == NH_FLD_ETH_TYPE)
201 : : strcat(string, ".type");
202 : : else
203 : : strcat(string, ".unknown field");
204 : : } else if (prot == NET_PROT_VLAN) {
205 : : strcpy(string, "vlan");
206 [ # # ]: 0 : if (field == NH_FLD_VLAN_TCI)
207 : : strcat(string, ".tci");
208 : : else
209 : : strcat(string, ".unknown field");
210 : : } else if (prot == NET_PROT_IP) {
211 : : strcpy(string, "ip");
212 [ # # ]: 0 : if (field == NH_FLD_IP_SRC)
213 : : strcat(string, ".src");
214 [ # # ]: 0 : else if (field == NH_FLD_IP_DST)
215 : : strcat(string, ".dst");
216 [ # # ]: 0 : else if (field == NH_FLD_IP_PROTO)
217 : : strcat(string, ".proto");
218 : : else
219 : : strcat(string, ".unknown field");
220 : : } else if (prot == NET_PROT_TCP) {
221 : : strcpy(string, "tcp");
222 [ # # ]: 0 : if (field == NH_FLD_TCP_PORT_SRC)
223 : : strcat(string, ".src");
224 [ # # ]: 0 : else if (field == NH_FLD_TCP_PORT_DST)
225 : : strcat(string, ".dst");
226 : : else
227 : : strcat(string, ".unknown field");
228 : : } else if (prot == NET_PROT_UDP) {
229 : : strcpy(string, "udp");
230 [ # # ]: 0 : if (field == NH_FLD_UDP_PORT_SRC)
231 : : strcat(string, ".src");
232 [ # # ]: 0 : else if (field == NH_FLD_UDP_PORT_DST)
233 : : strcat(string, ".dst");
234 : : else
235 : : strcat(string, ".unknown field");
236 : : } else if (prot == NET_PROT_ICMP) {
237 : : strcpy(string, "icmp");
238 [ # # ]: 0 : if (field == NH_FLD_ICMP_TYPE)
239 : : strcat(string, ".type");
240 [ # # ]: 0 : else if (field == NH_FLD_ICMP_CODE)
241 : : strcat(string, ".code");
242 : : else
243 : : strcat(string, ".unknown field");
244 : : } else if (prot == NET_PROT_SCTP) {
245 : : strcpy(string, "sctp");
246 [ # # ]: 0 : if (field == NH_FLD_SCTP_PORT_SRC)
247 : : strcat(string, ".src");
248 [ # # ]: 0 : else if (field == NH_FLD_SCTP_PORT_DST)
249 : : strcat(string, ".dst");
250 : : else
251 : : strcat(string, ".unknown field");
252 : : } else if (prot == NET_PROT_GRE) {
253 : : strcpy(string, "gre");
254 [ # # ]: 0 : if (field == NH_FLD_GRE_TYPE)
255 : : strcat(string, ".type");
256 : : else
257 : : strcat(string, ".unknown field");
258 : : } else if (prot == NET_PROT_GTP) {
259 : 0 : rte_strscpy(string, "gtp", DPAA2_PROT_FIELD_STRING_SIZE);
260 [ # # ]: 0 : if (field == NH_FLD_GTP_TEID)
261 : : strcat(string, ".teid");
262 : : else
263 : : strcat(string, ".unknown field");
264 : : } else if (prot == NET_PROT_IPSEC_ESP) {
265 : 0 : rte_strscpy(string, "esp", DPAA2_PROT_FIELD_STRING_SIZE);
266 [ # # ]: 0 : if (field == NH_FLD_IPSEC_ESP_SPI)
267 : : strcat(string, ".spi");
268 [ # # ]: 0 : else if (field == NH_FLD_IPSEC_ESP_SEQUENCE_NUM)
269 : : strcat(string, ".seq");
270 : : else
271 : : strcat(string, ".unknown field");
272 : : } else {
273 : : sprintf(string, "unknown protocol(%d)", prot);
274 : : }
275 : : }
276 : :
277 : : static inline void
278 : 0 : dpaa2_flow_qos_extracts_log(const struct dpaa2_dev_priv *priv)
279 : : {
280 : : int idx;
281 : : char string[32];
282 : : const struct dpkg_profile_cfg *dpkg =
283 : : &priv->extract.qos_key_extract.dpkg;
284 : : const struct dpkg_extract *extract;
285 : : enum dpkg_extract_type type;
286 : : enum net_prot prot;
287 : : uint32_t field;
288 : :
289 [ # # ]: 0 : if (!dpaa2_flow_control_log)
290 : 0 : return;
291 : :
292 : 0 : DPAA2_FLOW_DUMP("QoS table: %d extracts\r\n",
293 : 0 : dpkg->num_extracts);
294 [ # # ]: 0 : for (idx = 0; idx < dpkg->num_extracts; idx++) {
295 : : extract = &dpkg->extracts[idx];
296 : 0 : type = extract->type;
297 [ # # ]: 0 : if (type == DPKG_EXTRACT_FROM_HDR) {
298 : 0 : prot = extract->extract.from_hdr.prot;
299 : 0 : field = extract->extract.from_hdr.field;
300 : 0 : dpaa2_prot_field_string(prot, field,
301 : : string);
302 [ # # ]: 0 : } else if (type == DPKG_EXTRACT_FROM_DATA) {
303 : 0 : sprintf(string, "raw offset/len: %d/%d",
304 : 0 : extract->extract.from_data.offset,
305 : 0 : extract->extract.from_data.size);
306 [ # # ]: 0 : } else if (type == DPKG_EXTRACT_FROM_PARSE) {
307 : 0 : sprintf(string, "parse offset/len: %d/%d",
308 : 0 : extract->extract.from_parse.offset,
309 : 0 : extract->extract.from_parse.size);
310 : : }
311 : : DPAA2_FLOW_DUMP("%s", string);
312 [ # # ]: 0 : if ((idx + 1) < dpkg->num_extracts)
313 : : DPAA2_FLOW_DUMP(" / ");
314 : : }
315 : : DPAA2_FLOW_DUMP("\r\n");
316 : : }
317 : :
318 : : static inline void
319 : 0 : dpaa2_flow_fs_extracts_log(const struct dpaa2_dev_priv *priv,
320 : : int tc_id)
321 : : {
322 : : int idx;
323 : : char string[32];
324 : : const struct dpkg_profile_cfg *dpkg =
325 : : &priv->extract.tc_key_extract[tc_id].dpkg;
326 : : const struct dpkg_extract *extract;
327 : : enum dpkg_extract_type type;
328 : : enum net_prot prot;
329 : : uint32_t field;
330 : :
331 [ # # ]: 0 : if (!dpaa2_flow_control_log)
332 : 0 : return;
333 : :
334 : 0 : DPAA2_FLOW_DUMP("FS table: %d extracts in TC[%d]\r\n",
335 : 0 : dpkg->num_extracts, tc_id);
336 [ # # ]: 0 : for (idx = 0; idx < dpkg->num_extracts; idx++) {
337 : : extract = &dpkg->extracts[idx];
338 : 0 : type = extract->type;
339 [ # # ]: 0 : if (type == DPKG_EXTRACT_FROM_HDR) {
340 : 0 : prot = extract->extract.from_hdr.prot;
341 : 0 : field = extract->extract.from_hdr.field;
342 : 0 : dpaa2_prot_field_string(prot, field,
343 : : string);
344 [ # # ]: 0 : } else if (type == DPKG_EXTRACT_FROM_DATA) {
345 : 0 : sprintf(string, "raw offset/len: %d/%d",
346 : 0 : extract->extract.from_data.offset,
347 : 0 : extract->extract.from_data.size);
348 [ # # ]: 0 : } else if (type == DPKG_EXTRACT_FROM_PARSE) {
349 : 0 : sprintf(string, "parse offset/len: %d/%d",
350 : 0 : extract->extract.from_parse.offset,
351 : 0 : extract->extract.from_parse.size);
352 : : }
353 : : DPAA2_FLOW_DUMP("%s", string);
354 [ # # ]: 0 : if ((idx + 1) < dpkg->num_extracts)
355 : : DPAA2_FLOW_DUMP(" / ");
356 : : }
357 : : DPAA2_FLOW_DUMP("\r\n");
358 : : }
359 : :
360 : : static inline void
361 : 0 : dpaa2_flow_qos_entry_log(const char *log_info,
362 : : const struct dpaa2_dev_flow *flow, int qos_index)
363 : : {
364 : : int idx;
365 : : uint8_t *key, *mask;
366 : :
367 [ # # ]: 0 : if (!dpaa2_flow_control_log)
368 : : return;
369 : :
370 [ # # ]: 0 : if (qos_index >= 0) {
371 : 0 : DPAA2_FLOW_DUMP("%s QoS entry[%d](size %d/%d) for TC[%d]\r\n",
372 : 0 : log_info, qos_index, flow->qos_rule_size,
373 : 0 : flow->qos_rule.key_size,
374 : 0 : flow->tc_id);
375 : : } else {
376 : 0 : DPAA2_FLOW_DUMP("%s QoS entry(size %d/%d) for TC[%d]\r\n",
377 : 0 : log_info, flow->qos_rule_size,
378 : 0 : flow->qos_rule.key_size,
379 : 0 : flow->tc_id);
380 : : }
381 : :
382 : 0 : key = flow->qos_key_addr;
383 : 0 : mask = flow->qos_mask_addr;
384 : :
385 : : DPAA2_FLOW_DUMP("key:\r\n");
386 [ # # ]: 0 : for (idx = 0; idx < flow->qos_rule_size; idx++)
387 : 0 : DPAA2_FLOW_DUMP("%02x ", key[idx]);
388 : :
389 : : DPAA2_FLOW_DUMP("\r\nmask:\r\n");
390 [ # # ]: 0 : for (idx = 0; idx < flow->qos_rule_size; idx++)
391 : 0 : DPAA2_FLOW_DUMP("%02x ", mask[idx]);
392 : : DPAA2_FLOW_DUMP("\r\n");
393 : : }
394 : :
395 : : static inline void
396 : 0 : dpaa2_flow_fs_entry_log(const char *log_info,
397 : : const struct dpaa2_dev_flow *flow)
398 : : {
399 : : int idx;
400 : : uint8_t *key, *mask;
401 : :
402 [ # # ]: 0 : if (!dpaa2_flow_control_log)
403 : : return;
404 : :
405 : 0 : DPAA2_FLOW_DUMP("%s FS/TC entry[%d](size %d/%d) of TC[%d]\r\n",
406 : 0 : log_info, flow->tc_index,
407 : 0 : flow->fs_rule_size, flow->fs_rule.key_size,
408 : 0 : flow->tc_id);
409 : :
410 : 0 : key = flow->fs_key_addr;
411 : 0 : mask = flow->fs_mask_addr;
412 : :
413 : : DPAA2_FLOW_DUMP("key:\r\n");
414 [ # # ]: 0 : for (idx = 0; idx < flow->fs_rule_size; idx++)
415 : 0 : DPAA2_FLOW_DUMP("%02x ", key[idx]);
416 : :
417 : : DPAA2_FLOW_DUMP("\r\nmask:\r\n");
418 [ # # ]: 0 : for (idx = 0; idx < flow->fs_rule_size; idx++)
419 : 0 : DPAA2_FLOW_DUMP("%02x ", mask[idx]);
420 : : DPAA2_FLOW_DUMP("\r\n");
421 : : }
422 : :
423 : : /** For LX2160A, LS2088A and LS1088A*/
424 : : #define WRIOP_CCSR_BASE 0x8b80000
425 : : #define WRIOP_CCSR_CTLU_OFFSET 0
426 : : #define WRIOP_CCSR_CTLU_PARSER_OFFSET 0
427 : : #define WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET 0
428 : :
429 : : #define WRIOP_INGRESS_PARSER_PHY \
430 : : (WRIOP_CCSR_BASE + WRIOP_CCSR_CTLU_OFFSET + \
431 : : WRIOP_CCSR_CTLU_PARSER_OFFSET + \
432 : : WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET)
433 : :
434 : : struct dpaa2_parser_ccsr {
435 : : uint32_t psr_cfg;
436 : : uint32_t psr_idle;
437 : : uint32_t psr_pclm;
438 : : uint8_t psr_ver_min;
439 : : uint8_t psr_ver_maj;
440 : : uint8_t psr_id1_l;
441 : : uint8_t psr_id1_h;
442 : : uint32_t psr_rev2;
443 : : uint8_t rsv[0x2c];
444 : : uint8_t sp_ins[4032];
445 : : };
446 : :
447 : : int
448 : 0 : dpaa2_soft_parser_loaded(void)
449 : : {
450 : : int fd, i, ret = 0;
451 : : struct dpaa2_parser_ccsr *parser_ccsr = NULL;
452 : :
453 : 0 : dpaa2_flow_control_log = getenv("DPAA2_FLOW_CONTROL_LOG");
454 : :
455 [ # # ]: 0 : if (dpaa2_sp_loaded >= 0)
456 : : return dpaa2_sp_loaded;
457 : :
458 : : fd = open("/dev/mem", O_RDWR | O_SYNC);
459 [ # # ]: 0 : if (fd < 0) {
460 : 0 : DPAA2_PMD_ERR("open \"/dev/mem\" ERROR(%d)", fd);
461 : : ret = fd;
462 : 0 : goto exit;
463 : : }
464 : :
465 : 0 : parser_ccsr = mmap(NULL, sizeof(struct dpaa2_parser_ccsr),
466 : : PROT_READ | PROT_WRITE, MAP_SHARED, fd,
467 : : WRIOP_INGRESS_PARSER_PHY);
468 [ # # ]: 0 : if (!parser_ccsr) {
469 : 0 : DPAA2_PMD_ERR("Map 0x%" PRIx64 "(size=0x%x) failed",
470 : : (uint64_t)WRIOP_INGRESS_PARSER_PHY,
471 : : (uint32_t)sizeof(struct dpaa2_parser_ccsr));
472 : : ret = -ENOBUFS;
473 : 0 : goto exit;
474 : : }
475 : :
476 : 0 : DPAA2_PMD_INFO("Parser ID:0x%02x%02x, Rev:major(%02x), minor(%02x)",
477 : : parser_ccsr->psr_id1_h, parser_ccsr->psr_id1_l,
478 : : parser_ccsr->psr_ver_maj, parser_ccsr->psr_ver_min);
479 : :
480 [ # # ]: 0 : if (dpaa2_flow_control_log) {
481 [ # # ]: 0 : for (i = 0; i < 64; i++) {
482 : 0 : DPAA2_FLOW_DUMP("%02x ",
483 : 0 : parser_ccsr->sp_ins[i]);
484 [ # # ]: 0 : if (!((i + 1) % 16))
485 : : DPAA2_FLOW_DUMP("\r\n");
486 : : }
487 : : }
488 : :
489 [ # # ]: 0 : for (i = 0; i < 16; i++) {
490 [ # # ]: 0 : if (parser_ccsr->sp_ins[i]) {
491 : 0 : dpaa2_sp_loaded = 1;
492 : 0 : break;
493 : : }
494 : : }
495 [ # # ]: 0 : if (dpaa2_sp_loaded < 0)
496 : 0 : dpaa2_sp_loaded = 0;
497 : :
498 : 0 : ret = dpaa2_sp_loaded;
499 : :
500 : 0 : exit:
501 [ # # ]: 0 : if (parser_ccsr)
502 : 0 : munmap(parser_ccsr, sizeof(struct dpaa2_parser_ccsr));
503 [ # # ]: 0 : if (fd >= 0)
504 : 0 : close(fd);
505 : :
506 : : return ret;
507 : : }
508 : :
509 : : static int
510 : 0 : dpaa2_flow_ip_address_extract(enum net_prot prot,
511 : : uint32_t field)
512 : : {
513 [ # # ]: 0 : if (prot == NET_PROT_IPV4 &&
514 : 0 : (field == NH_FLD_IPV4_SRC_IP ||
515 [ # # ]: 0 : field == NH_FLD_IPV4_DST_IP))
516 : : return true;
517 [ # # ]: 0 : else if (prot == NET_PROT_IPV6 &&
518 : 0 : (field == NH_FLD_IPV6_SRC_IP ||
519 [ # # ]: 0 : field == NH_FLD_IPV6_DST_IP))
520 : : return true;
521 [ # # ]: 0 : else if (prot == NET_PROT_IP &&
522 : 0 : (field == NH_FLD_IP_SRC ||
523 [ # # ]: 0 : field == NH_FLD_IP_DST))
524 : 0 : return true;
525 : :
526 : : return false;
527 : : }
528 : :
529 : : static int
530 : : dpaa2_flow_l4_src_port_extract(enum net_prot prot,
531 : : uint32_t field)
532 : : {
533 : 0 : if (prot == NET_PROT_TCP &&
534 [ # # # # ]: 0 : field == NH_FLD_TCP_PORT_SRC)
535 : : return true;
536 [ # # # # : 0 : else if (prot == NET_PROT_UDP &&
# # ]
537 : : field == NH_FLD_UDP_PORT_SRC)
538 : : return true;
539 [ # # # # : 0 : else if (prot == NET_PROT_SCTP &&
# # ]
540 : : field == NH_FLD_SCTP_PORT_SRC)
541 : : return true;
542 : :
543 : : return false;
544 : : }
545 : :
546 : : static int
547 : : dpaa2_flow_l4_dst_port_extract(enum net_prot prot,
548 : : uint32_t field)
549 : : {
550 : 0 : if (prot == NET_PROT_TCP &&
551 [ # # # # : 0 : field == NH_FLD_TCP_PORT_DST)
# # ]
552 : : return true;
553 [ # # # # : 0 : else if (prot == NET_PROT_UDP &&
# # ]
554 : : field == NH_FLD_UDP_PORT_DST)
555 : : return true;
556 [ # # # # : 0 : else if (prot == NET_PROT_SCTP &&
# # ]
557 : : field == NH_FLD_SCTP_PORT_DST)
558 : : return true;
559 : :
560 : : return false;
561 : : }
562 : :
563 : : static int
564 : 0 : dpaa2_flow_add_qos_rule(struct dpaa2_dev_priv *priv,
565 : : struct dpaa2_dev_flow *flow)
566 : : {
567 : : uint16_t qos_index;
568 : : int ret;
569 : 0 : struct fsl_mc_io *dpni = priv->hw;
570 : :
571 [ # # ]: 0 : if (priv->num_rx_tc <= 1 &&
572 [ # # ]: 0 : flow->action_type != RTE_FLOW_ACTION_TYPE_RSS) {
573 : 0 : DPAA2_PMD_WARN("No QoS Table for FS");
574 : 0 : return -EINVAL;
575 : : }
576 : :
577 : : /* QoS entry added is only effective for multiple TCs.*/
578 : 0 : qos_index = flow->tc_id * priv->fs_entries + flow->tc_index;
579 [ # # ]: 0 : if (qos_index >= priv->qos_entries) {
580 : 0 : DPAA2_PMD_ERR("QoS table full(%d >= %d)",
581 : : qos_index, priv->qos_entries);
582 : 0 : return -EINVAL;
583 : : }
584 : :
585 : 0 : dpaa2_flow_qos_entry_log("Start add", flow, qos_index);
586 : :
587 : 0 : ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
588 : 0 : priv->token, &flow->qos_rule,
589 : 0 : flow->tc_id, qos_index,
590 : : 0, 0);
591 [ # # ]: 0 : if (ret < 0) {
592 : 0 : DPAA2_PMD_ERR("Add entry(%d) to table(%d) failed",
593 : : qos_index, flow->tc_id);
594 : 0 : return ret;
595 : : }
596 : :
597 : : return 0;
598 : : }
599 : :
600 : : static int
601 : 0 : dpaa2_flow_add_fs_rule(struct dpaa2_dev_priv *priv,
602 : : struct dpaa2_dev_flow *flow)
603 : : {
604 : : int ret;
605 : 0 : struct fsl_mc_io *dpni = priv->hw;
606 : :
607 [ # # ]: 0 : if (flow->tc_index >= priv->fs_entries) {
608 : 0 : DPAA2_PMD_ERR("FS table full(%d >= %d)",
609 : : flow->tc_index, priv->fs_entries);
610 : 0 : return -EINVAL;
611 : : }
612 : :
613 : 0 : dpaa2_flow_fs_entry_log("Start add", flow);
614 : :
615 : 0 : ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
616 : 0 : priv->token, flow->tc_id,
617 : 0 : flow->tc_index, &flow->fs_rule,
618 : 0 : &flow->fs_action_cfg);
619 [ # # ]: 0 : if (ret < 0) {
620 : 0 : DPAA2_PMD_ERR("Add rule(%d) to FS table(%d) failed",
621 : : flow->tc_index, flow->tc_id);
622 : 0 : return ret;
623 : : }
624 : :
625 : : return 0;
626 : : }
627 : :
628 : : static int
629 : 0 : dpaa2_flow_rule_insert_hole(struct dpaa2_dev_flow *flow,
630 : : int offset, int size,
631 : : enum dpaa2_flow_dist_type dist_type)
632 : : {
633 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
634 [ # # ]: 0 : if (offset < flow->qos_rule_size) {
635 : 0 : memmove(flow->qos_key_addr + offset + size,
636 : 0 : flow->qos_key_addr + offset,
637 : 0 : flow->qos_rule_size - offset);
638 : 0 : memset(flow->qos_key_addr + offset,
639 : : 0, size);
640 : :
641 : 0 : memmove(flow->qos_mask_addr + offset + size,
642 : 0 : flow->qos_mask_addr + offset,
643 : 0 : flow->qos_rule_size - offset);
644 : 0 : memset(flow->qos_mask_addr + offset,
645 : : 0, size);
646 : 0 : flow->qos_rule_size += size;
647 : : } else {
648 : 0 : flow->qos_rule_size = offset + size;
649 : : }
650 : : }
651 : :
652 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
653 [ # # ]: 0 : if (offset < flow->fs_rule_size) {
654 : 0 : memmove(flow->fs_key_addr + offset + size,
655 : 0 : flow->fs_key_addr + offset,
656 : 0 : flow->fs_rule_size - offset);
657 : 0 : memset(flow->fs_key_addr + offset,
658 : : 0, size);
659 : :
660 : 0 : memmove(flow->fs_mask_addr + offset + size,
661 : 0 : flow->fs_mask_addr + offset,
662 : 0 : flow->fs_rule_size - offset);
663 : 0 : memset(flow->fs_mask_addr + offset,
664 : : 0, size);
665 : 0 : flow->fs_rule_size += size;
666 : : } else {
667 : 0 : flow->fs_rule_size = offset + size;
668 : : }
669 : : }
670 : :
671 : 0 : return 0;
672 : : }
673 : :
674 : : static int
675 : 0 : dpaa2_flow_rule_add_all(struct dpaa2_dev_priv *priv,
676 : : enum dpaa2_flow_dist_type dist_type,
677 : : uint16_t entry_size, uint8_t tc_id)
678 : : {
679 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
680 : : int ret;
681 : :
682 [ # # ]: 0 : while (curr) {
683 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
684 [ # # ]: 0 : if (priv->num_rx_tc > 1 ||
685 [ # # ]: 0 : curr->action_type ==
686 : : RTE_FLOW_ACTION_TYPE_RSS) {
687 : 0 : curr->qos_rule.key_size = entry_size;
688 : 0 : ret = dpaa2_flow_add_qos_rule(priv, curr);
689 [ # # ]: 0 : if (ret)
690 : 0 : return ret;
691 : : }
692 : : }
693 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE &&
694 [ # # ]: 0 : curr->tc_id == tc_id) {
695 : 0 : curr->fs_rule.key_size = entry_size;
696 : 0 : ret = dpaa2_flow_add_fs_rule(priv, curr);
697 [ # # ]: 0 : if (ret)
698 : 0 : return ret;
699 : : }
700 : 0 : curr = LIST_NEXT(curr, next);
701 : : }
702 : :
703 : : return 0;
704 : : }
705 : :
706 : : static int
707 : 0 : dpaa2_flow_qos_rule_insert_hole(struct dpaa2_dev_priv *priv,
708 : : int offset, int size)
709 : : {
710 : : struct dpaa2_dev_flow *curr;
711 : : int ret;
712 : :
713 : 0 : curr = priv->curr;
714 [ # # ]: 0 : if (!curr) {
715 : 0 : DPAA2_PMD_ERR("Current qos flow insert hole failed.");
716 : 0 : return -EINVAL;
717 : : } else {
718 : 0 : ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
719 : : DPAA2_FLOW_QOS_TYPE);
720 [ # # ]: 0 : if (ret)
721 : : return ret;
722 : : }
723 : :
724 : 0 : curr = LIST_FIRST(&priv->flows);
725 [ # # ]: 0 : while (curr) {
726 : 0 : ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
727 : : DPAA2_FLOW_QOS_TYPE);
728 [ # # ]: 0 : if (ret)
729 : 0 : return ret;
730 : 0 : curr = LIST_NEXT(curr, next);
731 : : }
732 : :
733 : : return 0;
734 : : }
735 : :
736 : : static int
737 : 0 : dpaa2_flow_fs_rule_insert_hole(struct dpaa2_dev_priv *priv,
738 : : int offset, int size, int tc_id)
739 : : {
740 : : struct dpaa2_dev_flow *curr;
741 : : int ret;
742 : :
743 : 0 : curr = priv->curr;
744 [ # # # # ]: 0 : if (!curr || curr->tc_id != tc_id) {
745 : 0 : DPAA2_PMD_ERR("Current flow insert hole failed.");
746 : 0 : return -EINVAL;
747 : : } else {
748 : 0 : ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
749 : : DPAA2_FLOW_FS_TYPE);
750 [ # # ]: 0 : if (ret)
751 : : return ret;
752 : : }
753 : :
754 : 0 : curr = LIST_FIRST(&priv->flows);
755 : :
756 [ # # ]: 0 : while (curr) {
757 [ # # ]: 0 : if (curr->tc_id != tc_id) {
758 : 0 : curr = LIST_NEXT(curr, next);
759 : 0 : continue;
760 : : }
761 : 0 : ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
762 : : DPAA2_FLOW_FS_TYPE);
763 [ # # ]: 0 : if (ret)
764 : 0 : return ret;
765 : 0 : curr = LIST_NEXT(curr, next);
766 : : }
767 : :
768 : : return 0;
769 : : }
770 : :
771 : : static int
772 : 0 : dpaa2_flow_faf_advance(struct dpaa2_dev_priv *priv,
773 : : int faf_byte, enum dpaa2_flow_dist_type dist_type, int tc_id,
774 : : int *insert_offset)
775 : : {
776 : : int offset, ret;
777 : : struct dpaa2_key_profile *key_profile;
778 : : int num, pos;
779 : :
780 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
781 : 0 : key_profile = &priv->extract.qos_key_extract.key_profile;
782 : : else
783 : 0 : key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
784 : :
785 : 0 : num = key_profile->num;
786 : :
787 [ # # ]: 0 : if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
788 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
789 : 0 : return -EINVAL;
790 : : }
791 : :
792 [ # # ]: 0 : if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
793 : 0 : offset = key_profile->ip_addr_extract_off;
794 : 0 : pos = key_profile->ip_addr_extract_pos;
795 : 0 : key_profile->ip_addr_extract_pos++;
796 : 0 : key_profile->ip_addr_extract_off++;
797 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
798 : 0 : ret = dpaa2_flow_qos_rule_insert_hole(priv,
799 : : offset, 1);
800 : : } else {
801 : 0 : ret = dpaa2_flow_fs_rule_insert_hole(priv,
802 : : offset, 1, tc_id);
803 : : }
804 [ # # ]: 0 : if (ret)
805 : : return ret;
806 : : } else {
807 : : pos = num;
808 : : }
809 : :
810 [ # # ]: 0 : if (pos > 0) {
811 : 0 : key_profile->key_offset[pos] =
812 : 0 : key_profile->key_offset[pos - 1] +
813 : 0 : key_profile->key_size[pos - 1];
814 : : } else {
815 : 0 : key_profile->key_offset[pos] = 0;
816 : : }
817 : :
818 : 0 : key_profile->key_size[pos] = 1;
819 : 0 : key_profile->prot_field[pos].type = DPAA2_FAF_KEY;
820 : 0 : key_profile->prot_field[pos].key_field = faf_byte;
821 : 0 : key_profile->num++;
822 : :
823 [ # # ]: 0 : if (insert_offset)
824 : 0 : *insert_offset = key_profile->key_offset[pos];
825 : :
826 : 0 : key_profile->key_max_size++;
827 : :
828 : 0 : return pos;
829 : : }
830 : :
831 : : static int
832 : 0 : dpaa2_flow_pr_advance(struct dpaa2_dev_priv *priv,
833 : : uint32_t pr_offset, uint32_t pr_size,
834 : : enum dpaa2_flow_dist_type dist_type, int tc_id,
835 : : int *insert_offset)
836 : : {
837 : : int offset, ret;
838 : : struct dpaa2_key_profile *key_profile;
839 : : int num, pos;
840 : :
841 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
842 : 0 : key_profile = &priv->extract.qos_key_extract.key_profile;
843 : : else
844 : 0 : key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
845 : :
846 : 0 : num = key_profile->num;
847 : :
848 [ # # ]: 0 : if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
849 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
850 : 0 : return -EINVAL;
851 : : }
852 : :
853 [ # # ]: 0 : if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
854 : 0 : offset = key_profile->ip_addr_extract_off;
855 : 0 : pos = key_profile->ip_addr_extract_pos;
856 : 0 : key_profile->ip_addr_extract_pos++;
857 : 0 : key_profile->ip_addr_extract_off += pr_size;
858 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
859 : 0 : ret = dpaa2_flow_qos_rule_insert_hole(priv,
860 : : offset, pr_size);
861 : : } else {
862 : 0 : ret = dpaa2_flow_fs_rule_insert_hole(priv,
863 : : offset, pr_size, tc_id);
864 : : }
865 [ # # ]: 0 : if (ret)
866 : : return ret;
867 : : } else {
868 : : pos = num;
869 : : }
870 : :
871 [ # # ]: 0 : if (pos > 0) {
872 : 0 : key_profile->key_offset[pos] =
873 : 0 : key_profile->key_offset[pos - 1] +
874 : 0 : key_profile->key_size[pos - 1];
875 : : } else {
876 : 0 : key_profile->key_offset[pos] = 0;
877 : : }
878 : :
879 : 0 : key_profile->key_size[pos] = pr_size;
880 : 0 : key_profile->prot_field[pos].type = DPAA2_PR_KEY;
881 : 0 : key_profile->prot_field[pos].key_field =
882 : 0 : (pr_offset << 16) | pr_size;
883 : 0 : key_profile->num++;
884 : :
885 [ # # ]: 0 : if (insert_offset)
886 : 0 : *insert_offset = key_profile->key_offset[pos];
887 : :
888 : 0 : key_profile->key_max_size += pr_size;
889 : :
890 : 0 : return pos;
891 : : }
892 : :
893 : : /* Move IPv4/IPv6 addresses to fill new extract previous IP address.
894 : : * Current MC/WRIOP only support generic IP extract but IP address
895 : : * is not fixed, so we have to put them at end of extracts, otherwise,
896 : : * the extracts position following them can't be identified.
897 : : */
898 : : static int
899 : 0 : dpaa2_flow_key_profile_advance(enum net_prot prot,
900 : : uint32_t field, uint8_t field_size,
901 : : struct dpaa2_dev_priv *priv,
902 : : enum dpaa2_flow_dist_type dist_type, int tc_id,
903 : : int *insert_offset)
904 : : {
905 : : int offset, ret;
906 : : struct dpaa2_key_profile *key_profile;
907 : : int num, pos;
908 : :
909 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field)) {
910 : 0 : DPAA2_PMD_ERR("%s only for none IP address extract",
911 : : __func__);
912 : 0 : return -EINVAL;
913 : : }
914 : :
915 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
916 : 0 : key_profile = &priv->extract.qos_key_extract.key_profile;
917 : : else
918 : 0 : key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
919 : :
920 : 0 : num = key_profile->num;
921 : :
922 [ # # ]: 0 : if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
923 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
924 : 0 : return -EINVAL;
925 : : }
926 : :
927 [ # # ]: 0 : if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
928 : 0 : offset = key_profile->ip_addr_extract_off;
929 : 0 : pos = key_profile->ip_addr_extract_pos;
930 : 0 : key_profile->ip_addr_extract_pos++;
931 : 0 : key_profile->ip_addr_extract_off += field_size;
932 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
933 : 0 : ret = dpaa2_flow_qos_rule_insert_hole(priv,
934 : : offset, field_size);
935 : : } else {
936 : 0 : ret = dpaa2_flow_fs_rule_insert_hole(priv,
937 : : offset, field_size, tc_id);
938 : : }
939 [ # # ]: 0 : if (ret)
940 : : return ret;
941 : : } else {
942 : : pos = num;
943 : : }
944 : :
945 [ # # ]: 0 : if (pos > 0) {
946 : 0 : key_profile->key_offset[pos] =
947 : 0 : key_profile->key_offset[pos - 1] +
948 : 0 : key_profile->key_size[pos - 1];
949 : : } else {
950 : 0 : key_profile->key_offset[pos] = 0;
951 : : }
952 : :
953 : 0 : key_profile->key_size[pos] = field_size;
954 : 0 : key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY;
955 : 0 : key_profile->prot_field[pos].prot = prot;
956 : 0 : key_profile->prot_field[pos].key_field = field;
957 : 0 : key_profile->num++;
958 : :
959 [ # # ]: 0 : if (insert_offset)
960 : 0 : *insert_offset = key_profile->key_offset[pos];
961 : :
962 : : if (dpaa2_flow_l4_src_port_extract(prot, field)) {
963 : 0 : key_profile->l4_src_port_present = 1;
964 : 0 : key_profile->l4_src_port_pos = pos;
965 : 0 : key_profile->l4_src_port_offset =
966 : 0 : key_profile->key_offset[pos];
967 : : } else if (dpaa2_flow_l4_dst_port_extract(prot, field)) {
968 : 0 : key_profile->l4_dst_port_present = 1;
969 : 0 : key_profile->l4_dst_port_pos = pos;
970 : 0 : key_profile->l4_dst_port_offset =
971 : 0 : key_profile->key_offset[pos];
972 : : }
973 : 0 : key_profile->key_max_size += field_size;
974 : :
975 : 0 : return pos;
976 : : }
977 : :
978 : : static int
979 : 0 : dpaa2_flow_faf_add_hdr(int faf_byte,
980 : : struct dpaa2_dev_priv *priv,
981 : : enum dpaa2_flow_dist_type dist_type, int tc_id,
982 : : int *insert_offset)
983 : : {
984 : : int pos, i, offset;
985 : : struct dpaa2_key_extract *key_extract;
986 : : struct dpkg_profile_cfg *dpkg;
987 : : struct dpkg_extract *extracts;
988 : :
989 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
990 : 0 : key_extract = &priv->extract.qos_key_extract;
991 : : else
992 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
993 : :
994 : : dpkg = &key_extract->dpkg;
995 : 0 : extracts = dpkg->extracts;
996 : :
997 [ # # ]: 0 : if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
998 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
999 : 0 : return -EINVAL;
1000 : : }
1001 : :
1002 : 0 : pos = dpaa2_flow_faf_advance(priv,
1003 : : faf_byte, dist_type, tc_id,
1004 : : insert_offset);
1005 [ # # ]: 0 : if (pos < 0)
1006 : : return pos;
1007 : :
1008 [ # # ]: 0 : if (pos != dpkg->num_extracts) {
1009 : : /* Not the last pos, must have IP address extract.*/
1010 [ # # ]: 0 : for (i = dpkg->num_extracts - 1; i >= pos; i--) {
1011 : 0 : extracts[i + 1] = extracts[i];
1012 : : }
1013 : : }
1014 : :
1015 : 0 : offset = DPAA2_FAFE_PSR_OFFSET + faf_byte;
1016 : :
1017 : 0 : extracts[pos].type = DPKG_EXTRACT_FROM_PARSE;
1018 : 0 : extracts[pos].extract.from_parse.offset = offset;
1019 : 0 : extracts[pos].extract.from_parse.size = 1;
1020 : :
1021 : 0 : dpkg->num_extracts++;
1022 : :
1023 : 0 : return 0;
1024 : : }
1025 : :
1026 : : static int
1027 : 0 : dpaa2_flow_pr_add_hdr(uint32_t pr_offset,
1028 : : uint32_t pr_size, struct dpaa2_dev_priv *priv,
1029 : : enum dpaa2_flow_dist_type dist_type, int tc_id,
1030 : : int *insert_offset)
1031 : : {
1032 : : int pos, i;
1033 : : struct dpaa2_key_extract *key_extract;
1034 : : struct dpkg_profile_cfg *dpkg;
1035 : : struct dpkg_extract *extracts;
1036 : :
1037 [ # # ]: 0 : if ((pr_offset + pr_size) > DPAA2_FAPR_SIZE) {
1038 : 0 : DPAA2_PMD_ERR("PR extracts(%d:%d) overflow",
1039 : : pr_offset, pr_size);
1040 : 0 : return -EINVAL;
1041 : : }
1042 : :
1043 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1044 : 0 : key_extract = &priv->extract.qos_key_extract;
1045 : : else
1046 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1047 : :
1048 : : dpkg = &key_extract->dpkg;
1049 : 0 : extracts = dpkg->extracts;
1050 : :
1051 [ # # ]: 0 : if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
1052 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
1053 : 0 : return -EINVAL;
1054 : : }
1055 : :
1056 : 0 : pos = dpaa2_flow_pr_advance(priv,
1057 : : pr_offset, pr_size, dist_type, tc_id,
1058 : : insert_offset);
1059 [ # # ]: 0 : if (pos < 0)
1060 : : return pos;
1061 : :
1062 [ # # ]: 0 : if (pos != dpkg->num_extracts) {
1063 : : /* Not the last pos, must have IP address extract.*/
1064 [ # # ]: 0 : for (i = dpkg->num_extracts - 1; i >= pos; i--) {
1065 : 0 : extracts[i + 1] = extracts[i];
1066 : : }
1067 : : }
1068 : :
1069 : 0 : extracts[pos].type = DPKG_EXTRACT_FROM_PARSE;
1070 : 0 : extracts[pos].extract.from_parse.offset = pr_offset;
1071 : 0 : extracts[pos].extract.from_parse.size = pr_size;
1072 : :
1073 : 0 : dpkg->num_extracts++;
1074 : :
1075 : 0 : return 0;
1076 : : }
1077 : :
1078 : : static int
1079 : 0 : dpaa2_flow_extract_add_hdr(enum net_prot prot,
1080 : : uint32_t field, uint8_t field_size,
1081 : : struct dpaa2_dev_priv *priv,
1082 : : enum dpaa2_flow_dist_type dist_type, int tc_id,
1083 : : int *insert_offset)
1084 : : {
1085 : : int pos, i;
1086 : : struct dpaa2_key_extract *key_extract;
1087 : : struct dpkg_profile_cfg *dpkg;
1088 : : struct dpkg_extract *extracts;
1089 : :
1090 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1091 : 0 : key_extract = &priv->extract.qos_key_extract;
1092 : : else
1093 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1094 : :
1095 : : dpkg = &key_extract->dpkg;
1096 : 0 : extracts = dpkg->extracts;
1097 : :
1098 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field)) {
1099 : 0 : DPAA2_PMD_ERR("%s only for none IP address extract",
1100 : : __func__);
1101 : 0 : return -EINVAL;
1102 : : }
1103 : :
1104 [ # # ]: 0 : if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
1105 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
1106 : 0 : return -EINVAL;
1107 : : }
1108 : :
1109 : 0 : pos = dpaa2_flow_key_profile_advance(prot,
1110 : : field, field_size, priv,
1111 : : dist_type, tc_id,
1112 : : insert_offset);
1113 [ # # ]: 0 : if (pos < 0)
1114 : : return pos;
1115 : :
1116 [ # # ]: 0 : if (pos != dpkg->num_extracts) {
1117 : : /* Not the last pos, must have IP address extract.*/
1118 [ # # ]: 0 : for (i = dpkg->num_extracts - 1; i >= pos; i--) {
1119 : 0 : extracts[i + 1] = extracts[i];
1120 : : }
1121 : : }
1122 : :
1123 : 0 : extracts[pos].type = DPKG_EXTRACT_FROM_HDR;
1124 : 0 : extracts[pos].extract.from_hdr.prot = prot;
1125 : 0 : extracts[pos].extract.from_hdr.type = DPKG_FULL_FIELD;
1126 : 0 : extracts[pos].extract.from_hdr.field = field;
1127 : :
1128 : 0 : dpkg->num_extracts++;
1129 : :
1130 : 0 : return 0;
1131 : : }
1132 : :
1133 : : static int
1134 : 0 : dpaa2_flow_extract_new_raw(struct dpaa2_dev_priv *priv,
1135 : : int offset, int size,
1136 : : enum dpaa2_flow_dist_type dist_type, int tc_id)
1137 : : {
1138 : : struct dpaa2_key_extract *key_extract;
1139 : : struct dpkg_profile_cfg *dpkg;
1140 : : struct dpaa2_key_profile *key_profile;
1141 : : int last_extract_size, index, pos, item_size;
1142 : : uint8_t num_extracts;
1143 : : uint32_t field;
1144 : :
1145 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1146 : 0 : key_extract = &priv->extract.qos_key_extract;
1147 : : else
1148 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1149 : :
1150 : : dpkg = &key_extract->dpkg;
1151 : : key_profile = &key_extract->key_profile;
1152 : :
1153 : 0 : key_profile->raw_region.raw_start = 0;
1154 : 0 : key_profile->raw_region.raw_size = 0;
1155 : :
1156 : 0 : last_extract_size = (size % DPAA2_FLOW_MAX_KEY_SIZE);
1157 : 0 : num_extracts = (size / DPAA2_FLOW_MAX_KEY_SIZE);
1158 [ # # ]: 0 : if (last_extract_size)
1159 : 0 : num_extracts++;
1160 : : else
1161 : : last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE;
1162 : :
1163 [ # # ]: 0 : for (index = 0; index < num_extracts; index++) {
1164 [ # # ]: 0 : if (index == num_extracts - 1)
1165 : : item_size = last_extract_size;
1166 : : else
1167 : : item_size = DPAA2_FLOW_MAX_KEY_SIZE;
1168 : 0 : field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1169 : 0 : field |= item_size;
1170 : :
1171 : 0 : pos = dpaa2_flow_key_profile_advance(NET_PROT_PAYLOAD,
1172 : : field, item_size, priv, dist_type,
1173 : : tc_id, NULL);
1174 [ # # ]: 0 : if (pos < 0)
1175 : 0 : return pos;
1176 : :
1177 : 0 : dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA;
1178 : 0 : dpkg->extracts[pos].extract.from_data.size = item_size;
1179 : 0 : dpkg->extracts[pos].extract.from_data.offset = offset;
1180 : :
1181 [ # # ]: 0 : if (index == 0) {
1182 : 0 : key_profile->raw_extract_pos = pos;
1183 : 0 : key_profile->raw_extract_off =
1184 : 0 : key_profile->key_offset[pos];
1185 : 0 : key_profile->raw_region.raw_start = offset;
1186 : : }
1187 : 0 : key_profile->raw_extract_num++;
1188 : 0 : key_profile->raw_region.raw_size +=
1189 : 0 : key_profile->key_size[pos];
1190 : :
1191 : 0 : offset += item_size;
1192 : 0 : dpkg->num_extracts++;
1193 : : }
1194 : :
1195 : : return 0;
1196 : : }
1197 : :
1198 : : static int
1199 : 0 : dpaa2_flow_extract_add_raw(struct dpaa2_dev_priv *priv,
1200 : : int offset, int size, enum dpaa2_flow_dist_type dist_type,
1201 : : int tc_id, int *recfg)
1202 : : {
1203 : : struct dpaa2_key_profile *key_profile;
1204 : : struct dpaa2_raw_region *raw_region;
1205 : 0 : int end = offset + size, ret = 0, extract_extended, sz_extend;
1206 : : int start_cmp, end_cmp, new_size, index, pos, end_pos;
1207 : : int last_extract_size, item_size, num_extracts, bk_num = 0;
1208 : : struct dpkg_extract extract_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1209 : : uint8_t key_offset_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1210 : : uint8_t key_size_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1211 : : struct key_prot_field prot_field_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1212 : : struct dpaa2_raw_region raw_hole;
1213 : : struct dpkg_profile_cfg *dpkg;
1214 : : enum net_prot prot;
1215 : : uint32_t field;
1216 : :
1217 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
1218 : 0 : key_profile = &priv->extract.qos_key_extract.key_profile;
1219 : 0 : dpkg = &priv->extract.qos_key_extract.dpkg;
1220 : : } else {
1221 : 0 : key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
1222 : 0 : dpkg = &priv->extract.tc_key_extract[tc_id].dpkg;
1223 : : }
1224 : :
1225 : : raw_region = &key_profile->raw_region;
1226 [ # # ]: 0 : if (!raw_region->raw_size) {
1227 : : /* New RAW region*/
1228 : 0 : ret = dpaa2_flow_extract_new_raw(priv, offset, size,
1229 : : dist_type, tc_id);
1230 [ # # ]: 0 : if (!ret && recfg)
1231 : 0 : (*recfg) |= dist_type;
1232 : :
1233 : 0 : return ret;
1234 : : }
1235 : 0 : start_cmp = raw_region->raw_start;
1236 : 0 : end_cmp = raw_region->raw_start + raw_region->raw_size;
1237 : :
1238 [ # # ]: 0 : if (offset >= start_cmp && end <= end_cmp)
1239 : : return 0;
1240 : :
1241 : : sz_extend = 0;
1242 : : new_size = raw_region->raw_size;
1243 [ # # ]: 0 : if (offset < start_cmp) {
1244 : 0 : sz_extend += start_cmp - offset;
1245 : 0 : new_size += (start_cmp - offset);
1246 : : }
1247 [ # # ]: 0 : if (end > end_cmp) {
1248 : 0 : sz_extend += end - end_cmp;
1249 : 0 : new_size += (end - end_cmp);
1250 : : }
1251 : :
1252 : 0 : last_extract_size = (new_size % DPAA2_FLOW_MAX_KEY_SIZE);
1253 : 0 : num_extracts = (new_size / DPAA2_FLOW_MAX_KEY_SIZE);
1254 [ # # ]: 0 : if (last_extract_size)
1255 : 0 : num_extracts++;
1256 : : else
1257 : : last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE;
1258 : :
1259 : 0 : if ((key_profile->num + num_extracts -
1260 [ # # ]: 0 : key_profile->raw_extract_num) >=
1261 : : DPKG_MAX_NUM_OF_EXTRACTS) {
1262 : 0 : DPAA2_PMD_ERR("%s Failed to expand raw extracts",
1263 : : __func__);
1264 : 0 : return -EINVAL;
1265 : : }
1266 : :
1267 [ # # ]: 0 : if (offset < start_cmp) {
1268 : 0 : raw_hole.raw_start = key_profile->raw_extract_off;
1269 : 0 : raw_hole.raw_size = start_cmp - offset;
1270 : 0 : raw_region->raw_start = offset;
1271 : 0 : raw_region->raw_size += start_cmp - offset;
1272 : :
1273 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1274 : 0 : ret = dpaa2_flow_qos_rule_insert_hole(priv,
1275 : : raw_hole.raw_start,
1276 : : raw_hole.raw_size);
1277 [ # # ]: 0 : if (ret)
1278 : : return ret;
1279 : : }
1280 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1281 : 0 : ret = dpaa2_flow_fs_rule_insert_hole(priv,
1282 : : raw_hole.raw_start,
1283 : : raw_hole.raw_size, tc_id);
1284 [ # # ]: 0 : if (ret)
1285 : : return ret;
1286 : : }
1287 : : }
1288 : :
1289 [ # # ]: 0 : if (end > end_cmp) {
1290 : : raw_hole.raw_start =
1291 : 0 : key_profile->raw_extract_off +
1292 : 0 : raw_region->raw_size;
1293 : 0 : raw_hole.raw_size = end - end_cmp;
1294 : 0 : raw_region->raw_size += end - end_cmp;
1295 : :
1296 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1297 : 0 : ret = dpaa2_flow_qos_rule_insert_hole(priv,
1298 : : raw_hole.raw_start,
1299 : : raw_hole.raw_size);
1300 [ # # ]: 0 : if (ret)
1301 : : return ret;
1302 : : }
1303 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1304 : 0 : ret = dpaa2_flow_fs_rule_insert_hole(priv,
1305 : : raw_hole.raw_start,
1306 : : raw_hole.raw_size, tc_id);
1307 [ # # ]: 0 : if (ret)
1308 : : return ret;
1309 : : }
1310 : : }
1311 : :
1312 : 0 : end_pos = key_profile->raw_extract_pos +
1313 : 0 : key_profile->raw_extract_num;
1314 [ # # ]: 0 : if (key_profile->num > end_pos) {
1315 : 0 : bk_num = key_profile->num - end_pos;
1316 : 0 : memcpy(extract_bk, &dpkg->extracts[end_pos],
1317 : : bk_num * sizeof(struct dpkg_extract));
1318 : 0 : memcpy(key_offset_bk, &key_profile->key_offset[end_pos],
1319 : : bk_num * sizeof(uint8_t));
1320 : 0 : memcpy(key_size_bk, &key_profile->key_size[end_pos],
1321 : : bk_num * sizeof(uint8_t));
1322 : 0 : memcpy(prot_field_bk, &key_profile->prot_field[end_pos],
1323 : : bk_num * sizeof(struct key_prot_field));
1324 : :
1325 [ # # ]: 0 : for (index = 0; index < bk_num; index++) {
1326 : 0 : key_offset_bk[index] += sz_extend;
1327 : 0 : prot = prot_field_bk[index].prot;
1328 [ # # ]: 0 : field = prot_field_bk[index].key_field;
1329 : : if (dpaa2_flow_l4_src_port_extract(prot,
1330 : : field)) {
1331 : 0 : key_profile->l4_src_port_present = 1;
1332 : 0 : key_profile->l4_src_port_pos = end_pos + index;
1333 : 0 : key_profile->l4_src_port_offset =
1334 : : key_offset_bk[index];
1335 : : } else if (dpaa2_flow_l4_dst_port_extract(prot,
1336 : : field)) {
1337 : 0 : key_profile->l4_dst_port_present = 1;
1338 : 0 : key_profile->l4_dst_port_pos = end_pos + index;
1339 : 0 : key_profile->l4_dst_port_offset =
1340 : : key_offset_bk[index];
1341 : : }
1342 : : }
1343 : : }
1344 : :
1345 : : pos = key_profile->raw_extract_pos;
1346 : :
1347 [ # # ]: 0 : for (index = 0; index < num_extracts; index++) {
1348 [ # # ]: 0 : if (index == num_extracts - 1)
1349 : : item_size = last_extract_size;
1350 : : else
1351 : : item_size = DPAA2_FLOW_MAX_KEY_SIZE;
1352 : 0 : field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1353 : 0 : field |= item_size;
1354 : :
1355 [ # # ]: 0 : if (pos > 0) {
1356 : 0 : key_profile->key_offset[pos] =
1357 : 0 : key_profile->key_offset[pos - 1] +
1358 : 0 : key_profile->key_size[pos - 1];
1359 : : } else {
1360 : 0 : key_profile->key_offset[pos] = 0;
1361 : : }
1362 : 0 : key_profile->key_size[pos] = item_size;
1363 : 0 : key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY;
1364 : 0 : key_profile->prot_field[pos].prot = NET_PROT_PAYLOAD;
1365 : 0 : key_profile->prot_field[pos].key_field = field;
1366 : :
1367 : 0 : dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA;
1368 : 0 : dpkg->extracts[pos].extract.from_data.size = item_size;
1369 : 0 : dpkg->extracts[pos].extract.from_data.offset = offset;
1370 : 0 : offset += item_size;
1371 : 0 : pos++;
1372 : : }
1373 : :
1374 [ # # ]: 0 : if (bk_num) {
1375 : 0 : memcpy(&dpkg->extracts[pos], extract_bk,
1376 : : bk_num * sizeof(struct dpkg_extract));
1377 : 0 : memcpy(&key_profile->key_offset[end_pos],
1378 : : key_offset_bk, bk_num * sizeof(uint8_t));
1379 : 0 : memcpy(&key_profile->key_size[end_pos],
1380 : : key_size_bk, bk_num * sizeof(uint8_t));
1381 : 0 : memcpy(&key_profile->prot_field[end_pos],
1382 : : prot_field_bk, bk_num * sizeof(struct key_prot_field));
1383 : : }
1384 : :
1385 : 0 : extract_extended = num_extracts - key_profile->raw_extract_num;
1386 [ # # ]: 0 : if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
1387 : 0 : key_profile->ip_addr_extract_pos += extract_extended;
1388 : 0 : key_profile->ip_addr_extract_off += sz_extend;
1389 : : }
1390 : 0 : key_profile->raw_extract_num = num_extracts;
1391 : 0 : key_profile->num += extract_extended;
1392 : 0 : key_profile->key_max_size += sz_extend;
1393 : :
1394 : 0 : dpkg->num_extracts += extract_extended;
1395 [ # # ]: 0 : if (!ret && recfg)
1396 : 0 : (*recfg) |= dist_type;
1397 : :
1398 : : return ret;
1399 : : }
1400 : :
1401 : : static inline int
1402 : 0 : dpaa2_flow_extract_search(struct dpaa2_key_profile *key_profile,
1403 : : enum key_prot_type type, enum net_prot prot, uint32_t key_field)
1404 : : {
1405 : : int pos;
1406 : : struct key_prot_field *prot_field;
1407 : :
1408 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, key_field)) {
1409 : 0 : DPAA2_PMD_ERR("%s only for none IP address extract",
1410 : : __func__);
1411 : 0 : return -EINVAL;
1412 : : }
1413 : :
1414 : 0 : prot_field = key_profile->prot_field;
1415 [ # # ]: 0 : for (pos = 0; pos < key_profile->num; pos++) {
1416 [ # # ]: 0 : if (type == DPAA2_NET_PROT_KEY &&
1417 [ # # ]: 0 : prot_field[pos].prot == prot &&
1418 [ # # ]: 0 : prot_field[pos].key_field == key_field &&
1419 [ # # ]: 0 : prot_field[pos].type == type)
1420 : 0 : return pos;
1421 [ # # ]: 0 : else if (type == DPAA2_FAF_KEY &&
1422 [ # # ]: 0 : prot_field[pos].key_field == key_field &&
1423 [ # # ]: 0 : prot_field[pos].type == type)
1424 : 0 : return pos;
1425 [ # # ]: 0 : else if (type == DPAA2_PR_KEY &&
1426 [ # # ]: 0 : prot_field[pos].key_field == key_field &&
1427 [ # # ]: 0 : prot_field[pos].type == type)
1428 : 0 : return pos;
1429 : : }
1430 : :
1431 [ # # ]: 0 : if (type == DPAA2_NET_PROT_KEY &&
1432 : : dpaa2_flow_l4_src_port_extract(prot, key_field)) {
1433 [ # # ]: 0 : if (key_profile->l4_src_port_present)
1434 : 0 : return key_profile->l4_src_port_pos;
1435 [ # # ]: 0 : } else if (type == DPAA2_NET_PROT_KEY &&
1436 : : dpaa2_flow_l4_dst_port_extract(prot, key_field)) {
1437 [ # # ]: 0 : if (key_profile->l4_dst_port_present)
1438 : 0 : return key_profile->l4_dst_port_pos;
1439 : : }
1440 : :
1441 : : return -ENXIO;
1442 : : }
1443 : :
1444 : : static inline int
1445 : : dpaa2_flow_extract_key_offset(struct dpaa2_key_profile *key_profile,
1446 : : enum key_prot_type type, enum net_prot prot, uint32_t key_field)
1447 : : {
1448 : : int i;
1449 : :
1450 : 0 : i = dpaa2_flow_extract_search(key_profile, type, prot, key_field);
1451 [ # # # # : 0 : if (i >= 0)
# # # # #
# ]
1452 : 0 : return key_profile->key_offset[i];
1453 : : else
1454 : : return i;
1455 : : }
1456 : :
1457 : : static int
1458 : 0 : dpaa2_flow_faf_add_rule(struct dpaa2_dev_priv *priv,
1459 : : struct dpaa2_dev_flow *flow,
1460 : : enum dpaa2_rx_faf_offset faf_bit_off,
1461 : : int group,
1462 : : enum dpaa2_flow_dist_type dist_type)
1463 : : {
1464 : : int offset;
1465 : : uint8_t *key_addr;
1466 : : uint8_t *mask_addr;
1467 : : struct dpaa2_key_extract *key_extract;
1468 : : struct dpaa2_key_profile *key_profile;
1469 : 0 : uint8_t faf_byte = faf_bit_off / 8;
1470 : 0 : uint8_t faf_bit_in_byte = faf_bit_off % 8;
1471 : :
1472 : : faf_bit_in_byte = 7 - faf_bit_in_byte;
1473 : :
1474 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1475 : : key_extract = &priv->extract.qos_key_extract;
1476 : 0 : key_profile = &key_extract->key_profile;
1477 : :
1478 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1479 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1480 [ # # ]: 0 : if (offset < 0) {
1481 : 0 : DPAA2_PMD_ERR("%s QoS key extract failed", __func__);
1482 : 0 : return -EINVAL;
1483 : : }
1484 : 0 : key_addr = flow->qos_key_addr + offset;
1485 : 0 : mask_addr = flow->qos_mask_addr + offset;
1486 : :
1487 [ # # ]: 0 : if (!(*key_addr) &&
1488 [ # # ]: 0 : key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT &&
1489 [ # # ]: 0 : offset >= flow->qos_rule_size)
1490 : 0 : flow->qos_rule_size = offset + sizeof(uint8_t);
1491 : :
1492 : 0 : *key_addr |= (1 << faf_bit_in_byte);
1493 : 0 : *mask_addr |= (1 << faf_bit_in_byte);
1494 : : }
1495 : :
1496 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1497 : : key_extract = &priv->extract.tc_key_extract[group];
1498 : 0 : key_profile = &key_extract->key_profile;
1499 : :
1500 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1501 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1502 [ # # ]: 0 : if (offset < 0) {
1503 : 0 : DPAA2_PMD_ERR("%s TC[%d] key extract failed",
1504 : : __func__, group);
1505 : 0 : return -EINVAL;
1506 : : }
1507 : 0 : key_addr = flow->fs_key_addr + offset;
1508 : 0 : mask_addr = flow->fs_mask_addr + offset;
1509 : :
1510 [ # # ]: 0 : if (!(*key_addr) &&
1511 [ # # ]: 0 : key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT &&
1512 [ # # ]: 0 : offset >= flow->fs_rule_size)
1513 : 0 : flow->fs_rule_size = offset + sizeof(uint8_t);
1514 : :
1515 : 0 : *key_addr |= (1 << faf_bit_in_byte);
1516 : 0 : *mask_addr |= (1 << faf_bit_in_byte);
1517 : : }
1518 : :
1519 : : return 0;
1520 : : }
1521 : :
1522 : : static inline int
1523 : 0 : dpaa2_flow_pr_rule_data_set(struct dpaa2_dev_flow *flow,
1524 : : struct dpaa2_key_profile *key_profile,
1525 : : uint32_t pr_offset, uint32_t pr_size,
1526 : : const void *key, const void *mask,
1527 : : enum dpaa2_flow_dist_type dist_type)
1528 : : {
1529 : : int offset;
1530 : 0 : uint32_t pr_field = pr_offset << 16 | pr_size;
1531 : : char offset_info[64], size_info[64], rule_size_info[64];
1532 : :
1533 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1534 : : DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
1535 [ # # ]: 0 : if (offset < 0) {
1536 : 0 : DPAA2_PMD_ERR("PR off(%d)/size(%d) does not exist!",
1537 : : pr_offset, pr_size);
1538 : 0 : return -EINVAL;
1539 : : }
1540 : : sprintf(offset_info, "offset(%d)", offset);
1541 : : sprintf(size_info, "size(%d)", pr_size);
1542 : :
1543 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1544 : 0 : sprintf(rule_size_info, "qos rule size(%d)",
1545 [ # # ]: 0 : flow->qos_rule_size);
1546 [ # # ]: 0 : memcpy((flow->qos_key_addr + offset), key, pr_size);
1547 : 0 : memcpy((flow->qos_mask_addr + offset), mask, pr_size);
1548 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
1549 [ # # ]: 0 : if (offset >= flow->qos_rule_size) {
1550 : 0 : flow->qos_rule_size = offset + pr_size;
1551 [ # # ]: 0 : } else if ((offset + pr_size) > flow->qos_rule_size) {
1552 : 0 : DPAA2_PMD_ERR("%s < %s, but %s + %s > %s",
1553 : : offset_info, rule_size_info,
1554 : : offset_info, size_info,
1555 : : rule_size_info);
1556 : 0 : return -EINVAL;
1557 : : }
1558 : : }
1559 : : }
1560 : :
1561 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1562 : 0 : sprintf(rule_size_info, "fs rule size(%d)",
1563 [ # # ]: 0 : flow->fs_rule_size);
1564 [ # # ]: 0 : memcpy((flow->fs_key_addr + offset), key, pr_size);
1565 : 0 : memcpy((flow->fs_mask_addr + offset), mask, pr_size);
1566 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
1567 [ # # ]: 0 : if (offset >= flow->fs_rule_size) {
1568 : 0 : flow->fs_rule_size = offset + pr_size;
1569 [ # # ]: 0 : } else if ((offset + pr_size) > flow->fs_rule_size) {
1570 : 0 : DPAA2_PMD_ERR("%s < %s, but %s + %s > %s",
1571 : : offset_info, rule_size_info,
1572 : : offset_info, size_info,
1573 : : rule_size_info);
1574 : 0 : return -EINVAL;
1575 : : }
1576 : : }
1577 : : }
1578 : :
1579 : : return 0;
1580 : : }
1581 : :
1582 : : static inline int
1583 : 0 : dpaa2_flow_hdr_rule_data_set(struct dpaa2_dev_flow *flow,
1584 : : struct dpaa2_key_profile *key_profile,
1585 : : enum net_prot prot, uint32_t field, int size,
1586 : : const void *key, const void *mask,
1587 : : enum dpaa2_flow_dist_type dist_type)
1588 : : {
1589 : : int offset;
1590 : : char offset_info[64], size_info[64], rule_size_info[64];
1591 : :
1592 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field)) {
1593 : 0 : DPAA2_PMD_ERR("%s only for none IP address extract",
1594 : : __func__);
1595 : 0 : return -EINVAL;
1596 : : }
1597 : :
1598 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1599 : : DPAA2_NET_PROT_KEY, prot, field);
1600 [ # # ]: 0 : if (offset < 0) {
1601 : 0 : DPAA2_PMD_ERR("P(%d)/F(%d) does not exist!",
1602 : : prot, field);
1603 : 0 : return -EINVAL;
1604 : : }
1605 : : sprintf(offset_info, "offset(%d)", offset);
1606 : : sprintf(size_info, "size(%d)", size);
1607 : :
1608 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1609 : 0 : sprintf(rule_size_info, "qos rule size(%d)",
1610 [ # # ]: 0 : flow->qos_rule_size);
1611 [ # # ]: 0 : memcpy((flow->qos_key_addr + offset), key, size);
1612 : 0 : memcpy((flow->qos_mask_addr + offset), mask, size);
1613 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
1614 [ # # ]: 0 : if (offset >= flow->qos_rule_size) {
1615 : 0 : flow->qos_rule_size = offset + size;
1616 [ # # ]: 0 : } else if ((offset + size) > flow->qos_rule_size) {
1617 : 0 : DPAA2_PMD_ERR("%s: %s < %s, but %s + %s > %s",
1618 : : __func__, offset_info, rule_size_info,
1619 : : offset_info, size_info, rule_size_info);
1620 : 0 : return -EINVAL;
1621 : : }
1622 : : }
1623 : : }
1624 : :
1625 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1626 : 0 : sprintf(rule_size_info, "fs rule size(%d)",
1627 [ # # ]: 0 : flow->fs_rule_size);
1628 [ # # ]: 0 : memcpy((flow->fs_key_addr + offset), key, size);
1629 : 0 : memcpy((flow->fs_mask_addr + offset), mask, size);
1630 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
1631 [ # # ]: 0 : if (offset >= flow->fs_rule_size) {
1632 : 0 : flow->fs_rule_size = offset + size;
1633 [ # # ]: 0 : } else if ((offset + size) > flow->fs_rule_size) {
1634 : 0 : DPAA2_PMD_ERR("%s: %s < %s, but %s + %s > %s",
1635 : : __func__, offset_info, rule_size_info,
1636 : : offset_info, size_info, rule_size_info);
1637 : 0 : return -EINVAL;
1638 : : }
1639 : : }
1640 : : }
1641 : :
1642 : : return 0;
1643 : : }
1644 : :
1645 : : static inline int
1646 : 0 : dpaa2_flow_raw_rule_data_set(struct dpaa2_dev_flow *flow,
1647 : : struct dpaa2_key_profile *key_profile,
1648 : : uint32_t extract_offset, int size,
1649 : : const void *key, const void *mask,
1650 : : enum dpaa2_flow_dist_type dist_type)
1651 : : {
1652 : 0 : int extract_size = size > DPAA2_FLOW_MAX_KEY_SIZE ?
1653 : : DPAA2_FLOW_MAX_KEY_SIZE : size;
1654 : : int offset, field;
1655 : : char offset_info[64], size_info[64], rule_size_info[64];
1656 : :
1657 : 0 : field = extract_offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1658 : : field |= extract_size;
1659 : 0 : offset = dpaa2_flow_extract_key_offset(key_profile,
1660 : : DPAA2_NET_PROT_KEY, NET_PROT_PAYLOAD, field);
1661 [ # # ]: 0 : if (offset < 0) {
1662 : 0 : DPAA2_PMD_ERR("offset(%d)/size(%d) raw extract failed",
1663 : : extract_offset, size);
1664 : 0 : return -EINVAL;
1665 : : }
1666 : : sprintf(offset_info, "offset(%d)", offset);
1667 : : sprintf(size_info, "size(%d)", size);
1668 : :
1669 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1670 : 0 : sprintf(rule_size_info, "qos rule size(%d)",
1671 [ # # ]: 0 : flow->qos_rule_size);
1672 [ # # ]: 0 : memcpy((flow->qos_key_addr + offset), key, size);
1673 : 0 : memcpy((flow->qos_mask_addr + offset), mask, size);
1674 [ # # ]: 0 : if (offset >= flow->qos_rule_size) {
1675 : 0 : flow->qos_rule_size = offset + size;
1676 [ # # ]: 0 : } else if ((offset + size) > flow->qos_rule_size) {
1677 : 0 : DPAA2_PMD_ERR("%s: %s < %s, but %s + %s > %s",
1678 : : __func__, offset_info, rule_size_info,
1679 : : offset_info, size_info, rule_size_info);
1680 : 0 : return -EINVAL;
1681 : : }
1682 : : }
1683 : :
1684 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1685 : 0 : sprintf(rule_size_info, "fs rule size(%d)",
1686 [ # # ]: 0 : flow->fs_rule_size);
1687 [ # # ]: 0 : memcpy((flow->fs_key_addr + offset), key, size);
1688 : 0 : memcpy((flow->fs_mask_addr + offset), mask, size);
1689 [ # # ]: 0 : if (offset >= flow->fs_rule_size) {
1690 : 0 : flow->fs_rule_size = offset + size;
1691 [ # # ]: 0 : } else if ((offset + size) > flow->fs_rule_size) {
1692 : 0 : DPAA2_PMD_ERR("%s: %s < %s, but %s + %s > %s",
1693 : : __func__, offset_info, rule_size_info,
1694 : : offset_info, size_info, rule_size_info);
1695 : 0 : return -EINVAL;
1696 : : }
1697 : : }
1698 : :
1699 : : return 0;
1700 : : }
1701 : :
1702 : : static int
1703 : 0 : dpaa2_flow_extract_support(const uint8_t *mask_src,
1704 : : enum rte_flow_item_type type)
1705 : : {
1706 : : char mask[64];
1707 : : int i, size = 0;
1708 : : const char *mask_support = 0;
1709 : :
1710 [ # # # # : 0 : switch (type) {
# # # # #
# # # # #
# ]
1711 : : case RTE_FLOW_ITEM_TYPE_ETH:
1712 : : mask_support = (const char *)&dpaa2_flow_item_eth_mask;
1713 : : size = sizeof(struct rte_flow_item_eth);
1714 : : break;
1715 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
1716 : : mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
1717 : : size = sizeof(struct rte_flow_item_vlan);
1718 : 0 : break;
1719 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
1720 : : mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
1721 : : size = sizeof(struct rte_flow_item_ipv4);
1722 : 0 : break;
1723 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
1724 : : mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
1725 : : size = sizeof(struct rte_flow_item_ipv6);
1726 : 0 : break;
1727 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP:
1728 : : mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
1729 : : size = sizeof(struct rte_flow_item_icmp);
1730 : 0 : break;
1731 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
1732 : : mask_support = (const char *)&dpaa2_flow_item_udp_mask;
1733 : : size = sizeof(struct rte_flow_item_udp);
1734 : 0 : break;
1735 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
1736 : : mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
1737 : : size = sizeof(struct rte_flow_item_tcp);
1738 : 0 : break;
1739 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
1740 : : mask_support = (const char *)&dpaa2_flow_item_esp_mask;
1741 : : size = sizeof(struct rte_flow_item_esp);
1742 : 0 : break;
1743 : 0 : case RTE_FLOW_ITEM_TYPE_AH:
1744 : : mask_support = (const char *)&dpaa2_flow_item_ah_mask;
1745 : : size = sizeof(struct rte_flow_item_ah);
1746 : 0 : break;
1747 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
1748 : : mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
1749 : : size = sizeof(struct rte_flow_item_sctp);
1750 : 0 : break;
1751 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
1752 : : mask_support = (const char *)&dpaa2_flow_item_gre_mask;
1753 : : size = sizeof(struct rte_flow_item_gre);
1754 : 0 : break;
1755 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
1756 : : mask_support = (const char *)&dpaa2_flow_item_vxlan_mask;
1757 : : size = sizeof(struct rte_flow_item_vxlan);
1758 : 0 : break;
1759 : 0 : case RTE_FLOW_ITEM_TYPE_ECPRI:
1760 : : mask_support = (const char *)&dpaa2_flow_item_ecpri_mask;
1761 : : size = sizeof(struct rte_flow_item_ecpri);
1762 : 0 : break;
1763 : 0 : case RTE_FLOW_ITEM_TYPE_GTP:
1764 : : mask_support = (const char *)&dpaa2_flow_item_gtp_mask;
1765 : : size = sizeof(struct rte_flow_item_gtp);
1766 : 0 : break;
1767 : : default:
1768 : : return -EINVAL;
1769 : : }
1770 : :
1771 : 0 : memcpy(mask, mask_support, size);
1772 : :
1773 [ # # ]: 0 : for (i = 0; i < size; i++)
1774 : 0 : mask[i] = (mask[i] | mask_src[i]);
1775 : :
1776 [ # # ]: 0 : if (memcmp(mask, mask_support, size))
1777 : 0 : return -ENOTSUP;
1778 : :
1779 : : return 0;
1780 : : }
1781 : :
1782 : : static int
1783 : 0 : dpaa2_flow_identify_by_faf(struct dpaa2_dev_priv *priv,
1784 : : struct dpaa2_dev_flow *flow,
1785 : : enum dpaa2_rx_faf_offset faf_off,
1786 : : enum dpaa2_flow_dist_type dist_type,
1787 : : int group, int *recfg)
1788 : : {
1789 : : int ret, index, local_cfg = 0;
1790 : : struct dpaa2_key_extract *extract;
1791 : : struct dpaa2_key_profile *key_profile;
1792 : 0 : uint8_t faf_byte = faf_off / 8;
1793 : :
1794 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1795 : : extract = &priv->extract.qos_key_extract;
1796 : 0 : key_profile = &extract->key_profile;
1797 : :
1798 : 0 : index = dpaa2_flow_extract_search(key_profile,
1799 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1800 [ # # ]: 0 : if (index < 0) {
1801 : 0 : ret = dpaa2_flow_faf_add_hdr(faf_byte,
1802 : : priv, DPAA2_FLOW_QOS_TYPE, group,
1803 : : NULL);
1804 [ # # ]: 0 : if (ret) {
1805 : 0 : DPAA2_PMD_ERR("QOS faf extract add failed");
1806 : :
1807 : 0 : return -EINVAL;
1808 : : }
1809 : : local_cfg |= DPAA2_FLOW_QOS_TYPE;
1810 : : }
1811 : :
1812 : 0 : ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
1813 : : DPAA2_FLOW_QOS_TYPE);
1814 [ # # ]: 0 : if (ret) {
1815 : 0 : DPAA2_PMD_ERR("QoS faf rule set failed");
1816 : 0 : return -EINVAL;
1817 : : }
1818 : : }
1819 : :
1820 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1821 : : extract = &priv->extract.tc_key_extract[group];
1822 : 0 : key_profile = &extract->key_profile;
1823 : :
1824 : 0 : index = dpaa2_flow_extract_search(key_profile,
1825 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1826 [ # # ]: 0 : if (index < 0) {
1827 : 0 : ret = dpaa2_flow_faf_add_hdr(faf_byte,
1828 : : priv, DPAA2_FLOW_FS_TYPE, group,
1829 : : NULL);
1830 [ # # ]: 0 : if (ret) {
1831 : 0 : DPAA2_PMD_ERR("FS[%d] faf extract add failed",
1832 : : group);
1833 : :
1834 : 0 : return -EINVAL;
1835 : : }
1836 : 0 : local_cfg |= DPAA2_FLOW_FS_TYPE;
1837 : : }
1838 : :
1839 : 0 : ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
1840 : : DPAA2_FLOW_FS_TYPE);
1841 [ # # ]: 0 : if (ret) {
1842 : 0 : DPAA2_PMD_ERR("FS[%d] faf rule set failed",
1843 : : group);
1844 : 0 : return -EINVAL;
1845 : : }
1846 : : }
1847 : :
1848 [ # # ]: 0 : if (recfg)
1849 : 0 : *recfg |= local_cfg;
1850 : :
1851 : : return 0;
1852 : : }
1853 : :
1854 : : static int
1855 : 0 : dpaa2_flow_add_pr_extract_rule(struct dpaa2_dev_flow *flow,
1856 : : uint32_t pr_offset, uint32_t pr_size,
1857 : : const void *key, const void *mask,
1858 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1859 : : enum dpaa2_flow_dist_type dist_type)
1860 : : {
1861 : : int index, ret, local_cfg = 0;
1862 : : struct dpaa2_key_extract *key_extract;
1863 : : struct dpaa2_key_profile *key_profile;
1864 : 0 : uint32_t pr_field = pr_offset << 16 | pr_size;
1865 : :
1866 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1867 : 0 : key_extract = &priv->extract.qos_key_extract;
1868 : : else
1869 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1870 : :
1871 : 0 : key_profile = &key_extract->key_profile;
1872 : :
1873 : 0 : index = dpaa2_flow_extract_search(key_profile,
1874 : : DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
1875 [ # # ]: 0 : if (index < 0) {
1876 : 0 : ret = dpaa2_flow_pr_add_hdr(pr_offset,
1877 : : pr_size, priv,
1878 : : dist_type, tc_id, NULL);
1879 [ # # ]: 0 : if (ret) {
1880 : 0 : DPAA2_PMD_ERR("PR add off(%d)/size(%d) failed",
1881 : : pr_offset, pr_size);
1882 : :
1883 : 0 : return ret;
1884 : : }
1885 : 0 : local_cfg |= dist_type;
1886 : : }
1887 : :
1888 : 0 : ret = dpaa2_flow_pr_rule_data_set(flow, key_profile,
1889 : : pr_offset, pr_size, key, mask, dist_type);
1890 [ # # ]: 0 : if (ret) {
1891 : 0 : DPAA2_PMD_ERR("PR off(%d)/size(%d) rule data set failed",
1892 : : pr_offset, pr_size);
1893 : :
1894 : 0 : return ret;
1895 : : }
1896 : :
1897 [ # # ]: 0 : if (recfg)
1898 : 0 : *recfg |= local_cfg;
1899 : :
1900 : : return 0;
1901 : : }
1902 : :
1903 : : static int
1904 : 0 : dpaa2_flow_add_hdr_extract_rule(struct dpaa2_dev_flow *flow,
1905 : : enum net_prot prot, uint32_t field,
1906 : : const void *key, const void *mask, int size,
1907 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1908 : : enum dpaa2_flow_dist_type dist_type)
1909 : : {
1910 : : int index, ret, local_cfg = 0;
1911 : : struct dpaa2_key_extract *key_extract;
1912 : : struct dpaa2_key_profile *key_profile;
1913 : :
1914 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field))
1915 : : return -EINVAL;
1916 : :
1917 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1918 : 0 : key_extract = &priv->extract.qos_key_extract;
1919 : : else
1920 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1921 : :
1922 : 0 : key_profile = &key_extract->key_profile;
1923 : :
1924 : 0 : index = dpaa2_flow_extract_search(key_profile,
1925 : : DPAA2_NET_PROT_KEY, prot, field);
1926 [ # # ]: 0 : if (index < 0) {
1927 : 0 : ret = dpaa2_flow_extract_add_hdr(prot,
1928 : : field, size, priv,
1929 : : dist_type, tc_id, NULL);
1930 [ # # ]: 0 : if (ret) {
1931 : 0 : DPAA2_PMD_ERR("QoS Extract P(%d)/F(%d) failed",
1932 : : prot, field);
1933 : :
1934 : 0 : return ret;
1935 : : }
1936 : 0 : local_cfg |= dist_type;
1937 : : }
1938 : :
1939 : 0 : ret = dpaa2_flow_hdr_rule_data_set(flow, key_profile,
1940 : : prot, field, size, key, mask, dist_type);
1941 [ # # ]: 0 : if (ret) {
1942 : 0 : DPAA2_PMD_ERR("QoS P(%d)/F(%d) rule data set failed",
1943 : : prot, field);
1944 : :
1945 : 0 : return ret;
1946 : : }
1947 : :
1948 [ # # ]: 0 : if (recfg)
1949 : 0 : *recfg |= local_cfg;
1950 : :
1951 : : return 0;
1952 : : }
1953 : :
1954 : : static int
1955 : 0 : dpaa2_flow_add_ipaddr_extract_rule(struct dpaa2_dev_flow *flow,
1956 : : enum net_prot prot, uint32_t field,
1957 : : const void *key, const void *mask, int size,
1958 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1959 : : enum dpaa2_flow_dist_type dist_type)
1960 : : {
1961 : : int local_cfg = 0, num, ipaddr_extract_len = 0;
1962 : : struct dpaa2_key_extract *key_extract;
1963 : : struct dpaa2_key_profile *key_profile;
1964 : : struct dpkg_profile_cfg *dpkg;
1965 : : uint8_t *key_addr, *mask_addr;
1966 : : union ip_addr_extract_rule *ip_addr_data;
1967 : : union ip_addr_extract_rule *ip_addr_mask;
1968 : : enum net_prot orig_prot;
1969 : : uint32_t orig_field;
1970 : :
1971 [ # # ]: 0 : if (prot != NET_PROT_IPV4 && prot != NET_PROT_IPV6)
1972 : : return -EINVAL;
1973 : :
1974 [ # # # # ]: 0 : if (prot == NET_PROT_IPV4 && field != NH_FLD_IPV4_SRC_IP &&
1975 : : field != NH_FLD_IPV4_DST_IP) {
1976 : : return -EINVAL;
1977 : : }
1978 : :
1979 [ # # # # ]: 0 : if (prot == NET_PROT_IPV6 && field != NH_FLD_IPV6_SRC_IP &&
1980 : : field != NH_FLD_IPV6_DST_IP) {
1981 : : return -EINVAL;
1982 : : }
1983 : :
1984 : : orig_prot = prot;
1985 : : orig_field = field;
1986 : :
1987 : 0 : if (prot == NET_PROT_IPV4 &&
1988 [ # # ]: 0 : field == NH_FLD_IPV4_SRC_IP) {
1989 : : prot = NET_PROT_IP;
1990 : : field = NH_FLD_IP_SRC;
1991 : 0 : } else if (prot == NET_PROT_IPV4 &&
1992 [ # # ]: 0 : field == NH_FLD_IPV4_DST_IP) {
1993 : : prot = NET_PROT_IP;
1994 : : field = NH_FLD_IP_DST;
1995 : 0 : } else if (prot == NET_PROT_IPV6 &&
1996 [ # # ]: 0 : field == NH_FLD_IPV6_SRC_IP) {
1997 : : prot = NET_PROT_IP;
1998 : : field = NH_FLD_IP_SRC;
1999 : 0 : } else if (prot == NET_PROT_IPV6 &&
2000 [ # # ]: 0 : field == NH_FLD_IPV6_DST_IP) {
2001 : : prot = NET_PROT_IP;
2002 : : field = NH_FLD_IP_DST;
2003 : : } else {
2004 : 0 : DPAA2_PMD_ERR("Inval P(%d)/F(%d) to extract ip address",
2005 : : prot, field);
2006 : 0 : return -EINVAL;
2007 : : }
2008 : :
2009 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
2010 : : key_extract = &priv->extract.qos_key_extract;
2011 : 0 : key_profile = &key_extract->key_profile;
2012 : 0 : dpkg = &key_extract->dpkg;
2013 : 0 : num = key_profile->num;
2014 : 0 : key_addr = flow->qos_key_addr;
2015 : 0 : mask_addr = flow->qos_mask_addr;
2016 : : } else {
2017 : : key_extract = &priv->extract.tc_key_extract[tc_id];
2018 : 0 : key_profile = &key_extract->key_profile;
2019 : 0 : dpkg = &key_extract->dpkg;
2020 : 0 : num = key_profile->num;
2021 : 0 : key_addr = flow->fs_key_addr;
2022 : 0 : mask_addr = flow->fs_mask_addr;
2023 : : }
2024 : :
2025 [ # # ]: 0 : if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
2026 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
2027 : 0 : return -EINVAL;
2028 : : }
2029 : :
2030 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
2031 [ # # ]: 0 : if (field == NH_FLD_IP_SRC)
2032 : 0 : key_profile->ip_addr_type = IP_SRC_EXTRACT;
2033 : : else
2034 : 0 : key_profile->ip_addr_type = IP_DST_EXTRACT;
2035 : : ipaddr_extract_len = size;
2036 : :
2037 : 0 : key_profile->ip_addr_extract_pos = num;
2038 [ # # ]: 0 : if (num > 0) {
2039 : 0 : key_profile->ip_addr_extract_off =
2040 : 0 : key_profile->key_offset[num - 1] +
2041 : 0 : key_profile->key_size[num - 1];
2042 : : } else {
2043 : 0 : key_profile->ip_addr_extract_off = 0;
2044 : : }
2045 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
2046 [ # # ]: 0 : } else if (key_profile->ip_addr_type == IP_SRC_EXTRACT) {
2047 [ # # ]: 0 : if (field == NH_FLD_IP_SRC) {
2048 : : ipaddr_extract_len = size;
2049 : 0 : goto rule_configure;
2050 : : }
2051 : 0 : key_profile->ip_addr_type = IP_SRC_DST_EXTRACT;
2052 : 0 : ipaddr_extract_len = size * 2;
2053 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
2054 [ # # ]: 0 : } else if (key_profile->ip_addr_type == IP_DST_EXTRACT) {
2055 [ # # ]: 0 : if (field == NH_FLD_IP_DST) {
2056 : : ipaddr_extract_len = size;
2057 : 0 : goto rule_configure;
2058 : : }
2059 : 0 : key_profile->ip_addr_type = IP_DST_SRC_EXTRACT;
2060 : 0 : ipaddr_extract_len = size * 2;
2061 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
2062 : : }
2063 : 0 : key_profile->num++;
2064 : 0 : key_profile->prot_field[num].type = DPAA2_NET_PROT_KEY;
2065 : :
2066 : 0 : dpkg->extracts[num].extract.from_hdr.prot = prot;
2067 : 0 : dpkg->extracts[num].extract.from_hdr.field = field;
2068 : 0 : dpkg->extracts[num].extract.from_hdr.type = DPKG_FULL_FIELD;
2069 : 0 : dpkg->num_extracts++;
2070 : :
2071 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
2072 : : local_cfg = DPAA2_FLOW_QOS_TYPE;
2073 : : else
2074 : : local_cfg = DPAA2_FLOW_FS_TYPE;
2075 : :
2076 : 0 : rule_configure:
2077 : 0 : key_addr += key_profile->ip_addr_extract_off;
2078 : : ip_addr_data = (union ip_addr_extract_rule *)key_addr;
2079 : 0 : mask_addr += key_profile->ip_addr_extract_off;
2080 : : ip_addr_mask = (union ip_addr_extract_rule *)mask_addr;
2081 : :
2082 [ # # ]: 0 : if (orig_prot == NET_PROT_IPV4 &&
2083 : : orig_field == NH_FLD_IPV4_SRC_IP) {
2084 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
2085 : : key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
2086 : 0 : memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_src,
2087 : : key, size);
2088 : 0 : memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_src,
2089 : : mask, size);
2090 : : } else {
2091 : 0 : memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_src,
2092 : : key, size);
2093 : 0 : memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_src,
2094 : : mask, size);
2095 : : }
2096 : 0 : } else if (orig_prot == NET_PROT_IPV4 &&
2097 [ # # ]: 0 : orig_field == NH_FLD_IPV4_DST_IP) {
2098 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
2099 : : key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
2100 : 0 : memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_dst,
2101 : : key, size);
2102 : 0 : memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_dst,
2103 : : mask, size);
2104 : : } else {
2105 : 0 : memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_dst,
2106 : : key, size);
2107 : 0 : memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_dst,
2108 : : mask, size);
2109 : : }
2110 : 0 : } else if (orig_prot == NET_PROT_IPV6 &&
2111 [ # # ]: 0 : orig_field == NH_FLD_IPV6_SRC_IP) {
2112 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
2113 : : key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
2114 : 0 : memcpy(ip_addr_data->ipv6_sd_addr.ipv6_src,
2115 : : key, size);
2116 : 0 : memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_src,
2117 : : mask, size);
2118 : : } else {
2119 : 0 : memcpy(ip_addr_data->ipv6_ds_addr.ipv6_src,
2120 : : key, size);
2121 : 0 : memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_src,
2122 : : mask, size);
2123 : : }
2124 : 0 : } else if (orig_prot == NET_PROT_IPV6 &&
2125 [ # # ]: 0 : orig_field == NH_FLD_IPV6_DST_IP) {
2126 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
2127 : : key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
2128 : 0 : memcpy(ip_addr_data->ipv6_ds_addr.ipv6_dst,
2129 : : key, size);
2130 : 0 : memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_dst,
2131 : : mask, size);
2132 : : } else {
2133 : 0 : memcpy(ip_addr_data->ipv6_sd_addr.ipv6_dst,
2134 : : key, size);
2135 : 0 : memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_dst,
2136 : : mask, size);
2137 : : }
2138 : : }
2139 : :
2140 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
2141 : 0 : flow->qos_rule_size =
2142 : 0 : key_profile->ip_addr_extract_off + ipaddr_extract_len;
2143 : : } else {
2144 : 0 : flow->fs_rule_size =
2145 : 0 : key_profile->ip_addr_extract_off + ipaddr_extract_len;
2146 : : }
2147 : :
2148 [ # # ]: 0 : if (recfg)
2149 : 0 : *recfg |= local_cfg;
2150 : :
2151 : : return 0;
2152 : : }
2153 : :
2154 : : static int
2155 : 0 : dpaa2_configure_flow_tunnel_eth(struct dpaa2_dev_flow *flow,
2156 : : struct rte_eth_dev *dev,
2157 : : const struct rte_flow_attr *attr,
2158 : : const struct rte_flow_item *pattern,
2159 : : int *device_configured)
2160 : : {
2161 : 0 : int ret, local_cfg = 0;
2162 : : uint32_t group;
2163 : : const struct rte_flow_item_eth *spec, *mask;
2164 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2165 : 0 : const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
2166 : :
2167 : 0 : group = attr->group;
2168 : :
2169 : : /* Parse pattern list to get the matching parameters */
2170 : 0 : spec = pattern->spec;
2171 : 0 : mask = pattern->mask ?
2172 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_eth_mask;
2173 : :
2174 : : /* Get traffic class index and flow id to be configured */
2175 : 0 : flow->tc_id = group;
2176 : 0 : flow->tc_index = attr->priority;
2177 : :
2178 [ # # ]: 0 : if (!spec)
2179 : : return 0;
2180 : :
2181 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2182 : : RTE_FLOW_ITEM_TYPE_ETH);
2183 [ # # ]: 0 : if (ret) {
2184 : 0 : DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
2185 : :
2186 : 0 : return ret;
2187 : : }
2188 : :
2189 [ # # ]: 0 : if (memcmp((const char *)&mask->src,
2190 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2191 : : /*SRC[0:1]*/
2192 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2193 : : DPAA2_VXLAN_IN_SADDR0_OFFSET,
2194 : 0 : 1, &spec->src.addr_bytes[0],
2195 : 0 : &mask->src.addr_bytes[0],
2196 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2197 [ # # ]: 0 : if (ret)
2198 : : return ret;
2199 : : /*SRC[1:2]*/
2200 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2201 : : DPAA2_VXLAN_IN_SADDR1_OFFSET,
2202 : 0 : 2, &spec->src.addr_bytes[1],
2203 : 0 : &mask->src.addr_bytes[1],
2204 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2205 [ # # ]: 0 : if (ret)
2206 : : return ret;
2207 : : /*SRC[3:1]*/
2208 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2209 : : DPAA2_VXLAN_IN_SADDR3_OFFSET,
2210 : 0 : 1, &spec->src.addr_bytes[3],
2211 : 0 : &mask->src.addr_bytes[3],
2212 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2213 [ # # ]: 0 : if (ret)
2214 : : return ret;
2215 : : /*SRC[4:2]*/
2216 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2217 : : DPAA2_VXLAN_IN_SADDR4_OFFSET,
2218 : 0 : 2, &spec->src.addr_bytes[4],
2219 : 0 : &mask->src.addr_bytes[4],
2220 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2221 [ # # ]: 0 : if (ret)
2222 : : return ret;
2223 : :
2224 : : /*SRC[0:1]*/
2225 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2226 : : DPAA2_VXLAN_IN_SADDR0_OFFSET,
2227 : : 1, &spec->src.addr_bytes[0],
2228 : : &mask->src.addr_bytes[0],
2229 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2230 [ # # ]: 0 : if (ret)
2231 : : return ret;
2232 : : /*SRC[1:2]*/
2233 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2234 : : DPAA2_VXLAN_IN_SADDR1_OFFSET,
2235 : : 2, &spec->src.addr_bytes[1],
2236 : : &mask->src.addr_bytes[1],
2237 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2238 [ # # ]: 0 : if (ret)
2239 : : return ret;
2240 : : /*SRC[3:1]*/
2241 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2242 : : DPAA2_VXLAN_IN_SADDR3_OFFSET,
2243 : : 1, &spec->src.addr_bytes[3],
2244 : : &mask->src.addr_bytes[3],
2245 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2246 [ # # ]: 0 : if (ret)
2247 : : return ret;
2248 : : /*SRC[4:2]*/
2249 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2250 : : DPAA2_VXLAN_IN_SADDR4_OFFSET,
2251 : : 2, &spec->src.addr_bytes[4],
2252 : : &mask->src.addr_bytes[4],
2253 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2254 [ # # ]: 0 : if (ret)
2255 : : return ret;
2256 : : }
2257 : :
2258 [ # # ]: 0 : if (memcmp((const char *)&mask->dst,
2259 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2260 : : /*DST[0:1]*/
2261 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2262 : : DPAA2_VXLAN_IN_DADDR0_OFFSET,
2263 : 0 : 1, &spec->dst.addr_bytes[0],
2264 : 0 : &mask->dst.addr_bytes[0],
2265 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2266 [ # # ]: 0 : if (ret)
2267 : : return ret;
2268 : : /*DST[1:1]*/
2269 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2270 : : DPAA2_VXLAN_IN_DADDR1_OFFSET,
2271 : 0 : 1, &spec->dst.addr_bytes[1],
2272 : 0 : &mask->dst.addr_bytes[1],
2273 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2274 [ # # ]: 0 : if (ret)
2275 : : return ret;
2276 : : /*DST[2:3]*/
2277 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2278 : : DPAA2_VXLAN_IN_DADDR2_OFFSET,
2279 : 0 : 3, &spec->dst.addr_bytes[2],
2280 : 0 : &mask->dst.addr_bytes[2],
2281 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2282 [ # # ]: 0 : if (ret)
2283 : : return ret;
2284 : : /*DST[5:1]*/
2285 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2286 : : DPAA2_VXLAN_IN_DADDR5_OFFSET,
2287 : 0 : 1, &spec->dst.addr_bytes[5],
2288 : 0 : &mask->dst.addr_bytes[5],
2289 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2290 [ # # ]: 0 : if (ret)
2291 : : return ret;
2292 : :
2293 : : /*DST[0:1]*/
2294 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2295 : : DPAA2_VXLAN_IN_DADDR0_OFFSET,
2296 : : 1, &spec->dst.addr_bytes[0],
2297 : : &mask->dst.addr_bytes[0],
2298 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2299 [ # # ]: 0 : if (ret)
2300 : : return ret;
2301 : : /*DST[1:1]*/
2302 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2303 : : DPAA2_VXLAN_IN_DADDR1_OFFSET,
2304 : : 1, &spec->dst.addr_bytes[1],
2305 : : &mask->dst.addr_bytes[1],
2306 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2307 [ # # ]: 0 : if (ret)
2308 : : return ret;
2309 : : /*DST[2:3]*/
2310 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2311 : : DPAA2_VXLAN_IN_DADDR2_OFFSET,
2312 : : 3, &spec->dst.addr_bytes[2],
2313 : : &mask->dst.addr_bytes[2],
2314 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2315 [ # # ]: 0 : if (ret)
2316 : : return ret;
2317 : : /*DST[5:1]*/
2318 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2319 : : DPAA2_VXLAN_IN_DADDR5_OFFSET,
2320 : : 1, &spec->dst.addr_bytes[5],
2321 : : &mask->dst.addr_bytes[5],
2322 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2323 [ # # ]: 0 : if (ret)
2324 : : return ret;
2325 : : }
2326 : :
2327 [ # # ]: 0 : if (memcmp((const char *)&mask->type,
2328 : : zero_cmp, sizeof(rte_be16_t))) {
2329 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2330 : : DPAA2_VXLAN_IN_TYPE_OFFSET,
2331 : 0 : sizeof(rte_be16_t), &spec->type, &mask->type,
2332 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2333 [ # # ]: 0 : if (ret)
2334 : : return ret;
2335 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2336 : : DPAA2_VXLAN_IN_TYPE_OFFSET,
2337 : : sizeof(rte_be16_t), &spec->type, &mask->type,
2338 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2339 [ # # ]: 0 : if (ret)
2340 : : return ret;
2341 : : }
2342 : :
2343 : 0 : (*device_configured) |= local_cfg;
2344 : :
2345 : 0 : return 0;
2346 : : }
2347 : :
2348 : : static int
2349 : 0 : dpaa2_configure_flow_eth(struct dpaa2_dev_flow *flow,
2350 : : struct rte_eth_dev *dev,
2351 : : const struct rte_flow_attr *attr,
2352 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2353 : : const struct rte_flow_action actions[] __rte_unused,
2354 : : struct rte_flow_error *error __rte_unused,
2355 : : int *device_configured)
2356 : : {
2357 : 0 : int ret, local_cfg = 0;
2358 : : uint32_t group;
2359 : : const struct rte_flow_item_eth *spec, *mask;
2360 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2361 : 0 : const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
2362 : 0 : const struct rte_flow_item *pattern =
2363 : : &dpaa2_pattern->generic_item;
2364 : :
2365 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2366 : 0 : return dpaa2_configure_flow_tunnel_eth(flow,
2367 : : dev, attr, pattern, device_configured);
2368 : : }
2369 : :
2370 : 0 : group = attr->group;
2371 : :
2372 : : /* Parse pattern list to get the matching parameters */
2373 : 0 : spec = pattern->spec;
2374 : 0 : mask = pattern->mask ?
2375 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_eth_mask;
2376 : :
2377 : : /* Get traffic class index and flow id to be configured */
2378 : 0 : flow->tc_id = group;
2379 : 0 : flow->tc_index = attr->priority;
2380 : :
2381 [ # # ]: 0 : if (!spec) {
2382 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2383 : : FAF_ETH_FRAM, DPAA2_FLOW_QOS_TYPE,
2384 : : group, &local_cfg);
2385 [ # # ]: 0 : if (ret)
2386 : : return ret;
2387 : :
2388 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2389 : : FAF_ETH_FRAM, DPAA2_FLOW_FS_TYPE,
2390 : : group, &local_cfg);
2391 [ # # ]: 0 : if (ret)
2392 : : return ret;
2393 : :
2394 : 0 : (*device_configured) |= local_cfg;
2395 : 0 : return 0;
2396 : : }
2397 : :
2398 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2399 : : RTE_FLOW_ITEM_TYPE_ETH);
2400 [ # # ]: 0 : if (ret) {
2401 : 0 : DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
2402 : :
2403 : 0 : return ret;
2404 : : }
2405 : :
2406 [ # # ]: 0 : if (memcmp((const char *)&mask->src,
2407 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2408 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2409 : 0 : NH_FLD_ETH_SA, &spec->src.addr_bytes,
2410 : 0 : &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
2411 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2412 [ # # ]: 0 : if (ret)
2413 : : return ret;
2414 : :
2415 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2416 : : NH_FLD_ETH_SA, &spec->src.addr_bytes,
2417 : : &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
2418 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2419 [ # # ]: 0 : if (ret)
2420 : : return ret;
2421 : : }
2422 : :
2423 [ # # ]: 0 : if (memcmp((const char *)&mask->dst,
2424 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2425 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2426 : 0 : NH_FLD_ETH_DA, &spec->dst.addr_bytes,
2427 : 0 : &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
2428 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2429 [ # # ]: 0 : if (ret)
2430 : : return ret;
2431 : :
2432 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2433 : : NH_FLD_ETH_DA, &spec->dst.addr_bytes,
2434 : : &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
2435 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2436 [ # # ]: 0 : if (ret)
2437 : : return ret;
2438 : : }
2439 : :
2440 [ # # ]: 0 : if (memcmp((const char *)&mask->type,
2441 : : zero_cmp, sizeof(rte_be16_t))) {
2442 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2443 : 0 : NH_FLD_ETH_TYPE, &spec->type,
2444 : : &mask->type, sizeof(rte_be16_t),
2445 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2446 [ # # ]: 0 : if (ret)
2447 : : return ret;
2448 : :
2449 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2450 : : NH_FLD_ETH_TYPE, &spec->type,
2451 : : &mask->type, sizeof(rte_be16_t),
2452 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2453 [ # # ]: 0 : if (ret)
2454 : : return ret;
2455 : : }
2456 : :
2457 : 0 : (*device_configured) |= local_cfg;
2458 : :
2459 : 0 : return 0;
2460 : : }
2461 : :
2462 : : static int
2463 : 0 : dpaa2_configure_flow_tunnel_vlan(struct dpaa2_dev_flow *flow,
2464 : : struct rte_eth_dev *dev,
2465 : : const struct rte_flow_attr *attr,
2466 : : const struct rte_flow_item *pattern,
2467 : : int *device_configured)
2468 : : {
2469 : 0 : int ret, local_cfg = 0;
2470 : : uint32_t group;
2471 : : const struct rte_flow_item_vlan *spec, *mask;
2472 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2473 : :
2474 : 0 : group = attr->group;
2475 : :
2476 : : /* Parse pattern list to get the matching parameters */
2477 : 0 : spec = pattern->spec;
2478 : 0 : mask = pattern->mask ?
2479 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_vlan_mask;
2480 : :
2481 : : /* Get traffic class index and flow id to be configured */
2482 : 0 : flow->tc_id = group;
2483 : 0 : flow->tc_index = attr->priority;
2484 : :
2485 [ # # ]: 0 : if (!spec) {
2486 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2487 : : FAFE_VXLAN_IN_VLAN_FRAM,
2488 : : DPAA2_FLOW_QOS_TYPE,
2489 : : group, &local_cfg);
2490 [ # # ]: 0 : if (ret)
2491 : : return ret;
2492 : :
2493 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2494 : : FAFE_VXLAN_IN_VLAN_FRAM,
2495 : : DPAA2_FLOW_FS_TYPE,
2496 : : group, &local_cfg);
2497 [ # # ]: 0 : if (ret)
2498 : : return ret;
2499 : :
2500 : 0 : (*device_configured) |= local_cfg;
2501 : 0 : return 0;
2502 : : }
2503 : :
2504 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2505 : : RTE_FLOW_ITEM_TYPE_VLAN);
2506 [ # # ]: 0 : if (ret) {
2507 : 0 : DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
2508 : :
2509 : 0 : return ret;
2510 : : }
2511 : :
2512 [ # # ]: 0 : if (!mask->tci)
2513 : : return 0;
2514 : :
2515 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2516 : : DPAA2_VXLAN_IN_TCI_OFFSET,
2517 : 0 : sizeof(rte_be16_t), &spec->tci, &mask->tci,
2518 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2519 [ # # ]: 0 : if (ret)
2520 : : return ret;
2521 : :
2522 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2523 : : DPAA2_VXLAN_IN_TCI_OFFSET,
2524 : : sizeof(rte_be16_t), &spec->tci, &mask->tci,
2525 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2526 [ # # ]: 0 : if (ret)
2527 : : return ret;
2528 : :
2529 : 0 : (*device_configured) |= local_cfg;
2530 : :
2531 : 0 : return 0;
2532 : : }
2533 : :
2534 : : static int
2535 : 0 : dpaa2_configure_flow_vlan(struct dpaa2_dev_flow *flow,
2536 : : struct rte_eth_dev *dev,
2537 : : const struct rte_flow_attr *attr,
2538 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2539 : : const struct rte_flow_action actions[] __rte_unused,
2540 : : struct rte_flow_error *error __rte_unused,
2541 : : int *device_configured)
2542 : : {
2543 : 0 : int ret, local_cfg = 0;
2544 : : uint32_t group;
2545 : : const struct rte_flow_item_vlan *spec, *mask;
2546 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2547 : 0 : const struct rte_flow_item *pattern =
2548 : : &dpaa2_pattern->generic_item;
2549 : :
2550 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2551 : 0 : return dpaa2_configure_flow_tunnel_vlan(flow,
2552 : : dev, attr, pattern, device_configured);
2553 : : }
2554 : :
2555 : 0 : group = attr->group;
2556 : :
2557 : : /* Parse pattern list to get the matching parameters */
2558 : 0 : spec = pattern->spec;
2559 [ # # ]: 0 : mask = pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask;
2560 : :
2561 : : /* Get traffic class index and flow id to be configured */
2562 : 0 : flow->tc_id = group;
2563 : 0 : flow->tc_index = attr->priority;
2564 : :
2565 [ # # ]: 0 : if (!spec) {
2566 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2567 : : DPAA2_FLOW_QOS_TYPE, group,
2568 : : &local_cfg);
2569 [ # # ]: 0 : if (ret)
2570 : : return ret;
2571 : :
2572 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2573 : : DPAA2_FLOW_FS_TYPE, group,
2574 : : &local_cfg);
2575 [ # # ]: 0 : if (ret)
2576 : : return ret;
2577 : :
2578 : 0 : (*device_configured) |= local_cfg;
2579 : 0 : return 0;
2580 : : }
2581 : :
2582 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2583 : : RTE_FLOW_ITEM_TYPE_VLAN);
2584 [ # # ]: 0 : if (ret) {
2585 : 0 : DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
2586 : 0 : return ret;
2587 : : }
2588 : :
2589 [ # # ]: 0 : if (!mask->tci)
2590 : : return 0;
2591 : :
2592 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
2593 : 0 : NH_FLD_VLAN_TCI, &spec->tci,
2594 : 0 : &mask->tci, sizeof(rte_be16_t),
2595 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2596 [ # # ]: 0 : if (ret)
2597 : : return ret;
2598 : :
2599 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
2600 : : NH_FLD_VLAN_TCI, &spec->tci,
2601 : : &mask->tci, sizeof(rte_be16_t),
2602 : : priv, group, &local_cfg,
2603 : : DPAA2_FLOW_FS_TYPE);
2604 [ # # ]: 0 : if (ret)
2605 : : return ret;
2606 : :
2607 : 0 : (*device_configured) |= local_cfg;
2608 : 0 : return 0;
2609 : : }
2610 : :
2611 : : static int
2612 : 0 : dpaa2_configure_flow_ipv4(struct dpaa2_dev_flow *flow,
2613 : : struct rte_eth_dev *dev,
2614 : : const struct rte_flow_attr *attr,
2615 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2616 : : const struct rte_flow_action actions[] __rte_unused,
2617 : : struct rte_flow_error *error __rte_unused,
2618 : : int *device_configured)
2619 : : {
2620 : 0 : int ret, local_cfg = 0;
2621 : : uint32_t group;
2622 : : const struct rte_flow_item_ipv4 *spec_ipv4 = 0, *mask_ipv4 = 0;
2623 : : const void *key, *mask;
2624 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2625 : : int size;
2626 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2627 : :
2628 : 0 : group = attr->group;
2629 : :
2630 : : /* Parse pattern list to get the matching parameters */
2631 : 0 : spec_ipv4 = pattern->spec;
2632 : 0 : mask_ipv4 = pattern->mask ?
2633 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_ipv4_mask;
2634 : :
2635 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2636 [ # # ]: 0 : if (spec_ipv4) {
2637 : 0 : DPAA2_PMD_ERR("Tunnel-IPv4 distribution not support");
2638 : 0 : return -ENOTSUP;
2639 : : }
2640 : :
2641 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2642 : : FAFE_VXLAN_IN_IPV4_FRAM,
2643 : : DPAA2_FLOW_QOS_TYPE, group,
2644 : : &local_cfg);
2645 [ # # ]: 0 : if (ret)
2646 : : return ret;
2647 : :
2648 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2649 : : FAFE_VXLAN_IN_IPV4_FRAM,
2650 : : DPAA2_FLOW_FS_TYPE, group,
2651 : : &local_cfg);
2652 : 0 : return ret;
2653 : : }
2654 : :
2655 : : /* Get traffic class index and flow id to be configured */
2656 : 0 : flow->tc_id = group;
2657 : 0 : flow->tc_index = attr->priority;
2658 : :
2659 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2660 : : DPAA2_FLOW_QOS_TYPE, group,
2661 : : &local_cfg);
2662 [ # # ]: 0 : if (ret)
2663 : : return ret;
2664 : :
2665 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2666 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2667 [ # # ]: 0 : if (ret)
2668 : : return ret;
2669 : :
2670 [ # # ]: 0 : if (!spec_ipv4) {
2671 : 0 : (*device_configured) |= local_cfg;
2672 : 0 : return 0;
2673 : : }
2674 : :
2675 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
2676 : : RTE_FLOW_ITEM_TYPE_IPV4);
2677 [ # # ]: 0 : if (ret) {
2678 : 0 : DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
2679 : 0 : return ret;
2680 : : }
2681 : :
2682 [ # # ]: 0 : if (mask_ipv4->hdr.src_addr) {
2683 : 0 : key = &spec_ipv4->hdr.src_addr;
2684 : 0 : mask = &mask_ipv4->hdr.src_addr;
2685 : : size = sizeof(rte_be32_t);
2686 : :
2687 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2688 : : NH_FLD_IPV4_SRC_IP,
2689 : : key, mask, size, priv,
2690 : : group, &local_cfg,
2691 : : DPAA2_FLOW_QOS_TYPE);
2692 [ # # ]: 0 : if (ret)
2693 : : return ret;
2694 : :
2695 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2696 : : NH_FLD_IPV4_SRC_IP,
2697 : : key, mask, size, priv,
2698 : : group, &local_cfg,
2699 : : DPAA2_FLOW_FS_TYPE);
2700 [ # # ]: 0 : if (ret)
2701 : : return ret;
2702 : : }
2703 : :
2704 [ # # ]: 0 : if (mask_ipv4->hdr.dst_addr) {
2705 : 0 : key = &spec_ipv4->hdr.dst_addr;
2706 : 0 : mask = &mask_ipv4->hdr.dst_addr;
2707 : : size = sizeof(rte_be32_t);
2708 : :
2709 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2710 : : NH_FLD_IPV4_DST_IP,
2711 : : key, mask, size, priv,
2712 : : group, &local_cfg,
2713 : : DPAA2_FLOW_QOS_TYPE);
2714 [ # # ]: 0 : if (ret)
2715 : : return ret;
2716 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2717 : : NH_FLD_IPV4_DST_IP,
2718 : : key, mask, size, priv,
2719 : : group, &local_cfg,
2720 : : DPAA2_FLOW_FS_TYPE);
2721 [ # # ]: 0 : if (ret)
2722 : : return ret;
2723 : : }
2724 : :
2725 [ # # ]: 0 : if (mask_ipv4->hdr.next_proto_id) {
2726 : 0 : key = &spec_ipv4->hdr.next_proto_id;
2727 : 0 : mask = &mask_ipv4->hdr.next_proto_id;
2728 : : size = sizeof(uint8_t);
2729 : :
2730 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2731 : : NH_FLD_IP_PROTO, key,
2732 : : mask, size, priv, group,
2733 : : &local_cfg,
2734 : : DPAA2_FLOW_QOS_TYPE);
2735 [ # # ]: 0 : if (ret)
2736 : : return ret;
2737 : :
2738 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2739 : : NH_FLD_IP_PROTO, key,
2740 : : mask, size, priv, group,
2741 : : &local_cfg,
2742 : : DPAA2_FLOW_FS_TYPE);
2743 [ # # ]: 0 : if (ret)
2744 : : return ret;
2745 : : }
2746 : :
2747 : 0 : (*device_configured) |= local_cfg;
2748 : 0 : return 0;
2749 : : }
2750 : :
2751 : : static int
2752 : 0 : dpaa2_configure_flow_ipv6(struct dpaa2_dev_flow *flow,
2753 : : struct rte_eth_dev *dev,
2754 : : const struct rte_flow_attr *attr,
2755 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2756 : : const struct rte_flow_action actions[] __rte_unused,
2757 : : struct rte_flow_error *error __rte_unused,
2758 : : int *device_configured)
2759 : : {
2760 : 0 : int ret, local_cfg = 0;
2761 : : uint32_t group;
2762 : : const struct rte_flow_item_ipv6 *spec_ipv6 = 0, *mask_ipv6 = 0;
2763 : : const void *key, *mask;
2764 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2765 : 0 : const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
2766 : : int size;
2767 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2768 : :
2769 : 0 : group = attr->group;
2770 : :
2771 : : /* Parse pattern list to get the matching parameters */
2772 : 0 : spec_ipv6 = pattern->spec;
2773 [ # # ]: 0 : mask_ipv6 = pattern->mask ? pattern->mask : &dpaa2_flow_item_ipv6_mask;
2774 : :
2775 : : /* Get traffic class index and flow id to be configured */
2776 : 0 : flow->tc_id = group;
2777 : 0 : flow->tc_index = attr->priority;
2778 : :
2779 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2780 [ # # ]: 0 : if (spec_ipv6) {
2781 : 0 : DPAA2_PMD_ERR("Tunnel-IPv6 distribution not support");
2782 : 0 : return -ENOTSUP;
2783 : : }
2784 : :
2785 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2786 : : FAFE_VXLAN_IN_IPV6_FRAM,
2787 : : DPAA2_FLOW_QOS_TYPE, group,
2788 : : &local_cfg);
2789 [ # # ]: 0 : if (ret)
2790 : : return ret;
2791 : :
2792 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2793 : : FAFE_VXLAN_IN_IPV6_FRAM,
2794 : : DPAA2_FLOW_FS_TYPE, group,
2795 : : &local_cfg);
2796 : 0 : return ret;
2797 : : }
2798 : :
2799 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2800 : : DPAA2_FLOW_QOS_TYPE, group,
2801 : : &local_cfg);
2802 [ # # ]: 0 : if (ret)
2803 : : return ret;
2804 : :
2805 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2806 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2807 [ # # ]: 0 : if (ret)
2808 : : return ret;
2809 : :
2810 [ # # ]: 0 : if (!spec_ipv6) {
2811 : 0 : (*device_configured) |= local_cfg;
2812 : 0 : return 0;
2813 : : }
2814 : :
2815 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
2816 : : RTE_FLOW_ITEM_TYPE_IPV6);
2817 [ # # ]: 0 : if (ret) {
2818 : 0 : DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
2819 : 0 : return ret;
2820 : : }
2821 : :
2822 [ # # ]: 0 : if (memcmp((const char *)&mask_ipv6->hdr.src_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
2823 : 0 : key = &spec_ipv6->hdr.src_addr;
2824 : : mask = &mask_ipv6->hdr.src_addr;
2825 : : size = NH_FLD_IPV6_ADDR_SIZE;
2826 : :
2827 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2828 : : NH_FLD_IPV6_SRC_IP,
2829 : : key, mask, size, priv,
2830 : : group, &local_cfg,
2831 : : DPAA2_FLOW_QOS_TYPE);
2832 [ # # ]: 0 : if (ret)
2833 : : return ret;
2834 : :
2835 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2836 : : NH_FLD_IPV6_SRC_IP,
2837 : : key, mask, size, priv,
2838 : : group, &local_cfg,
2839 : : DPAA2_FLOW_FS_TYPE);
2840 [ # # ]: 0 : if (ret)
2841 : : return ret;
2842 : : }
2843 : :
2844 [ # # ]: 0 : if (memcmp((const char *)&mask_ipv6->hdr.dst_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
2845 : 0 : key = &spec_ipv6->hdr.dst_addr;
2846 : : mask = &mask_ipv6->hdr.dst_addr;
2847 : : size = NH_FLD_IPV6_ADDR_SIZE;
2848 : :
2849 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2850 : : NH_FLD_IPV6_DST_IP,
2851 : : key, mask, size, priv,
2852 : : group, &local_cfg,
2853 : : DPAA2_FLOW_QOS_TYPE);
2854 [ # # ]: 0 : if (ret)
2855 : : return ret;
2856 : :
2857 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2858 : : NH_FLD_IPV6_DST_IP,
2859 : : key, mask, size, priv,
2860 : : group, &local_cfg,
2861 : : DPAA2_FLOW_FS_TYPE);
2862 [ # # ]: 0 : if (ret)
2863 : : return ret;
2864 : : }
2865 : :
2866 [ # # ]: 0 : if (mask_ipv6->hdr.proto) {
2867 : 0 : key = &spec_ipv6->hdr.proto;
2868 : 0 : mask = &mask_ipv6->hdr.proto;
2869 : : size = sizeof(uint8_t);
2870 : :
2871 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2872 : : NH_FLD_IP_PROTO, key,
2873 : : mask, size, priv, group,
2874 : : &local_cfg,
2875 : : DPAA2_FLOW_QOS_TYPE);
2876 [ # # ]: 0 : if (ret)
2877 : : return ret;
2878 : :
2879 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2880 : : NH_FLD_IP_PROTO, key,
2881 : : mask, size, priv, group,
2882 : : &local_cfg,
2883 : : DPAA2_FLOW_FS_TYPE);
2884 [ # # ]: 0 : if (ret)
2885 : : return ret;
2886 : : }
2887 : :
2888 : 0 : (*device_configured) |= local_cfg;
2889 : 0 : return 0;
2890 : : }
2891 : :
2892 : : static int
2893 : 0 : dpaa2_configure_flow_icmp(struct dpaa2_dev_flow *flow,
2894 : : struct rte_eth_dev *dev,
2895 : : const struct rte_flow_attr *attr,
2896 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2897 : : const struct rte_flow_action actions[] __rte_unused,
2898 : : struct rte_flow_error *error __rte_unused,
2899 : : int *device_configured)
2900 : : {
2901 : 0 : int ret, local_cfg = 0;
2902 : : uint32_t group;
2903 : : const struct rte_flow_item_icmp *spec, *mask;
2904 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2905 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2906 : :
2907 : 0 : group = attr->group;
2908 : :
2909 : : /* Parse pattern list to get the matching parameters */
2910 : 0 : spec = pattern->spec;
2911 : 0 : mask = pattern->mask ?
2912 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_icmp_mask;
2913 : :
2914 : : /* Get traffic class index and flow id to be configured */
2915 : 0 : flow->tc_id = group;
2916 : 0 : flow->tc_index = attr->priority;
2917 : :
2918 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2919 : 0 : DPAA2_PMD_ERR("Tunnel-ICMP distribution not support");
2920 : 0 : return -ENOTSUP;
2921 : : }
2922 : :
2923 [ # # ]: 0 : if (!spec) {
2924 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2925 : : FAF_ICMP_FRAM, DPAA2_FLOW_QOS_TYPE,
2926 : : group, &local_cfg);
2927 [ # # ]: 0 : if (ret)
2928 : : return ret;
2929 : :
2930 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2931 : : FAF_ICMP_FRAM, DPAA2_FLOW_FS_TYPE,
2932 : : group, &local_cfg);
2933 [ # # ]: 0 : if (ret)
2934 : : return ret;
2935 : :
2936 : 0 : (*device_configured) |= local_cfg;
2937 : 0 : return 0;
2938 : : }
2939 : :
2940 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2941 : : RTE_FLOW_ITEM_TYPE_ICMP);
2942 [ # # ]: 0 : if (ret) {
2943 : 0 : DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
2944 : :
2945 : 0 : return ret;
2946 : : }
2947 : :
2948 [ # # ]: 0 : if (mask->hdr.icmp_type) {
2949 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2950 : 0 : NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
2951 : 0 : &mask->hdr.icmp_type, sizeof(uint8_t),
2952 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2953 [ # # ]: 0 : if (ret)
2954 : : return ret;
2955 : :
2956 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2957 : : NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
2958 : : &mask->hdr.icmp_type, sizeof(uint8_t),
2959 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2960 [ # # ]: 0 : if (ret)
2961 : : return ret;
2962 : : }
2963 : :
2964 [ # # ]: 0 : if (mask->hdr.icmp_code) {
2965 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2966 : 0 : NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
2967 : 0 : &mask->hdr.icmp_code, sizeof(uint8_t),
2968 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2969 [ # # ]: 0 : if (ret)
2970 : : return ret;
2971 : :
2972 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2973 : : NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
2974 : : &mask->hdr.icmp_code, sizeof(uint8_t),
2975 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2976 [ # # ]: 0 : if (ret)
2977 : : return ret;
2978 : : }
2979 : :
2980 : 0 : (*device_configured) |= local_cfg;
2981 : :
2982 : 0 : return 0;
2983 : : }
2984 : :
2985 : : static int
2986 : 0 : dpaa2_configure_flow_udp(struct dpaa2_dev_flow *flow,
2987 : : struct rte_eth_dev *dev,
2988 : : const struct rte_flow_attr *attr,
2989 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2990 : : const struct rte_flow_action actions[] __rte_unused,
2991 : : struct rte_flow_error *error __rte_unused,
2992 : : int *device_configured)
2993 : : {
2994 : 0 : int ret, local_cfg = 0;
2995 : : uint32_t group;
2996 : : const struct rte_flow_item_udp *spec, *mask;
2997 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2998 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2999 : :
3000 : 0 : group = attr->group;
3001 : :
3002 : : /* Parse pattern list to get the matching parameters */
3003 : 0 : spec = pattern->spec;
3004 : 0 : mask = pattern->mask ?
3005 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_udp_mask;
3006 : :
3007 : : /* Get traffic class index and flow id to be configured */
3008 : 0 : flow->tc_id = group;
3009 : 0 : flow->tc_index = attr->priority;
3010 : :
3011 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3012 [ # # ]: 0 : if (spec) {
3013 : 0 : DPAA2_PMD_ERR("Tunnel-UDP distribution not support");
3014 : 0 : return -ENOTSUP;
3015 : : }
3016 : :
3017 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3018 : : FAFE_VXLAN_IN_UDP_FRAM,
3019 : : DPAA2_FLOW_QOS_TYPE, group,
3020 : : &local_cfg);
3021 [ # # ]: 0 : if (ret)
3022 : : return ret;
3023 : :
3024 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3025 : : FAFE_VXLAN_IN_UDP_FRAM,
3026 : : DPAA2_FLOW_FS_TYPE, group,
3027 : : &local_cfg);
3028 : 0 : return ret;
3029 : : }
3030 : :
3031 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3032 : : FAF_UDP_FRAM, DPAA2_FLOW_QOS_TYPE,
3033 : : group, &local_cfg);
3034 [ # # ]: 0 : if (ret)
3035 : : return ret;
3036 : :
3037 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3038 : : FAF_UDP_FRAM, DPAA2_FLOW_FS_TYPE,
3039 : : group, &local_cfg);
3040 [ # # ]: 0 : if (ret)
3041 : : return ret;
3042 : :
3043 [ # # ]: 0 : if (!spec) {
3044 : 0 : (*device_configured) |= local_cfg;
3045 : 0 : return 0;
3046 : : }
3047 : :
3048 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3049 : : RTE_FLOW_ITEM_TYPE_UDP);
3050 [ # # ]: 0 : if (ret) {
3051 : 0 : DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
3052 : :
3053 : 0 : return ret;
3054 : : }
3055 : :
3056 [ # # ]: 0 : if (mask->hdr.src_port) {
3057 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3058 : 0 : NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
3059 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
3060 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3061 [ # # ]: 0 : if (ret)
3062 : : return ret;
3063 : :
3064 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3065 : : NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
3066 : : &mask->hdr.src_port, sizeof(rte_be16_t),
3067 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3068 [ # # ]: 0 : if (ret)
3069 : : return ret;
3070 : : }
3071 : :
3072 [ # # ]: 0 : if (mask->hdr.dst_port) {
3073 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3074 : 0 : NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
3075 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3076 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3077 [ # # ]: 0 : if (ret)
3078 : : return ret;
3079 : :
3080 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3081 : : NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
3082 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3083 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3084 [ # # ]: 0 : if (ret)
3085 : : return ret;
3086 : : }
3087 : :
3088 : 0 : (*device_configured) |= local_cfg;
3089 : :
3090 : 0 : return 0;
3091 : : }
3092 : :
3093 : : static int
3094 : 0 : dpaa2_configure_flow_tcp(struct dpaa2_dev_flow *flow,
3095 : : struct rte_eth_dev *dev,
3096 : : const struct rte_flow_attr *attr,
3097 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3098 : : const struct rte_flow_action actions[] __rte_unused,
3099 : : struct rte_flow_error *error __rte_unused,
3100 : : int *device_configured)
3101 : : {
3102 : 0 : int ret, local_cfg = 0;
3103 : : uint32_t group;
3104 : : const struct rte_flow_item_tcp *spec, *mask;
3105 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3106 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3107 : :
3108 : 0 : group = attr->group;
3109 : :
3110 : : /* Parse pattern list to get the matching parameters */
3111 : 0 : spec = pattern->spec;
3112 : 0 : mask = pattern->mask ?
3113 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_tcp_mask;
3114 : :
3115 : : /* Get traffic class index and flow id to be configured */
3116 : 0 : flow->tc_id = group;
3117 : 0 : flow->tc_index = attr->priority;
3118 : :
3119 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3120 [ # # ]: 0 : if (spec) {
3121 : 0 : DPAA2_PMD_ERR("Tunnel-TCP distribution not support");
3122 : 0 : return -ENOTSUP;
3123 : : }
3124 : :
3125 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3126 : : FAFE_VXLAN_IN_TCP_FRAM,
3127 : : DPAA2_FLOW_QOS_TYPE, group,
3128 : : &local_cfg);
3129 [ # # ]: 0 : if (ret)
3130 : : return ret;
3131 : :
3132 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3133 : : FAFE_VXLAN_IN_TCP_FRAM,
3134 : : DPAA2_FLOW_FS_TYPE, group,
3135 : : &local_cfg);
3136 : 0 : return ret;
3137 : : }
3138 : :
3139 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3140 : : FAF_TCP_FRAM, DPAA2_FLOW_QOS_TYPE,
3141 : : group, &local_cfg);
3142 [ # # ]: 0 : if (ret)
3143 : : return ret;
3144 : :
3145 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3146 : : FAF_TCP_FRAM, DPAA2_FLOW_FS_TYPE,
3147 : : group, &local_cfg);
3148 [ # # ]: 0 : if (ret)
3149 : : return ret;
3150 : :
3151 [ # # ]: 0 : if (!spec) {
3152 : 0 : (*device_configured) |= local_cfg;
3153 : 0 : return 0;
3154 : : }
3155 : :
3156 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3157 : : RTE_FLOW_ITEM_TYPE_TCP);
3158 [ # # ]: 0 : if (ret) {
3159 : 0 : DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
3160 : :
3161 : 0 : return ret;
3162 : : }
3163 : :
3164 [ # # ]: 0 : if (mask->hdr.src_port) {
3165 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3166 : 0 : NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
3167 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
3168 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3169 [ # # ]: 0 : if (ret)
3170 : : return ret;
3171 : :
3172 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3173 : : NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
3174 : : &mask->hdr.src_port, sizeof(rte_be16_t),
3175 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3176 [ # # ]: 0 : if (ret)
3177 : : return ret;
3178 : : }
3179 : :
3180 [ # # ]: 0 : if (mask->hdr.dst_port) {
3181 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3182 : 0 : NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
3183 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3184 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3185 [ # # ]: 0 : if (ret)
3186 : : return ret;
3187 : :
3188 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3189 : : NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
3190 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3191 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3192 [ # # ]: 0 : if (ret)
3193 : : return ret;
3194 : : }
3195 : :
3196 : 0 : (*device_configured) |= local_cfg;
3197 : :
3198 : 0 : return 0;
3199 : : }
3200 : :
3201 : : static int
3202 : 0 : dpaa2_configure_flow_esp(struct dpaa2_dev_flow *flow,
3203 : : struct rte_eth_dev *dev,
3204 : : const struct rte_flow_attr *attr,
3205 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3206 : : const struct rte_flow_action actions[] __rte_unused,
3207 : : struct rte_flow_error *error __rte_unused,
3208 : : int *device_configured)
3209 : : {
3210 : 0 : int ret, local_cfg = 0;
3211 : : uint32_t group;
3212 : : const struct rte_flow_item_esp *spec, *mask;
3213 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3214 : : const struct rte_flow_item *pattern =
3215 : : &dpaa2_pattern->generic_item;
3216 : :
3217 : 0 : group = attr->group;
3218 : :
3219 : : /* Parse pattern list to get the matching parameters */
3220 : 0 : spec = pattern->spec;
3221 : 0 : mask = pattern->mask ?
3222 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_esp_mask;
3223 : :
3224 : : /* Get traffic class index and flow id to be configured */
3225 : 0 : flow->tc_id = group;
3226 : 0 : flow->tc_index = attr->priority;
3227 : :
3228 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3229 : 0 : DPAA2_PMD_ERR("Tunnel-ESP distribution not support");
3230 : 0 : return -ENOTSUP;
3231 : : }
3232 : :
3233 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3234 : : FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_QOS_TYPE,
3235 : : group, &local_cfg);
3236 [ # # ]: 0 : if (ret)
3237 : : return ret;
3238 : :
3239 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3240 : : FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_FS_TYPE,
3241 : : group, &local_cfg);
3242 [ # # ]: 0 : if (ret)
3243 : : return ret;
3244 : :
3245 [ # # ]: 0 : if (!spec) {
3246 : 0 : (*device_configured) |= local_cfg;
3247 : 0 : return 0;
3248 : : }
3249 : :
3250 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3251 : : RTE_FLOW_ITEM_TYPE_ESP);
3252 [ # # ]: 0 : if (ret) {
3253 : 0 : DPAA2_PMD_WARN("Extract field(s) of ESP not support.");
3254 : :
3255 : 0 : return ret;
3256 : : }
3257 : :
3258 [ # # ]: 0 : if (mask->hdr.spi) {
3259 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3260 : 0 : NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
3261 : 0 : &mask->hdr.spi, sizeof(rte_be32_t),
3262 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3263 [ # # ]: 0 : if (ret)
3264 : : return ret;
3265 : :
3266 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3267 : : NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
3268 : : &mask->hdr.spi, sizeof(rte_be32_t),
3269 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3270 [ # # ]: 0 : if (ret)
3271 : : return ret;
3272 : : }
3273 : :
3274 [ # # ]: 0 : if (mask->hdr.seq) {
3275 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3276 : 0 : NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
3277 : 0 : &mask->hdr.seq, sizeof(rte_be32_t),
3278 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3279 [ # # ]: 0 : if (ret)
3280 : : return ret;
3281 : :
3282 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3283 : : NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
3284 : : &mask->hdr.seq, sizeof(rte_be32_t),
3285 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3286 [ # # ]: 0 : if (ret)
3287 : : return ret;
3288 : : }
3289 : :
3290 : 0 : (*device_configured) |= local_cfg;
3291 : :
3292 : 0 : return 0;
3293 : : }
3294 : :
3295 : : static int
3296 : 0 : dpaa2_configure_flow_ah(struct dpaa2_dev_flow *flow,
3297 : : struct rte_eth_dev *dev,
3298 : : const struct rte_flow_attr *attr,
3299 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3300 : : const struct rte_flow_action actions[] __rte_unused,
3301 : : struct rte_flow_error *error __rte_unused,
3302 : : int *device_configured)
3303 : : {
3304 : 0 : int ret, local_cfg = 0;
3305 : : uint32_t group;
3306 : : const struct rte_flow_item_ah *spec, *mask;
3307 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3308 : : const struct rte_flow_item *pattern =
3309 : : &dpaa2_pattern->generic_item;
3310 : :
3311 : 0 : group = attr->group;
3312 : :
3313 : : /* Parse pattern list to get the matching parameters */
3314 : 0 : spec = pattern->spec;
3315 : 0 : mask = pattern->mask ?
3316 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_ah_mask;
3317 : :
3318 : : /* Get traffic class index and flow id to be configured */
3319 : 0 : flow->tc_id = group;
3320 : 0 : flow->tc_index = attr->priority;
3321 : :
3322 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3323 : 0 : DPAA2_PMD_ERR("Tunnel-AH distribution not support");
3324 : 0 : return -ENOTSUP;
3325 : : }
3326 : :
3327 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3328 : : FAF_IPSEC_AH_FRAM, DPAA2_FLOW_QOS_TYPE,
3329 : : group, &local_cfg);
3330 [ # # ]: 0 : if (ret)
3331 : : return ret;
3332 : :
3333 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3334 : : FAF_IPSEC_AH_FRAM, DPAA2_FLOW_FS_TYPE,
3335 : : group, &local_cfg);
3336 [ # # ]: 0 : if (ret)
3337 : : return ret;
3338 : :
3339 [ # # ]: 0 : if (!spec) {
3340 : 0 : (*device_configured) |= local_cfg;
3341 : 0 : return 0;
3342 : : }
3343 : :
3344 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3345 : : RTE_FLOW_ITEM_TYPE_AH);
3346 [ # # ]: 0 : if (ret) {
3347 : 0 : DPAA2_PMD_WARN("Extract field(s) of AH not support.");
3348 : :
3349 : 0 : return ret;
3350 : : }
3351 : :
3352 [ # # ]: 0 : if (mask->spi) {
3353 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
3354 : 0 : NH_FLD_IPSEC_AH_SPI, &spec->spi,
3355 : 0 : &mask->spi, sizeof(rte_be32_t),
3356 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3357 [ # # ]: 0 : if (ret)
3358 : : return ret;
3359 : :
3360 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
3361 : : NH_FLD_IPSEC_AH_SPI, &spec->spi,
3362 : : &mask->spi, sizeof(rte_be32_t),
3363 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3364 [ # # ]: 0 : if (ret)
3365 : : return ret;
3366 : : }
3367 : :
3368 [ # # ]: 0 : if (mask->seq_num) {
3369 : 0 : DPAA2_PMD_ERR("AH seq distribution not support");
3370 : 0 : return -ENOTSUP;
3371 : : }
3372 : :
3373 : 0 : (*device_configured) |= local_cfg;
3374 : :
3375 : 0 : return 0;
3376 : : }
3377 : :
3378 : : static int
3379 : 0 : dpaa2_configure_flow_sctp(struct dpaa2_dev_flow *flow,
3380 : : struct rte_eth_dev *dev,
3381 : : const struct rte_flow_attr *attr,
3382 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3383 : : const struct rte_flow_action actions[] __rte_unused,
3384 : : struct rte_flow_error *error __rte_unused,
3385 : : int *device_configured)
3386 : : {
3387 : 0 : int ret, local_cfg = 0;
3388 : : uint32_t group;
3389 : : const struct rte_flow_item_sctp *spec, *mask;
3390 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3391 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3392 : :
3393 : 0 : group = attr->group;
3394 : :
3395 : : /* Parse pattern list to get the matching parameters */
3396 : 0 : spec = pattern->spec;
3397 : 0 : mask = pattern->mask ?
3398 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_sctp_mask;
3399 : :
3400 : : /* Get traffic class index and flow id to be configured */
3401 : 0 : flow->tc_id = group;
3402 : 0 : flow->tc_index = attr->priority;
3403 : :
3404 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3405 : 0 : DPAA2_PMD_ERR("Tunnel-SCTP distribution not support");
3406 : 0 : return -ENOTSUP;
3407 : : }
3408 : :
3409 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3410 : : FAF_SCTP_FRAM, DPAA2_FLOW_QOS_TYPE,
3411 : : group, &local_cfg);
3412 [ # # ]: 0 : if (ret)
3413 : : return ret;
3414 : :
3415 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3416 : : FAF_SCTP_FRAM, DPAA2_FLOW_FS_TYPE,
3417 : : group, &local_cfg);
3418 [ # # ]: 0 : if (ret)
3419 : : return ret;
3420 : :
3421 [ # # ]: 0 : if (!spec) {
3422 : 0 : (*device_configured) |= local_cfg;
3423 : 0 : return 0;
3424 : : }
3425 : :
3426 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3427 : : RTE_FLOW_ITEM_TYPE_SCTP);
3428 [ # # ]: 0 : if (ret) {
3429 : 0 : DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
3430 : :
3431 : 0 : return ret;
3432 : : }
3433 : :
3434 [ # # ]: 0 : if (mask->hdr.src_port) {
3435 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3436 : 0 : NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
3437 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
3438 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3439 [ # # ]: 0 : if (ret)
3440 : : return ret;
3441 : :
3442 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3443 : : NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
3444 : : &mask->hdr.src_port, sizeof(rte_be16_t),
3445 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3446 [ # # ]: 0 : if (ret)
3447 : : return ret;
3448 : : }
3449 : :
3450 [ # # ]: 0 : if (mask->hdr.dst_port) {
3451 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3452 : 0 : NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
3453 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3454 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3455 [ # # ]: 0 : if (ret)
3456 : : return ret;
3457 : :
3458 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3459 : : NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
3460 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3461 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3462 [ # # ]: 0 : if (ret)
3463 : : return ret;
3464 : : }
3465 : :
3466 : 0 : (*device_configured) |= local_cfg;
3467 : :
3468 : 0 : return 0;
3469 : : }
3470 : :
3471 : : static int
3472 : 0 : dpaa2_configure_flow_gre(struct dpaa2_dev_flow *flow,
3473 : : struct rte_eth_dev *dev,
3474 : : const struct rte_flow_attr *attr,
3475 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3476 : : const struct rte_flow_action actions[] __rte_unused,
3477 : : struct rte_flow_error *error __rte_unused,
3478 : : int *device_configured)
3479 : : {
3480 : 0 : int ret, local_cfg = 0;
3481 : : uint32_t group;
3482 : : const struct rte_flow_item_gre *spec, *mask;
3483 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3484 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3485 : :
3486 : 0 : group = attr->group;
3487 : :
3488 : : /* Parse pattern list to get the matching parameters */
3489 : 0 : spec = pattern->spec;
3490 : 0 : mask = pattern->mask ?
3491 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_gre_mask;
3492 : :
3493 : : /* Get traffic class index and flow id to be configured */
3494 : 0 : flow->tc_id = group;
3495 : 0 : flow->tc_index = attr->priority;
3496 : :
3497 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3498 : 0 : DPAA2_PMD_ERR("Tunnel-GRE distribution not support");
3499 : 0 : return -ENOTSUP;
3500 : : }
3501 : :
3502 [ # # ]: 0 : if (!spec) {
3503 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3504 : : FAF_GRE_FRAM, DPAA2_FLOW_QOS_TYPE,
3505 : : group, &local_cfg);
3506 [ # # ]: 0 : if (ret)
3507 : : return ret;
3508 : :
3509 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3510 : : FAF_GRE_FRAM, DPAA2_FLOW_FS_TYPE,
3511 : : group, &local_cfg);
3512 [ # # ]: 0 : if (ret)
3513 : : return ret;
3514 : :
3515 : 0 : (*device_configured) |= local_cfg;
3516 : 0 : return 0;
3517 : : }
3518 : :
3519 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3520 : : RTE_FLOW_ITEM_TYPE_GRE);
3521 [ # # ]: 0 : if (ret) {
3522 : 0 : DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
3523 : :
3524 : 0 : return ret;
3525 : : }
3526 : :
3527 [ # # ]: 0 : if (!mask->protocol)
3528 : : return 0;
3529 : :
3530 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
3531 : 0 : NH_FLD_GRE_TYPE, &spec->protocol,
3532 : 0 : &mask->protocol, sizeof(rte_be16_t),
3533 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3534 [ # # ]: 0 : if (ret)
3535 : : return ret;
3536 : :
3537 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
3538 : : NH_FLD_GRE_TYPE, &spec->protocol,
3539 : : &mask->protocol, sizeof(rte_be16_t),
3540 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3541 [ # # ]: 0 : if (ret)
3542 : : return ret;
3543 : :
3544 : 0 : (*device_configured) |= local_cfg;
3545 : :
3546 : 0 : return 0;
3547 : : }
3548 : :
3549 : : static int
3550 : 0 : dpaa2_configure_flow_vxlan(struct dpaa2_dev_flow *flow,
3551 : : struct rte_eth_dev *dev,
3552 : : const struct rte_flow_attr *attr,
3553 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3554 : : const struct rte_flow_action actions[] __rte_unused,
3555 : : struct rte_flow_error *error __rte_unused,
3556 : : int *device_configured)
3557 : : {
3558 : 0 : int ret, local_cfg = 0;
3559 : : uint32_t group;
3560 : : const struct rte_flow_item_vxlan *spec, *mask;
3561 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3562 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3563 : :
3564 : 0 : group = attr->group;
3565 : :
3566 : : /* Parse pattern list to get the matching parameters */
3567 : 0 : spec = pattern->spec;
3568 : 0 : mask = pattern->mask ?
3569 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_vxlan_mask;
3570 : :
3571 : : /* Get traffic class index and flow id to be configured */
3572 : 0 : flow->tc_id = group;
3573 : 0 : flow->tc_index = attr->priority;
3574 : :
3575 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3576 : 0 : DPAA2_PMD_ERR("Tunnel-VXLAN distribution not support");
3577 : 0 : return -ENOTSUP;
3578 : : }
3579 : :
3580 [ # # ]: 0 : if (!spec) {
3581 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3582 : : FAF_VXLAN_FRAM, DPAA2_FLOW_QOS_TYPE,
3583 : : group, &local_cfg);
3584 [ # # ]: 0 : if (ret)
3585 : : return ret;
3586 : :
3587 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3588 : : FAF_VXLAN_FRAM, DPAA2_FLOW_FS_TYPE,
3589 : : group, &local_cfg);
3590 [ # # ]: 0 : if (ret)
3591 : : return ret;
3592 : :
3593 : 0 : (*device_configured) |= local_cfg;
3594 : 0 : return 0;
3595 : : }
3596 : :
3597 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3598 : : RTE_FLOW_ITEM_TYPE_VXLAN);
3599 [ # # ]: 0 : if (ret) {
3600 : 0 : DPAA2_PMD_WARN("Extract field(s) of VXLAN not support.");
3601 : :
3602 : 0 : return ret;
3603 : : }
3604 : :
3605 [ # # ]: 0 : if (mask->flags) {
3606 [ # # ]: 0 : if (spec->flags != VXLAN_HF_VNI) {
3607 : 0 : DPAA2_PMD_ERR("vxlan flag(0x%02x) must be 0x%02x.",
3608 : : spec->flags, VXLAN_HF_VNI);
3609 : 0 : return -EINVAL;
3610 : : }
3611 [ # # ]: 0 : if (mask->flags != 0xff) {
3612 : 0 : DPAA2_PMD_ERR("Not support to extract vxlan flag.");
3613 : 0 : return -EINVAL;
3614 : : }
3615 : : }
3616 : :
3617 [ # # # # : 0 : if (mask->vni[0] || mask->vni[1] || mask->vni[2]) {
# # ]
3618 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3619 : : DPAA2_VXLAN_VNI_OFFSET,
3620 : 0 : sizeof(mask->vni), spec->vni,
3621 : 0 : mask->vni,
3622 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3623 [ # # ]: 0 : if (ret)
3624 : : return ret;
3625 : :
3626 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3627 : : DPAA2_VXLAN_VNI_OFFSET,
3628 : : sizeof(mask->vni), spec->vni,
3629 : : mask->vni,
3630 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3631 [ # # ]: 0 : if (ret)
3632 : : return ret;
3633 : : }
3634 : :
3635 : 0 : (*device_configured) |= local_cfg;
3636 : :
3637 : 0 : return 0;
3638 : : }
3639 : :
3640 : : static int
3641 : 0 : dpaa2_configure_flow_ecpri(struct dpaa2_dev_flow *flow,
3642 : : struct rte_eth_dev *dev,
3643 : : const struct rte_flow_attr *attr,
3644 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3645 : : const struct rte_flow_action actions[] __rte_unused,
3646 : : struct rte_flow_error *error __rte_unused,
3647 : : int *device_configured)
3648 : : {
3649 : 0 : int ret, local_cfg = 0;
3650 : : uint32_t group;
3651 : : const struct rte_flow_item_ecpri *spec, *mask;
3652 : : struct rte_flow_item_ecpri local_mask;
3653 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3654 : : const struct rte_flow_item *pattern =
3655 : : &dpaa2_pattern->generic_item;
3656 : : uint8_t extract_nb = 0, i;
3657 : : uint64_t rule_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3658 : : uint64_t mask_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3659 : : uint8_t extract_size[DPAA2_ECPRI_MAX_EXTRACT_NB];
3660 : : uint8_t extract_off[DPAA2_ECPRI_MAX_EXTRACT_NB];
3661 : :
3662 : 0 : group = attr->group;
3663 : :
3664 : : /* Parse pattern list to get the matching parameters */
3665 : 0 : spec = pattern->spec;
3666 [ # # ]: 0 : if (pattern->mask) {
3667 : : memcpy(&local_mask, pattern->mask,
3668 : : sizeof(struct rte_flow_item_ecpri));
3669 : 0 : local_mask.hdr.common.u32 =
3670 [ # # ]: 0 : rte_be_to_cpu_32(local_mask.hdr.common.u32);
3671 : : mask = &local_mask;
3672 : : } else {
3673 : : mask = &dpaa2_flow_item_ecpri_mask;
3674 : : }
3675 : :
3676 : : /* Get traffic class index and flow id to be configured */
3677 : 0 : flow->tc_id = group;
3678 : 0 : flow->tc_index = attr->priority;
3679 : :
3680 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3681 : 0 : DPAA2_PMD_ERR("Tunnel-ECPRI distribution not support");
3682 : 0 : return -ENOTSUP;
3683 : : }
3684 : :
3685 [ # # ]: 0 : if (!spec) {
3686 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3687 : : FAFE_ECPRI_FRAM, DPAA2_FLOW_QOS_TYPE,
3688 : : group, &local_cfg);
3689 [ # # ]: 0 : if (ret)
3690 : : return ret;
3691 : :
3692 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3693 : : FAFE_ECPRI_FRAM, DPAA2_FLOW_FS_TYPE,
3694 : : group, &local_cfg);
3695 [ # # ]: 0 : if (ret)
3696 : : return ret;
3697 : :
3698 : 0 : (*device_configured) |= local_cfg;
3699 : 0 : return 0;
3700 : : }
3701 : :
3702 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3703 : : RTE_FLOW_ITEM_TYPE_ECPRI);
3704 [ # # ]: 0 : if (ret) {
3705 : 0 : DPAA2_PMD_WARN("Extract field(s) of ECPRI not support.");
3706 : :
3707 : 0 : return ret;
3708 : : }
3709 : :
3710 [ # # ]: 0 : if (mask->hdr.common.type != 0xff) {
3711 : 0 : DPAA2_PMD_WARN("ECPRI header type not specified.");
3712 : :
3713 : 0 : return -EINVAL;
3714 : : }
3715 : :
3716 [ # # ]: 0 : if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_IQ_DATA) {
3717 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_0;
3718 : 0 : mask_data[extract_nb] = 0xff;
3719 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3720 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3721 : : extract_nb++;
3722 : :
3723 [ # # ]: 0 : if (mask->hdr.type0.pc_id) {
3724 : 0 : rule_data[extract_nb] = spec->hdr.type0.pc_id;
3725 : 0 : mask_data[extract_nb] = mask->hdr.type0.pc_id;
3726 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3727 : 0 : extract_off[extract_nb] =
3728 : : DPAA2_ECPRI_MSG_OFFSET +
3729 : : offsetof(struct rte_ecpri_msg_iq_data, pc_id);
3730 : : extract_nb++;
3731 : : }
3732 [ # # ]: 0 : if (mask->hdr.type0.seq_id) {
3733 : 0 : rule_data[extract_nb] = spec->hdr.type0.seq_id;
3734 : 0 : mask_data[extract_nb] = mask->hdr.type0.seq_id;
3735 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3736 : 0 : extract_off[extract_nb] =
3737 : : DPAA2_ECPRI_MSG_OFFSET +
3738 : : offsetof(struct rte_ecpri_msg_iq_data, seq_id);
3739 : 0 : extract_nb++;
3740 : : }
3741 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_BIT_SEQ) {
3742 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_1;
3743 : 0 : mask_data[extract_nb] = 0xff;
3744 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3745 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3746 : : extract_nb++;
3747 : :
3748 [ # # ]: 0 : if (mask->hdr.type1.pc_id) {
3749 : 0 : rule_data[extract_nb] = spec->hdr.type1.pc_id;
3750 : 0 : mask_data[extract_nb] = mask->hdr.type1.pc_id;
3751 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3752 : 0 : extract_off[extract_nb] =
3753 : : DPAA2_ECPRI_MSG_OFFSET +
3754 : : offsetof(struct rte_ecpri_msg_bit_seq, pc_id);
3755 : : extract_nb++;
3756 : : }
3757 [ # # ]: 0 : if (mask->hdr.type1.seq_id) {
3758 : 0 : rule_data[extract_nb] = spec->hdr.type1.seq_id;
3759 : 0 : mask_data[extract_nb] = mask->hdr.type1.seq_id;
3760 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3761 : 0 : extract_off[extract_nb] =
3762 : : DPAA2_ECPRI_MSG_OFFSET +
3763 : : offsetof(struct rte_ecpri_msg_bit_seq, seq_id);
3764 : 0 : extract_nb++;
3765 : : }
3766 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RTC_CTRL) {
3767 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_2;
3768 : 0 : mask_data[extract_nb] = 0xff;
3769 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3770 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3771 : : extract_nb++;
3772 : :
3773 [ # # ]: 0 : if (mask->hdr.type2.rtc_id) {
3774 : 0 : rule_data[extract_nb] = spec->hdr.type2.rtc_id;
3775 : 0 : mask_data[extract_nb] = mask->hdr.type2.rtc_id;
3776 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3777 : 0 : extract_off[extract_nb] =
3778 : : DPAA2_ECPRI_MSG_OFFSET +
3779 : : offsetof(struct rte_ecpri_msg_rtc_ctrl, rtc_id);
3780 : : extract_nb++;
3781 : : }
3782 [ # # ]: 0 : if (mask->hdr.type2.seq_id) {
3783 : 0 : rule_data[extract_nb] = spec->hdr.type2.seq_id;
3784 : 0 : mask_data[extract_nb] = mask->hdr.type2.seq_id;
3785 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3786 : 0 : extract_off[extract_nb] =
3787 : : DPAA2_ECPRI_MSG_OFFSET +
3788 : : offsetof(struct rte_ecpri_msg_rtc_ctrl, seq_id);
3789 : 0 : extract_nb++;
3790 : : }
3791 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_GEN_DATA) {
3792 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_3;
3793 : 0 : mask_data[extract_nb] = 0xff;
3794 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3795 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3796 : : extract_nb++;
3797 : :
3798 [ # # # # ]: 0 : if (mask->hdr.type3.pc_id || mask->hdr.type3.seq_id)
3799 : 0 : DPAA2_PMD_WARN("Extract type3 msg not support.");
3800 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RM_ACC) {
3801 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_4;
3802 : 0 : mask_data[extract_nb] = 0xff;
3803 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3804 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3805 : : extract_nb++;
3806 : :
3807 [ # # ]: 0 : if (mask->hdr.type4.rma_id) {
3808 : 0 : rule_data[extract_nb] = spec->hdr.type4.rma_id;
3809 : 0 : mask_data[extract_nb] = mask->hdr.type4.rma_id;
3810 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3811 : 0 : extract_off[extract_nb] =
3812 : : DPAA2_ECPRI_MSG_OFFSET + 0;
3813 : : /** Compiler not support to take address
3814 : : * of bit-field
3815 : : * offsetof(struct rte_ecpri_msg_rm_access,
3816 : : * rma_id);
3817 : : */
3818 : : extract_nb++;
3819 : : }
3820 [ # # ]: 0 : if (mask->hdr.type4.ele_id) {
3821 : 0 : rule_data[extract_nb] = spec->hdr.type4.ele_id;
3822 : 0 : mask_data[extract_nb] = mask->hdr.type4.ele_id;
3823 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3824 : 0 : extract_off[extract_nb] =
3825 : : DPAA2_ECPRI_MSG_OFFSET + 2;
3826 : : /** Compiler not support to take address
3827 : : * of bit-field
3828 : : * offsetof(struct rte_ecpri_msg_rm_access,
3829 : : * ele_id);
3830 : : */
3831 : 0 : extract_nb++;
3832 : : }
3833 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_DLY_MSR) {
3834 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_5;
3835 : 0 : mask_data[extract_nb] = 0xff;
3836 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3837 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3838 : : extract_nb++;
3839 : :
3840 [ # # ]: 0 : if (mask->hdr.type5.msr_id) {
3841 : 0 : rule_data[extract_nb] = spec->hdr.type5.msr_id;
3842 : 0 : mask_data[extract_nb] = mask->hdr.type5.msr_id;
3843 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3844 : 0 : extract_off[extract_nb] =
3845 : : DPAA2_ECPRI_MSG_OFFSET +
3846 : : offsetof(struct rte_ecpri_msg_delay_measure,
3847 : : msr_id);
3848 : : extract_nb++;
3849 : : }
3850 [ # # ]: 0 : if (mask->hdr.type5.act_type) {
3851 : 0 : rule_data[extract_nb] = spec->hdr.type5.act_type;
3852 : 0 : mask_data[extract_nb] = mask->hdr.type5.act_type;
3853 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3854 : 0 : extract_off[extract_nb] =
3855 : : DPAA2_ECPRI_MSG_OFFSET +
3856 : : offsetof(struct rte_ecpri_msg_delay_measure,
3857 : : act_type);
3858 : 0 : extract_nb++;
3859 : : }
3860 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RMT_RST) {
3861 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_6;
3862 : 0 : mask_data[extract_nb] = 0xff;
3863 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3864 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3865 : : extract_nb++;
3866 : :
3867 [ # # ]: 0 : if (mask->hdr.type6.rst_id) {
3868 : 0 : rule_data[extract_nb] = spec->hdr.type6.rst_id;
3869 : 0 : mask_data[extract_nb] = mask->hdr.type6.rst_id;
3870 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3871 : 0 : extract_off[extract_nb] =
3872 : : DPAA2_ECPRI_MSG_OFFSET +
3873 : : offsetof(struct rte_ecpri_msg_remote_reset,
3874 : : rst_id);
3875 : : extract_nb++;
3876 : : }
3877 [ # # ]: 0 : if (mask->hdr.type6.rst_op) {
3878 : 0 : rule_data[extract_nb] = spec->hdr.type6.rst_op;
3879 : 0 : mask_data[extract_nb] = mask->hdr.type6.rst_op;
3880 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3881 : 0 : extract_off[extract_nb] =
3882 : : DPAA2_ECPRI_MSG_OFFSET +
3883 : : offsetof(struct rte_ecpri_msg_remote_reset,
3884 : : rst_op);
3885 : 0 : extract_nb++;
3886 : : }
3887 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_EVT_IND) {
3888 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_7;
3889 : 0 : mask_data[extract_nb] = 0xff;
3890 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3891 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3892 : : extract_nb++;
3893 : :
3894 [ # # ]: 0 : if (mask->hdr.type7.evt_id) {
3895 : 0 : rule_data[extract_nb] = spec->hdr.type7.evt_id;
3896 : 0 : mask_data[extract_nb] = mask->hdr.type7.evt_id;
3897 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3898 : 0 : extract_off[extract_nb] =
3899 : : DPAA2_ECPRI_MSG_OFFSET +
3900 : : offsetof(struct rte_ecpri_msg_event_ind,
3901 : : evt_id);
3902 : : extract_nb++;
3903 : : }
3904 [ # # ]: 0 : if (mask->hdr.type7.evt_type) {
3905 : 0 : rule_data[extract_nb] = spec->hdr.type7.evt_type;
3906 : 0 : mask_data[extract_nb] = mask->hdr.type7.evt_type;
3907 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3908 : 0 : extract_off[extract_nb] =
3909 : : DPAA2_ECPRI_MSG_OFFSET +
3910 : : offsetof(struct rte_ecpri_msg_event_ind,
3911 : : evt_type);
3912 : 0 : extract_nb++;
3913 : : }
3914 [ # # ]: 0 : if (mask->hdr.type7.seq) {
3915 : 0 : rule_data[extract_nb] = spec->hdr.type7.seq;
3916 : 0 : mask_data[extract_nb] = mask->hdr.type7.seq;
3917 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3918 : 0 : extract_off[extract_nb] =
3919 : : DPAA2_ECPRI_MSG_OFFSET +
3920 : : offsetof(struct rte_ecpri_msg_event_ind,
3921 : : seq);
3922 : 0 : extract_nb++;
3923 : : }
3924 [ # # ]: 0 : if (mask->hdr.type7.number) {
3925 : 0 : rule_data[extract_nb] = spec->hdr.type7.number;
3926 : 0 : mask_data[extract_nb] = mask->hdr.type7.number;
3927 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3928 : 0 : extract_off[extract_nb] =
3929 : : DPAA2_ECPRI_MSG_OFFSET +
3930 : : offsetof(struct rte_ecpri_msg_event_ind,
3931 : : number);
3932 : 0 : extract_nb++;
3933 : : }
3934 : : } else {
3935 : 0 : DPAA2_PMD_ERR("Invalid ecpri header type(%d)",
3936 : : spec->hdr.common.type);
3937 : 0 : return -EINVAL;
3938 : : }
3939 : :
3940 [ # # ]: 0 : for (i = 0; i < extract_nb; i++) {
3941 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3942 : 0 : extract_off[i],
3943 : 0 : extract_size[i], &rule_data[i], &mask_data[i],
3944 : : priv, group,
3945 : : device_configured,
3946 : : DPAA2_FLOW_QOS_TYPE);
3947 [ # # ]: 0 : if (ret)
3948 : 0 : return ret;
3949 : :
3950 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3951 : : extract_off[i],
3952 : : extract_size[i], &rule_data[i], &mask_data[i],
3953 : : priv, group,
3954 : : device_configured,
3955 : : DPAA2_FLOW_FS_TYPE);
3956 [ # # ]: 0 : if (ret)
3957 : 0 : return ret;
3958 : : }
3959 : :
3960 : : (*device_configured) |= local_cfg;
3961 : :
3962 : : return 0;
3963 : : }
3964 : :
3965 : : static int
3966 : 0 : dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow,
3967 : : struct rte_eth_dev *dev,
3968 : : const struct rte_flow_attr *attr,
3969 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3970 : : const struct rte_flow_action actions[] __rte_unused,
3971 : : struct rte_flow_error *error __rte_unused,
3972 : : int *device_configured)
3973 : : {
3974 : 0 : int ret, local_cfg = 0;
3975 : : uint32_t group;
3976 : : const struct rte_flow_item_gtp *spec, *mask;
3977 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3978 : : const struct rte_flow_item *pattern =
3979 : : &dpaa2_pattern->generic_item;
3980 : :
3981 : 0 : group = attr->group;
3982 : :
3983 : : /* Parse pattern list to get the matching parameters */
3984 : 0 : spec = pattern->spec;
3985 : 0 : mask = pattern->mask ?
3986 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_gtp_mask;
3987 : :
3988 : : /* Get traffic class index and flow id to be configured */
3989 : 0 : flow->tc_id = group;
3990 : 0 : flow->tc_index = attr->priority;
3991 : :
3992 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3993 : 0 : DPAA2_PMD_ERR("Tunnel-GTP distribution not support");
3994 : 0 : return -ENOTSUP;
3995 : : }
3996 : :
3997 [ # # ]: 0 : if (!spec) {
3998 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3999 : : FAF_GTP_FRAM, DPAA2_FLOW_QOS_TYPE,
4000 : : group, &local_cfg);
4001 [ # # ]: 0 : if (ret)
4002 : : return ret;
4003 : :
4004 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
4005 : : FAF_GTP_FRAM, DPAA2_FLOW_FS_TYPE,
4006 : : group, &local_cfg);
4007 [ # # ]: 0 : if (ret)
4008 : : return ret;
4009 : :
4010 : 0 : (*device_configured) |= local_cfg;
4011 : 0 : return 0;
4012 : : }
4013 : :
4014 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
4015 : : RTE_FLOW_ITEM_TYPE_GTP);
4016 [ # # ]: 0 : if (ret) {
4017 : 0 : DPAA2_PMD_WARN("Extract field(s) of GTP not support.");
4018 : :
4019 : 0 : return ret;
4020 : : }
4021 : :
4022 [ # # ]: 0 : if (!mask->teid)
4023 : : return 0;
4024 : :
4025 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
4026 : 0 : NH_FLD_GTP_TEID, &spec->teid,
4027 : 0 : &mask->teid, sizeof(rte_be32_t),
4028 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
4029 [ # # ]: 0 : if (ret)
4030 : : return ret;
4031 : :
4032 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
4033 : : NH_FLD_GTP_TEID, &spec->teid,
4034 : : &mask->teid, sizeof(rte_be32_t),
4035 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
4036 [ # # ]: 0 : if (ret)
4037 : : return ret;
4038 : :
4039 : 0 : (*device_configured) |= local_cfg;
4040 : :
4041 : 0 : return 0;
4042 : : }
4043 : :
4044 : : static int
4045 : 0 : dpaa2_configure_flow_raw(struct dpaa2_dev_flow *flow,
4046 : : struct rte_eth_dev *dev,
4047 : : const struct rte_flow_attr *attr,
4048 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
4049 : : const struct rte_flow_action actions[] __rte_unused,
4050 : : struct rte_flow_error *error __rte_unused,
4051 : : int *device_configured)
4052 : : {
4053 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4054 : 0 : int local_cfg = 0, ret;
4055 : : uint32_t group;
4056 : : struct dpaa2_key_extract *qos_key_extract;
4057 : : struct dpaa2_key_extract *tc_key_extract;
4058 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
4059 : 0 : const struct rte_flow_item_raw *spec = pattern->spec;
4060 : 0 : const struct rte_flow_item_raw *mask = pattern->mask;
4061 : :
4062 : : /* Need both spec and mask */
4063 [ # # ]: 0 : if (!spec || !mask) {
4064 : 0 : DPAA2_PMD_ERR("spec or mask not present.");
4065 : 0 : return -EINVAL;
4066 : : }
4067 : :
4068 [ # # ]: 0 : if (spec->relative) {
4069 : : /* TBD: relative offset support.
4070 : : * To support relative offset of previous L3 protocol item,
4071 : : * extracts should be expanded to identify if the frame is:
4072 : : * vlan or none-vlan.
4073 : : *
4074 : : * To support relative offset of previous L4 protocol item,
4075 : : * extracts should be expanded to identify if the frame is:
4076 : : * vlan/IPv4 or vlan/IPv6 or none-vlan/IPv4 or none-vlan/IPv6.
4077 : : */
4078 : 0 : DPAA2_PMD_ERR("relative not supported.");
4079 : 0 : return -EINVAL;
4080 : : }
4081 : :
4082 [ # # ]: 0 : if (spec->search) {
4083 : 0 : DPAA2_PMD_ERR("search not supported.");
4084 : 0 : return -EINVAL;
4085 : : }
4086 : :
4087 : : /* Spec len and mask len should be same */
4088 [ # # ]: 0 : if (spec->length != mask->length) {
4089 : 0 : DPAA2_PMD_ERR("Spec len and mask len mismatch.");
4090 : 0 : return -EINVAL;
4091 : : }
4092 : :
4093 : : /* Get traffic class index and flow id to be configured */
4094 : 0 : group = attr->group;
4095 : 0 : flow->tc_id = group;
4096 : 0 : flow->tc_index = attr->priority;
4097 : :
4098 : : qos_key_extract = &priv->extract.qos_key_extract;
4099 : : tc_key_extract = &priv->extract.tc_key_extract[group];
4100 : :
4101 : 0 : ret = dpaa2_flow_extract_add_raw(priv,
4102 : 0 : spec->offset, spec->length,
4103 : : DPAA2_FLOW_QOS_TYPE, 0, &local_cfg);
4104 [ # # ]: 0 : if (ret) {
4105 : 0 : DPAA2_PMD_ERR("QoS Extract RAW add failed.");
4106 : 0 : return -EINVAL;
4107 : : }
4108 : :
4109 : 0 : ret = dpaa2_flow_extract_add_raw(priv,
4110 : 0 : spec->offset, spec->length,
4111 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
4112 [ # # ]: 0 : if (ret) {
4113 : 0 : DPAA2_PMD_ERR("FS[%d] Extract RAW add failed.",
4114 : : group);
4115 : 0 : return -EINVAL;
4116 : : }
4117 : :
4118 : 0 : ret = dpaa2_flow_raw_rule_data_set(flow,
4119 : : &qos_key_extract->key_profile,
4120 : 0 : spec->offset, spec->length,
4121 : 0 : spec->pattern, mask->pattern,
4122 : : DPAA2_FLOW_QOS_TYPE);
4123 [ # # ]: 0 : if (ret) {
4124 : 0 : DPAA2_PMD_ERR("QoS RAW rule data set failed");
4125 : 0 : return -EINVAL;
4126 : : }
4127 : :
4128 : 0 : ret = dpaa2_flow_raw_rule_data_set(flow,
4129 : : &tc_key_extract->key_profile,
4130 : 0 : spec->offset, spec->length,
4131 : 0 : spec->pattern, mask->pattern,
4132 : : DPAA2_FLOW_FS_TYPE);
4133 [ # # ]: 0 : if (ret) {
4134 : 0 : DPAA2_PMD_ERR("FS RAW rule data set failed");
4135 : 0 : return -EINVAL;
4136 : : }
4137 : :
4138 : 0 : (*device_configured) |= local_cfg;
4139 : :
4140 : 0 : return 0;
4141 : : }
4142 : :
4143 : : static inline int
4144 : 0 : dpaa2_flow_verify_attr(struct dpaa2_dev_priv *priv,
4145 : : const struct rte_flow_attr *attr)
4146 : : {
4147 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4148 : :
4149 [ # # ]: 0 : while (curr) {
4150 [ # # ]: 0 : if (curr->tc_id == attr->group &&
4151 [ # # ]: 0 : curr->tc_index == attr->priority) {
4152 : 0 : DPAA2_PMD_ERR("Flow(TC[%d].entry[%d] exists",
4153 : : attr->group, attr->priority);
4154 : :
4155 : 0 : return -EINVAL;
4156 : : }
4157 : 0 : curr = LIST_NEXT(curr, next);
4158 : : }
4159 : :
4160 : : return 0;
4161 : : }
4162 : :
4163 : : static inline struct rte_eth_dev *
4164 : 0 : dpaa2_flow_redirect_dev(struct dpaa2_dev_priv *priv,
4165 : : const struct rte_flow_action *action)
4166 : : {
4167 : : const struct rte_flow_action_port_id *port_id;
4168 : : const struct rte_flow_action_ethdev *ethdev;
4169 : : int idx = -1;
4170 : : struct rte_eth_dev *dest_dev;
4171 : :
4172 [ # # ]: 0 : if (action->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
4173 : 0 : port_id = action->conf;
4174 [ # # ]: 0 : if (!port_id->original)
4175 : 0 : idx = port_id->id;
4176 [ # # ]: 0 : } else if (action->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
4177 : 0 : ethdev = action->conf;
4178 : 0 : idx = ethdev->port_id;
4179 : : } else {
4180 : : return NULL;
4181 : : }
4182 : :
4183 [ # # ]: 0 : if (idx >= 0) {
4184 [ # # ]: 0 : if (!rte_eth_dev_is_valid_port(idx))
4185 : : return NULL;
4186 [ # # ]: 0 : if (!rte_pmd_dpaa2_dev_is_dpaa2(idx))
4187 : : return NULL;
4188 : 0 : dest_dev = &rte_eth_devices[idx];
4189 : : } else {
4190 : 0 : dest_dev = priv->eth_dev;
4191 : : }
4192 : :
4193 : : return dest_dev;
4194 : : }
4195 : :
4196 : : static inline int
4197 : 0 : dpaa2_flow_verify_action(struct dpaa2_dev_priv *priv,
4198 : : const struct rte_flow_attr *attr,
4199 : : const struct rte_flow_action actions[])
4200 : : {
4201 : : int end_of_list = 0, i, j = 0;
4202 : : const struct rte_flow_action_queue *dest_queue;
4203 : : const struct rte_flow_action_rss *rss_conf;
4204 : : struct dpaa2_queue *rxq;
4205 : :
4206 [ # # ]: 0 : while (!end_of_list) {
4207 [ # # # # : 0 : switch (actions[j].type) {
# # ]
4208 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
4209 : 0 : dest_queue = actions[j].conf;
4210 : 0 : rxq = priv->rx_vq[dest_queue->index];
4211 [ # # ]: 0 : if (attr->group != rxq->tc_index) {
4212 : 0 : DPAA2_PMD_ERR("FSQ(%d.%d) not in TC[%d]",
4213 : : rxq->tc_index, rxq->flow_id,
4214 : : attr->group);
4215 : :
4216 : 0 : return -ENOTSUP;
4217 : : }
4218 : : break;
4219 : 0 : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4220 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
4221 [ # # ]: 0 : if (!dpaa2_flow_redirect_dev(priv, &actions[j])) {
4222 : 0 : DPAA2_PMD_ERR("Invalid port id of action");
4223 : 0 : return -ENOTSUP;
4224 : : }
4225 : : break;
4226 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
4227 : 0 : rss_conf = (const struct rte_flow_action_rss *)
4228 : : (actions[j].conf);
4229 [ # # ]: 0 : if (rss_conf->queue_num > priv->dist_queues) {
4230 : 0 : DPAA2_PMD_ERR("RSS number too large");
4231 : 0 : return -ENOTSUP;
4232 : : }
4233 [ # # ]: 0 : for (i = 0; i < (int)rss_conf->queue_num; i++) {
4234 [ # # ]: 0 : if (rss_conf->queue[i] >= priv->nb_rx_queues) {
4235 : 0 : DPAA2_PMD_ERR("RSS queue not in range");
4236 : 0 : return -ENOTSUP;
4237 : : }
4238 : 0 : rxq = priv->rx_vq[rss_conf->queue[i]];
4239 [ # # ]: 0 : if (rxq->tc_index != attr->group) {
4240 : 0 : DPAA2_PMD_ERR("RSS queue not in group");
4241 : 0 : return -ENOTSUP;
4242 : : }
4243 : : }
4244 : :
4245 : : break;
4246 : : case RTE_FLOW_ACTION_TYPE_PF:
4247 : : /* Skip this action, have to add for vxlan */
4248 : : break;
4249 : 0 : case RTE_FLOW_ACTION_TYPE_END:
4250 : : end_of_list = 1;
4251 : 0 : break;
4252 : 0 : default:
4253 : 0 : DPAA2_PMD_ERR("Invalid action type");
4254 : 0 : return -ENOTSUP;
4255 : : }
4256 : 0 : j++;
4257 : : }
4258 : :
4259 : : return 0;
4260 : : }
4261 : :
4262 : : static int
4263 : 0 : dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv,
4264 : : struct dpaa2_dev_flow *flow,
4265 : : const struct rte_flow_action *rte_action)
4266 : : {
4267 : : struct rte_eth_dev *dest_dev;
4268 : : struct dpaa2_dev_priv *dest_priv;
4269 : : const struct rte_flow_action_queue *dest_queue;
4270 : : struct dpaa2_queue *dest_q;
4271 : :
4272 [ # # ]: 0 : memset(&flow->fs_action_cfg, 0,
4273 : : sizeof(struct dpni_fs_action_cfg));
4274 : 0 : flow->action_type = rte_action->type;
4275 : :
4276 [ # # ]: 0 : if (flow->action_type == RTE_FLOW_ACTION_TYPE_QUEUE) {
4277 : 0 : dest_queue = rte_action->conf;
4278 : 0 : dest_q = priv->rx_vq[dest_queue->index];
4279 : 0 : flow->fs_action_cfg.flow_id = dest_q->flow_id;
4280 [ # # ]: 0 : } else if (flow->action_type == RTE_FLOW_ACTION_TYPE_PORT_ID ||
4281 : : flow->action_type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
4282 : 0 : dest_dev = dpaa2_flow_redirect_dev(priv, rte_action);
4283 [ # # ]: 0 : if (!dest_dev) {
4284 : 0 : DPAA2_PMD_ERR("Invalid device to redirect");
4285 : 0 : return -EINVAL;
4286 : : }
4287 : :
4288 : 0 : dest_priv = dest_dev->data->dev_private;
4289 : 0 : dest_q = dest_priv->tx_vq[0];
4290 : 0 : flow->fs_action_cfg.options =
4291 : : DPNI_FS_OPT_REDIRECT_TO_DPNI_TX;
4292 : 0 : flow->fs_action_cfg.redirect_obj_token =
4293 : 0 : dest_priv->token;
4294 : 0 : flow->fs_action_cfg.flow_id = dest_q->flow_id;
4295 : : }
4296 : :
4297 : : return 0;
4298 : : }
4299 : :
4300 : : static inline uint16_t
4301 : : dpaa2_flow_entry_size(uint16_t key_max_size)
4302 : : {
4303 : 0 : if (key_max_size > DPAA2_FLOW_ENTRY_MAX_SIZE) {
4304 : 0 : DPAA2_PMD_ERR("Key size(%d) > max(%d)",
4305 : : key_max_size,
4306 : : DPAA2_FLOW_ENTRY_MAX_SIZE);
4307 : :
4308 : 0 : return 0;
4309 : : }
4310 : :
4311 : : if (key_max_size > DPAA2_FLOW_ENTRY_MIN_SIZE)
4312 : : return DPAA2_FLOW_ENTRY_MAX_SIZE;
4313 : :
4314 : : /* Current MC only support fixed entry size(56)*/
4315 : : return DPAA2_FLOW_ENTRY_MAX_SIZE;
4316 : : }
4317 : :
4318 : : static inline int
4319 : 0 : dpaa2_flow_clear_fs_table(struct dpaa2_dev_priv *priv,
4320 : : uint8_t tc_id)
4321 : : {
4322 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4323 : : int need_clear = 0, ret;
4324 : 0 : struct fsl_mc_io *dpni = priv->hw;
4325 : :
4326 [ # # ]: 0 : while (curr) {
4327 [ # # ]: 0 : if (curr->tc_id == tc_id) {
4328 : : need_clear = 1;
4329 : : break;
4330 : : }
4331 : 0 : curr = LIST_NEXT(curr, next);
4332 : : }
4333 : :
4334 [ # # ]: 0 : if (need_clear) {
4335 : 0 : ret = dpni_clear_fs_entries(dpni, CMD_PRI_LOW,
4336 : 0 : priv->token, tc_id);
4337 [ # # ]: 0 : if (ret) {
4338 : 0 : DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
4339 : 0 : return ret;
4340 : : }
4341 : : }
4342 : :
4343 : : return 0;
4344 : : }
4345 : :
4346 : : static int
4347 : 0 : dpaa2_configure_fs_rss_table(struct dpaa2_dev_priv *priv,
4348 : : uint8_t tc_id, uint16_t dist_size, int rss_dist)
4349 : : {
4350 : : struct dpaa2_key_extract *tc_extract;
4351 : : uint8_t *key_cfg_buf;
4352 : : uint64_t key_cfg_iova;
4353 : : int ret;
4354 : : struct dpni_rx_dist_cfg tc_cfg;
4355 : 0 : struct fsl_mc_io *dpni = priv->hw;
4356 : : uint16_t entry_size;
4357 : : uint16_t key_max_size;
4358 : :
4359 : 0 : ret = dpaa2_flow_clear_fs_table(priv, tc_id);
4360 [ # # ]: 0 : if (ret < 0) {
4361 : 0 : DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
4362 : 0 : return ret;
4363 : : }
4364 : :
4365 : : tc_extract = &priv->extract.tc_key_extract[tc_id];
4366 : 0 : key_cfg_buf = priv->extract.tc_extract_param[tc_id];
4367 : 0 : key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
4368 : : DPAA2_EXTRACT_PARAM_MAX_SIZE);
4369 [ # # ]: 0 : if (key_cfg_iova == RTE_BAD_IOVA) {
4370 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
4371 : : __func__, key_cfg_buf);
4372 : :
4373 : 0 : return -ENOBUFS;
4374 : : }
4375 : :
4376 : 0 : key_max_size = tc_extract->key_profile.key_max_size;
4377 [ # # ]: 0 : entry_size = dpaa2_flow_entry_size(key_max_size);
4378 : :
4379 : 0 : dpaa2_flow_fs_extracts_log(priv, tc_id);
4380 : 0 : ret = dpkg_prepare_key_cfg(&tc_extract->dpkg,
4381 : : key_cfg_buf);
4382 [ # # ]: 0 : if (ret < 0) {
4383 : 0 : DPAA2_PMD_ERR("TC[%d] prepare key failed", tc_id);
4384 : 0 : return ret;
4385 : : }
4386 : :
4387 : : memset(&tc_cfg, 0, sizeof(struct dpni_rx_dist_cfg));
4388 : 0 : tc_cfg.dist_size = dist_size;
4389 : 0 : tc_cfg.key_cfg_iova = key_cfg_iova;
4390 [ # # ]: 0 : if (rss_dist)
4391 : 0 : tc_cfg.enable = true;
4392 : : else
4393 : : tc_cfg.enable = false;
4394 : 0 : tc_cfg.tc = tc_id;
4395 : 0 : ret = dpni_set_rx_hash_dist(dpni, CMD_PRI_LOW,
4396 : 0 : priv->token, &tc_cfg);
4397 [ # # ]: 0 : if (ret < 0) {
4398 [ # # ]: 0 : if (rss_dist) {
4399 : 0 : DPAA2_PMD_ERR("RSS TC[%d] set failed",
4400 : : tc_id);
4401 : : } else {
4402 : 0 : DPAA2_PMD_ERR("FS TC[%d] hash disable failed",
4403 : : tc_id);
4404 : : }
4405 : :
4406 : 0 : return ret;
4407 : : }
4408 : :
4409 [ # # ]: 0 : if (rss_dist)
4410 : : return 0;
4411 : :
4412 : 0 : tc_cfg.enable = true;
4413 : 0 : tc_cfg.fs_miss_flow_id = dpaa2_flow_miss_flow_id;
4414 : 0 : ret = dpni_set_rx_fs_dist(dpni, CMD_PRI_LOW,
4415 : 0 : priv->token, &tc_cfg);
4416 [ # # ]: 0 : if (ret < 0) {
4417 : 0 : DPAA2_PMD_ERR("TC[%d] FS configured failed", tc_id);
4418 : 0 : return ret;
4419 : : }
4420 : :
4421 : 0 : ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_FS_TYPE,
4422 : : entry_size, tc_id);
4423 [ # # ]: 0 : if (ret)
4424 : 0 : return ret;
4425 : :
4426 : : return 0;
4427 : : }
4428 : :
4429 : : static int
4430 : 0 : dpaa2_configure_qos_table(struct dpaa2_dev_priv *priv,
4431 : : int rss_dist)
4432 : : {
4433 : : struct dpaa2_key_extract *qos_extract;
4434 : : uint8_t *key_cfg_buf;
4435 : : uint64_t key_cfg_iova;
4436 : : int ret;
4437 : : struct dpni_qos_tbl_cfg qos_cfg;
4438 : 0 : struct fsl_mc_io *dpni = priv->hw;
4439 : : uint16_t entry_size;
4440 : : uint16_t key_max_size;
4441 : :
4442 [ # # # # ]: 0 : if (!rss_dist && priv->num_rx_tc <= 1) {
4443 : : /* QoS table is effecitive for FS multiple TCs or RSS.*/
4444 : : return 0;
4445 : : }
4446 : :
4447 [ # # ]: 0 : if (LIST_FIRST(&priv->flows)) {
4448 : 0 : ret = dpni_clear_qos_table(dpni, CMD_PRI_LOW,
4449 : 0 : priv->token);
4450 [ # # ]: 0 : if (ret < 0) {
4451 : 0 : DPAA2_PMD_ERR("QoS table clear failed");
4452 : 0 : return ret;
4453 : : }
4454 : : }
4455 : :
4456 : : qos_extract = &priv->extract.qos_key_extract;
4457 : 0 : key_cfg_buf = priv->extract.qos_extract_param;
4458 : 0 : key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
4459 : : DPAA2_EXTRACT_PARAM_MAX_SIZE);
4460 [ # # ]: 0 : if (key_cfg_iova == RTE_BAD_IOVA) {
4461 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
4462 : : __func__, key_cfg_buf);
4463 : :
4464 : 0 : return -ENOBUFS;
4465 : : }
4466 : :
4467 : 0 : key_max_size = qos_extract->key_profile.key_max_size;
4468 [ # # ]: 0 : entry_size = dpaa2_flow_entry_size(key_max_size);
4469 : :
4470 : 0 : dpaa2_flow_qos_extracts_log(priv);
4471 : :
4472 : 0 : ret = dpkg_prepare_key_cfg(&qos_extract->dpkg,
4473 : : key_cfg_buf);
4474 [ # # ]: 0 : if (ret < 0) {
4475 : 0 : DPAA2_PMD_ERR("QoS prepare extract failed");
4476 : 0 : return ret;
4477 : : }
4478 : : memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
4479 : 0 : qos_cfg.keep_entries = true;
4480 : 0 : qos_cfg.key_cfg_iova = key_cfg_iova;
4481 [ # # ]: 0 : if (rss_dist) {
4482 : 0 : qos_cfg.discard_on_miss = true;
4483 : : } else {
4484 : : qos_cfg.discard_on_miss = false;
4485 : : qos_cfg.default_tc = 0;
4486 : : }
4487 : :
4488 : 0 : ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
4489 : 0 : priv->token, &qos_cfg);
4490 [ # # ]: 0 : if (ret < 0) {
4491 : 0 : DPAA2_PMD_ERR("QoS table set failed");
4492 : 0 : return ret;
4493 : : }
4494 : :
4495 : 0 : ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_QOS_TYPE,
4496 : : entry_size, 0);
4497 [ # # ]: 0 : if (ret)
4498 : 0 : return ret;
4499 : :
4500 : : return 0;
4501 : : }
4502 : :
4503 : : static int
4504 : 0 : dpaa2_flow_item_convert(const struct rte_flow_item pattern[],
4505 : : struct rte_dpaa2_flow_item **dpaa2_pattern)
4506 : : {
4507 : : struct rte_dpaa2_flow_item *new_pattern;
4508 : : int num = 0, tunnel_start = 0;
4509 : :
4510 : : while (1) {
4511 : 0 : num++;
4512 [ # # ]: 0 : if (pattern[num].type == RTE_FLOW_ITEM_TYPE_END)
4513 : : break;
4514 : : }
4515 : :
4516 : 0 : new_pattern = rte_malloc(NULL, sizeof(struct rte_dpaa2_flow_item) * num,
4517 : : RTE_CACHE_LINE_SIZE);
4518 [ # # ]: 0 : if (!new_pattern) {
4519 : 0 : DPAA2_PMD_ERR("Failed to alloc %d flow items", num);
4520 : 0 : return -ENOMEM;
4521 : : }
4522 : :
4523 : : num = 0;
4524 [ # # ]: 0 : while (pattern[num].type != RTE_FLOW_ITEM_TYPE_END) {
4525 [ # # ]: 0 : memcpy(&new_pattern[num].generic_item, &pattern[num],
4526 : : sizeof(struct rte_flow_item));
4527 : 0 : new_pattern[num].in_tunnel = 0;
4528 : :
4529 [ # # ]: 0 : if (pattern[num].type == RTE_FLOW_ITEM_TYPE_VXLAN)
4530 : : tunnel_start = 1;
4531 [ # # ]: 0 : else if (tunnel_start)
4532 : 0 : new_pattern[num].in_tunnel = 1;
4533 : 0 : num++;
4534 : : }
4535 : :
4536 : 0 : new_pattern[num].generic_item.type = RTE_FLOW_ITEM_TYPE_END;
4537 : 0 : *dpaa2_pattern = new_pattern;
4538 : :
4539 : 0 : return 0;
4540 : : }
4541 : :
4542 : : static int
4543 : 0 : dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow,
4544 : : struct rte_eth_dev *dev,
4545 : : const struct rte_flow_attr *attr,
4546 : : const struct rte_flow_item pattern[],
4547 : : const struct rte_flow_action actions[],
4548 : : struct rte_flow_error *error)
4549 : : {
4550 : : const struct rte_flow_action_rss *rss_conf;
4551 : 0 : int is_keycfg_configured = 0, end_of_list = 0;
4552 : : int ret = 0, i = 0, j = 0;
4553 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4554 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4555 : : uint16_t dist_size, key_size;
4556 : : struct dpaa2_key_extract *qos_key_extract;
4557 : : struct dpaa2_key_extract *tc_key_extract;
4558 : 0 : struct rte_dpaa2_flow_item *dpaa2_pattern = NULL;
4559 : :
4560 : 0 : ret = dpaa2_flow_verify_attr(priv, attr);
4561 [ # # ]: 0 : if (ret)
4562 : : return ret;
4563 : :
4564 : 0 : ret = dpaa2_flow_verify_action(priv, attr, actions);
4565 [ # # ]: 0 : if (ret)
4566 : : return ret;
4567 : :
4568 : 0 : ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern);
4569 [ # # ]: 0 : if (ret)
4570 : : return ret;
4571 : :
4572 : : /* Parse pattern list to get the matching parameters */
4573 [ # # ]: 0 : while (!end_of_list) {
4574 [ # # # # : 0 : switch (pattern[i].type) {
# # # # #
# # # # #
# # # ]
4575 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
4576 : 0 : ret = dpaa2_configure_flow_eth(flow, dev, attr,
4577 : 0 : &dpaa2_pattern[i],
4578 : : actions, error,
4579 : : &is_keycfg_configured);
4580 [ # # ]: 0 : if (ret) {
4581 : 0 : DPAA2_PMD_ERR("ETH flow config failed!");
4582 : 0 : goto end_flow_set;
4583 : : }
4584 : : break;
4585 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
4586 : 0 : ret = dpaa2_configure_flow_vlan(flow, dev, attr,
4587 : 0 : &dpaa2_pattern[i],
4588 : : actions, error,
4589 : : &is_keycfg_configured);
4590 [ # # ]: 0 : if (ret) {
4591 : 0 : DPAA2_PMD_ERR("vLan flow config failed!");
4592 : 0 : goto end_flow_set;
4593 : : }
4594 : : break;
4595 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
4596 : 0 : ret = dpaa2_configure_flow_ipv4(flow, dev, attr,
4597 : 0 : &dpaa2_pattern[i],
4598 : : actions, error,
4599 : : &is_keycfg_configured);
4600 [ # # ]: 0 : if (ret) {
4601 : 0 : DPAA2_PMD_ERR("IPV4 flow config failed!");
4602 : 0 : goto end_flow_set;
4603 : : }
4604 : : break;
4605 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
4606 : 0 : ret = dpaa2_configure_flow_ipv6(flow, dev, attr,
4607 : 0 : &dpaa2_pattern[i],
4608 : : actions, error,
4609 : : &is_keycfg_configured);
4610 [ # # ]: 0 : if (ret) {
4611 : 0 : DPAA2_PMD_ERR("IPV6 flow config failed!");
4612 : 0 : goto end_flow_set;
4613 : : }
4614 : : break;
4615 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP:
4616 : 0 : ret = dpaa2_configure_flow_icmp(flow, dev, attr,
4617 : 0 : &dpaa2_pattern[i],
4618 : : actions, error,
4619 : : &is_keycfg_configured);
4620 [ # # ]: 0 : if (ret) {
4621 : 0 : DPAA2_PMD_ERR("ICMP flow config failed!");
4622 : 0 : goto end_flow_set;
4623 : : }
4624 : : break;
4625 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
4626 : 0 : ret = dpaa2_configure_flow_udp(flow, dev, attr,
4627 : 0 : &dpaa2_pattern[i],
4628 : : actions, error,
4629 : : &is_keycfg_configured);
4630 [ # # ]: 0 : if (ret) {
4631 : 0 : DPAA2_PMD_ERR("UDP flow config failed!");
4632 : 0 : goto end_flow_set;
4633 : : }
4634 : : break;
4635 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
4636 : 0 : ret = dpaa2_configure_flow_tcp(flow, dev, attr,
4637 : 0 : &dpaa2_pattern[i],
4638 : : actions, error,
4639 : : &is_keycfg_configured);
4640 [ # # ]: 0 : if (ret) {
4641 : 0 : DPAA2_PMD_ERR("TCP flow config failed!");
4642 : 0 : goto end_flow_set;
4643 : : }
4644 : : break;
4645 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
4646 : 0 : ret = dpaa2_configure_flow_sctp(flow, dev, attr,
4647 : 0 : &dpaa2_pattern[i],
4648 : : actions, error,
4649 : : &is_keycfg_configured);
4650 [ # # ]: 0 : if (ret) {
4651 : 0 : DPAA2_PMD_ERR("SCTP flow config failed!");
4652 : 0 : goto end_flow_set;
4653 : : }
4654 : : break;
4655 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
4656 : 0 : ret = dpaa2_configure_flow_esp(flow,
4657 : 0 : dev, attr, &dpaa2_pattern[i],
4658 : : actions, error,
4659 : : &is_keycfg_configured);
4660 [ # # ]: 0 : if (ret) {
4661 : 0 : DPAA2_PMD_ERR("ESP flow config failed!");
4662 : 0 : goto end_flow_set;
4663 : : }
4664 : : break;
4665 : 0 : case RTE_FLOW_ITEM_TYPE_AH:
4666 : 0 : ret = dpaa2_configure_flow_ah(flow,
4667 : 0 : dev, attr, &dpaa2_pattern[i],
4668 : : actions, error,
4669 : : &is_keycfg_configured);
4670 [ # # ]: 0 : if (ret) {
4671 : 0 : DPAA2_PMD_ERR("AH flow config failed!");
4672 : 0 : goto end_flow_set;
4673 : : }
4674 : : break;
4675 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
4676 : 0 : ret = dpaa2_configure_flow_gre(flow, dev, attr,
4677 : 0 : &dpaa2_pattern[i],
4678 : : actions, error,
4679 : : &is_keycfg_configured);
4680 [ # # ]: 0 : if (ret) {
4681 : 0 : DPAA2_PMD_ERR("GRE flow config failed!");
4682 : 0 : goto end_flow_set;
4683 : : }
4684 : : break;
4685 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
4686 : 0 : ret = dpaa2_configure_flow_vxlan(flow, dev, attr,
4687 : 0 : &dpaa2_pattern[i],
4688 : : actions, error,
4689 : : &is_keycfg_configured);
4690 [ # # ]: 0 : if (ret) {
4691 : 0 : DPAA2_PMD_ERR("VXLAN flow config failed!");
4692 : 0 : goto end_flow_set;
4693 : : }
4694 : : break;
4695 : 0 : case RTE_FLOW_ITEM_TYPE_ECPRI:
4696 : 0 : ret = dpaa2_configure_flow_ecpri(flow,
4697 : 0 : dev, attr, &dpaa2_pattern[i],
4698 : : actions, error,
4699 : : &is_keycfg_configured);
4700 [ # # ]: 0 : if (ret) {
4701 : 0 : DPAA2_PMD_ERR("ECPRI flow config failed!");
4702 : 0 : goto end_flow_set;
4703 : : }
4704 : : break;
4705 : 0 : case RTE_FLOW_ITEM_TYPE_GTP:
4706 : 0 : ret = dpaa2_configure_flow_gtp(flow,
4707 : 0 : dev, attr, &dpaa2_pattern[i],
4708 : : actions, error,
4709 : : &is_keycfg_configured);
4710 [ # # ]: 0 : if (ret) {
4711 : 0 : DPAA2_PMD_ERR("GTP flow config failed!");
4712 : 0 : goto end_flow_set;
4713 : : }
4714 : : break;
4715 : 0 : case RTE_FLOW_ITEM_TYPE_RAW:
4716 : 0 : ret = dpaa2_configure_flow_raw(flow, dev, attr,
4717 : 0 : &dpaa2_pattern[i],
4718 : : actions, error,
4719 : : &is_keycfg_configured);
4720 [ # # ]: 0 : if (ret) {
4721 : 0 : DPAA2_PMD_ERR("RAW flow config failed!");
4722 : 0 : goto end_flow_set;
4723 : : }
4724 : : break;
4725 : : case RTE_FLOW_ITEM_TYPE_END:
4726 : : end_of_list = 1;
4727 : : break; /*End of List*/
4728 : 0 : default:
4729 : 0 : DPAA2_PMD_ERR("Invalid flow item[%d] type(%d)",
4730 : : i, pattern[i].type);
4731 : : ret = -ENOTSUP;
4732 : 0 : break;
4733 : : }
4734 : 0 : i++;
4735 : : }
4736 : :
4737 : : qos_key_extract = &priv->extract.qos_key_extract;
4738 : 0 : key_size = qos_key_extract->key_profile.key_max_size;
4739 [ # # ]: 0 : flow->qos_rule.key_size = dpaa2_flow_entry_size(key_size);
4740 : :
4741 : 0 : tc_key_extract = &priv->extract.tc_key_extract[flow->tc_id];
4742 : 0 : key_size = tc_key_extract->key_profile.key_max_size;
4743 [ # # ]: 0 : flow->fs_rule.key_size = dpaa2_flow_entry_size(key_size);
4744 : :
4745 : : /* Let's parse action on matching traffic */
4746 : : end_of_list = 0;
4747 [ # # ]: 0 : while (!end_of_list) {
4748 [ # # # # : 0 : switch (actions[j].type) {
# ]
4749 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
4750 : : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4751 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
4752 : 0 : ret = dpaa2_configure_flow_fs_action(priv, flow,
4753 : : &actions[j]);
4754 [ # # ]: 0 : if (ret)
4755 : 0 : goto end_flow_set;
4756 : :
4757 : : /* Configure FS table first*/
4758 : 0 : dist_size = priv->nb_rx_queues / priv->num_rx_tc;
4759 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
4760 : 0 : ret = dpaa2_configure_fs_rss_table(priv,
4761 : 0 : flow->tc_id,
4762 : : dist_size,
4763 : : false);
4764 [ # # ]: 0 : if (ret)
4765 : 0 : goto end_flow_set;
4766 : : }
4767 : :
4768 : : /* Configure QoS table then.*/
4769 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
4770 : 0 : ret = dpaa2_configure_qos_table(priv, false);
4771 [ # # ]: 0 : if (ret)
4772 : 0 : goto end_flow_set;
4773 : : }
4774 : :
4775 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
4776 : 0 : ret = dpaa2_flow_add_qos_rule(priv, flow);
4777 [ # # ]: 0 : if (ret)
4778 : 0 : goto end_flow_set;
4779 : : }
4780 : :
4781 [ # # ]: 0 : if (flow->tc_index >= priv->fs_entries) {
4782 : 0 : DPAA2_PMD_ERR("FS table with %d entries full",
4783 : : priv->fs_entries);
4784 : 0 : return -1;
4785 : : }
4786 : :
4787 : 0 : ret = dpaa2_flow_add_fs_rule(priv, flow);
4788 [ # # ]: 0 : if (ret)
4789 : 0 : goto end_flow_set;
4790 : :
4791 : : break;
4792 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
4793 : 0 : rss_conf = actions[j].conf;
4794 : 0 : flow->action_type = RTE_FLOW_ACTION_TYPE_RSS;
4795 : :
4796 : 0 : ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
4797 : : &tc_key_extract->dpkg);
4798 [ # # ]: 0 : if (ret < 0) {
4799 : 0 : DPAA2_PMD_ERR("TC[%d] distset RSS failed",
4800 : : flow->tc_id);
4801 : 0 : goto end_flow_set;
4802 : : }
4803 : :
4804 : 0 : dist_size = rss_conf->queue_num;
4805 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
4806 : 0 : ret = dpaa2_configure_fs_rss_table(priv,
4807 : 0 : flow->tc_id,
4808 : : dist_size,
4809 : : true);
4810 [ # # ]: 0 : if (ret)
4811 : 0 : goto end_flow_set;
4812 : : }
4813 : :
4814 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
4815 : 0 : ret = dpaa2_configure_qos_table(priv, true);
4816 [ # # ]: 0 : if (ret)
4817 : 0 : goto end_flow_set;
4818 : : }
4819 : :
4820 : 0 : ret = dpaa2_flow_add_qos_rule(priv, flow);
4821 [ # # ]: 0 : if (ret)
4822 : 0 : goto end_flow_set;
4823 : :
4824 : 0 : ret = dpaa2_flow_add_fs_rule(priv, flow);
4825 [ # # ]: 0 : if (ret)
4826 : 0 : goto end_flow_set;
4827 : :
4828 : : break;
4829 : : case RTE_FLOW_ACTION_TYPE_PF:
4830 : : /* Skip this action, have to add for vxlan */
4831 : : break;
4832 : 0 : case RTE_FLOW_ACTION_TYPE_END:
4833 : : end_of_list = 1;
4834 : 0 : break;
4835 : 0 : default:
4836 : 0 : DPAA2_PMD_ERR("Invalid action type");
4837 : : ret = -ENOTSUP;
4838 : 0 : break;
4839 : : }
4840 : 0 : j++;
4841 : : }
4842 : :
4843 : 0 : end_flow_set:
4844 [ # # ]: 0 : if (!ret) {
4845 : : /* New rules are inserted. */
4846 [ # # ]: 0 : if (!curr) {
4847 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->flows, flow, next);
4848 : : } else {
4849 [ # # ]: 0 : while (LIST_NEXT(curr, next))
4850 : : curr = LIST_NEXT(curr, next);
4851 : 0 : LIST_INSERT_AFTER(curr, flow, next);
4852 : : }
4853 : : }
4854 : :
4855 : 0 : rte_free(dpaa2_pattern);
4856 : :
4857 : 0 : return ret;
4858 : : }
4859 : :
4860 : : static inline int
4861 : 0 : dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
4862 : : const struct rte_flow_attr *attr)
4863 : : {
4864 : : int ret = 0;
4865 : :
4866 [ # # ]: 0 : if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
4867 : 0 : DPAA2_PMD_ERR("Group/TC(%d) is out of range(%d)",
4868 : : attr->group, dpni_attr->num_rx_tcs);
4869 : : ret = -ENOTSUP;
4870 : : }
4871 [ # # ]: 0 : if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
4872 : 0 : DPAA2_PMD_ERR("Priority(%d) within group is out of range(%d)",
4873 : : attr->priority, dpni_attr->fs_entries);
4874 : : ret = -ENOTSUP;
4875 : : }
4876 [ # # ]: 0 : if (unlikely(attr->egress)) {
4877 : 0 : DPAA2_PMD_ERR("Egress flow configuration is not supported");
4878 : : ret = -ENOTSUP;
4879 : : }
4880 [ # # ]: 0 : if (unlikely(!attr->ingress)) {
4881 : 0 : DPAA2_PMD_ERR("Ingress flag must be configured");
4882 : : ret = -EINVAL;
4883 : : }
4884 : 0 : return ret;
4885 : : }
4886 : :
4887 : : static inline int
4888 : 0 : dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
4889 : : {
4890 : : unsigned int i, j, is_found = 0;
4891 : : int ret = 0;
4892 : : const enum rte_flow_item_type *hp_supported;
4893 : : const enum rte_flow_item_type *sp_supported;
4894 : : uint64_t hp_supported_num, sp_supported_num;
4895 : :
4896 : : hp_supported = dpaa2_hp_supported_pattern_type;
4897 : : hp_supported_num = RTE_DIM(dpaa2_hp_supported_pattern_type);
4898 : :
4899 : : sp_supported = dpaa2_sp_supported_pattern_type;
4900 : : sp_supported_num = RTE_DIM(dpaa2_sp_supported_pattern_type);
4901 : :
4902 [ # # ]: 0 : for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
4903 : : is_found = 0;
4904 [ # # ]: 0 : for (i = 0; i < hp_supported_num; i++) {
4905 [ # # ]: 0 : if (hp_supported[i] == pattern[j].type) {
4906 : : is_found = 1;
4907 : : break;
4908 : : }
4909 : : }
4910 [ # # ]: 0 : if (is_found)
4911 : 0 : continue;
4912 [ # # ]: 0 : if (dpaa2_sp_loaded > 0) {
4913 [ # # ]: 0 : for (i = 0; i < sp_supported_num; i++) {
4914 [ # # ]: 0 : if (sp_supported[i] == pattern[j].type) {
4915 : : is_found = 1;
4916 : : break;
4917 : : }
4918 : : }
4919 : : }
4920 [ # # ]: 0 : if (!is_found) {
4921 : 0 : DPAA2_PMD_WARN("Flow type(%d) not supported",
4922 : : pattern[j].type);
4923 : : ret = -ENOTSUP;
4924 : 0 : break;
4925 : : }
4926 : : }
4927 : :
4928 : 0 : return ret;
4929 : : }
4930 : :
4931 : : static inline int
4932 : 0 : dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
4933 : : {
4934 : : unsigned int i, j, is_found = 0;
4935 : : int ret = 0;
4936 : :
4937 [ # # ]: 0 : for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
4938 [ # # ]: 0 : for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
4939 [ # # ]: 0 : if (dpaa2_supported_action_type[i] == actions[j].type) {
4940 : : is_found = 1;
4941 : : break;
4942 : : }
4943 : : }
4944 [ # # ]: 0 : if (!is_found) {
4945 : : ret = -ENOTSUP;
4946 : : break;
4947 : : }
4948 : : }
4949 [ # # ]: 0 : for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
4950 [ # # ]: 0 : if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
4951 [ # # ]: 0 : !actions[j].conf)
4952 : : ret = -EINVAL;
4953 : : }
4954 : 0 : return ret;
4955 : : }
4956 : :
4957 : : static int
4958 : 0 : dpaa2_flow_validate(struct rte_eth_dev *dev,
4959 : : const struct rte_flow_attr *flow_attr,
4960 : : const struct rte_flow_item pattern[],
4961 : : const struct rte_flow_action actions[],
4962 : : struct rte_flow_error *error)
4963 : : {
4964 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4965 : : struct dpni_attr dpni_attr;
4966 : 0 : struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
4967 : 0 : uint16_t token = priv->token;
4968 : : int ret = 0;
4969 : :
4970 : : memset(&dpni_attr, 0, sizeof(struct dpni_attr));
4971 : 0 : ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
4972 [ # # ]: 0 : if (ret < 0) {
4973 : 0 : DPAA2_PMD_ERR("Get dpni@%d attribute failed(%d)",
4974 : : priv->hw_id, ret);
4975 : 0 : rte_flow_error_set(error, EPERM,
4976 : : RTE_FLOW_ERROR_TYPE_ATTR,
4977 : : flow_attr, "invalid");
4978 : 0 : return ret;
4979 : : }
4980 : :
4981 : : /* Verify input attributes */
4982 : 0 : ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
4983 [ # # ]: 0 : if (ret < 0) {
4984 : 0 : DPAA2_PMD_ERR("Invalid attributes are given");
4985 : 0 : rte_flow_error_set(error, EPERM,
4986 : : RTE_FLOW_ERROR_TYPE_ATTR,
4987 : : flow_attr, "invalid");
4988 : 0 : goto not_valid_params;
4989 : : }
4990 : : /* Verify input pattern list */
4991 : 0 : ret = dpaa2_dev_verify_patterns(pattern);
4992 [ # # ]: 0 : if (ret < 0) {
4993 : 0 : DPAA2_PMD_ERR("Invalid pattern list is given");
4994 : 0 : rte_flow_error_set(error, EPERM,
4995 : : RTE_FLOW_ERROR_TYPE_ITEM,
4996 : : pattern, "invalid");
4997 : 0 : goto not_valid_params;
4998 : : }
4999 : : /* Verify input action list */
5000 : 0 : ret = dpaa2_dev_verify_actions(actions);
5001 [ # # ]: 0 : if (ret < 0) {
5002 : 0 : DPAA2_PMD_ERR("Invalid action list is given");
5003 : 0 : rte_flow_error_set(error, EPERM,
5004 : : RTE_FLOW_ERROR_TYPE_ACTION,
5005 : : actions, "invalid");
5006 : 0 : goto not_valid_params;
5007 : : }
5008 : 0 : not_valid_params:
5009 : : return ret;
5010 : : }
5011 : :
5012 : : static struct rte_flow *
5013 : 0 : dpaa2_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
5014 : : const struct rte_flow_item pattern[],
5015 : : const struct rte_flow_action actions[],
5016 : : struct rte_flow_error *error)
5017 : : {
5018 : : struct dpaa2_dev_flow *flow = NULL;
5019 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5020 : : int ret;
5021 : : uint64_t iova;
5022 : :
5023 : 0 : dpaa2_flow_control_log =
5024 : 0 : getenv("DPAA2_FLOW_CONTROL_LOG");
5025 : :
5026 [ # # ]: 0 : if (getenv("DPAA2_FLOW_CONTROL_MISS_FLOW")) {
5027 : 0 : dpaa2_flow_miss_flow_id =
5028 : 0 : (uint16_t)atoi(getenv("DPAA2_FLOW_CONTROL_MISS_FLOW"));
5029 [ # # ]: 0 : if (dpaa2_flow_miss_flow_id >= priv->dist_queues) {
5030 : 0 : DPAA2_PMD_ERR("Missed flow ID %d >= dist size(%d)",
5031 : : dpaa2_flow_miss_flow_id,
5032 : : priv->dist_queues);
5033 : 0 : return NULL;
5034 : : }
5035 : : }
5036 : :
5037 : 0 : flow = rte_zmalloc(NULL, sizeof(struct dpaa2_dev_flow),
5038 : : RTE_CACHE_LINE_SIZE);
5039 [ # # ]: 0 : if (!flow) {
5040 : 0 : DPAA2_PMD_ERR("Failure to allocate memory for flow");
5041 : 0 : goto mem_failure;
5042 : : }
5043 : :
5044 : : /* Allocate DMA'ble memory to write the qos rules */
5045 : 0 : flow->qos_key_addr = rte_zmalloc(NULL,
5046 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5047 [ # # ]: 0 : if (!flow->qos_key_addr) {
5048 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5049 : 0 : goto mem_failure;
5050 : : }
5051 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_key_addr,
5052 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5053 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5054 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for qos key(%p)",
5055 : : __func__, flow->qos_key_addr);
5056 : 0 : goto mem_failure;
5057 : : }
5058 : 0 : flow->qos_rule.key_iova = iova;
5059 : :
5060 : 0 : flow->qos_mask_addr = rte_zmalloc(NULL,
5061 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5062 [ # # ]: 0 : if (!flow->qos_mask_addr) {
5063 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5064 : 0 : goto mem_failure;
5065 : : }
5066 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_mask_addr,
5067 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5068 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5069 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for qos mask(%p)",
5070 : : __func__, flow->qos_mask_addr);
5071 : 0 : goto mem_failure;
5072 : : }
5073 : 0 : flow->qos_rule.mask_iova = iova;
5074 : :
5075 : : /* Allocate DMA'ble memory to write the FS rules */
5076 : 0 : flow->fs_key_addr = rte_zmalloc(NULL,
5077 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5078 [ # # ]: 0 : if (!flow->fs_key_addr) {
5079 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5080 : 0 : goto mem_failure;
5081 : : }
5082 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_key_addr,
5083 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5084 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5085 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for fs key(%p)",
5086 : : __func__, flow->fs_key_addr);
5087 : 0 : goto mem_failure;
5088 : : }
5089 : 0 : flow->fs_rule.key_iova = iova;
5090 : :
5091 : 0 : flow->fs_mask_addr = rte_zmalloc(NULL,
5092 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5093 [ # # ]: 0 : if (!flow->fs_mask_addr) {
5094 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5095 : 0 : goto mem_failure;
5096 : : }
5097 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_mask_addr,
5098 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5099 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5100 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for fs mask(%p)",
5101 : : __func__, flow->fs_mask_addr);
5102 : 0 : goto mem_failure;
5103 : : }
5104 : 0 : flow->fs_rule.mask_iova = iova;
5105 : :
5106 : 0 : priv->curr = flow;
5107 : :
5108 : 0 : ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, actions, error);
5109 [ # # ]: 0 : if (ret < 0) {
5110 [ # # # # ]: 0 : if (error && error->type > RTE_FLOW_ERROR_TYPE_ACTION)
5111 : 0 : rte_flow_error_set(error, EPERM,
5112 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
5113 : : attr, "unknown");
5114 : 0 : DPAA2_PMD_ERR("Create flow failed (%d)", ret);
5115 : 0 : goto creation_error;
5116 : : }
5117 : :
5118 : 0 : priv->curr = NULL;
5119 : 0 : return (struct rte_flow *)flow;
5120 : :
5121 : 0 : mem_failure:
5122 : 0 : rte_flow_error_set(error, EPERM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
5123 : : "memory alloc");
5124 : :
5125 : 0 : creation_error:
5126 [ # # ]: 0 : if (flow) {
5127 : 0 : rte_free(flow->qos_key_addr);
5128 : 0 : rte_free(flow->qos_mask_addr);
5129 : 0 : rte_free(flow->fs_key_addr);
5130 : 0 : rte_free(flow->fs_mask_addr);
5131 : 0 : rte_free(flow);
5132 : : }
5133 : 0 : priv->curr = NULL;
5134 : :
5135 : 0 : return NULL;
5136 : : }
5137 : :
5138 : : static int
5139 : 0 : dpaa2_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *_flow,
5140 : : struct rte_flow_error *error)
5141 : : {
5142 : : int ret = 0;
5143 : : struct dpaa2_dev_flow *flow;
5144 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5145 : 0 : struct fsl_mc_io *dpni = priv->hw;
5146 : :
5147 : : flow = (struct dpaa2_dev_flow *)_flow;
5148 : :
5149 [ # # # ]: 0 : switch (flow->action_type) {
5150 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
5151 : : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
5152 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
5153 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
5154 : : /* Remove entry from QoS table first */
5155 : 0 : ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
5156 : 0 : priv->token,
5157 : 0 : &flow->qos_rule);
5158 [ # # ]: 0 : if (ret < 0) {
5159 : 0 : DPAA2_PMD_ERR("Remove FS QoS entry failed");
5160 : 0 : dpaa2_flow_qos_entry_log("Delete failed", flow,
5161 : : -1);
5162 : 0 : abort();
5163 : : goto error;
5164 : : }
5165 : : }
5166 : :
5167 : : /* Then remove entry from FS table */
5168 : 0 : ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
5169 : 0 : flow->tc_id, &flow->fs_rule);
5170 [ # # ]: 0 : if (ret < 0) {
5171 : 0 : DPAA2_PMD_ERR("Remove entry from FS[%d] failed",
5172 : : flow->tc_id);
5173 : 0 : goto error;
5174 : : }
5175 : : break;
5176 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
5177 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
5178 : 0 : ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
5179 : 0 : priv->token,
5180 : 0 : &flow->qos_rule);
5181 [ # # ]: 0 : if (ret < 0) {
5182 : 0 : DPAA2_PMD_ERR("Remove RSS QoS entry failed");
5183 : 0 : goto error;
5184 : : }
5185 : : }
5186 : : break;
5187 : 0 : default:
5188 : 0 : DPAA2_PMD_ERR("Action(%d) not supported", flow->action_type);
5189 : : ret = -ENOTSUP;
5190 : 0 : break;
5191 : : }
5192 : :
5193 [ # # ]: 0 : LIST_REMOVE(flow, next);
5194 : 0 : rte_free(flow->qos_key_addr);
5195 : 0 : rte_free(flow->qos_mask_addr);
5196 : 0 : rte_free(flow->fs_key_addr);
5197 : 0 : rte_free(flow->fs_mask_addr);
5198 : : /* Now free the flow */
5199 : 0 : rte_free(flow);
5200 : :
5201 : 0 : error:
5202 [ # # ]: 0 : if (ret)
5203 : 0 : rte_flow_error_set(error, EPERM,
5204 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
5205 : : NULL, "unknown");
5206 : 0 : return ret;
5207 : : }
5208 : :
5209 : : /**
5210 : : * Destroy user-configured flow rules.
5211 : : *
5212 : : * This function skips internal flows rules.
5213 : : *
5214 : : * @see rte_flow_flush()
5215 : : * @see rte_flow_ops
5216 : : */
5217 : : static int
5218 : 0 : dpaa2_flow_flush(struct rte_eth_dev *dev,
5219 : : struct rte_flow_error *error)
5220 : : {
5221 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5222 : 0 : struct dpaa2_dev_flow *flow = LIST_FIRST(&priv->flows);
5223 : :
5224 [ # # ]: 0 : while (flow) {
5225 : 0 : struct dpaa2_dev_flow *next = LIST_NEXT(flow, next);
5226 : :
5227 : 0 : dpaa2_flow_destroy(dev, (struct rte_flow *)flow, error);
5228 : : flow = next;
5229 : : }
5230 : 0 : return 0;
5231 : : }
5232 : :
5233 : : static int
5234 : 0 : dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
5235 : : struct rte_flow *_flow __rte_unused,
5236 : : const struct rte_flow_action *actions __rte_unused,
5237 : : void *data __rte_unused,
5238 : : struct rte_flow_error *error __rte_unused)
5239 : : {
5240 : 0 : return 0;
5241 : : }
5242 : :
5243 : : /**
5244 : : * Clean up all flow rules.
5245 : : *
5246 : : * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
5247 : : * rules regardless of whether they are internal or user-configured.
5248 : : *
5249 : : * @param priv
5250 : : * Pointer to private structure.
5251 : : */
5252 : : void
5253 : 0 : dpaa2_flow_clean(struct rte_eth_dev *dev)
5254 : : {
5255 : : struct dpaa2_dev_flow *flow;
5256 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5257 : :
5258 [ # # ]: 0 : while ((flow = LIST_FIRST(&priv->flows)))
5259 : 0 : dpaa2_flow_destroy(dev, (struct rte_flow *)flow, NULL);
5260 : 0 : }
5261 : :
5262 : : const struct rte_flow_ops dpaa2_flow_ops = {
5263 : : .create = dpaa2_flow_create,
5264 : : .validate = dpaa2_flow_validate,
5265 : : .destroy = dpaa2_flow_destroy,
5266 : : .flush = dpaa2_flow_flush,
5267 : : .query = dpaa2_flow_query,
5268 : : };
|