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 : : int end;
634 : :
635 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
636 : 0 : end = flow->qos_rule_size;
637 [ # # ]: 0 : if (end > offset) {
638 : 0 : memmove(flow->qos_key_addr + offset + size,
639 : 0 : flow->qos_key_addr + offset,
640 : 0 : end - offset);
641 : 0 : memset(flow->qos_key_addr + offset,
642 : : 0, size);
643 : :
644 : 0 : memmove(flow->qos_mask_addr + offset + size,
645 : 0 : flow->qos_mask_addr + offset,
646 : : end - offset);
647 : 0 : memset(flow->qos_mask_addr + offset,
648 : : 0, size);
649 : : }
650 : 0 : flow->qos_rule_size += size;
651 : : }
652 : :
653 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
654 : 0 : end = flow->fs_rule_size;
655 [ # # ]: 0 : if (end > offset) {
656 : 0 : memmove(flow->fs_key_addr + offset + size,
657 : 0 : flow->fs_key_addr + offset,
658 : 0 : end - offset);
659 : 0 : memset(flow->fs_key_addr + offset,
660 : : 0, size);
661 : :
662 : 0 : memmove(flow->fs_mask_addr + offset + size,
663 : 0 : flow->fs_mask_addr + offset,
664 : : end - offset);
665 : 0 : memset(flow->fs_mask_addr + offset,
666 : : 0, size);
667 : : }
668 : 0 : flow->fs_rule_size += size;
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 : flow->qos_rule_size++;
1490 : :
1491 : 0 : *key_addr |= (1 << faf_bit_in_byte);
1492 : 0 : *mask_addr |= (1 << faf_bit_in_byte);
1493 : : }
1494 : :
1495 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1496 : : key_extract = &priv->extract.tc_key_extract[group];
1497 : 0 : key_profile = &key_extract->key_profile;
1498 : :
1499 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1500 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1501 [ # # ]: 0 : if (offset < 0) {
1502 : 0 : DPAA2_PMD_ERR("%s TC[%d] key extract failed",
1503 : : __func__, group);
1504 : 0 : return -EINVAL;
1505 : : }
1506 : 0 : key_addr = flow->fs_key_addr + offset;
1507 : 0 : mask_addr = flow->fs_mask_addr + offset;
1508 : :
1509 [ # # ]: 0 : if (!(*key_addr) &&
1510 [ # # ]: 0 : key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1511 : 0 : flow->fs_rule_size++;
1512 : :
1513 : 0 : *key_addr |= (1 << faf_bit_in_byte);
1514 : 0 : *mask_addr |= (1 << faf_bit_in_byte);
1515 : : }
1516 : :
1517 : : return 0;
1518 : : }
1519 : :
1520 : : static inline int
1521 : 0 : dpaa2_flow_pr_rule_data_set(struct dpaa2_dev_flow *flow,
1522 : : struct dpaa2_key_profile *key_profile,
1523 : : uint32_t pr_offset, uint32_t pr_size,
1524 : : const void *key, const void *mask,
1525 : : enum dpaa2_flow_dist_type dist_type)
1526 : : {
1527 : : int offset;
1528 : 0 : uint32_t pr_field = pr_offset << 16 | pr_size;
1529 : :
1530 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1531 : : DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
1532 [ # # ]: 0 : if (offset < 0) {
1533 : 0 : DPAA2_PMD_ERR("PR off(%d)/size(%d) does not exist!",
1534 : : pr_offset, pr_size);
1535 : 0 : return -EINVAL;
1536 : : }
1537 : :
1538 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1539 [ # # ]: 0 : memcpy((flow->qos_key_addr + offset), key, pr_size);
1540 : 0 : memcpy((flow->qos_mask_addr + offset), mask, pr_size);
1541 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1542 : 0 : flow->qos_rule_size = offset + pr_size;
1543 : : }
1544 : :
1545 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1546 [ # # ]: 0 : memcpy((flow->fs_key_addr + offset), key, pr_size);
1547 : 0 : memcpy((flow->fs_mask_addr + offset), mask, pr_size);
1548 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1549 : 0 : flow->fs_rule_size = offset + pr_size;
1550 : : }
1551 : :
1552 : : return 0;
1553 : : }
1554 : :
1555 : : static inline int
1556 : 0 : dpaa2_flow_hdr_rule_data_set(struct dpaa2_dev_flow *flow,
1557 : : struct dpaa2_key_profile *key_profile,
1558 : : enum net_prot prot, uint32_t field, int size,
1559 : : const void *key, const void *mask,
1560 : : enum dpaa2_flow_dist_type dist_type)
1561 : : {
1562 : : int offset;
1563 : :
1564 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field)) {
1565 : 0 : DPAA2_PMD_ERR("%s only for none IP address extract",
1566 : : __func__);
1567 : 0 : return -EINVAL;
1568 : : }
1569 : :
1570 : : offset = dpaa2_flow_extract_key_offset(key_profile,
1571 : : DPAA2_NET_PROT_KEY, prot, field);
1572 [ # # ]: 0 : if (offset < 0) {
1573 : 0 : DPAA2_PMD_ERR("P(%d)/F(%d) does not exist!",
1574 : : prot, field);
1575 : 0 : return -EINVAL;
1576 : : }
1577 : :
1578 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1579 [ # # ]: 0 : memcpy((flow->qos_key_addr + offset), key, size);
1580 : 0 : memcpy((flow->qos_mask_addr + offset), mask, size);
1581 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1582 : 0 : flow->qos_rule_size = offset + size;
1583 : : }
1584 : :
1585 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1586 [ # # ]: 0 : memcpy((flow->fs_key_addr + offset), key, size);
1587 : 0 : memcpy((flow->fs_mask_addr + offset), mask, size);
1588 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1589 : 0 : flow->fs_rule_size = offset + size;
1590 : : }
1591 : :
1592 : : return 0;
1593 : : }
1594 : :
1595 : : static inline int
1596 : 0 : dpaa2_flow_raw_rule_data_set(struct dpaa2_dev_flow *flow,
1597 : : struct dpaa2_key_profile *key_profile,
1598 : : uint32_t extract_offset, int size,
1599 : : const void *key, const void *mask,
1600 : : enum dpaa2_flow_dist_type dist_type)
1601 : : {
1602 : 0 : int extract_size = size > DPAA2_FLOW_MAX_KEY_SIZE ?
1603 : : DPAA2_FLOW_MAX_KEY_SIZE : size;
1604 : : int offset, field;
1605 : :
1606 : 0 : field = extract_offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1607 : : field |= extract_size;
1608 : 0 : offset = dpaa2_flow_extract_key_offset(key_profile,
1609 : : DPAA2_NET_PROT_KEY, NET_PROT_PAYLOAD, field);
1610 [ # # ]: 0 : if (offset < 0) {
1611 : 0 : DPAA2_PMD_ERR("offset(%d)/size(%d) raw extract failed",
1612 : : extract_offset, size);
1613 : 0 : return -EINVAL;
1614 : : }
1615 : :
1616 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1617 : 0 : memcpy((flow->qos_key_addr + offset), key, size);
1618 : 0 : memcpy((flow->qos_mask_addr + offset), mask, size);
1619 : 0 : flow->qos_rule_size = offset + size;
1620 : : }
1621 : :
1622 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1623 : 0 : memcpy((flow->fs_key_addr + offset), key, size);
1624 : 0 : memcpy((flow->fs_mask_addr + offset), mask, size);
1625 : 0 : flow->fs_rule_size = offset + size;
1626 : : }
1627 : :
1628 : : return 0;
1629 : : }
1630 : :
1631 : : static int
1632 : 0 : dpaa2_flow_extract_support(const uint8_t *mask_src,
1633 : : enum rte_flow_item_type type)
1634 : : {
1635 : : char mask[64];
1636 : : int i, size = 0;
1637 : : const char *mask_support = 0;
1638 : :
1639 [ # # # # : 0 : switch (type) {
# # # # #
# # # # #
# ]
1640 : : case RTE_FLOW_ITEM_TYPE_ETH:
1641 : : mask_support = (const char *)&dpaa2_flow_item_eth_mask;
1642 : : size = sizeof(struct rte_flow_item_eth);
1643 : : break;
1644 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
1645 : : mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
1646 : : size = sizeof(struct rte_flow_item_vlan);
1647 : 0 : break;
1648 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
1649 : : mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
1650 : : size = sizeof(struct rte_flow_item_ipv4);
1651 : 0 : break;
1652 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
1653 : : mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
1654 : : size = sizeof(struct rte_flow_item_ipv6);
1655 : 0 : break;
1656 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP:
1657 : : mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
1658 : : size = sizeof(struct rte_flow_item_icmp);
1659 : 0 : break;
1660 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
1661 : : mask_support = (const char *)&dpaa2_flow_item_udp_mask;
1662 : : size = sizeof(struct rte_flow_item_udp);
1663 : 0 : break;
1664 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
1665 : : mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
1666 : : size = sizeof(struct rte_flow_item_tcp);
1667 : 0 : break;
1668 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
1669 : : mask_support = (const char *)&dpaa2_flow_item_esp_mask;
1670 : : size = sizeof(struct rte_flow_item_esp);
1671 : 0 : break;
1672 : 0 : case RTE_FLOW_ITEM_TYPE_AH:
1673 : : mask_support = (const char *)&dpaa2_flow_item_ah_mask;
1674 : : size = sizeof(struct rte_flow_item_ah);
1675 : 0 : break;
1676 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
1677 : : mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
1678 : : size = sizeof(struct rte_flow_item_sctp);
1679 : 0 : break;
1680 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
1681 : : mask_support = (const char *)&dpaa2_flow_item_gre_mask;
1682 : : size = sizeof(struct rte_flow_item_gre);
1683 : 0 : break;
1684 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
1685 : : mask_support = (const char *)&dpaa2_flow_item_vxlan_mask;
1686 : : size = sizeof(struct rte_flow_item_vxlan);
1687 : 0 : break;
1688 : 0 : case RTE_FLOW_ITEM_TYPE_ECPRI:
1689 : : mask_support = (const char *)&dpaa2_flow_item_ecpri_mask;
1690 : : size = sizeof(struct rte_flow_item_ecpri);
1691 : 0 : break;
1692 : 0 : case RTE_FLOW_ITEM_TYPE_GTP:
1693 : : mask_support = (const char *)&dpaa2_flow_item_gtp_mask;
1694 : : size = sizeof(struct rte_flow_item_gtp);
1695 : 0 : break;
1696 : : default:
1697 : : return -EINVAL;
1698 : : }
1699 : :
1700 : 0 : memcpy(mask, mask_support, size);
1701 : :
1702 [ # # ]: 0 : for (i = 0; i < size; i++)
1703 : 0 : mask[i] = (mask[i] | mask_src[i]);
1704 : :
1705 [ # # ]: 0 : if (memcmp(mask, mask_support, size))
1706 : 0 : return -ENOTSUP;
1707 : :
1708 : : return 0;
1709 : : }
1710 : :
1711 : : static int
1712 : 0 : dpaa2_flow_identify_by_faf(struct dpaa2_dev_priv *priv,
1713 : : struct dpaa2_dev_flow *flow,
1714 : : enum dpaa2_rx_faf_offset faf_off,
1715 : : enum dpaa2_flow_dist_type dist_type,
1716 : : int group, int *recfg)
1717 : : {
1718 : : int ret, index, local_cfg = 0;
1719 : : struct dpaa2_key_extract *extract;
1720 : : struct dpaa2_key_profile *key_profile;
1721 : 0 : uint8_t faf_byte = faf_off / 8;
1722 : :
1723 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1724 : : extract = &priv->extract.qos_key_extract;
1725 : 0 : key_profile = &extract->key_profile;
1726 : :
1727 : 0 : index = dpaa2_flow_extract_search(key_profile,
1728 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1729 [ # # ]: 0 : if (index < 0) {
1730 : 0 : ret = dpaa2_flow_faf_add_hdr(faf_byte,
1731 : : priv, DPAA2_FLOW_QOS_TYPE, group,
1732 : : NULL);
1733 [ # # ]: 0 : if (ret) {
1734 : 0 : DPAA2_PMD_ERR("QOS faf extract add failed");
1735 : :
1736 : 0 : return -EINVAL;
1737 : : }
1738 : : local_cfg |= DPAA2_FLOW_QOS_TYPE;
1739 : : }
1740 : :
1741 : 0 : ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
1742 : : DPAA2_FLOW_QOS_TYPE);
1743 [ # # ]: 0 : if (ret) {
1744 : 0 : DPAA2_PMD_ERR("QoS faf rule set failed");
1745 : 0 : return -EINVAL;
1746 : : }
1747 : : }
1748 : :
1749 [ # # ]: 0 : if (dist_type & DPAA2_FLOW_FS_TYPE) {
1750 : : extract = &priv->extract.tc_key_extract[group];
1751 : 0 : key_profile = &extract->key_profile;
1752 : :
1753 : 0 : index = dpaa2_flow_extract_search(key_profile,
1754 : : DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
1755 [ # # ]: 0 : if (index < 0) {
1756 : 0 : ret = dpaa2_flow_faf_add_hdr(faf_byte,
1757 : : priv, DPAA2_FLOW_FS_TYPE, group,
1758 : : NULL);
1759 [ # # ]: 0 : if (ret) {
1760 : 0 : DPAA2_PMD_ERR("FS[%d] faf extract add failed",
1761 : : group);
1762 : :
1763 : 0 : return -EINVAL;
1764 : : }
1765 : 0 : local_cfg |= DPAA2_FLOW_FS_TYPE;
1766 : : }
1767 : :
1768 : 0 : ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
1769 : : DPAA2_FLOW_FS_TYPE);
1770 [ # # ]: 0 : if (ret) {
1771 : 0 : DPAA2_PMD_ERR("FS[%d] faf rule set failed",
1772 : : group);
1773 : 0 : return -EINVAL;
1774 : : }
1775 : : }
1776 : :
1777 [ # # ]: 0 : if (recfg)
1778 : 0 : *recfg |= local_cfg;
1779 : :
1780 : : return 0;
1781 : : }
1782 : :
1783 : : static int
1784 : 0 : dpaa2_flow_add_pr_extract_rule(struct dpaa2_dev_flow *flow,
1785 : : uint32_t pr_offset, uint32_t pr_size,
1786 : : const void *key, const void *mask,
1787 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1788 : : enum dpaa2_flow_dist_type dist_type)
1789 : : {
1790 : : int index, ret, local_cfg = 0;
1791 : : struct dpaa2_key_extract *key_extract;
1792 : : struct dpaa2_key_profile *key_profile;
1793 : 0 : uint32_t pr_field = pr_offset << 16 | pr_size;
1794 : :
1795 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1796 : 0 : key_extract = &priv->extract.qos_key_extract;
1797 : : else
1798 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1799 : :
1800 : 0 : key_profile = &key_extract->key_profile;
1801 : :
1802 : 0 : index = dpaa2_flow_extract_search(key_profile,
1803 : : DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
1804 [ # # ]: 0 : if (index < 0) {
1805 : 0 : ret = dpaa2_flow_pr_add_hdr(pr_offset,
1806 : : pr_size, priv,
1807 : : dist_type, tc_id, NULL);
1808 [ # # ]: 0 : if (ret) {
1809 : 0 : DPAA2_PMD_ERR("PR add off(%d)/size(%d) failed",
1810 : : pr_offset, pr_size);
1811 : :
1812 : 0 : return ret;
1813 : : }
1814 : 0 : local_cfg |= dist_type;
1815 : : }
1816 : :
1817 : 0 : ret = dpaa2_flow_pr_rule_data_set(flow, key_profile,
1818 : : pr_offset, pr_size, key, mask, dist_type);
1819 [ # # ]: 0 : if (ret) {
1820 : 0 : DPAA2_PMD_ERR("PR off(%d)/size(%d) rule data set failed",
1821 : : pr_offset, pr_size);
1822 : :
1823 : 0 : return ret;
1824 : : }
1825 : :
1826 [ # # ]: 0 : if (recfg)
1827 : 0 : *recfg |= local_cfg;
1828 : :
1829 : : return 0;
1830 : : }
1831 : :
1832 : : static int
1833 : 0 : dpaa2_flow_add_hdr_extract_rule(struct dpaa2_dev_flow *flow,
1834 : : enum net_prot prot, uint32_t field,
1835 : : const void *key, const void *mask, int size,
1836 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1837 : : enum dpaa2_flow_dist_type dist_type)
1838 : : {
1839 : : int index, ret, local_cfg = 0;
1840 : : struct dpaa2_key_extract *key_extract;
1841 : : struct dpaa2_key_profile *key_profile;
1842 : :
1843 [ # # ]: 0 : if (dpaa2_flow_ip_address_extract(prot, field))
1844 : : return -EINVAL;
1845 : :
1846 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
1847 : 0 : key_extract = &priv->extract.qos_key_extract;
1848 : : else
1849 : 0 : key_extract = &priv->extract.tc_key_extract[tc_id];
1850 : :
1851 : 0 : key_profile = &key_extract->key_profile;
1852 : :
1853 : 0 : index = dpaa2_flow_extract_search(key_profile,
1854 : : DPAA2_NET_PROT_KEY, prot, field);
1855 [ # # ]: 0 : if (index < 0) {
1856 : 0 : ret = dpaa2_flow_extract_add_hdr(prot,
1857 : : field, size, priv,
1858 : : dist_type, tc_id, NULL);
1859 [ # # ]: 0 : if (ret) {
1860 : 0 : DPAA2_PMD_ERR("QoS Extract P(%d)/F(%d) failed",
1861 : : prot, field);
1862 : :
1863 : 0 : return ret;
1864 : : }
1865 : 0 : local_cfg |= dist_type;
1866 : : }
1867 : :
1868 : 0 : ret = dpaa2_flow_hdr_rule_data_set(flow, key_profile,
1869 : : prot, field, size, key, mask, dist_type);
1870 [ # # ]: 0 : if (ret) {
1871 : 0 : DPAA2_PMD_ERR("QoS P(%d)/F(%d) rule data set failed",
1872 : : prot, field);
1873 : :
1874 : 0 : return ret;
1875 : : }
1876 : :
1877 [ # # ]: 0 : if (recfg)
1878 : 0 : *recfg |= local_cfg;
1879 : :
1880 : : return 0;
1881 : : }
1882 : :
1883 : : static int
1884 : 0 : dpaa2_flow_add_ipaddr_extract_rule(struct dpaa2_dev_flow *flow,
1885 : : enum net_prot prot, uint32_t field,
1886 : : const void *key, const void *mask, int size,
1887 : : struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
1888 : : enum dpaa2_flow_dist_type dist_type)
1889 : : {
1890 : : int local_cfg = 0, num, ipaddr_extract_len = 0;
1891 : : struct dpaa2_key_extract *key_extract;
1892 : : struct dpaa2_key_profile *key_profile;
1893 : : struct dpkg_profile_cfg *dpkg;
1894 : : uint8_t *key_addr, *mask_addr;
1895 : : union ip_addr_extract_rule *ip_addr_data;
1896 : : union ip_addr_extract_rule *ip_addr_mask;
1897 : : enum net_prot orig_prot;
1898 : : uint32_t orig_field;
1899 : :
1900 [ # # ]: 0 : if (prot != NET_PROT_IPV4 && prot != NET_PROT_IPV6)
1901 : : return -EINVAL;
1902 : :
1903 [ # # # # ]: 0 : if (prot == NET_PROT_IPV4 && field != NH_FLD_IPV4_SRC_IP &&
1904 : : field != NH_FLD_IPV4_DST_IP) {
1905 : : return -EINVAL;
1906 : : }
1907 : :
1908 [ # # # # ]: 0 : if (prot == NET_PROT_IPV6 && field != NH_FLD_IPV6_SRC_IP &&
1909 : : field != NH_FLD_IPV6_DST_IP) {
1910 : : return -EINVAL;
1911 : : }
1912 : :
1913 : : orig_prot = prot;
1914 : : orig_field = field;
1915 : :
1916 : 0 : if (prot == NET_PROT_IPV4 &&
1917 [ # # ]: 0 : field == NH_FLD_IPV4_SRC_IP) {
1918 : : prot = NET_PROT_IP;
1919 : : field = NH_FLD_IP_SRC;
1920 : 0 : } else if (prot == NET_PROT_IPV4 &&
1921 [ # # ]: 0 : field == NH_FLD_IPV4_DST_IP) {
1922 : : prot = NET_PROT_IP;
1923 : : field = NH_FLD_IP_DST;
1924 : 0 : } else if (prot == NET_PROT_IPV6 &&
1925 [ # # ]: 0 : field == NH_FLD_IPV6_SRC_IP) {
1926 : : prot = NET_PROT_IP;
1927 : : field = NH_FLD_IP_SRC;
1928 : 0 : } else if (prot == NET_PROT_IPV6 &&
1929 [ # # ]: 0 : field == NH_FLD_IPV6_DST_IP) {
1930 : : prot = NET_PROT_IP;
1931 : : field = NH_FLD_IP_DST;
1932 : : } else {
1933 : 0 : DPAA2_PMD_ERR("Inval P(%d)/F(%d) to extract ip address",
1934 : : prot, field);
1935 : 0 : return -EINVAL;
1936 : : }
1937 : :
1938 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
1939 : : key_extract = &priv->extract.qos_key_extract;
1940 : 0 : key_profile = &key_extract->key_profile;
1941 : 0 : dpkg = &key_extract->dpkg;
1942 : 0 : num = key_profile->num;
1943 : 0 : key_addr = flow->qos_key_addr;
1944 : 0 : mask_addr = flow->qos_mask_addr;
1945 : : } else {
1946 : : key_extract = &priv->extract.tc_key_extract[tc_id];
1947 : 0 : key_profile = &key_extract->key_profile;
1948 : 0 : dpkg = &key_extract->dpkg;
1949 : 0 : num = key_profile->num;
1950 : 0 : key_addr = flow->fs_key_addr;
1951 : 0 : mask_addr = flow->fs_mask_addr;
1952 : : }
1953 : :
1954 [ # # ]: 0 : if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
1955 : 0 : DPAA2_PMD_ERR("Number of extracts overflows");
1956 : 0 : return -EINVAL;
1957 : : }
1958 : :
1959 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
1960 [ # # ]: 0 : if (field == NH_FLD_IP_SRC)
1961 : 0 : key_profile->ip_addr_type = IP_SRC_EXTRACT;
1962 : : else
1963 : 0 : key_profile->ip_addr_type = IP_DST_EXTRACT;
1964 : : ipaddr_extract_len = size;
1965 : :
1966 : 0 : key_profile->ip_addr_extract_pos = num;
1967 [ # # ]: 0 : if (num > 0) {
1968 : 0 : key_profile->ip_addr_extract_off =
1969 : 0 : key_profile->key_offset[num - 1] +
1970 : 0 : key_profile->key_size[num - 1];
1971 : : } else {
1972 : 0 : key_profile->ip_addr_extract_off = 0;
1973 : : }
1974 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
1975 [ # # ]: 0 : } else if (key_profile->ip_addr_type == IP_SRC_EXTRACT) {
1976 [ # # ]: 0 : if (field == NH_FLD_IP_SRC) {
1977 : : ipaddr_extract_len = size;
1978 : 0 : goto rule_configure;
1979 : : }
1980 : 0 : key_profile->ip_addr_type = IP_SRC_DST_EXTRACT;
1981 : 0 : ipaddr_extract_len = size * 2;
1982 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
1983 [ # # ]: 0 : } else if (key_profile->ip_addr_type == IP_DST_EXTRACT) {
1984 [ # # ]: 0 : if (field == NH_FLD_IP_DST) {
1985 : : ipaddr_extract_len = size;
1986 : 0 : goto rule_configure;
1987 : : }
1988 : 0 : key_profile->ip_addr_type = IP_DST_SRC_EXTRACT;
1989 : 0 : ipaddr_extract_len = size * 2;
1990 : 0 : key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
1991 : : }
1992 : 0 : key_profile->num++;
1993 : 0 : key_profile->prot_field[num].type = DPAA2_NET_PROT_KEY;
1994 : :
1995 : 0 : dpkg->extracts[num].extract.from_hdr.prot = prot;
1996 : 0 : dpkg->extracts[num].extract.from_hdr.field = field;
1997 : 0 : dpkg->extracts[num].extract.from_hdr.type = DPKG_FULL_FIELD;
1998 : 0 : dpkg->num_extracts++;
1999 : :
2000 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE)
2001 : : local_cfg = DPAA2_FLOW_QOS_TYPE;
2002 : : else
2003 : : local_cfg = DPAA2_FLOW_FS_TYPE;
2004 : :
2005 : 0 : rule_configure:
2006 : 0 : key_addr += key_profile->ip_addr_extract_off;
2007 : : ip_addr_data = (union ip_addr_extract_rule *)key_addr;
2008 : 0 : mask_addr += key_profile->ip_addr_extract_off;
2009 : : ip_addr_mask = (union ip_addr_extract_rule *)mask_addr;
2010 : :
2011 [ # # ]: 0 : if (orig_prot == NET_PROT_IPV4 &&
2012 : : orig_field == NH_FLD_IPV4_SRC_IP) {
2013 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
2014 : : key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
2015 : 0 : memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_src,
2016 : : key, size);
2017 : 0 : memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_src,
2018 : : mask, size);
2019 : : } else {
2020 : 0 : memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_src,
2021 : : key, size);
2022 : 0 : memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_src,
2023 : : mask, size);
2024 : : }
2025 : 0 : } else if (orig_prot == NET_PROT_IPV4 &&
2026 [ # # ]: 0 : orig_field == NH_FLD_IPV4_DST_IP) {
2027 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
2028 : : key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
2029 : 0 : memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_dst,
2030 : : key, size);
2031 : 0 : memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_dst,
2032 : : mask, size);
2033 : : } else {
2034 : 0 : memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_dst,
2035 : : key, size);
2036 : 0 : memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_dst,
2037 : : mask, size);
2038 : : }
2039 : 0 : } else if (orig_prot == NET_PROT_IPV6 &&
2040 [ # # ]: 0 : orig_field == NH_FLD_IPV6_SRC_IP) {
2041 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
2042 : : key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
2043 : 0 : memcpy(ip_addr_data->ipv6_sd_addr.ipv6_src,
2044 : : key, size);
2045 : 0 : memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_src,
2046 : : mask, size);
2047 : : } else {
2048 : 0 : memcpy(ip_addr_data->ipv6_ds_addr.ipv6_src,
2049 : : key, size);
2050 : 0 : memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_src,
2051 : : mask, size);
2052 : : }
2053 : 0 : } else if (orig_prot == NET_PROT_IPV6 &&
2054 [ # # ]: 0 : orig_field == NH_FLD_IPV6_DST_IP) {
2055 [ # # ]: 0 : if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
2056 : : key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
2057 : 0 : memcpy(ip_addr_data->ipv6_ds_addr.ipv6_dst,
2058 : : key, size);
2059 : 0 : memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_dst,
2060 : : mask, size);
2061 : : } else {
2062 : 0 : memcpy(ip_addr_data->ipv6_sd_addr.ipv6_dst,
2063 : : key, size);
2064 : 0 : memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_dst,
2065 : : mask, size);
2066 : : }
2067 : : }
2068 : :
2069 [ # # ]: 0 : if (dist_type == DPAA2_FLOW_QOS_TYPE) {
2070 : 0 : flow->qos_rule_size =
2071 : 0 : key_profile->ip_addr_extract_off + ipaddr_extract_len;
2072 : : } else {
2073 : 0 : flow->fs_rule_size =
2074 : 0 : key_profile->ip_addr_extract_off + ipaddr_extract_len;
2075 : : }
2076 : :
2077 [ # # ]: 0 : if (recfg)
2078 : 0 : *recfg |= local_cfg;
2079 : :
2080 : : return 0;
2081 : : }
2082 : :
2083 : : static int
2084 : 0 : dpaa2_configure_flow_tunnel_eth(struct dpaa2_dev_flow *flow,
2085 : : struct rte_eth_dev *dev,
2086 : : const struct rte_flow_attr *attr,
2087 : : const struct rte_flow_item *pattern,
2088 : : int *device_configured)
2089 : : {
2090 : 0 : int ret, local_cfg = 0;
2091 : : uint32_t group;
2092 : : const struct rte_flow_item_eth *spec, *mask;
2093 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2094 : 0 : const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
2095 : :
2096 : 0 : group = attr->group;
2097 : :
2098 : : /* Parse pattern list to get the matching parameters */
2099 : 0 : spec = pattern->spec;
2100 : 0 : mask = pattern->mask ?
2101 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_eth_mask;
2102 : :
2103 : : /* Get traffic class index and flow id to be configured */
2104 : 0 : flow->tc_id = group;
2105 : 0 : flow->tc_index = attr->priority;
2106 : :
2107 [ # # ]: 0 : if (!spec)
2108 : : return 0;
2109 : :
2110 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2111 : : RTE_FLOW_ITEM_TYPE_ETH);
2112 [ # # ]: 0 : if (ret) {
2113 : 0 : DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
2114 : :
2115 : 0 : return ret;
2116 : : }
2117 : :
2118 [ # # ]: 0 : if (memcmp((const char *)&mask->src,
2119 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2120 : : /*SRC[0:1]*/
2121 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2122 : : DPAA2_VXLAN_IN_SADDR0_OFFSET,
2123 : 0 : 1, &spec->src.addr_bytes[0],
2124 : 0 : &mask->src.addr_bytes[0],
2125 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2126 [ # # ]: 0 : if (ret)
2127 : : return ret;
2128 : : /*SRC[1:2]*/
2129 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2130 : : DPAA2_VXLAN_IN_SADDR1_OFFSET,
2131 : 0 : 2, &spec->src.addr_bytes[1],
2132 : 0 : &mask->src.addr_bytes[1],
2133 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2134 [ # # ]: 0 : if (ret)
2135 : : return ret;
2136 : : /*SRC[3:1]*/
2137 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2138 : : DPAA2_VXLAN_IN_SADDR3_OFFSET,
2139 : 0 : 1, &spec->src.addr_bytes[3],
2140 : 0 : &mask->src.addr_bytes[3],
2141 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2142 [ # # ]: 0 : if (ret)
2143 : : return ret;
2144 : : /*SRC[4:2]*/
2145 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2146 : : DPAA2_VXLAN_IN_SADDR4_OFFSET,
2147 : 0 : 2, &spec->src.addr_bytes[4],
2148 : 0 : &mask->src.addr_bytes[4],
2149 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2150 [ # # ]: 0 : if (ret)
2151 : : return ret;
2152 : :
2153 : : /*SRC[0:1]*/
2154 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2155 : : DPAA2_VXLAN_IN_SADDR0_OFFSET,
2156 : : 1, &spec->src.addr_bytes[0],
2157 : : &mask->src.addr_bytes[0],
2158 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2159 [ # # ]: 0 : if (ret)
2160 : : return ret;
2161 : : /*SRC[1:2]*/
2162 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2163 : : DPAA2_VXLAN_IN_SADDR1_OFFSET,
2164 : : 2, &spec->src.addr_bytes[1],
2165 : : &mask->src.addr_bytes[1],
2166 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2167 [ # # ]: 0 : if (ret)
2168 : : return ret;
2169 : : /*SRC[3:1]*/
2170 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2171 : : DPAA2_VXLAN_IN_SADDR3_OFFSET,
2172 : : 1, &spec->src.addr_bytes[3],
2173 : : &mask->src.addr_bytes[3],
2174 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2175 [ # # ]: 0 : if (ret)
2176 : : return ret;
2177 : : /*SRC[4:2]*/
2178 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2179 : : DPAA2_VXLAN_IN_SADDR4_OFFSET,
2180 : : 2, &spec->src.addr_bytes[4],
2181 : : &mask->src.addr_bytes[4],
2182 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2183 [ # # ]: 0 : if (ret)
2184 : : return ret;
2185 : : }
2186 : :
2187 [ # # ]: 0 : if (memcmp((const char *)&mask->dst,
2188 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2189 : : /*DST[0:1]*/
2190 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2191 : : DPAA2_VXLAN_IN_DADDR0_OFFSET,
2192 : 0 : 1, &spec->dst.addr_bytes[0],
2193 : 0 : &mask->dst.addr_bytes[0],
2194 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2195 [ # # ]: 0 : if (ret)
2196 : : return ret;
2197 : : /*DST[1:1]*/
2198 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2199 : : DPAA2_VXLAN_IN_DADDR1_OFFSET,
2200 : 0 : 1, &spec->dst.addr_bytes[1],
2201 : 0 : &mask->dst.addr_bytes[1],
2202 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2203 [ # # ]: 0 : if (ret)
2204 : : return ret;
2205 : : /*DST[2:3]*/
2206 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2207 : : DPAA2_VXLAN_IN_DADDR2_OFFSET,
2208 : 0 : 3, &spec->dst.addr_bytes[2],
2209 : 0 : &mask->dst.addr_bytes[2],
2210 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2211 [ # # ]: 0 : if (ret)
2212 : : return ret;
2213 : : /*DST[5:1]*/
2214 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2215 : : DPAA2_VXLAN_IN_DADDR5_OFFSET,
2216 : 0 : 1, &spec->dst.addr_bytes[5],
2217 : 0 : &mask->dst.addr_bytes[5],
2218 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2219 [ # # ]: 0 : if (ret)
2220 : : return ret;
2221 : :
2222 : : /*DST[0:1]*/
2223 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2224 : : DPAA2_VXLAN_IN_DADDR0_OFFSET,
2225 : : 1, &spec->dst.addr_bytes[0],
2226 : : &mask->dst.addr_bytes[0],
2227 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2228 [ # # ]: 0 : if (ret)
2229 : : return ret;
2230 : : /*DST[1:1]*/
2231 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2232 : : DPAA2_VXLAN_IN_DADDR1_OFFSET,
2233 : : 1, &spec->dst.addr_bytes[1],
2234 : : &mask->dst.addr_bytes[1],
2235 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2236 [ # # ]: 0 : if (ret)
2237 : : return ret;
2238 : : /*DST[2:3]*/
2239 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2240 : : DPAA2_VXLAN_IN_DADDR2_OFFSET,
2241 : : 3, &spec->dst.addr_bytes[2],
2242 : : &mask->dst.addr_bytes[2],
2243 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2244 [ # # ]: 0 : if (ret)
2245 : : return ret;
2246 : : /*DST[5:1]*/
2247 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2248 : : DPAA2_VXLAN_IN_DADDR5_OFFSET,
2249 : : 1, &spec->dst.addr_bytes[5],
2250 : : &mask->dst.addr_bytes[5],
2251 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2252 [ # # ]: 0 : if (ret)
2253 : : return ret;
2254 : : }
2255 : :
2256 [ # # ]: 0 : if (memcmp((const char *)&mask->type,
2257 : : zero_cmp, sizeof(rte_be16_t))) {
2258 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2259 : : DPAA2_VXLAN_IN_TYPE_OFFSET,
2260 : 0 : sizeof(rte_be16_t), &spec->type, &mask->type,
2261 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2262 [ # # ]: 0 : if (ret)
2263 : : return ret;
2264 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2265 : : DPAA2_VXLAN_IN_TYPE_OFFSET,
2266 : : sizeof(rte_be16_t), &spec->type, &mask->type,
2267 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2268 [ # # ]: 0 : if (ret)
2269 : : return ret;
2270 : : }
2271 : :
2272 : 0 : (*device_configured) |= local_cfg;
2273 : :
2274 : 0 : return 0;
2275 : : }
2276 : :
2277 : : static int
2278 : 0 : dpaa2_configure_flow_eth(struct dpaa2_dev_flow *flow,
2279 : : struct rte_eth_dev *dev,
2280 : : const struct rte_flow_attr *attr,
2281 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2282 : : const struct rte_flow_action actions[] __rte_unused,
2283 : : struct rte_flow_error *error __rte_unused,
2284 : : int *device_configured)
2285 : : {
2286 : 0 : int ret, local_cfg = 0;
2287 : : uint32_t group;
2288 : : const struct rte_flow_item_eth *spec, *mask;
2289 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2290 : 0 : const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
2291 : 0 : const struct rte_flow_item *pattern =
2292 : : &dpaa2_pattern->generic_item;
2293 : :
2294 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2295 : 0 : return dpaa2_configure_flow_tunnel_eth(flow,
2296 : : dev, attr, pattern, device_configured);
2297 : : }
2298 : :
2299 : 0 : group = attr->group;
2300 : :
2301 : : /* Parse pattern list to get the matching parameters */
2302 : 0 : spec = pattern->spec;
2303 : 0 : mask = pattern->mask ?
2304 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_eth_mask;
2305 : :
2306 : : /* Get traffic class index and flow id to be configured */
2307 : 0 : flow->tc_id = group;
2308 : 0 : flow->tc_index = attr->priority;
2309 : :
2310 [ # # ]: 0 : if (!spec) {
2311 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2312 : : FAF_ETH_FRAM, DPAA2_FLOW_QOS_TYPE,
2313 : : group, &local_cfg);
2314 [ # # ]: 0 : if (ret)
2315 : : return ret;
2316 : :
2317 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2318 : : FAF_ETH_FRAM, DPAA2_FLOW_FS_TYPE,
2319 : : group, &local_cfg);
2320 [ # # ]: 0 : if (ret)
2321 : : return ret;
2322 : :
2323 : 0 : (*device_configured) |= local_cfg;
2324 : 0 : return 0;
2325 : : }
2326 : :
2327 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2328 : : RTE_FLOW_ITEM_TYPE_ETH);
2329 [ # # ]: 0 : if (ret) {
2330 : 0 : DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
2331 : :
2332 : 0 : return ret;
2333 : : }
2334 : :
2335 [ # # ]: 0 : if (memcmp((const char *)&mask->src,
2336 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2337 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2338 : 0 : NH_FLD_ETH_SA, &spec->src.addr_bytes,
2339 : 0 : &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
2340 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2341 [ # # ]: 0 : if (ret)
2342 : : return ret;
2343 : :
2344 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2345 : : NH_FLD_ETH_SA, &spec->src.addr_bytes,
2346 : : &mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
2347 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2348 [ # # ]: 0 : if (ret)
2349 : : return ret;
2350 : : }
2351 : :
2352 [ # # ]: 0 : if (memcmp((const char *)&mask->dst,
2353 : : zero_cmp, RTE_ETHER_ADDR_LEN)) {
2354 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2355 : 0 : NH_FLD_ETH_DA, &spec->dst.addr_bytes,
2356 : 0 : &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
2357 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2358 [ # # ]: 0 : if (ret)
2359 : : return ret;
2360 : :
2361 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2362 : : NH_FLD_ETH_DA, &spec->dst.addr_bytes,
2363 : : &mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
2364 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2365 [ # # ]: 0 : if (ret)
2366 : : return ret;
2367 : : }
2368 : :
2369 [ # # ]: 0 : if (memcmp((const char *)&mask->type,
2370 : : zero_cmp, sizeof(rte_be16_t))) {
2371 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2372 : 0 : NH_FLD_ETH_TYPE, &spec->type,
2373 : : &mask->type, sizeof(rte_be16_t),
2374 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2375 [ # # ]: 0 : if (ret)
2376 : : return ret;
2377 : :
2378 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
2379 : : NH_FLD_ETH_TYPE, &spec->type,
2380 : : &mask->type, sizeof(rte_be16_t),
2381 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2382 [ # # ]: 0 : if (ret)
2383 : : return ret;
2384 : : }
2385 : :
2386 : 0 : (*device_configured) |= local_cfg;
2387 : :
2388 : 0 : return 0;
2389 : : }
2390 : :
2391 : : static int
2392 : 0 : dpaa2_configure_flow_tunnel_vlan(struct dpaa2_dev_flow *flow,
2393 : : struct rte_eth_dev *dev,
2394 : : const struct rte_flow_attr *attr,
2395 : : const struct rte_flow_item *pattern,
2396 : : int *device_configured)
2397 : : {
2398 : 0 : int ret, local_cfg = 0;
2399 : : uint32_t group;
2400 : : const struct rte_flow_item_vlan *spec, *mask;
2401 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2402 : :
2403 : 0 : group = attr->group;
2404 : :
2405 : : /* Parse pattern list to get the matching parameters */
2406 : 0 : spec = pattern->spec;
2407 : 0 : mask = pattern->mask ?
2408 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_vlan_mask;
2409 : :
2410 : : /* Get traffic class index and flow id to be configured */
2411 : 0 : flow->tc_id = group;
2412 : 0 : flow->tc_index = attr->priority;
2413 : :
2414 [ # # ]: 0 : if (!spec) {
2415 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2416 : : FAFE_VXLAN_IN_VLAN_FRAM,
2417 : : DPAA2_FLOW_QOS_TYPE,
2418 : : group, &local_cfg);
2419 [ # # ]: 0 : if (ret)
2420 : : return ret;
2421 : :
2422 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2423 : : FAFE_VXLAN_IN_VLAN_FRAM,
2424 : : DPAA2_FLOW_FS_TYPE,
2425 : : group, &local_cfg);
2426 [ # # ]: 0 : if (ret)
2427 : : return ret;
2428 : :
2429 : 0 : (*device_configured) |= local_cfg;
2430 : 0 : return 0;
2431 : : }
2432 : :
2433 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2434 : : RTE_FLOW_ITEM_TYPE_VLAN);
2435 [ # # ]: 0 : if (ret) {
2436 : 0 : DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
2437 : :
2438 : 0 : return ret;
2439 : : }
2440 : :
2441 [ # # ]: 0 : if (!mask->tci)
2442 : : return 0;
2443 : :
2444 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2445 : : DPAA2_VXLAN_IN_TCI_OFFSET,
2446 : 0 : sizeof(rte_be16_t), &spec->tci, &mask->tci,
2447 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2448 [ # # ]: 0 : if (ret)
2449 : : return ret;
2450 : :
2451 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
2452 : : DPAA2_VXLAN_IN_TCI_OFFSET,
2453 : : sizeof(rte_be16_t), &spec->tci, &mask->tci,
2454 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2455 [ # # ]: 0 : if (ret)
2456 : : return ret;
2457 : :
2458 : 0 : (*device_configured) |= local_cfg;
2459 : :
2460 : 0 : return 0;
2461 : : }
2462 : :
2463 : : static int
2464 : 0 : dpaa2_configure_flow_vlan(struct dpaa2_dev_flow *flow,
2465 : : struct rte_eth_dev *dev,
2466 : : const struct rte_flow_attr *attr,
2467 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2468 : : const struct rte_flow_action actions[] __rte_unused,
2469 : : struct rte_flow_error *error __rte_unused,
2470 : : int *device_configured)
2471 : : {
2472 : 0 : int ret, local_cfg = 0;
2473 : : uint32_t group;
2474 : : const struct rte_flow_item_vlan *spec, *mask;
2475 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2476 : 0 : const struct rte_flow_item *pattern =
2477 : : &dpaa2_pattern->generic_item;
2478 : :
2479 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2480 : 0 : return dpaa2_configure_flow_tunnel_vlan(flow,
2481 : : dev, attr, pattern, device_configured);
2482 : : }
2483 : :
2484 : 0 : group = attr->group;
2485 : :
2486 : : /* Parse pattern list to get the matching parameters */
2487 : 0 : spec = pattern->spec;
2488 [ # # ]: 0 : mask = pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask;
2489 : :
2490 : : /* Get traffic class index and flow id to be configured */
2491 : 0 : flow->tc_id = group;
2492 : 0 : flow->tc_index = attr->priority;
2493 : :
2494 [ # # ]: 0 : if (!spec) {
2495 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2496 : : DPAA2_FLOW_QOS_TYPE, group,
2497 : : &local_cfg);
2498 [ # # ]: 0 : if (ret)
2499 : : return ret;
2500 : :
2501 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2502 : : DPAA2_FLOW_FS_TYPE, group,
2503 : : &local_cfg);
2504 [ # # ]: 0 : if (ret)
2505 : : return ret;
2506 : :
2507 : 0 : (*device_configured) |= local_cfg;
2508 : 0 : return 0;
2509 : : }
2510 : :
2511 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2512 : : RTE_FLOW_ITEM_TYPE_VLAN);
2513 [ # # ]: 0 : if (ret) {
2514 : 0 : DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
2515 : 0 : return ret;
2516 : : }
2517 : :
2518 [ # # ]: 0 : if (!mask->tci)
2519 : : return 0;
2520 : :
2521 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
2522 : 0 : NH_FLD_VLAN_TCI, &spec->tci,
2523 : 0 : &mask->tci, sizeof(rte_be16_t),
2524 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2525 [ # # ]: 0 : if (ret)
2526 : : return ret;
2527 : :
2528 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
2529 : : NH_FLD_VLAN_TCI, &spec->tci,
2530 : : &mask->tci, sizeof(rte_be16_t),
2531 : : priv, group, &local_cfg,
2532 : : DPAA2_FLOW_FS_TYPE);
2533 [ # # ]: 0 : if (ret)
2534 : : return ret;
2535 : :
2536 : 0 : (*device_configured) |= local_cfg;
2537 : 0 : return 0;
2538 : : }
2539 : :
2540 : : static int
2541 : 0 : dpaa2_configure_flow_ipv4(struct dpaa2_dev_flow *flow,
2542 : : struct rte_eth_dev *dev,
2543 : : const struct rte_flow_attr *attr,
2544 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2545 : : const struct rte_flow_action actions[] __rte_unused,
2546 : : struct rte_flow_error *error __rte_unused,
2547 : : int *device_configured)
2548 : : {
2549 : 0 : int ret, local_cfg = 0;
2550 : : uint32_t group;
2551 : : const struct rte_flow_item_ipv4 *spec_ipv4 = 0, *mask_ipv4 = 0;
2552 : : const void *key, *mask;
2553 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2554 : : int size;
2555 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2556 : :
2557 : 0 : group = attr->group;
2558 : :
2559 : : /* Parse pattern list to get the matching parameters */
2560 : 0 : spec_ipv4 = pattern->spec;
2561 : 0 : mask_ipv4 = pattern->mask ?
2562 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_ipv4_mask;
2563 : :
2564 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2565 [ # # ]: 0 : if (spec_ipv4) {
2566 : 0 : DPAA2_PMD_ERR("Tunnel-IPv4 distribution not support");
2567 : 0 : return -ENOTSUP;
2568 : : }
2569 : :
2570 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2571 : : FAFE_VXLAN_IN_IPV4_FRAM,
2572 : : DPAA2_FLOW_QOS_TYPE, group,
2573 : : &local_cfg);
2574 [ # # ]: 0 : if (ret)
2575 : : return ret;
2576 : :
2577 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2578 : : FAFE_VXLAN_IN_IPV4_FRAM,
2579 : : DPAA2_FLOW_FS_TYPE, group,
2580 : : &local_cfg);
2581 : 0 : return ret;
2582 : : }
2583 : :
2584 : : /* Get traffic class index and flow id to be configured */
2585 : 0 : flow->tc_id = group;
2586 : 0 : flow->tc_index = attr->priority;
2587 : :
2588 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2589 : : DPAA2_FLOW_QOS_TYPE, group,
2590 : : &local_cfg);
2591 [ # # ]: 0 : if (ret)
2592 : : return ret;
2593 : :
2594 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2595 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2596 [ # # ]: 0 : if (ret)
2597 : : return ret;
2598 : :
2599 [ # # ]: 0 : if (!spec_ipv4) {
2600 : 0 : (*device_configured) |= local_cfg;
2601 : 0 : return 0;
2602 : : }
2603 : :
2604 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
2605 : : RTE_FLOW_ITEM_TYPE_IPV4);
2606 [ # # ]: 0 : if (ret) {
2607 : 0 : DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
2608 : 0 : return ret;
2609 : : }
2610 : :
2611 [ # # ]: 0 : if (mask_ipv4->hdr.src_addr) {
2612 : 0 : key = &spec_ipv4->hdr.src_addr;
2613 : 0 : mask = &mask_ipv4->hdr.src_addr;
2614 : : size = sizeof(rte_be32_t);
2615 : :
2616 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2617 : : NH_FLD_IPV4_SRC_IP,
2618 : : key, mask, size, priv,
2619 : : group, &local_cfg,
2620 : : DPAA2_FLOW_QOS_TYPE);
2621 [ # # ]: 0 : if (ret)
2622 : : return ret;
2623 : :
2624 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2625 : : NH_FLD_IPV4_SRC_IP,
2626 : : key, mask, size, priv,
2627 : : group, &local_cfg,
2628 : : DPAA2_FLOW_FS_TYPE);
2629 [ # # ]: 0 : if (ret)
2630 : : return ret;
2631 : : }
2632 : :
2633 [ # # ]: 0 : if (mask_ipv4->hdr.dst_addr) {
2634 : 0 : key = &spec_ipv4->hdr.dst_addr;
2635 : 0 : mask = &mask_ipv4->hdr.dst_addr;
2636 : : size = sizeof(rte_be32_t);
2637 : :
2638 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2639 : : NH_FLD_IPV4_DST_IP,
2640 : : key, mask, size, priv,
2641 : : group, &local_cfg,
2642 : : DPAA2_FLOW_QOS_TYPE);
2643 [ # # ]: 0 : if (ret)
2644 : : return ret;
2645 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
2646 : : NH_FLD_IPV4_DST_IP,
2647 : : key, mask, size, priv,
2648 : : group, &local_cfg,
2649 : : DPAA2_FLOW_FS_TYPE);
2650 [ # # ]: 0 : if (ret)
2651 : : return ret;
2652 : : }
2653 : :
2654 [ # # ]: 0 : if (mask_ipv4->hdr.next_proto_id) {
2655 : 0 : key = &spec_ipv4->hdr.next_proto_id;
2656 : 0 : mask = &mask_ipv4->hdr.next_proto_id;
2657 : : size = sizeof(uint8_t);
2658 : :
2659 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2660 : : NH_FLD_IP_PROTO, key,
2661 : : mask, size, priv, group,
2662 : : &local_cfg,
2663 : : DPAA2_FLOW_QOS_TYPE);
2664 [ # # ]: 0 : if (ret)
2665 : : return ret;
2666 : :
2667 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2668 : : NH_FLD_IP_PROTO, key,
2669 : : mask, size, priv, group,
2670 : : &local_cfg,
2671 : : DPAA2_FLOW_FS_TYPE);
2672 [ # # ]: 0 : if (ret)
2673 : : return ret;
2674 : : }
2675 : :
2676 : 0 : (*device_configured) |= local_cfg;
2677 : 0 : return 0;
2678 : : }
2679 : :
2680 : : static int
2681 : 0 : dpaa2_configure_flow_ipv6(struct dpaa2_dev_flow *flow,
2682 : : struct rte_eth_dev *dev,
2683 : : const struct rte_flow_attr *attr,
2684 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2685 : : const struct rte_flow_action actions[] __rte_unused,
2686 : : struct rte_flow_error *error __rte_unused,
2687 : : int *device_configured)
2688 : : {
2689 : 0 : int ret, local_cfg = 0;
2690 : : uint32_t group;
2691 : : const struct rte_flow_item_ipv6 *spec_ipv6 = 0, *mask_ipv6 = 0;
2692 : : const void *key, *mask;
2693 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2694 : 0 : const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
2695 : : int size;
2696 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2697 : :
2698 : 0 : group = attr->group;
2699 : :
2700 : : /* Parse pattern list to get the matching parameters */
2701 : 0 : spec_ipv6 = pattern->spec;
2702 [ # # ]: 0 : mask_ipv6 = pattern->mask ? pattern->mask : &dpaa2_flow_item_ipv6_mask;
2703 : :
2704 : : /* Get traffic class index and flow id to be configured */
2705 : 0 : flow->tc_id = group;
2706 : 0 : flow->tc_index = attr->priority;
2707 : :
2708 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2709 [ # # ]: 0 : if (spec_ipv6) {
2710 : 0 : DPAA2_PMD_ERR("Tunnel-IPv6 distribution not support");
2711 : 0 : return -ENOTSUP;
2712 : : }
2713 : :
2714 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2715 : : FAFE_VXLAN_IN_IPV6_FRAM,
2716 : : DPAA2_FLOW_QOS_TYPE, group,
2717 : : &local_cfg);
2718 [ # # ]: 0 : if (ret)
2719 : : return ret;
2720 : :
2721 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2722 : : FAFE_VXLAN_IN_IPV6_FRAM,
2723 : : DPAA2_FLOW_FS_TYPE, group,
2724 : : &local_cfg);
2725 : 0 : return ret;
2726 : : }
2727 : :
2728 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2729 : : DPAA2_FLOW_QOS_TYPE, group,
2730 : : &local_cfg);
2731 [ # # ]: 0 : if (ret)
2732 : : return ret;
2733 : :
2734 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2735 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2736 [ # # ]: 0 : if (ret)
2737 : : return ret;
2738 : :
2739 [ # # ]: 0 : if (!spec_ipv6) {
2740 : 0 : (*device_configured) |= local_cfg;
2741 : 0 : return 0;
2742 : : }
2743 : :
2744 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
2745 : : RTE_FLOW_ITEM_TYPE_IPV6);
2746 [ # # ]: 0 : if (ret) {
2747 : 0 : DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
2748 : 0 : return ret;
2749 : : }
2750 : :
2751 [ # # ]: 0 : if (memcmp((const char *)&mask_ipv6->hdr.src_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
2752 : 0 : key = &spec_ipv6->hdr.src_addr;
2753 : : mask = &mask_ipv6->hdr.src_addr;
2754 : : size = NH_FLD_IPV6_ADDR_SIZE;
2755 : :
2756 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2757 : : NH_FLD_IPV6_SRC_IP,
2758 : : key, mask, size, priv,
2759 : : group, &local_cfg,
2760 : : DPAA2_FLOW_QOS_TYPE);
2761 [ # # ]: 0 : if (ret)
2762 : : return ret;
2763 : :
2764 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2765 : : NH_FLD_IPV6_SRC_IP,
2766 : : key, mask, size, priv,
2767 : : group, &local_cfg,
2768 : : DPAA2_FLOW_FS_TYPE);
2769 [ # # ]: 0 : if (ret)
2770 : : return ret;
2771 : : }
2772 : :
2773 [ # # ]: 0 : if (memcmp((const char *)&mask_ipv6->hdr.dst_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
2774 : 0 : key = &spec_ipv6->hdr.dst_addr;
2775 : : mask = &mask_ipv6->hdr.dst_addr;
2776 : : size = NH_FLD_IPV6_ADDR_SIZE;
2777 : :
2778 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2779 : : NH_FLD_IPV6_DST_IP,
2780 : : key, mask, size, priv,
2781 : : group, &local_cfg,
2782 : : DPAA2_FLOW_QOS_TYPE);
2783 [ # # ]: 0 : if (ret)
2784 : : return ret;
2785 : :
2786 : 0 : ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
2787 : : NH_FLD_IPV6_DST_IP,
2788 : : key, mask, size, priv,
2789 : : group, &local_cfg,
2790 : : DPAA2_FLOW_FS_TYPE);
2791 [ # # ]: 0 : if (ret)
2792 : : return ret;
2793 : : }
2794 : :
2795 [ # # ]: 0 : if (mask_ipv6->hdr.proto) {
2796 : 0 : key = &spec_ipv6->hdr.proto;
2797 : 0 : mask = &mask_ipv6->hdr.proto;
2798 : : size = sizeof(uint8_t);
2799 : :
2800 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2801 : : NH_FLD_IP_PROTO, key,
2802 : : mask, size, priv, group,
2803 : : &local_cfg,
2804 : : DPAA2_FLOW_QOS_TYPE);
2805 [ # # ]: 0 : if (ret)
2806 : : return ret;
2807 : :
2808 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
2809 : : NH_FLD_IP_PROTO, key,
2810 : : mask, size, priv, group,
2811 : : &local_cfg,
2812 : : DPAA2_FLOW_FS_TYPE);
2813 [ # # ]: 0 : if (ret)
2814 : : return ret;
2815 : : }
2816 : :
2817 : 0 : (*device_configured) |= local_cfg;
2818 : 0 : return 0;
2819 : : }
2820 : :
2821 : : static int
2822 : 0 : dpaa2_configure_flow_icmp(struct dpaa2_dev_flow *flow,
2823 : : struct rte_eth_dev *dev,
2824 : : const struct rte_flow_attr *attr,
2825 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2826 : : const struct rte_flow_action actions[] __rte_unused,
2827 : : struct rte_flow_error *error __rte_unused,
2828 : : int *device_configured)
2829 : : {
2830 : 0 : int ret, local_cfg = 0;
2831 : : uint32_t group;
2832 : : const struct rte_flow_item_icmp *spec, *mask;
2833 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2834 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2835 : :
2836 : 0 : group = attr->group;
2837 : :
2838 : : /* Parse pattern list to get the matching parameters */
2839 : 0 : spec = pattern->spec;
2840 : 0 : mask = pattern->mask ?
2841 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_icmp_mask;
2842 : :
2843 : : /* Get traffic class index and flow id to be configured */
2844 : 0 : flow->tc_id = group;
2845 : 0 : flow->tc_index = attr->priority;
2846 : :
2847 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2848 : 0 : DPAA2_PMD_ERR("Tunnel-ICMP distribution not support");
2849 : 0 : return -ENOTSUP;
2850 : : }
2851 : :
2852 [ # # ]: 0 : if (!spec) {
2853 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2854 : : FAF_ICMP_FRAM, DPAA2_FLOW_QOS_TYPE,
2855 : : group, &local_cfg);
2856 [ # # ]: 0 : if (ret)
2857 : : return ret;
2858 : :
2859 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2860 : : FAF_ICMP_FRAM, DPAA2_FLOW_FS_TYPE,
2861 : : group, &local_cfg);
2862 [ # # ]: 0 : if (ret)
2863 : : return ret;
2864 : :
2865 : 0 : (*device_configured) |= local_cfg;
2866 : 0 : return 0;
2867 : : }
2868 : :
2869 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2870 : : RTE_FLOW_ITEM_TYPE_ICMP);
2871 [ # # ]: 0 : if (ret) {
2872 : 0 : DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
2873 : :
2874 : 0 : return ret;
2875 : : }
2876 : :
2877 [ # # ]: 0 : if (mask->hdr.icmp_type) {
2878 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2879 : 0 : NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
2880 : 0 : &mask->hdr.icmp_type, sizeof(uint8_t),
2881 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2882 [ # # ]: 0 : if (ret)
2883 : : return ret;
2884 : :
2885 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2886 : : NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
2887 : : &mask->hdr.icmp_type, sizeof(uint8_t),
2888 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2889 [ # # ]: 0 : if (ret)
2890 : : return ret;
2891 : : }
2892 : :
2893 [ # # ]: 0 : if (mask->hdr.icmp_code) {
2894 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2895 : 0 : NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
2896 : 0 : &mask->hdr.icmp_code, sizeof(uint8_t),
2897 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2898 [ # # ]: 0 : if (ret)
2899 : : return ret;
2900 : :
2901 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
2902 : : NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
2903 : : &mask->hdr.icmp_code, sizeof(uint8_t),
2904 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2905 [ # # ]: 0 : if (ret)
2906 : : return ret;
2907 : : }
2908 : :
2909 : 0 : (*device_configured) |= local_cfg;
2910 : :
2911 : 0 : return 0;
2912 : : }
2913 : :
2914 : : static int
2915 : 0 : dpaa2_configure_flow_udp(struct dpaa2_dev_flow *flow,
2916 : : struct rte_eth_dev *dev,
2917 : : const struct rte_flow_attr *attr,
2918 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
2919 : : const struct rte_flow_action actions[] __rte_unused,
2920 : : struct rte_flow_error *error __rte_unused,
2921 : : int *device_configured)
2922 : : {
2923 : 0 : int ret, local_cfg = 0;
2924 : : uint32_t group;
2925 : : const struct rte_flow_item_udp *spec, *mask;
2926 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
2927 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2928 : :
2929 : 0 : group = attr->group;
2930 : :
2931 : : /* Parse pattern list to get the matching parameters */
2932 : 0 : spec = pattern->spec;
2933 : 0 : mask = pattern->mask ?
2934 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_udp_mask;
2935 : :
2936 : : /* Get traffic class index and flow id to be configured */
2937 : 0 : flow->tc_id = group;
2938 : 0 : flow->tc_index = attr->priority;
2939 : :
2940 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
2941 [ # # ]: 0 : if (spec) {
2942 : 0 : DPAA2_PMD_ERR("Tunnel-UDP distribution not support");
2943 : 0 : return -ENOTSUP;
2944 : : }
2945 : :
2946 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2947 : : FAFE_VXLAN_IN_UDP_FRAM,
2948 : : DPAA2_FLOW_QOS_TYPE, group,
2949 : : &local_cfg);
2950 [ # # ]: 0 : if (ret)
2951 : : return ret;
2952 : :
2953 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2954 : : FAFE_VXLAN_IN_UDP_FRAM,
2955 : : DPAA2_FLOW_FS_TYPE, group,
2956 : : &local_cfg);
2957 : 0 : return ret;
2958 : : }
2959 : :
2960 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2961 : : FAF_UDP_FRAM, DPAA2_FLOW_QOS_TYPE,
2962 : : group, &local_cfg);
2963 [ # # ]: 0 : if (ret)
2964 : : return ret;
2965 : :
2966 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
2967 : : FAF_UDP_FRAM, DPAA2_FLOW_FS_TYPE,
2968 : : group, &local_cfg);
2969 [ # # ]: 0 : if (ret)
2970 : : return ret;
2971 : :
2972 [ # # ]: 0 : if (!spec) {
2973 : 0 : (*device_configured) |= local_cfg;
2974 : 0 : return 0;
2975 : : }
2976 : :
2977 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
2978 : : RTE_FLOW_ITEM_TYPE_UDP);
2979 [ # # ]: 0 : if (ret) {
2980 : 0 : DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
2981 : :
2982 : 0 : return ret;
2983 : : }
2984 : :
2985 [ # # ]: 0 : if (mask->hdr.src_port) {
2986 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
2987 : 0 : NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
2988 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
2989 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
2990 [ # # ]: 0 : if (ret)
2991 : : return ret;
2992 : :
2993 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
2994 : : NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
2995 : : &mask->hdr.src_port, sizeof(rte_be16_t),
2996 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
2997 [ # # ]: 0 : if (ret)
2998 : : return ret;
2999 : : }
3000 : :
3001 [ # # ]: 0 : if (mask->hdr.dst_port) {
3002 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3003 : 0 : NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
3004 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3005 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3006 [ # # ]: 0 : if (ret)
3007 : : return ret;
3008 : :
3009 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
3010 : : NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
3011 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3012 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3013 [ # # ]: 0 : if (ret)
3014 : : return ret;
3015 : : }
3016 : :
3017 : 0 : (*device_configured) |= local_cfg;
3018 : :
3019 : 0 : return 0;
3020 : : }
3021 : :
3022 : : static int
3023 : 0 : dpaa2_configure_flow_tcp(struct dpaa2_dev_flow *flow,
3024 : : struct rte_eth_dev *dev,
3025 : : const struct rte_flow_attr *attr,
3026 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3027 : : const struct rte_flow_action actions[] __rte_unused,
3028 : : struct rte_flow_error *error __rte_unused,
3029 : : int *device_configured)
3030 : : {
3031 : 0 : int ret, local_cfg = 0;
3032 : : uint32_t group;
3033 : : const struct rte_flow_item_tcp *spec, *mask;
3034 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3035 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3036 : :
3037 : 0 : group = attr->group;
3038 : :
3039 : : /* Parse pattern list to get the matching parameters */
3040 : 0 : spec = pattern->spec;
3041 : 0 : mask = pattern->mask ?
3042 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_tcp_mask;
3043 : :
3044 : : /* Get traffic class index and flow id to be configured */
3045 : 0 : flow->tc_id = group;
3046 : 0 : flow->tc_index = attr->priority;
3047 : :
3048 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3049 [ # # ]: 0 : if (spec) {
3050 : 0 : DPAA2_PMD_ERR("Tunnel-TCP distribution not support");
3051 : 0 : return -ENOTSUP;
3052 : : }
3053 : :
3054 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3055 : : FAFE_VXLAN_IN_TCP_FRAM,
3056 : : DPAA2_FLOW_QOS_TYPE, group,
3057 : : &local_cfg);
3058 [ # # ]: 0 : if (ret)
3059 : : return ret;
3060 : :
3061 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3062 : : FAFE_VXLAN_IN_TCP_FRAM,
3063 : : DPAA2_FLOW_FS_TYPE, group,
3064 : : &local_cfg);
3065 : 0 : return ret;
3066 : : }
3067 : :
3068 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3069 : : FAF_TCP_FRAM, DPAA2_FLOW_QOS_TYPE,
3070 : : group, &local_cfg);
3071 [ # # ]: 0 : if (ret)
3072 : : return ret;
3073 : :
3074 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3075 : : FAF_TCP_FRAM, DPAA2_FLOW_FS_TYPE,
3076 : : group, &local_cfg);
3077 [ # # ]: 0 : if (ret)
3078 : : return ret;
3079 : :
3080 [ # # ]: 0 : if (!spec) {
3081 : 0 : (*device_configured) |= local_cfg;
3082 : 0 : return 0;
3083 : : }
3084 : :
3085 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3086 : : RTE_FLOW_ITEM_TYPE_TCP);
3087 [ # # ]: 0 : if (ret) {
3088 : 0 : DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
3089 : :
3090 : 0 : return ret;
3091 : : }
3092 : :
3093 [ # # ]: 0 : if (mask->hdr.src_port) {
3094 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3095 : 0 : NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
3096 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
3097 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3098 [ # # ]: 0 : if (ret)
3099 : : return ret;
3100 : :
3101 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3102 : : NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
3103 : : &mask->hdr.src_port, sizeof(rte_be16_t),
3104 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3105 [ # # ]: 0 : if (ret)
3106 : : return ret;
3107 : : }
3108 : :
3109 [ # # ]: 0 : if (mask->hdr.dst_port) {
3110 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3111 : 0 : NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
3112 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3113 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3114 [ # # ]: 0 : if (ret)
3115 : : return ret;
3116 : :
3117 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
3118 : : NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
3119 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3120 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3121 [ # # ]: 0 : if (ret)
3122 : : return ret;
3123 : : }
3124 : :
3125 : 0 : (*device_configured) |= local_cfg;
3126 : :
3127 : 0 : return 0;
3128 : : }
3129 : :
3130 : : static int
3131 : 0 : dpaa2_configure_flow_esp(struct dpaa2_dev_flow *flow,
3132 : : struct rte_eth_dev *dev,
3133 : : const struct rte_flow_attr *attr,
3134 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3135 : : const struct rte_flow_action actions[] __rte_unused,
3136 : : struct rte_flow_error *error __rte_unused,
3137 : : int *device_configured)
3138 : : {
3139 : 0 : int ret, local_cfg = 0;
3140 : : uint32_t group;
3141 : : const struct rte_flow_item_esp *spec, *mask;
3142 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3143 : : const struct rte_flow_item *pattern =
3144 : : &dpaa2_pattern->generic_item;
3145 : :
3146 : 0 : group = attr->group;
3147 : :
3148 : : /* Parse pattern list to get the matching parameters */
3149 : 0 : spec = pattern->spec;
3150 : 0 : mask = pattern->mask ?
3151 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_esp_mask;
3152 : :
3153 : : /* Get traffic class index and flow id to be configured */
3154 : 0 : flow->tc_id = group;
3155 : 0 : flow->tc_index = attr->priority;
3156 : :
3157 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3158 : 0 : DPAA2_PMD_ERR("Tunnel-ESP distribution not support");
3159 : 0 : return -ENOTSUP;
3160 : : }
3161 : :
3162 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3163 : : FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_QOS_TYPE,
3164 : : group, &local_cfg);
3165 [ # # ]: 0 : if (ret)
3166 : : return ret;
3167 : :
3168 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3169 : : FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_FS_TYPE,
3170 : : group, &local_cfg);
3171 [ # # ]: 0 : if (ret)
3172 : : return ret;
3173 : :
3174 [ # # ]: 0 : if (!spec) {
3175 : 0 : (*device_configured) |= local_cfg;
3176 : 0 : return 0;
3177 : : }
3178 : :
3179 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3180 : : RTE_FLOW_ITEM_TYPE_ESP);
3181 [ # # ]: 0 : if (ret) {
3182 : 0 : DPAA2_PMD_WARN("Extract field(s) of ESP not support.");
3183 : :
3184 : 0 : return ret;
3185 : : }
3186 : :
3187 [ # # ]: 0 : if (mask->hdr.spi) {
3188 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3189 : 0 : NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
3190 : 0 : &mask->hdr.spi, sizeof(rte_be32_t),
3191 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3192 [ # # ]: 0 : if (ret)
3193 : : return ret;
3194 : :
3195 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3196 : : NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
3197 : : &mask->hdr.spi, sizeof(rte_be32_t),
3198 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3199 [ # # ]: 0 : if (ret)
3200 : : return ret;
3201 : : }
3202 : :
3203 [ # # ]: 0 : if (mask->hdr.seq) {
3204 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3205 : 0 : NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
3206 : 0 : &mask->hdr.seq, sizeof(rte_be32_t),
3207 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3208 [ # # ]: 0 : if (ret)
3209 : : return ret;
3210 : :
3211 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
3212 : : NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
3213 : : &mask->hdr.seq, sizeof(rte_be32_t),
3214 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3215 [ # # ]: 0 : if (ret)
3216 : : return ret;
3217 : : }
3218 : :
3219 : 0 : (*device_configured) |= local_cfg;
3220 : :
3221 : 0 : return 0;
3222 : : }
3223 : :
3224 : : static int
3225 : 0 : dpaa2_configure_flow_ah(struct dpaa2_dev_flow *flow,
3226 : : struct rte_eth_dev *dev,
3227 : : const struct rte_flow_attr *attr,
3228 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3229 : : const struct rte_flow_action actions[] __rte_unused,
3230 : : struct rte_flow_error *error __rte_unused,
3231 : : int *device_configured)
3232 : : {
3233 : 0 : int ret, local_cfg = 0;
3234 : : uint32_t group;
3235 : : const struct rte_flow_item_ah *spec, *mask;
3236 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3237 : : const struct rte_flow_item *pattern =
3238 : : &dpaa2_pattern->generic_item;
3239 : :
3240 : 0 : group = attr->group;
3241 : :
3242 : : /* Parse pattern list to get the matching parameters */
3243 : 0 : spec = pattern->spec;
3244 : 0 : mask = pattern->mask ?
3245 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_ah_mask;
3246 : :
3247 : : /* Get traffic class index and flow id to be configured */
3248 : 0 : flow->tc_id = group;
3249 : 0 : flow->tc_index = attr->priority;
3250 : :
3251 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3252 : 0 : DPAA2_PMD_ERR("Tunnel-AH distribution not support");
3253 : 0 : return -ENOTSUP;
3254 : : }
3255 : :
3256 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3257 : : FAF_IPSEC_AH_FRAM, DPAA2_FLOW_QOS_TYPE,
3258 : : group, &local_cfg);
3259 [ # # ]: 0 : if (ret)
3260 : : return ret;
3261 : :
3262 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3263 : : FAF_IPSEC_AH_FRAM, DPAA2_FLOW_FS_TYPE,
3264 : : group, &local_cfg);
3265 [ # # ]: 0 : if (ret)
3266 : : return ret;
3267 : :
3268 [ # # ]: 0 : if (!spec) {
3269 : 0 : (*device_configured) |= local_cfg;
3270 : 0 : return 0;
3271 : : }
3272 : :
3273 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3274 : : RTE_FLOW_ITEM_TYPE_AH);
3275 [ # # ]: 0 : if (ret) {
3276 : 0 : DPAA2_PMD_WARN("Extract field(s) of AH not support.");
3277 : :
3278 : 0 : return ret;
3279 : : }
3280 : :
3281 [ # # ]: 0 : if (mask->spi) {
3282 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
3283 : 0 : NH_FLD_IPSEC_AH_SPI, &spec->spi,
3284 : 0 : &mask->spi, sizeof(rte_be32_t),
3285 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3286 [ # # ]: 0 : if (ret)
3287 : : return ret;
3288 : :
3289 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
3290 : : NH_FLD_IPSEC_AH_SPI, &spec->spi,
3291 : : &mask->spi, sizeof(rte_be32_t),
3292 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3293 [ # # ]: 0 : if (ret)
3294 : : return ret;
3295 : : }
3296 : :
3297 [ # # ]: 0 : if (mask->seq_num) {
3298 : 0 : DPAA2_PMD_ERR("AH seq distribution not support");
3299 : 0 : return -ENOTSUP;
3300 : : }
3301 : :
3302 : 0 : (*device_configured) |= local_cfg;
3303 : :
3304 : 0 : return 0;
3305 : : }
3306 : :
3307 : : static int
3308 : 0 : dpaa2_configure_flow_sctp(struct dpaa2_dev_flow *flow,
3309 : : struct rte_eth_dev *dev,
3310 : : const struct rte_flow_attr *attr,
3311 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3312 : : const struct rte_flow_action actions[] __rte_unused,
3313 : : struct rte_flow_error *error __rte_unused,
3314 : : int *device_configured)
3315 : : {
3316 : 0 : int ret, local_cfg = 0;
3317 : : uint32_t group;
3318 : : const struct rte_flow_item_sctp *spec, *mask;
3319 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3320 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3321 : :
3322 : 0 : group = attr->group;
3323 : :
3324 : : /* Parse pattern list to get the matching parameters */
3325 : 0 : spec = pattern->spec;
3326 : 0 : mask = pattern->mask ?
3327 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_sctp_mask;
3328 : :
3329 : : /* Get traffic class index and flow id to be configured */
3330 : 0 : flow->tc_id = group;
3331 : 0 : flow->tc_index = attr->priority;
3332 : :
3333 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3334 : 0 : DPAA2_PMD_ERR("Tunnel-SCTP distribution not support");
3335 : 0 : return -ENOTSUP;
3336 : : }
3337 : :
3338 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3339 : : FAF_SCTP_FRAM, DPAA2_FLOW_QOS_TYPE,
3340 : : group, &local_cfg);
3341 [ # # ]: 0 : if (ret)
3342 : : return ret;
3343 : :
3344 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3345 : : FAF_SCTP_FRAM, DPAA2_FLOW_FS_TYPE,
3346 : : group, &local_cfg);
3347 [ # # ]: 0 : if (ret)
3348 : : return ret;
3349 : :
3350 [ # # ]: 0 : if (!spec) {
3351 : 0 : (*device_configured) |= local_cfg;
3352 : 0 : return 0;
3353 : : }
3354 : :
3355 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3356 : : RTE_FLOW_ITEM_TYPE_SCTP);
3357 [ # # ]: 0 : if (ret) {
3358 : 0 : DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
3359 : :
3360 : 0 : return ret;
3361 : : }
3362 : :
3363 [ # # ]: 0 : if (mask->hdr.src_port) {
3364 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3365 : 0 : NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
3366 : 0 : &mask->hdr.src_port, sizeof(rte_be16_t),
3367 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3368 [ # # ]: 0 : if (ret)
3369 : : return ret;
3370 : :
3371 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3372 : : NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
3373 : : &mask->hdr.src_port, sizeof(rte_be16_t),
3374 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3375 [ # # ]: 0 : if (ret)
3376 : : return ret;
3377 : : }
3378 : :
3379 [ # # ]: 0 : if (mask->hdr.dst_port) {
3380 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3381 : 0 : NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
3382 : 0 : &mask->hdr.dst_port, sizeof(rte_be16_t),
3383 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3384 [ # # ]: 0 : if (ret)
3385 : : return ret;
3386 : :
3387 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
3388 : : NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
3389 : : &mask->hdr.dst_port, sizeof(rte_be16_t),
3390 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3391 [ # # ]: 0 : if (ret)
3392 : : return ret;
3393 : : }
3394 : :
3395 : 0 : (*device_configured) |= local_cfg;
3396 : :
3397 : 0 : return 0;
3398 : : }
3399 : :
3400 : : static int
3401 : 0 : dpaa2_configure_flow_gre(struct dpaa2_dev_flow *flow,
3402 : : struct rte_eth_dev *dev,
3403 : : const struct rte_flow_attr *attr,
3404 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3405 : : const struct rte_flow_action actions[] __rte_unused,
3406 : : struct rte_flow_error *error __rte_unused,
3407 : : int *device_configured)
3408 : : {
3409 : 0 : int ret, local_cfg = 0;
3410 : : uint32_t group;
3411 : : const struct rte_flow_item_gre *spec, *mask;
3412 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3413 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3414 : :
3415 : 0 : group = attr->group;
3416 : :
3417 : : /* Parse pattern list to get the matching parameters */
3418 : 0 : spec = pattern->spec;
3419 : 0 : mask = pattern->mask ?
3420 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_gre_mask;
3421 : :
3422 : : /* Get traffic class index and flow id to be configured */
3423 : 0 : flow->tc_id = group;
3424 : 0 : flow->tc_index = attr->priority;
3425 : :
3426 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3427 : 0 : DPAA2_PMD_ERR("Tunnel-GRE distribution not support");
3428 : 0 : return -ENOTSUP;
3429 : : }
3430 : :
3431 [ # # ]: 0 : if (!spec) {
3432 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3433 : : FAF_GRE_FRAM, DPAA2_FLOW_QOS_TYPE,
3434 : : group, &local_cfg);
3435 [ # # ]: 0 : if (ret)
3436 : : return ret;
3437 : :
3438 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3439 : : FAF_GRE_FRAM, DPAA2_FLOW_FS_TYPE,
3440 : : group, &local_cfg);
3441 [ # # ]: 0 : if (ret)
3442 : : return ret;
3443 : :
3444 : 0 : (*device_configured) |= local_cfg;
3445 : 0 : return 0;
3446 : : }
3447 : :
3448 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3449 : : RTE_FLOW_ITEM_TYPE_GRE);
3450 [ # # ]: 0 : if (ret) {
3451 : 0 : DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
3452 : :
3453 : 0 : return ret;
3454 : : }
3455 : :
3456 [ # # ]: 0 : if (!mask->protocol)
3457 : : return 0;
3458 : :
3459 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
3460 : 0 : NH_FLD_GRE_TYPE, &spec->protocol,
3461 : 0 : &mask->protocol, sizeof(rte_be16_t),
3462 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3463 [ # # ]: 0 : if (ret)
3464 : : return ret;
3465 : :
3466 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
3467 : : NH_FLD_GRE_TYPE, &spec->protocol,
3468 : : &mask->protocol, sizeof(rte_be16_t),
3469 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3470 [ # # ]: 0 : if (ret)
3471 : : return ret;
3472 : :
3473 : 0 : (*device_configured) |= local_cfg;
3474 : :
3475 : 0 : return 0;
3476 : : }
3477 : :
3478 : : static int
3479 : 0 : dpaa2_configure_flow_vxlan(struct dpaa2_dev_flow *flow,
3480 : : struct rte_eth_dev *dev,
3481 : : const struct rte_flow_attr *attr,
3482 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3483 : : const struct rte_flow_action actions[] __rte_unused,
3484 : : struct rte_flow_error *error __rte_unused,
3485 : : int *device_configured)
3486 : : {
3487 : 0 : int ret, local_cfg = 0;
3488 : : uint32_t group;
3489 : : const struct rte_flow_item_vxlan *spec, *mask;
3490 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3491 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3492 : :
3493 : 0 : group = attr->group;
3494 : :
3495 : : /* Parse pattern list to get the matching parameters */
3496 : 0 : spec = pattern->spec;
3497 : 0 : mask = pattern->mask ?
3498 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_vxlan_mask;
3499 : :
3500 : : /* Get traffic class index and flow id to be configured */
3501 : 0 : flow->tc_id = group;
3502 : 0 : flow->tc_index = attr->priority;
3503 : :
3504 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3505 : 0 : DPAA2_PMD_ERR("Tunnel-VXLAN distribution not support");
3506 : 0 : return -ENOTSUP;
3507 : : }
3508 : :
3509 [ # # ]: 0 : if (!spec) {
3510 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3511 : : FAF_VXLAN_FRAM, DPAA2_FLOW_QOS_TYPE,
3512 : : group, &local_cfg);
3513 [ # # ]: 0 : if (ret)
3514 : : return ret;
3515 : :
3516 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3517 : : FAF_VXLAN_FRAM, DPAA2_FLOW_FS_TYPE,
3518 : : group, &local_cfg);
3519 [ # # ]: 0 : if (ret)
3520 : : return ret;
3521 : :
3522 : 0 : (*device_configured) |= local_cfg;
3523 : 0 : return 0;
3524 : : }
3525 : :
3526 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3527 : : RTE_FLOW_ITEM_TYPE_VXLAN);
3528 [ # # ]: 0 : if (ret) {
3529 : 0 : DPAA2_PMD_WARN("Extract field(s) of VXLAN not support.");
3530 : :
3531 : 0 : return ret;
3532 : : }
3533 : :
3534 [ # # ]: 0 : if (mask->flags) {
3535 [ # # ]: 0 : if (spec->flags != VXLAN_HF_VNI) {
3536 : 0 : DPAA2_PMD_ERR("vxlan flag(0x%02x) must be 0x%02x.",
3537 : : spec->flags, VXLAN_HF_VNI);
3538 : 0 : return -EINVAL;
3539 : : }
3540 [ # # ]: 0 : if (mask->flags != 0xff) {
3541 : 0 : DPAA2_PMD_ERR("Not support to extract vxlan flag.");
3542 : 0 : return -EINVAL;
3543 : : }
3544 : : }
3545 : :
3546 [ # # # # : 0 : if (mask->vni[0] || mask->vni[1] || mask->vni[2]) {
# # ]
3547 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3548 : : DPAA2_VXLAN_VNI_OFFSET,
3549 : 0 : sizeof(mask->vni), spec->vni,
3550 : 0 : mask->vni,
3551 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3552 [ # # ]: 0 : if (ret)
3553 : : return ret;
3554 : :
3555 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3556 : : DPAA2_VXLAN_VNI_OFFSET,
3557 : : sizeof(mask->vni), spec->vni,
3558 : : mask->vni,
3559 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3560 [ # # ]: 0 : if (ret)
3561 : : return ret;
3562 : : }
3563 : :
3564 : 0 : (*device_configured) |= local_cfg;
3565 : :
3566 : 0 : return 0;
3567 : : }
3568 : :
3569 : : static int
3570 : 0 : dpaa2_configure_flow_ecpri(struct dpaa2_dev_flow *flow,
3571 : : struct rte_eth_dev *dev,
3572 : : const struct rte_flow_attr *attr,
3573 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3574 : : const struct rte_flow_action actions[] __rte_unused,
3575 : : struct rte_flow_error *error __rte_unused,
3576 : : int *device_configured)
3577 : : {
3578 : 0 : int ret, local_cfg = 0;
3579 : : uint32_t group;
3580 : : const struct rte_flow_item_ecpri *spec, *mask;
3581 : : struct rte_flow_item_ecpri local_mask;
3582 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3583 : : const struct rte_flow_item *pattern =
3584 : : &dpaa2_pattern->generic_item;
3585 : : uint8_t extract_nb = 0, i;
3586 : : uint64_t rule_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3587 : : uint64_t mask_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3588 : : uint8_t extract_size[DPAA2_ECPRI_MAX_EXTRACT_NB];
3589 : : uint8_t extract_off[DPAA2_ECPRI_MAX_EXTRACT_NB];
3590 : :
3591 : 0 : group = attr->group;
3592 : :
3593 : : /* Parse pattern list to get the matching parameters */
3594 : 0 : spec = pattern->spec;
3595 [ # # ]: 0 : if (pattern->mask) {
3596 : : memcpy(&local_mask, pattern->mask,
3597 : : sizeof(struct rte_flow_item_ecpri));
3598 : 0 : local_mask.hdr.common.u32 =
3599 [ # # ]: 0 : rte_be_to_cpu_32(local_mask.hdr.common.u32);
3600 : : mask = &local_mask;
3601 : : } else {
3602 : : mask = &dpaa2_flow_item_ecpri_mask;
3603 : : }
3604 : :
3605 : : /* Get traffic class index and flow id to be configured */
3606 : 0 : flow->tc_id = group;
3607 : 0 : flow->tc_index = attr->priority;
3608 : :
3609 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3610 : 0 : DPAA2_PMD_ERR("Tunnel-ECPRI distribution not support");
3611 : 0 : return -ENOTSUP;
3612 : : }
3613 : :
3614 [ # # ]: 0 : if (!spec) {
3615 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3616 : : FAFE_ECPRI_FRAM, DPAA2_FLOW_QOS_TYPE,
3617 : : group, &local_cfg);
3618 [ # # ]: 0 : if (ret)
3619 : : return ret;
3620 : :
3621 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3622 : : FAFE_ECPRI_FRAM, DPAA2_FLOW_FS_TYPE,
3623 : : group, &local_cfg);
3624 [ # # ]: 0 : if (ret)
3625 : : return ret;
3626 : :
3627 : 0 : (*device_configured) |= local_cfg;
3628 : 0 : return 0;
3629 : : }
3630 : :
3631 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3632 : : RTE_FLOW_ITEM_TYPE_ECPRI);
3633 [ # # ]: 0 : if (ret) {
3634 : 0 : DPAA2_PMD_WARN("Extract field(s) of ECPRI not support.");
3635 : :
3636 : 0 : return ret;
3637 : : }
3638 : :
3639 [ # # ]: 0 : if (mask->hdr.common.type != 0xff) {
3640 : 0 : DPAA2_PMD_WARN("ECPRI header type not specified.");
3641 : :
3642 : 0 : return -EINVAL;
3643 : : }
3644 : :
3645 [ # # ]: 0 : if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_IQ_DATA) {
3646 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_0;
3647 : 0 : mask_data[extract_nb] = 0xff;
3648 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3649 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3650 : : extract_nb++;
3651 : :
3652 [ # # ]: 0 : if (mask->hdr.type0.pc_id) {
3653 : 0 : rule_data[extract_nb] = spec->hdr.type0.pc_id;
3654 : 0 : mask_data[extract_nb] = mask->hdr.type0.pc_id;
3655 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3656 : 0 : extract_off[extract_nb] =
3657 : : DPAA2_ECPRI_MSG_OFFSET +
3658 : : offsetof(struct rte_ecpri_msg_iq_data, pc_id);
3659 : : extract_nb++;
3660 : : }
3661 [ # # ]: 0 : if (mask->hdr.type0.seq_id) {
3662 : 0 : rule_data[extract_nb] = spec->hdr.type0.seq_id;
3663 : 0 : mask_data[extract_nb] = mask->hdr.type0.seq_id;
3664 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3665 : 0 : extract_off[extract_nb] =
3666 : : DPAA2_ECPRI_MSG_OFFSET +
3667 : : offsetof(struct rte_ecpri_msg_iq_data, seq_id);
3668 : 0 : extract_nb++;
3669 : : }
3670 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_BIT_SEQ) {
3671 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_1;
3672 : 0 : mask_data[extract_nb] = 0xff;
3673 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3674 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3675 : : extract_nb++;
3676 : :
3677 [ # # ]: 0 : if (mask->hdr.type1.pc_id) {
3678 : 0 : rule_data[extract_nb] = spec->hdr.type1.pc_id;
3679 : 0 : mask_data[extract_nb] = mask->hdr.type1.pc_id;
3680 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3681 : 0 : extract_off[extract_nb] =
3682 : : DPAA2_ECPRI_MSG_OFFSET +
3683 : : offsetof(struct rte_ecpri_msg_bit_seq, pc_id);
3684 : : extract_nb++;
3685 : : }
3686 [ # # ]: 0 : if (mask->hdr.type1.seq_id) {
3687 : 0 : rule_data[extract_nb] = spec->hdr.type1.seq_id;
3688 : 0 : mask_data[extract_nb] = mask->hdr.type1.seq_id;
3689 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3690 : 0 : extract_off[extract_nb] =
3691 : : DPAA2_ECPRI_MSG_OFFSET +
3692 : : offsetof(struct rte_ecpri_msg_bit_seq, seq_id);
3693 : 0 : extract_nb++;
3694 : : }
3695 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RTC_CTRL) {
3696 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_2;
3697 : 0 : mask_data[extract_nb] = 0xff;
3698 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3699 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3700 : : extract_nb++;
3701 : :
3702 [ # # ]: 0 : if (mask->hdr.type2.rtc_id) {
3703 : 0 : rule_data[extract_nb] = spec->hdr.type2.rtc_id;
3704 : 0 : mask_data[extract_nb] = mask->hdr.type2.rtc_id;
3705 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3706 : 0 : extract_off[extract_nb] =
3707 : : DPAA2_ECPRI_MSG_OFFSET +
3708 : : offsetof(struct rte_ecpri_msg_rtc_ctrl, rtc_id);
3709 : : extract_nb++;
3710 : : }
3711 [ # # ]: 0 : if (mask->hdr.type2.seq_id) {
3712 : 0 : rule_data[extract_nb] = spec->hdr.type2.seq_id;
3713 : 0 : mask_data[extract_nb] = mask->hdr.type2.seq_id;
3714 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3715 : 0 : extract_off[extract_nb] =
3716 : : DPAA2_ECPRI_MSG_OFFSET +
3717 : : offsetof(struct rte_ecpri_msg_rtc_ctrl, seq_id);
3718 : 0 : extract_nb++;
3719 : : }
3720 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_GEN_DATA) {
3721 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_3;
3722 : 0 : mask_data[extract_nb] = 0xff;
3723 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3724 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3725 : : extract_nb++;
3726 : :
3727 [ # # # # ]: 0 : if (mask->hdr.type3.pc_id || mask->hdr.type3.seq_id)
3728 : 0 : DPAA2_PMD_WARN("Extract type3 msg not support.");
3729 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RM_ACC) {
3730 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_4;
3731 : 0 : mask_data[extract_nb] = 0xff;
3732 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3733 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3734 : : extract_nb++;
3735 : :
3736 [ # # ]: 0 : if (mask->hdr.type4.rma_id) {
3737 : 0 : rule_data[extract_nb] = spec->hdr.type4.rma_id;
3738 : 0 : mask_data[extract_nb] = mask->hdr.type4.rma_id;
3739 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3740 : 0 : extract_off[extract_nb] =
3741 : : DPAA2_ECPRI_MSG_OFFSET + 0;
3742 : : /** Compiler not support to take address
3743 : : * of bit-field
3744 : : * offsetof(struct rte_ecpri_msg_rm_access,
3745 : : * rma_id);
3746 : : */
3747 : : extract_nb++;
3748 : : }
3749 [ # # ]: 0 : if (mask->hdr.type4.ele_id) {
3750 : 0 : rule_data[extract_nb] = spec->hdr.type4.ele_id;
3751 : 0 : mask_data[extract_nb] = mask->hdr.type4.ele_id;
3752 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3753 : 0 : extract_off[extract_nb] =
3754 : : DPAA2_ECPRI_MSG_OFFSET + 2;
3755 : : /** Compiler not support to take address
3756 : : * of bit-field
3757 : : * offsetof(struct rte_ecpri_msg_rm_access,
3758 : : * ele_id);
3759 : : */
3760 : 0 : extract_nb++;
3761 : : }
3762 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_DLY_MSR) {
3763 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_5;
3764 : 0 : mask_data[extract_nb] = 0xff;
3765 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3766 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3767 : : extract_nb++;
3768 : :
3769 [ # # ]: 0 : if (mask->hdr.type5.msr_id) {
3770 : 0 : rule_data[extract_nb] = spec->hdr.type5.msr_id;
3771 : 0 : mask_data[extract_nb] = mask->hdr.type5.msr_id;
3772 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3773 : 0 : extract_off[extract_nb] =
3774 : : DPAA2_ECPRI_MSG_OFFSET +
3775 : : offsetof(struct rte_ecpri_msg_delay_measure,
3776 : : msr_id);
3777 : : extract_nb++;
3778 : : }
3779 [ # # ]: 0 : if (mask->hdr.type5.act_type) {
3780 : 0 : rule_data[extract_nb] = spec->hdr.type5.act_type;
3781 : 0 : mask_data[extract_nb] = mask->hdr.type5.act_type;
3782 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3783 : 0 : extract_off[extract_nb] =
3784 : : DPAA2_ECPRI_MSG_OFFSET +
3785 : : offsetof(struct rte_ecpri_msg_delay_measure,
3786 : : act_type);
3787 : 0 : extract_nb++;
3788 : : }
3789 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RMT_RST) {
3790 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_6;
3791 : 0 : mask_data[extract_nb] = 0xff;
3792 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3793 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3794 : : extract_nb++;
3795 : :
3796 [ # # ]: 0 : if (mask->hdr.type6.rst_id) {
3797 : 0 : rule_data[extract_nb] = spec->hdr.type6.rst_id;
3798 : 0 : mask_data[extract_nb] = mask->hdr.type6.rst_id;
3799 : 0 : extract_size[extract_nb] = sizeof(rte_be16_t);
3800 : 0 : extract_off[extract_nb] =
3801 : : DPAA2_ECPRI_MSG_OFFSET +
3802 : : offsetof(struct rte_ecpri_msg_remote_reset,
3803 : : rst_id);
3804 : : extract_nb++;
3805 : : }
3806 [ # # ]: 0 : if (mask->hdr.type6.rst_op) {
3807 : 0 : rule_data[extract_nb] = spec->hdr.type6.rst_op;
3808 : 0 : mask_data[extract_nb] = mask->hdr.type6.rst_op;
3809 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3810 : 0 : extract_off[extract_nb] =
3811 : : DPAA2_ECPRI_MSG_OFFSET +
3812 : : offsetof(struct rte_ecpri_msg_remote_reset,
3813 : : rst_op);
3814 : 0 : extract_nb++;
3815 : : }
3816 : : } else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_EVT_IND) {
3817 : 0 : rule_data[extract_nb] = ECPRI_FAFE_TYPE_7;
3818 : 0 : mask_data[extract_nb] = 0xff;
3819 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3820 : 0 : extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3821 : : extract_nb++;
3822 : :
3823 [ # # ]: 0 : if (mask->hdr.type7.evt_id) {
3824 : 0 : rule_data[extract_nb] = spec->hdr.type7.evt_id;
3825 : 0 : mask_data[extract_nb] = mask->hdr.type7.evt_id;
3826 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3827 : 0 : extract_off[extract_nb] =
3828 : : DPAA2_ECPRI_MSG_OFFSET +
3829 : : offsetof(struct rte_ecpri_msg_event_ind,
3830 : : evt_id);
3831 : : extract_nb++;
3832 : : }
3833 [ # # ]: 0 : if (mask->hdr.type7.evt_type) {
3834 : 0 : rule_data[extract_nb] = spec->hdr.type7.evt_type;
3835 : 0 : mask_data[extract_nb] = mask->hdr.type7.evt_type;
3836 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3837 : 0 : extract_off[extract_nb] =
3838 : : DPAA2_ECPRI_MSG_OFFSET +
3839 : : offsetof(struct rte_ecpri_msg_event_ind,
3840 : : evt_type);
3841 : 0 : extract_nb++;
3842 : : }
3843 [ # # ]: 0 : if (mask->hdr.type7.seq) {
3844 : 0 : rule_data[extract_nb] = spec->hdr.type7.seq;
3845 : 0 : mask_data[extract_nb] = mask->hdr.type7.seq;
3846 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3847 : 0 : extract_off[extract_nb] =
3848 : : DPAA2_ECPRI_MSG_OFFSET +
3849 : : offsetof(struct rte_ecpri_msg_event_ind,
3850 : : seq);
3851 : 0 : extract_nb++;
3852 : : }
3853 [ # # ]: 0 : if (mask->hdr.type7.number) {
3854 : 0 : rule_data[extract_nb] = spec->hdr.type7.number;
3855 : 0 : mask_data[extract_nb] = mask->hdr.type7.number;
3856 : 0 : extract_size[extract_nb] = sizeof(uint8_t);
3857 : 0 : extract_off[extract_nb] =
3858 : : DPAA2_ECPRI_MSG_OFFSET +
3859 : : offsetof(struct rte_ecpri_msg_event_ind,
3860 : : number);
3861 : 0 : extract_nb++;
3862 : : }
3863 : : } else {
3864 : 0 : DPAA2_PMD_ERR("Invalid ecpri header type(%d)",
3865 : : spec->hdr.common.type);
3866 : 0 : return -EINVAL;
3867 : : }
3868 : :
3869 [ # # ]: 0 : for (i = 0; i < extract_nb; i++) {
3870 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3871 : 0 : extract_off[i],
3872 : 0 : extract_size[i], &rule_data[i], &mask_data[i],
3873 : : priv, group,
3874 : : device_configured,
3875 : : DPAA2_FLOW_QOS_TYPE);
3876 [ # # ]: 0 : if (ret)
3877 : 0 : return ret;
3878 : :
3879 : 0 : ret = dpaa2_flow_add_pr_extract_rule(flow,
3880 : : extract_off[i],
3881 : : extract_size[i], &rule_data[i], &mask_data[i],
3882 : : priv, group,
3883 : : device_configured,
3884 : : DPAA2_FLOW_FS_TYPE);
3885 [ # # ]: 0 : if (ret)
3886 : 0 : return ret;
3887 : : }
3888 : :
3889 : : (*device_configured) |= local_cfg;
3890 : :
3891 : : return 0;
3892 : : }
3893 : :
3894 : : static int
3895 : 0 : dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow,
3896 : : struct rte_eth_dev *dev,
3897 : : const struct rte_flow_attr *attr,
3898 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3899 : : const struct rte_flow_action actions[] __rte_unused,
3900 : : struct rte_flow_error *error __rte_unused,
3901 : : int *device_configured)
3902 : : {
3903 : 0 : int ret, local_cfg = 0;
3904 : : uint32_t group;
3905 : : const struct rte_flow_item_gtp *spec, *mask;
3906 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3907 : : const struct rte_flow_item *pattern =
3908 : : &dpaa2_pattern->generic_item;
3909 : :
3910 : 0 : group = attr->group;
3911 : :
3912 : : /* Parse pattern list to get the matching parameters */
3913 : 0 : spec = pattern->spec;
3914 : 0 : mask = pattern->mask ?
3915 [ # # ]: 0 : pattern->mask : &dpaa2_flow_item_gtp_mask;
3916 : :
3917 : : /* Get traffic class index and flow id to be configured */
3918 : 0 : flow->tc_id = group;
3919 : 0 : flow->tc_index = attr->priority;
3920 : :
3921 [ # # ]: 0 : if (dpaa2_pattern->in_tunnel) {
3922 : 0 : DPAA2_PMD_ERR("Tunnel-GTP distribution not support");
3923 : 0 : return -ENOTSUP;
3924 : : }
3925 : :
3926 [ # # ]: 0 : if (!spec) {
3927 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3928 : : FAF_GTP_FRAM, DPAA2_FLOW_QOS_TYPE,
3929 : : group, &local_cfg);
3930 [ # # ]: 0 : if (ret)
3931 : : return ret;
3932 : :
3933 : 0 : ret = dpaa2_flow_identify_by_faf(priv, flow,
3934 : : FAF_GTP_FRAM, DPAA2_FLOW_FS_TYPE,
3935 : : group, &local_cfg);
3936 [ # # ]: 0 : if (ret)
3937 : : return ret;
3938 : :
3939 : 0 : (*device_configured) |= local_cfg;
3940 : 0 : return 0;
3941 : : }
3942 : :
3943 : 0 : ret = dpaa2_flow_extract_support((const uint8_t *)mask,
3944 : : RTE_FLOW_ITEM_TYPE_GTP);
3945 [ # # ]: 0 : if (ret) {
3946 : 0 : DPAA2_PMD_WARN("Extract field(s) of GTP not support.");
3947 : :
3948 : 0 : return ret;
3949 : : }
3950 : :
3951 [ # # ]: 0 : if (!mask->teid)
3952 : : return 0;
3953 : :
3954 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
3955 : 0 : NH_FLD_GTP_TEID, &spec->teid,
3956 : 0 : &mask->teid, sizeof(rte_be32_t),
3957 : : priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3958 [ # # ]: 0 : if (ret)
3959 : : return ret;
3960 : :
3961 : 0 : ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
3962 : : NH_FLD_GTP_TEID, &spec->teid,
3963 : : &mask->teid, sizeof(rte_be32_t),
3964 : : priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3965 [ # # ]: 0 : if (ret)
3966 : : return ret;
3967 : :
3968 : 0 : (*device_configured) |= local_cfg;
3969 : :
3970 : 0 : return 0;
3971 : : }
3972 : :
3973 : : static int
3974 : 0 : dpaa2_configure_flow_raw(struct dpaa2_dev_flow *flow,
3975 : : struct rte_eth_dev *dev,
3976 : : const struct rte_flow_attr *attr,
3977 : : const struct rte_dpaa2_flow_item *dpaa2_pattern,
3978 : : const struct rte_flow_action actions[] __rte_unused,
3979 : : struct rte_flow_error *error __rte_unused,
3980 : : int *device_configured)
3981 : : {
3982 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
3983 : 0 : int local_cfg = 0, ret;
3984 : : uint32_t group;
3985 : : struct dpaa2_key_extract *qos_key_extract;
3986 : : struct dpaa2_key_extract *tc_key_extract;
3987 : : const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3988 : 0 : const struct rte_flow_item_raw *spec = pattern->spec;
3989 : 0 : const struct rte_flow_item_raw *mask = pattern->mask;
3990 : :
3991 : : /* Need both spec and mask */
3992 [ # # ]: 0 : if (!spec || !mask) {
3993 : 0 : DPAA2_PMD_ERR("spec or mask not present.");
3994 : 0 : return -EINVAL;
3995 : : }
3996 : :
3997 [ # # ]: 0 : if (spec->relative) {
3998 : : /* TBD: relative offset support.
3999 : : * To support relative offset of previous L3 protocol item,
4000 : : * extracts should be expanded to identify if the frame is:
4001 : : * vlan or none-vlan.
4002 : : *
4003 : : * To support relative offset of previous L4 protocol item,
4004 : : * extracts should be expanded to identify if the frame is:
4005 : : * vlan/IPv4 or vlan/IPv6 or none-vlan/IPv4 or none-vlan/IPv6.
4006 : : */
4007 : 0 : DPAA2_PMD_ERR("relative not supported.");
4008 : 0 : return -EINVAL;
4009 : : }
4010 : :
4011 [ # # ]: 0 : if (spec->search) {
4012 : 0 : DPAA2_PMD_ERR("search not supported.");
4013 : 0 : return -EINVAL;
4014 : : }
4015 : :
4016 : : /* Spec len and mask len should be same */
4017 [ # # ]: 0 : if (spec->length != mask->length) {
4018 : 0 : DPAA2_PMD_ERR("Spec len and mask len mismatch.");
4019 : 0 : return -EINVAL;
4020 : : }
4021 : :
4022 : : /* Get traffic class index and flow id to be configured */
4023 : 0 : group = attr->group;
4024 : 0 : flow->tc_id = group;
4025 : 0 : flow->tc_index = attr->priority;
4026 : :
4027 : : qos_key_extract = &priv->extract.qos_key_extract;
4028 : : tc_key_extract = &priv->extract.tc_key_extract[group];
4029 : :
4030 : 0 : ret = dpaa2_flow_extract_add_raw(priv,
4031 : 0 : spec->offset, spec->length,
4032 : : DPAA2_FLOW_QOS_TYPE, 0, &local_cfg);
4033 [ # # ]: 0 : if (ret) {
4034 : 0 : DPAA2_PMD_ERR("QoS Extract RAW add failed.");
4035 : 0 : return -EINVAL;
4036 : : }
4037 : :
4038 : 0 : ret = dpaa2_flow_extract_add_raw(priv,
4039 : 0 : spec->offset, spec->length,
4040 : : DPAA2_FLOW_FS_TYPE, group, &local_cfg);
4041 [ # # ]: 0 : if (ret) {
4042 : 0 : DPAA2_PMD_ERR("FS[%d] Extract RAW add failed.",
4043 : : group);
4044 : 0 : return -EINVAL;
4045 : : }
4046 : :
4047 : 0 : ret = dpaa2_flow_raw_rule_data_set(flow,
4048 : : &qos_key_extract->key_profile,
4049 : 0 : spec->offset, spec->length,
4050 : 0 : spec->pattern, mask->pattern,
4051 : : DPAA2_FLOW_QOS_TYPE);
4052 [ # # ]: 0 : if (ret) {
4053 : 0 : DPAA2_PMD_ERR("QoS RAW rule data set failed");
4054 : 0 : return -EINVAL;
4055 : : }
4056 : :
4057 : 0 : ret = dpaa2_flow_raw_rule_data_set(flow,
4058 : : &tc_key_extract->key_profile,
4059 : 0 : spec->offset, spec->length,
4060 : 0 : spec->pattern, mask->pattern,
4061 : : DPAA2_FLOW_FS_TYPE);
4062 [ # # ]: 0 : if (ret) {
4063 : 0 : DPAA2_PMD_ERR("FS RAW rule data set failed");
4064 : 0 : return -EINVAL;
4065 : : }
4066 : :
4067 : 0 : (*device_configured) |= local_cfg;
4068 : :
4069 : 0 : return 0;
4070 : : }
4071 : :
4072 : : static inline int
4073 : 0 : dpaa2_flow_verify_attr(struct dpaa2_dev_priv *priv,
4074 : : const struct rte_flow_attr *attr)
4075 : : {
4076 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4077 : :
4078 [ # # ]: 0 : while (curr) {
4079 [ # # ]: 0 : if (curr->tc_id == attr->group &&
4080 [ # # ]: 0 : curr->tc_index == attr->priority) {
4081 : 0 : DPAA2_PMD_ERR("Flow(TC[%d].entry[%d] exists",
4082 : : attr->group, attr->priority);
4083 : :
4084 : 0 : return -EINVAL;
4085 : : }
4086 : 0 : curr = LIST_NEXT(curr, next);
4087 : : }
4088 : :
4089 : : return 0;
4090 : : }
4091 : :
4092 : : static inline struct rte_eth_dev *
4093 : 0 : dpaa2_flow_redirect_dev(struct dpaa2_dev_priv *priv,
4094 : : const struct rte_flow_action *action)
4095 : : {
4096 : : const struct rte_flow_action_port_id *port_id;
4097 : : const struct rte_flow_action_ethdev *ethdev;
4098 : : int idx = -1;
4099 : : struct rte_eth_dev *dest_dev;
4100 : :
4101 [ # # ]: 0 : if (action->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
4102 : 0 : port_id = action->conf;
4103 [ # # ]: 0 : if (!port_id->original)
4104 : 0 : idx = port_id->id;
4105 [ # # ]: 0 : } else if (action->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
4106 : 0 : ethdev = action->conf;
4107 : 0 : idx = ethdev->port_id;
4108 : : } else {
4109 : : return NULL;
4110 : : }
4111 : :
4112 [ # # ]: 0 : if (idx >= 0) {
4113 [ # # ]: 0 : if (!rte_eth_dev_is_valid_port(idx))
4114 : : return NULL;
4115 [ # # ]: 0 : if (!rte_pmd_dpaa2_dev_is_dpaa2(idx))
4116 : : return NULL;
4117 : 0 : dest_dev = &rte_eth_devices[idx];
4118 : : } else {
4119 : 0 : dest_dev = priv->eth_dev;
4120 : : }
4121 : :
4122 : : return dest_dev;
4123 : : }
4124 : :
4125 : : static inline int
4126 : 0 : dpaa2_flow_verify_action(struct dpaa2_dev_priv *priv,
4127 : : const struct rte_flow_attr *attr,
4128 : : const struct rte_flow_action actions[])
4129 : : {
4130 : : int end_of_list = 0, i, j = 0;
4131 : : const struct rte_flow_action_queue *dest_queue;
4132 : : const struct rte_flow_action_rss *rss_conf;
4133 : : struct dpaa2_queue *rxq;
4134 : :
4135 [ # # ]: 0 : while (!end_of_list) {
4136 [ # # # # : 0 : switch (actions[j].type) {
# # ]
4137 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
4138 : 0 : dest_queue = actions[j].conf;
4139 : 0 : rxq = priv->rx_vq[dest_queue->index];
4140 [ # # ]: 0 : if (attr->group != rxq->tc_index) {
4141 : 0 : DPAA2_PMD_ERR("FSQ(%d.%d) not in TC[%d]",
4142 : : rxq->tc_index, rxq->flow_id,
4143 : : attr->group);
4144 : :
4145 : 0 : return -ENOTSUP;
4146 : : }
4147 : : break;
4148 : 0 : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4149 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
4150 [ # # ]: 0 : if (!dpaa2_flow_redirect_dev(priv, &actions[j])) {
4151 : 0 : DPAA2_PMD_ERR("Invalid port id of action");
4152 : 0 : return -ENOTSUP;
4153 : : }
4154 : : break;
4155 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
4156 : 0 : rss_conf = (const struct rte_flow_action_rss *)
4157 : : (actions[j].conf);
4158 [ # # ]: 0 : if (rss_conf->queue_num > priv->dist_queues) {
4159 : 0 : DPAA2_PMD_ERR("RSS number too large");
4160 : 0 : return -ENOTSUP;
4161 : : }
4162 [ # # ]: 0 : for (i = 0; i < (int)rss_conf->queue_num; i++) {
4163 [ # # ]: 0 : if (rss_conf->queue[i] >= priv->nb_rx_queues) {
4164 : 0 : DPAA2_PMD_ERR("RSS queue not in range");
4165 : 0 : return -ENOTSUP;
4166 : : }
4167 : 0 : rxq = priv->rx_vq[rss_conf->queue[i]];
4168 [ # # ]: 0 : if (rxq->tc_index != attr->group) {
4169 : 0 : DPAA2_PMD_ERR("RSS queue not in group");
4170 : 0 : return -ENOTSUP;
4171 : : }
4172 : : }
4173 : :
4174 : : break;
4175 : : case RTE_FLOW_ACTION_TYPE_PF:
4176 : : /* Skip this action, have to add for vxlan */
4177 : : break;
4178 : 0 : case RTE_FLOW_ACTION_TYPE_END:
4179 : : end_of_list = 1;
4180 : 0 : break;
4181 : 0 : default:
4182 : 0 : DPAA2_PMD_ERR("Invalid action type");
4183 : 0 : return -ENOTSUP;
4184 : : }
4185 : 0 : j++;
4186 : : }
4187 : :
4188 : : return 0;
4189 : : }
4190 : :
4191 : : static int
4192 : 0 : dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv,
4193 : : struct dpaa2_dev_flow *flow,
4194 : : const struct rte_flow_action *rte_action)
4195 : : {
4196 : : struct rte_eth_dev *dest_dev;
4197 : : struct dpaa2_dev_priv *dest_priv;
4198 : : const struct rte_flow_action_queue *dest_queue;
4199 : : struct dpaa2_queue *dest_q;
4200 : :
4201 [ # # ]: 0 : memset(&flow->fs_action_cfg, 0,
4202 : : sizeof(struct dpni_fs_action_cfg));
4203 : 0 : flow->action_type = rte_action->type;
4204 : :
4205 [ # # ]: 0 : if (flow->action_type == RTE_FLOW_ACTION_TYPE_QUEUE) {
4206 : 0 : dest_queue = rte_action->conf;
4207 : 0 : dest_q = priv->rx_vq[dest_queue->index];
4208 : 0 : flow->fs_action_cfg.flow_id = dest_q->flow_id;
4209 [ # # ]: 0 : } else if (flow->action_type == RTE_FLOW_ACTION_TYPE_PORT_ID ||
4210 : : flow->action_type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
4211 : 0 : dest_dev = dpaa2_flow_redirect_dev(priv, rte_action);
4212 [ # # ]: 0 : if (!dest_dev) {
4213 : 0 : DPAA2_PMD_ERR("Invalid device to redirect");
4214 : 0 : return -EINVAL;
4215 : : }
4216 : :
4217 : 0 : dest_priv = dest_dev->data->dev_private;
4218 : 0 : dest_q = dest_priv->tx_vq[0];
4219 : 0 : flow->fs_action_cfg.options =
4220 : : DPNI_FS_OPT_REDIRECT_TO_DPNI_TX;
4221 : 0 : flow->fs_action_cfg.redirect_obj_token =
4222 : 0 : dest_priv->token;
4223 : 0 : flow->fs_action_cfg.flow_id = dest_q->flow_id;
4224 : : }
4225 : :
4226 : : return 0;
4227 : : }
4228 : :
4229 : : static inline uint16_t
4230 : : dpaa2_flow_entry_size(uint16_t key_max_size)
4231 : : {
4232 : 0 : if (key_max_size > DPAA2_FLOW_ENTRY_MAX_SIZE) {
4233 : 0 : DPAA2_PMD_ERR("Key size(%d) > max(%d)",
4234 : : key_max_size,
4235 : : DPAA2_FLOW_ENTRY_MAX_SIZE);
4236 : :
4237 : 0 : return 0;
4238 : : }
4239 : :
4240 : : if (key_max_size > DPAA2_FLOW_ENTRY_MIN_SIZE)
4241 : : return DPAA2_FLOW_ENTRY_MAX_SIZE;
4242 : :
4243 : : /* Current MC only support fixed entry size(56)*/
4244 : : return DPAA2_FLOW_ENTRY_MAX_SIZE;
4245 : : }
4246 : :
4247 : : static inline int
4248 : 0 : dpaa2_flow_clear_fs_table(struct dpaa2_dev_priv *priv,
4249 : : uint8_t tc_id)
4250 : : {
4251 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4252 : : int need_clear = 0, ret;
4253 : 0 : struct fsl_mc_io *dpni = priv->hw;
4254 : :
4255 [ # # ]: 0 : while (curr) {
4256 [ # # ]: 0 : if (curr->tc_id == tc_id) {
4257 : : need_clear = 1;
4258 : : break;
4259 : : }
4260 : 0 : curr = LIST_NEXT(curr, next);
4261 : : }
4262 : :
4263 [ # # ]: 0 : if (need_clear) {
4264 : 0 : ret = dpni_clear_fs_entries(dpni, CMD_PRI_LOW,
4265 : 0 : priv->token, tc_id);
4266 [ # # ]: 0 : if (ret) {
4267 : 0 : DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
4268 : 0 : return ret;
4269 : : }
4270 : : }
4271 : :
4272 : : return 0;
4273 : : }
4274 : :
4275 : : static int
4276 : 0 : dpaa2_configure_fs_rss_table(struct dpaa2_dev_priv *priv,
4277 : : uint8_t tc_id, uint16_t dist_size, int rss_dist)
4278 : : {
4279 : : struct dpaa2_key_extract *tc_extract;
4280 : : uint8_t *key_cfg_buf;
4281 : : uint64_t key_cfg_iova;
4282 : : int ret;
4283 : : struct dpni_rx_dist_cfg tc_cfg;
4284 : 0 : struct fsl_mc_io *dpni = priv->hw;
4285 : : uint16_t entry_size;
4286 : : uint16_t key_max_size;
4287 : :
4288 : 0 : ret = dpaa2_flow_clear_fs_table(priv, tc_id);
4289 [ # # ]: 0 : if (ret < 0) {
4290 : 0 : DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
4291 : 0 : return ret;
4292 : : }
4293 : :
4294 : : tc_extract = &priv->extract.tc_key_extract[tc_id];
4295 : 0 : key_cfg_buf = priv->extract.tc_extract_param[tc_id];
4296 : 0 : key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
4297 : : DPAA2_EXTRACT_PARAM_MAX_SIZE);
4298 [ # # ]: 0 : if (key_cfg_iova == RTE_BAD_IOVA) {
4299 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
4300 : : __func__, key_cfg_buf);
4301 : :
4302 : 0 : return -ENOBUFS;
4303 : : }
4304 : :
4305 : 0 : key_max_size = tc_extract->key_profile.key_max_size;
4306 [ # # ]: 0 : entry_size = dpaa2_flow_entry_size(key_max_size);
4307 : :
4308 : 0 : dpaa2_flow_fs_extracts_log(priv, tc_id);
4309 : 0 : ret = dpkg_prepare_key_cfg(&tc_extract->dpkg,
4310 : : key_cfg_buf);
4311 [ # # ]: 0 : if (ret < 0) {
4312 : 0 : DPAA2_PMD_ERR("TC[%d] prepare key failed", tc_id);
4313 : 0 : return ret;
4314 : : }
4315 : :
4316 : : memset(&tc_cfg, 0, sizeof(struct dpni_rx_dist_cfg));
4317 : 0 : tc_cfg.dist_size = dist_size;
4318 : 0 : tc_cfg.key_cfg_iova = key_cfg_iova;
4319 [ # # ]: 0 : if (rss_dist)
4320 : 0 : tc_cfg.enable = true;
4321 : : else
4322 : : tc_cfg.enable = false;
4323 : 0 : tc_cfg.tc = tc_id;
4324 : 0 : ret = dpni_set_rx_hash_dist(dpni, CMD_PRI_LOW,
4325 : 0 : priv->token, &tc_cfg);
4326 [ # # ]: 0 : if (ret < 0) {
4327 [ # # ]: 0 : if (rss_dist) {
4328 : 0 : DPAA2_PMD_ERR("RSS TC[%d] set failed",
4329 : : tc_id);
4330 : : } else {
4331 : 0 : DPAA2_PMD_ERR("FS TC[%d] hash disable failed",
4332 : : tc_id);
4333 : : }
4334 : :
4335 : 0 : return ret;
4336 : : }
4337 : :
4338 [ # # ]: 0 : if (rss_dist)
4339 : : return 0;
4340 : :
4341 : 0 : tc_cfg.enable = true;
4342 : 0 : tc_cfg.fs_miss_flow_id = dpaa2_flow_miss_flow_id;
4343 : 0 : ret = dpni_set_rx_fs_dist(dpni, CMD_PRI_LOW,
4344 : 0 : priv->token, &tc_cfg);
4345 [ # # ]: 0 : if (ret < 0) {
4346 : 0 : DPAA2_PMD_ERR("TC[%d] FS configured failed", tc_id);
4347 : 0 : return ret;
4348 : : }
4349 : :
4350 : 0 : ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_FS_TYPE,
4351 : : entry_size, tc_id);
4352 [ # # ]: 0 : if (ret)
4353 : 0 : return ret;
4354 : :
4355 : : return 0;
4356 : : }
4357 : :
4358 : : static int
4359 : 0 : dpaa2_configure_qos_table(struct dpaa2_dev_priv *priv,
4360 : : int rss_dist)
4361 : : {
4362 : : struct dpaa2_key_extract *qos_extract;
4363 : : uint8_t *key_cfg_buf;
4364 : : uint64_t key_cfg_iova;
4365 : : int ret;
4366 : : struct dpni_qos_tbl_cfg qos_cfg;
4367 : 0 : struct fsl_mc_io *dpni = priv->hw;
4368 : : uint16_t entry_size;
4369 : : uint16_t key_max_size;
4370 : :
4371 [ # # # # ]: 0 : if (!rss_dist && priv->num_rx_tc <= 1) {
4372 : : /* QoS table is effecitive for FS multiple TCs or RSS.*/
4373 : : return 0;
4374 : : }
4375 : :
4376 [ # # ]: 0 : if (LIST_FIRST(&priv->flows)) {
4377 : 0 : ret = dpni_clear_qos_table(dpni, CMD_PRI_LOW,
4378 : 0 : priv->token);
4379 [ # # ]: 0 : if (ret < 0) {
4380 : 0 : DPAA2_PMD_ERR("QoS table clear failed");
4381 : 0 : return ret;
4382 : : }
4383 : : }
4384 : :
4385 : : qos_extract = &priv->extract.qos_key_extract;
4386 : 0 : key_cfg_buf = priv->extract.qos_extract_param;
4387 : 0 : key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
4388 : : DPAA2_EXTRACT_PARAM_MAX_SIZE);
4389 [ # # ]: 0 : if (key_cfg_iova == RTE_BAD_IOVA) {
4390 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
4391 : : __func__, key_cfg_buf);
4392 : :
4393 : 0 : return -ENOBUFS;
4394 : : }
4395 : :
4396 : 0 : key_max_size = qos_extract->key_profile.key_max_size;
4397 [ # # ]: 0 : entry_size = dpaa2_flow_entry_size(key_max_size);
4398 : :
4399 : 0 : dpaa2_flow_qos_extracts_log(priv);
4400 : :
4401 : 0 : ret = dpkg_prepare_key_cfg(&qos_extract->dpkg,
4402 : : key_cfg_buf);
4403 [ # # ]: 0 : if (ret < 0) {
4404 : 0 : DPAA2_PMD_ERR("QoS prepare extract failed");
4405 : 0 : return ret;
4406 : : }
4407 : : memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
4408 : 0 : qos_cfg.keep_entries = true;
4409 : 0 : qos_cfg.key_cfg_iova = key_cfg_iova;
4410 [ # # ]: 0 : if (rss_dist) {
4411 : 0 : qos_cfg.discard_on_miss = true;
4412 : : } else {
4413 : : qos_cfg.discard_on_miss = false;
4414 : : qos_cfg.default_tc = 0;
4415 : : }
4416 : :
4417 : 0 : ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
4418 : 0 : priv->token, &qos_cfg);
4419 [ # # ]: 0 : if (ret < 0) {
4420 : 0 : DPAA2_PMD_ERR("QoS table set failed");
4421 : 0 : return ret;
4422 : : }
4423 : :
4424 : 0 : ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_QOS_TYPE,
4425 : : entry_size, 0);
4426 [ # # ]: 0 : if (ret)
4427 : 0 : return ret;
4428 : :
4429 : : return 0;
4430 : : }
4431 : :
4432 : : static int
4433 : 0 : dpaa2_flow_item_convert(const struct rte_flow_item pattern[],
4434 : : struct rte_dpaa2_flow_item **dpaa2_pattern)
4435 : : {
4436 : : struct rte_dpaa2_flow_item *new_pattern;
4437 : : int num = 0, tunnel_start = 0;
4438 : :
4439 : : while (1) {
4440 : 0 : num++;
4441 [ # # ]: 0 : if (pattern[num].type == RTE_FLOW_ITEM_TYPE_END)
4442 : : break;
4443 : : }
4444 : :
4445 : 0 : new_pattern = rte_malloc(NULL, sizeof(struct rte_dpaa2_flow_item) * num,
4446 : : RTE_CACHE_LINE_SIZE);
4447 [ # # ]: 0 : if (!new_pattern) {
4448 : 0 : DPAA2_PMD_ERR("Failed to alloc %d flow items", num);
4449 : 0 : return -ENOMEM;
4450 : : }
4451 : :
4452 : : num = 0;
4453 [ # # ]: 0 : while (pattern[num].type != RTE_FLOW_ITEM_TYPE_END) {
4454 [ # # ]: 0 : memcpy(&new_pattern[num].generic_item, &pattern[num],
4455 : : sizeof(struct rte_flow_item));
4456 : 0 : new_pattern[num].in_tunnel = 0;
4457 : :
4458 [ # # ]: 0 : if (pattern[num].type == RTE_FLOW_ITEM_TYPE_VXLAN)
4459 : : tunnel_start = 1;
4460 [ # # ]: 0 : else if (tunnel_start)
4461 : 0 : new_pattern[num].in_tunnel = 1;
4462 : 0 : num++;
4463 : : }
4464 : :
4465 : 0 : new_pattern[num].generic_item.type = RTE_FLOW_ITEM_TYPE_END;
4466 : 0 : *dpaa2_pattern = new_pattern;
4467 : :
4468 : 0 : return 0;
4469 : : }
4470 : :
4471 : : static int
4472 : 0 : dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow,
4473 : : struct rte_eth_dev *dev,
4474 : : const struct rte_flow_attr *attr,
4475 : : const struct rte_flow_item pattern[],
4476 : : const struct rte_flow_action actions[],
4477 : : struct rte_flow_error *error)
4478 : : {
4479 : : const struct rte_flow_action_rss *rss_conf;
4480 : 0 : int is_keycfg_configured = 0, end_of_list = 0;
4481 : : int ret = 0, i = 0, j = 0;
4482 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4483 : 0 : struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
4484 : : uint16_t dist_size, key_size;
4485 : : struct dpaa2_key_extract *qos_key_extract;
4486 : : struct dpaa2_key_extract *tc_key_extract;
4487 : 0 : struct rte_dpaa2_flow_item *dpaa2_pattern = NULL;
4488 : :
4489 : 0 : ret = dpaa2_flow_verify_attr(priv, attr);
4490 [ # # ]: 0 : if (ret)
4491 : : return ret;
4492 : :
4493 : 0 : ret = dpaa2_flow_verify_action(priv, attr, actions);
4494 [ # # ]: 0 : if (ret)
4495 : : return ret;
4496 : :
4497 : 0 : ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern);
4498 [ # # ]: 0 : if (ret)
4499 : : return ret;
4500 : :
4501 : : /* Parse pattern list to get the matching parameters */
4502 [ # # ]: 0 : while (!end_of_list) {
4503 [ # # # # : 0 : switch (pattern[i].type) {
# # # # #
# # # # #
# # # ]
4504 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
4505 : 0 : ret = dpaa2_configure_flow_eth(flow, dev, attr,
4506 : 0 : &dpaa2_pattern[i],
4507 : : actions, error,
4508 : : &is_keycfg_configured);
4509 [ # # ]: 0 : if (ret) {
4510 : 0 : DPAA2_PMD_ERR("ETH flow config failed!");
4511 : 0 : goto end_flow_set;
4512 : : }
4513 : : break;
4514 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
4515 : 0 : ret = dpaa2_configure_flow_vlan(flow, dev, attr,
4516 : 0 : &dpaa2_pattern[i],
4517 : : actions, error,
4518 : : &is_keycfg_configured);
4519 [ # # ]: 0 : if (ret) {
4520 : 0 : DPAA2_PMD_ERR("vLan flow config failed!");
4521 : 0 : goto end_flow_set;
4522 : : }
4523 : : break;
4524 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
4525 : 0 : ret = dpaa2_configure_flow_ipv4(flow, dev, attr,
4526 : 0 : &dpaa2_pattern[i],
4527 : : actions, error,
4528 : : &is_keycfg_configured);
4529 [ # # ]: 0 : if (ret) {
4530 : 0 : DPAA2_PMD_ERR("IPV4 flow config failed!");
4531 : 0 : goto end_flow_set;
4532 : : }
4533 : : break;
4534 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
4535 : 0 : ret = dpaa2_configure_flow_ipv6(flow, dev, attr,
4536 : 0 : &dpaa2_pattern[i],
4537 : : actions, error,
4538 : : &is_keycfg_configured);
4539 [ # # ]: 0 : if (ret) {
4540 : 0 : DPAA2_PMD_ERR("IPV6 flow config failed!");
4541 : 0 : goto end_flow_set;
4542 : : }
4543 : : break;
4544 : 0 : case RTE_FLOW_ITEM_TYPE_ICMP:
4545 : 0 : ret = dpaa2_configure_flow_icmp(flow, dev, attr,
4546 : 0 : &dpaa2_pattern[i],
4547 : : actions, error,
4548 : : &is_keycfg_configured);
4549 [ # # ]: 0 : if (ret) {
4550 : 0 : DPAA2_PMD_ERR("ICMP flow config failed!");
4551 : 0 : goto end_flow_set;
4552 : : }
4553 : : break;
4554 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
4555 : 0 : ret = dpaa2_configure_flow_udp(flow, dev, attr,
4556 : 0 : &dpaa2_pattern[i],
4557 : : actions, error,
4558 : : &is_keycfg_configured);
4559 [ # # ]: 0 : if (ret) {
4560 : 0 : DPAA2_PMD_ERR("UDP flow config failed!");
4561 : 0 : goto end_flow_set;
4562 : : }
4563 : : break;
4564 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
4565 : 0 : ret = dpaa2_configure_flow_tcp(flow, dev, attr,
4566 : 0 : &dpaa2_pattern[i],
4567 : : actions, error,
4568 : : &is_keycfg_configured);
4569 [ # # ]: 0 : if (ret) {
4570 : 0 : DPAA2_PMD_ERR("TCP flow config failed!");
4571 : 0 : goto end_flow_set;
4572 : : }
4573 : : break;
4574 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
4575 : 0 : ret = dpaa2_configure_flow_sctp(flow, dev, attr,
4576 : 0 : &dpaa2_pattern[i],
4577 : : actions, error,
4578 : : &is_keycfg_configured);
4579 [ # # ]: 0 : if (ret) {
4580 : 0 : DPAA2_PMD_ERR("SCTP flow config failed!");
4581 : 0 : goto end_flow_set;
4582 : : }
4583 : : break;
4584 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
4585 : 0 : ret = dpaa2_configure_flow_esp(flow,
4586 : 0 : dev, attr, &dpaa2_pattern[i],
4587 : : actions, error,
4588 : : &is_keycfg_configured);
4589 [ # # ]: 0 : if (ret) {
4590 : 0 : DPAA2_PMD_ERR("ESP flow config failed!");
4591 : 0 : goto end_flow_set;
4592 : : }
4593 : : break;
4594 : 0 : case RTE_FLOW_ITEM_TYPE_AH:
4595 : 0 : ret = dpaa2_configure_flow_ah(flow,
4596 : 0 : dev, attr, &dpaa2_pattern[i],
4597 : : actions, error,
4598 : : &is_keycfg_configured);
4599 [ # # ]: 0 : if (ret) {
4600 : 0 : DPAA2_PMD_ERR("AH flow config failed!");
4601 : 0 : goto end_flow_set;
4602 : : }
4603 : : break;
4604 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
4605 : 0 : ret = dpaa2_configure_flow_gre(flow, dev, attr,
4606 : 0 : &dpaa2_pattern[i],
4607 : : actions, error,
4608 : : &is_keycfg_configured);
4609 [ # # ]: 0 : if (ret) {
4610 : 0 : DPAA2_PMD_ERR("GRE flow config failed!");
4611 : 0 : goto end_flow_set;
4612 : : }
4613 : : break;
4614 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
4615 : 0 : ret = dpaa2_configure_flow_vxlan(flow, dev, attr,
4616 : 0 : &dpaa2_pattern[i],
4617 : : actions, error,
4618 : : &is_keycfg_configured);
4619 [ # # ]: 0 : if (ret) {
4620 : 0 : DPAA2_PMD_ERR("VXLAN flow config failed!");
4621 : 0 : goto end_flow_set;
4622 : : }
4623 : : break;
4624 : 0 : case RTE_FLOW_ITEM_TYPE_ECPRI:
4625 : 0 : ret = dpaa2_configure_flow_ecpri(flow,
4626 : 0 : dev, attr, &dpaa2_pattern[i],
4627 : : actions, error,
4628 : : &is_keycfg_configured);
4629 [ # # ]: 0 : if (ret) {
4630 : 0 : DPAA2_PMD_ERR("ECPRI flow config failed!");
4631 : 0 : goto end_flow_set;
4632 : : }
4633 : : break;
4634 : 0 : case RTE_FLOW_ITEM_TYPE_GTP:
4635 : 0 : ret = dpaa2_configure_flow_gtp(flow,
4636 : 0 : dev, attr, &dpaa2_pattern[i],
4637 : : actions, error,
4638 : : &is_keycfg_configured);
4639 [ # # ]: 0 : if (ret) {
4640 : 0 : DPAA2_PMD_ERR("GTP flow config failed!");
4641 : 0 : goto end_flow_set;
4642 : : }
4643 : : break;
4644 : 0 : case RTE_FLOW_ITEM_TYPE_RAW:
4645 : 0 : ret = dpaa2_configure_flow_raw(flow, dev, attr,
4646 : 0 : &dpaa2_pattern[i],
4647 : : actions, error,
4648 : : &is_keycfg_configured);
4649 [ # # ]: 0 : if (ret) {
4650 : 0 : DPAA2_PMD_ERR("RAW flow config failed!");
4651 : 0 : goto end_flow_set;
4652 : : }
4653 : : break;
4654 : : case RTE_FLOW_ITEM_TYPE_END:
4655 : : end_of_list = 1;
4656 : : break; /*End of List*/
4657 : 0 : default:
4658 : 0 : DPAA2_PMD_ERR("Invalid flow item[%d] type(%d)",
4659 : : i, pattern[i].type);
4660 : : ret = -ENOTSUP;
4661 : 0 : break;
4662 : : }
4663 : 0 : i++;
4664 : : }
4665 : :
4666 : : qos_key_extract = &priv->extract.qos_key_extract;
4667 : 0 : key_size = qos_key_extract->key_profile.key_max_size;
4668 [ # # ]: 0 : flow->qos_rule.key_size = dpaa2_flow_entry_size(key_size);
4669 : :
4670 : 0 : tc_key_extract = &priv->extract.tc_key_extract[flow->tc_id];
4671 : 0 : key_size = tc_key_extract->key_profile.key_max_size;
4672 [ # # ]: 0 : flow->fs_rule.key_size = dpaa2_flow_entry_size(key_size);
4673 : :
4674 : : /* Let's parse action on matching traffic */
4675 : : end_of_list = 0;
4676 [ # # ]: 0 : while (!end_of_list) {
4677 [ # # # # : 0 : switch (actions[j].type) {
# ]
4678 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
4679 : : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4680 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
4681 : 0 : ret = dpaa2_configure_flow_fs_action(priv, flow,
4682 : : &actions[j]);
4683 [ # # ]: 0 : if (ret)
4684 : 0 : goto end_flow_set;
4685 : :
4686 : : /* Configure FS table first*/
4687 : 0 : dist_size = priv->nb_rx_queues / priv->num_rx_tc;
4688 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
4689 : 0 : ret = dpaa2_configure_fs_rss_table(priv,
4690 : 0 : flow->tc_id,
4691 : : dist_size,
4692 : : false);
4693 [ # # ]: 0 : if (ret)
4694 : 0 : goto end_flow_set;
4695 : : }
4696 : :
4697 : : /* Configure QoS table then.*/
4698 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
4699 : 0 : ret = dpaa2_configure_qos_table(priv, false);
4700 [ # # ]: 0 : if (ret)
4701 : 0 : goto end_flow_set;
4702 : : }
4703 : :
4704 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
4705 : 0 : ret = dpaa2_flow_add_qos_rule(priv, flow);
4706 [ # # ]: 0 : if (ret)
4707 : 0 : goto end_flow_set;
4708 : : }
4709 : :
4710 [ # # ]: 0 : if (flow->tc_index >= priv->fs_entries) {
4711 : 0 : DPAA2_PMD_ERR("FS table with %d entries full",
4712 : : priv->fs_entries);
4713 : 0 : return -1;
4714 : : }
4715 : :
4716 : 0 : ret = dpaa2_flow_add_fs_rule(priv, flow);
4717 [ # # ]: 0 : if (ret)
4718 : 0 : goto end_flow_set;
4719 : :
4720 : : break;
4721 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
4722 : 0 : rss_conf = actions[j].conf;
4723 : 0 : flow->action_type = RTE_FLOW_ACTION_TYPE_RSS;
4724 : :
4725 : 0 : ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
4726 : : &tc_key_extract->dpkg);
4727 [ # # ]: 0 : if (ret < 0) {
4728 : 0 : DPAA2_PMD_ERR("TC[%d] distset RSS failed",
4729 : : flow->tc_id);
4730 : 0 : goto end_flow_set;
4731 : : }
4732 : :
4733 : 0 : dist_size = rss_conf->queue_num;
4734 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
4735 : 0 : ret = dpaa2_configure_fs_rss_table(priv,
4736 : 0 : flow->tc_id,
4737 : : dist_size,
4738 : : true);
4739 [ # # ]: 0 : if (ret)
4740 : 0 : goto end_flow_set;
4741 : : }
4742 : :
4743 [ # # ]: 0 : if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
4744 : 0 : ret = dpaa2_configure_qos_table(priv, true);
4745 [ # # ]: 0 : if (ret)
4746 : 0 : goto end_flow_set;
4747 : : }
4748 : :
4749 : 0 : ret = dpaa2_flow_add_qos_rule(priv, flow);
4750 [ # # ]: 0 : if (ret)
4751 : 0 : goto end_flow_set;
4752 : :
4753 : 0 : ret = dpaa2_flow_add_fs_rule(priv, flow);
4754 [ # # ]: 0 : if (ret)
4755 : 0 : goto end_flow_set;
4756 : :
4757 : : break;
4758 : : case RTE_FLOW_ACTION_TYPE_PF:
4759 : : /* Skip this action, have to add for vxlan */
4760 : : break;
4761 : 0 : case RTE_FLOW_ACTION_TYPE_END:
4762 : : end_of_list = 1;
4763 : 0 : break;
4764 : 0 : default:
4765 : 0 : DPAA2_PMD_ERR("Invalid action type");
4766 : : ret = -ENOTSUP;
4767 : 0 : break;
4768 : : }
4769 : 0 : j++;
4770 : : }
4771 : :
4772 : 0 : end_flow_set:
4773 [ # # ]: 0 : if (!ret) {
4774 : : /* New rules are inserted. */
4775 [ # # ]: 0 : if (!curr) {
4776 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->flows, flow, next);
4777 : : } else {
4778 [ # # ]: 0 : while (LIST_NEXT(curr, next))
4779 : : curr = LIST_NEXT(curr, next);
4780 : 0 : LIST_INSERT_AFTER(curr, flow, next);
4781 : : }
4782 : : }
4783 : :
4784 : 0 : rte_free(dpaa2_pattern);
4785 : :
4786 : 0 : return ret;
4787 : : }
4788 : :
4789 : : static inline int
4790 : 0 : dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
4791 : : const struct rte_flow_attr *attr)
4792 : : {
4793 : : int ret = 0;
4794 : :
4795 [ # # ]: 0 : if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
4796 : 0 : DPAA2_PMD_ERR("Group/TC(%d) is out of range(%d)",
4797 : : attr->group, dpni_attr->num_rx_tcs);
4798 : : ret = -ENOTSUP;
4799 : : }
4800 [ # # ]: 0 : if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
4801 : 0 : DPAA2_PMD_ERR("Priority(%d) within group is out of range(%d)",
4802 : : attr->priority, dpni_attr->fs_entries);
4803 : : ret = -ENOTSUP;
4804 : : }
4805 [ # # ]: 0 : if (unlikely(attr->egress)) {
4806 : 0 : DPAA2_PMD_ERR("Egress flow configuration is not supported");
4807 : : ret = -ENOTSUP;
4808 : : }
4809 [ # # ]: 0 : if (unlikely(!attr->ingress)) {
4810 : 0 : DPAA2_PMD_ERR("Ingress flag must be configured");
4811 : : ret = -EINVAL;
4812 : : }
4813 : 0 : return ret;
4814 : : }
4815 : :
4816 : : static inline int
4817 : 0 : dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
4818 : : {
4819 : : unsigned int i, j, is_found = 0;
4820 : : int ret = 0;
4821 : : const enum rte_flow_item_type *hp_supported;
4822 : : const enum rte_flow_item_type *sp_supported;
4823 : : uint64_t hp_supported_num, sp_supported_num;
4824 : :
4825 : : hp_supported = dpaa2_hp_supported_pattern_type;
4826 : : hp_supported_num = RTE_DIM(dpaa2_hp_supported_pattern_type);
4827 : :
4828 : : sp_supported = dpaa2_sp_supported_pattern_type;
4829 : : sp_supported_num = RTE_DIM(dpaa2_sp_supported_pattern_type);
4830 : :
4831 [ # # ]: 0 : for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
4832 : : is_found = 0;
4833 [ # # ]: 0 : for (i = 0; i < hp_supported_num; i++) {
4834 [ # # ]: 0 : if (hp_supported[i] == pattern[j].type) {
4835 : : is_found = 1;
4836 : : break;
4837 : : }
4838 : : }
4839 [ # # ]: 0 : if (is_found)
4840 : 0 : continue;
4841 [ # # ]: 0 : if (dpaa2_sp_loaded > 0) {
4842 [ # # ]: 0 : for (i = 0; i < sp_supported_num; i++) {
4843 [ # # ]: 0 : if (sp_supported[i] == pattern[j].type) {
4844 : : is_found = 1;
4845 : : break;
4846 : : }
4847 : : }
4848 : : }
4849 [ # # ]: 0 : if (!is_found) {
4850 : 0 : DPAA2_PMD_WARN("Flow type(%d) not supported",
4851 : : pattern[j].type);
4852 : : ret = -ENOTSUP;
4853 : 0 : break;
4854 : : }
4855 : : }
4856 : :
4857 : 0 : return ret;
4858 : : }
4859 : :
4860 : : static inline int
4861 : 0 : dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
4862 : : {
4863 : : unsigned int i, j, is_found = 0;
4864 : : int ret = 0;
4865 : :
4866 [ # # ]: 0 : for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
4867 [ # # ]: 0 : for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
4868 [ # # ]: 0 : if (dpaa2_supported_action_type[i] == actions[j].type) {
4869 : : is_found = 1;
4870 : : break;
4871 : : }
4872 : : }
4873 [ # # ]: 0 : if (!is_found) {
4874 : : ret = -ENOTSUP;
4875 : : break;
4876 : : }
4877 : : }
4878 [ # # ]: 0 : for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
4879 [ # # ]: 0 : if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
4880 [ # # ]: 0 : !actions[j].conf)
4881 : : ret = -EINVAL;
4882 : : }
4883 : 0 : return ret;
4884 : : }
4885 : :
4886 : : static int
4887 : 0 : dpaa2_flow_validate(struct rte_eth_dev *dev,
4888 : : const struct rte_flow_attr *flow_attr,
4889 : : const struct rte_flow_item pattern[],
4890 : : const struct rte_flow_action actions[],
4891 : : struct rte_flow_error *error)
4892 : : {
4893 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4894 : : struct dpni_attr dpni_attr;
4895 : 0 : struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
4896 : 0 : uint16_t token = priv->token;
4897 : : int ret = 0;
4898 : :
4899 : : memset(&dpni_attr, 0, sizeof(struct dpni_attr));
4900 : 0 : ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
4901 [ # # ]: 0 : if (ret < 0) {
4902 : 0 : DPAA2_PMD_ERR("Get dpni@%d attribute failed(%d)",
4903 : : priv->hw_id, ret);
4904 : 0 : rte_flow_error_set(error, EPERM,
4905 : : RTE_FLOW_ERROR_TYPE_ATTR,
4906 : : flow_attr, "invalid");
4907 : 0 : return ret;
4908 : : }
4909 : :
4910 : : /* Verify input attributes */
4911 : 0 : ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
4912 [ # # ]: 0 : if (ret < 0) {
4913 : 0 : DPAA2_PMD_ERR("Invalid attributes are given");
4914 : 0 : rte_flow_error_set(error, EPERM,
4915 : : RTE_FLOW_ERROR_TYPE_ATTR,
4916 : : flow_attr, "invalid");
4917 : 0 : goto not_valid_params;
4918 : : }
4919 : : /* Verify input pattern list */
4920 : 0 : ret = dpaa2_dev_verify_patterns(pattern);
4921 [ # # ]: 0 : if (ret < 0) {
4922 : 0 : DPAA2_PMD_ERR("Invalid pattern list is given");
4923 : 0 : rte_flow_error_set(error, EPERM,
4924 : : RTE_FLOW_ERROR_TYPE_ITEM,
4925 : : pattern, "invalid");
4926 : 0 : goto not_valid_params;
4927 : : }
4928 : : /* Verify input action list */
4929 : 0 : ret = dpaa2_dev_verify_actions(actions);
4930 [ # # ]: 0 : if (ret < 0) {
4931 : 0 : DPAA2_PMD_ERR("Invalid action list is given");
4932 : 0 : rte_flow_error_set(error, EPERM,
4933 : : RTE_FLOW_ERROR_TYPE_ACTION,
4934 : : actions, "invalid");
4935 : 0 : goto not_valid_params;
4936 : : }
4937 : 0 : not_valid_params:
4938 : : return ret;
4939 : : }
4940 : :
4941 : : static struct rte_flow *
4942 : 0 : dpaa2_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
4943 : : const struct rte_flow_item pattern[],
4944 : : const struct rte_flow_action actions[],
4945 : : struct rte_flow_error *error)
4946 : : {
4947 : : struct dpaa2_dev_flow *flow = NULL;
4948 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
4949 : : int ret;
4950 : : uint64_t iova;
4951 : :
4952 : 0 : dpaa2_flow_control_log =
4953 : 0 : getenv("DPAA2_FLOW_CONTROL_LOG");
4954 : :
4955 [ # # ]: 0 : if (getenv("DPAA2_FLOW_CONTROL_MISS_FLOW")) {
4956 : 0 : dpaa2_flow_miss_flow_id =
4957 : 0 : (uint16_t)atoi(getenv("DPAA2_FLOW_CONTROL_MISS_FLOW"));
4958 [ # # ]: 0 : if (dpaa2_flow_miss_flow_id >= priv->dist_queues) {
4959 : 0 : DPAA2_PMD_ERR("Missed flow ID %d >= dist size(%d)",
4960 : : dpaa2_flow_miss_flow_id,
4961 : : priv->dist_queues);
4962 : 0 : return NULL;
4963 : : }
4964 : : }
4965 : :
4966 : 0 : flow = rte_zmalloc(NULL, sizeof(struct dpaa2_dev_flow),
4967 : : RTE_CACHE_LINE_SIZE);
4968 [ # # ]: 0 : if (!flow) {
4969 : 0 : DPAA2_PMD_ERR("Failure to allocate memory for flow");
4970 : 0 : goto mem_failure;
4971 : : }
4972 : :
4973 : : /* Allocate DMA'ble memory to write the qos rules */
4974 : 0 : flow->qos_key_addr = rte_zmalloc(NULL,
4975 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
4976 [ # # ]: 0 : if (!flow->qos_key_addr) {
4977 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
4978 : 0 : goto mem_failure;
4979 : : }
4980 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_key_addr,
4981 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
4982 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
4983 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for qos key(%p)",
4984 : : __func__, flow->qos_key_addr);
4985 : 0 : goto mem_failure;
4986 : : }
4987 : 0 : flow->qos_rule.key_iova = iova;
4988 : :
4989 : 0 : flow->qos_mask_addr = rte_zmalloc(NULL,
4990 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
4991 [ # # ]: 0 : if (!flow->qos_mask_addr) {
4992 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
4993 : 0 : goto mem_failure;
4994 : : }
4995 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_mask_addr,
4996 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
4997 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
4998 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for qos mask(%p)",
4999 : : __func__, flow->qos_mask_addr);
5000 : 0 : goto mem_failure;
5001 : : }
5002 : 0 : flow->qos_rule.mask_iova = iova;
5003 : :
5004 : : /* Allocate DMA'ble memory to write the FS rules */
5005 : 0 : flow->fs_key_addr = rte_zmalloc(NULL,
5006 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5007 [ # # ]: 0 : if (!flow->fs_key_addr) {
5008 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5009 : 0 : goto mem_failure;
5010 : : }
5011 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_key_addr,
5012 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5013 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5014 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for fs key(%p)",
5015 : : __func__, flow->fs_key_addr);
5016 : 0 : goto mem_failure;
5017 : : }
5018 : 0 : flow->fs_rule.key_iova = iova;
5019 : :
5020 : 0 : flow->fs_mask_addr = rte_zmalloc(NULL,
5021 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
5022 [ # # ]: 0 : if (!flow->fs_mask_addr) {
5023 : 0 : DPAA2_PMD_ERR("Memory allocation failed");
5024 : 0 : goto mem_failure;
5025 : : }
5026 : 0 : iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_mask_addr,
5027 : : DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
5028 [ # # ]: 0 : if (iova == RTE_BAD_IOVA) {
5029 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for fs mask(%p)",
5030 : : __func__, flow->fs_mask_addr);
5031 : 0 : goto mem_failure;
5032 : : }
5033 : 0 : flow->fs_rule.mask_iova = iova;
5034 : :
5035 : 0 : priv->curr = flow;
5036 : :
5037 : 0 : ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, actions, error);
5038 [ # # ]: 0 : if (ret < 0) {
5039 [ # # # # ]: 0 : if (error && error->type > RTE_FLOW_ERROR_TYPE_ACTION)
5040 : 0 : rte_flow_error_set(error, EPERM,
5041 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
5042 : : attr, "unknown");
5043 : 0 : DPAA2_PMD_ERR("Create flow failed (%d)", ret);
5044 : 0 : goto creation_error;
5045 : : }
5046 : :
5047 : 0 : priv->curr = NULL;
5048 : 0 : return (struct rte_flow *)flow;
5049 : :
5050 : 0 : mem_failure:
5051 : 0 : rte_flow_error_set(error, EPERM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
5052 : : "memory alloc");
5053 : :
5054 : 0 : creation_error:
5055 [ # # ]: 0 : if (flow) {
5056 : 0 : rte_free(flow->qos_key_addr);
5057 : 0 : rte_free(flow->qos_mask_addr);
5058 : 0 : rte_free(flow->fs_key_addr);
5059 : 0 : rte_free(flow->fs_mask_addr);
5060 : 0 : rte_free(flow);
5061 : : }
5062 : 0 : priv->curr = NULL;
5063 : :
5064 : 0 : return NULL;
5065 : : }
5066 : :
5067 : : static int
5068 : 0 : dpaa2_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *_flow,
5069 : : struct rte_flow_error *error)
5070 : : {
5071 : : int ret = 0;
5072 : : struct dpaa2_dev_flow *flow;
5073 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5074 : 0 : struct fsl_mc_io *dpni = priv->hw;
5075 : :
5076 : : flow = (struct dpaa2_dev_flow *)_flow;
5077 : :
5078 [ # # # ]: 0 : switch (flow->action_type) {
5079 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
5080 : : case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
5081 : : case RTE_FLOW_ACTION_TYPE_PORT_ID:
5082 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
5083 : : /* Remove entry from QoS table first */
5084 : 0 : ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
5085 : 0 : priv->token,
5086 : 0 : &flow->qos_rule);
5087 [ # # ]: 0 : if (ret < 0) {
5088 : 0 : DPAA2_PMD_ERR("Remove FS QoS entry failed");
5089 : 0 : dpaa2_flow_qos_entry_log("Delete failed", flow,
5090 : : -1);
5091 : 0 : abort();
5092 : : goto error;
5093 : : }
5094 : : }
5095 : :
5096 : : /* Then remove entry from FS table */
5097 : 0 : ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
5098 : 0 : flow->tc_id, &flow->fs_rule);
5099 [ # # ]: 0 : if (ret < 0) {
5100 : 0 : DPAA2_PMD_ERR("Remove entry from FS[%d] failed",
5101 : : flow->tc_id);
5102 : 0 : goto error;
5103 : : }
5104 : : break;
5105 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
5106 [ # # ]: 0 : if (priv->num_rx_tc > 1) {
5107 : 0 : ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
5108 : 0 : priv->token,
5109 : 0 : &flow->qos_rule);
5110 [ # # ]: 0 : if (ret < 0) {
5111 : 0 : DPAA2_PMD_ERR("Remove RSS QoS entry failed");
5112 : 0 : goto error;
5113 : : }
5114 : : }
5115 : : break;
5116 : 0 : default:
5117 : 0 : DPAA2_PMD_ERR("Action(%d) not supported", flow->action_type);
5118 : : ret = -ENOTSUP;
5119 : 0 : break;
5120 : : }
5121 : :
5122 [ # # ]: 0 : LIST_REMOVE(flow, next);
5123 : 0 : rte_free(flow->qos_key_addr);
5124 : 0 : rte_free(flow->qos_mask_addr);
5125 : 0 : rte_free(flow->fs_key_addr);
5126 : 0 : rte_free(flow->fs_mask_addr);
5127 : : /* Now free the flow */
5128 : 0 : rte_free(flow);
5129 : :
5130 : 0 : error:
5131 [ # # ]: 0 : if (ret)
5132 : 0 : rte_flow_error_set(error, EPERM,
5133 : : RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
5134 : : NULL, "unknown");
5135 : 0 : return ret;
5136 : : }
5137 : :
5138 : : /**
5139 : : * Destroy user-configured flow rules.
5140 : : *
5141 : : * This function skips internal flows rules.
5142 : : *
5143 : : * @see rte_flow_flush()
5144 : : * @see rte_flow_ops
5145 : : */
5146 : : static int
5147 : 0 : dpaa2_flow_flush(struct rte_eth_dev *dev,
5148 : : struct rte_flow_error *error)
5149 : : {
5150 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5151 : 0 : struct dpaa2_dev_flow *flow = LIST_FIRST(&priv->flows);
5152 : :
5153 [ # # ]: 0 : while (flow) {
5154 : 0 : struct dpaa2_dev_flow *next = LIST_NEXT(flow, next);
5155 : :
5156 : 0 : dpaa2_flow_destroy(dev, (struct rte_flow *)flow, error);
5157 : : flow = next;
5158 : : }
5159 : 0 : return 0;
5160 : : }
5161 : :
5162 : : static int
5163 : 0 : dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
5164 : : struct rte_flow *_flow __rte_unused,
5165 : : const struct rte_flow_action *actions __rte_unused,
5166 : : void *data __rte_unused,
5167 : : struct rte_flow_error *error __rte_unused)
5168 : : {
5169 : 0 : return 0;
5170 : : }
5171 : :
5172 : : /**
5173 : : * Clean up all flow rules.
5174 : : *
5175 : : * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
5176 : : * rules regardless of whether they are internal or user-configured.
5177 : : *
5178 : : * @param priv
5179 : : * Pointer to private structure.
5180 : : */
5181 : : void
5182 : 0 : dpaa2_flow_clean(struct rte_eth_dev *dev)
5183 : : {
5184 : : struct dpaa2_dev_flow *flow;
5185 : 0 : struct dpaa2_dev_priv *priv = dev->data->dev_private;
5186 : :
5187 [ # # ]: 0 : while ((flow = LIST_FIRST(&priv->flows)))
5188 : 0 : dpaa2_flow_destroy(dev, (struct rte_flow *)flow, NULL);
5189 : 0 : }
5190 : :
5191 : : const struct rte_flow_ops dpaa2_flow_ops = {
5192 : : .create = dpaa2_flow_create,
5193 : : .validate = dpaa2_flow_validate,
5194 : : .destroy = dpaa2_flow_destroy,
5195 : : .flush = dpaa2_flow_flush,
5196 : : .query = dpaa2_flow_query,
5197 : : };
|