Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include <fcntl.h>
6 : : #include <unistd.h>
7 : :
8 : : #include <cnxk_flow.h>
9 : : #include <cnxk_rep.h>
10 : : #include <cnxk_rep_msg.h>
11 : :
12 : : #define DEFAULT_DUMP_FILE_NAME "/tmp/fdump"
13 : : #define MAX_BUFFER_SIZE 1500
14 : :
15 : : const struct cnxk_rte_flow_action_info action_info[] = {
16 : : [RTE_FLOW_ACTION_TYPE_MARK] = {sizeof(struct rte_flow_action_mark)},
17 : : [RTE_FLOW_ACTION_TYPE_VF] = {sizeof(struct rte_flow_action_vf)},
18 : : [RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = {sizeof(struct rte_flow_action_port_id)},
19 : : [RTE_FLOW_ACTION_TYPE_PORT_ID] = {sizeof(struct rte_flow_action_port_id)},
20 : : [RTE_FLOW_ACTION_TYPE_QUEUE] = {sizeof(struct rte_flow_action_queue)},
21 : : [RTE_FLOW_ACTION_TYPE_RSS] = {sizeof(struct rte_flow_action_rss)},
22 : : [RTE_FLOW_ACTION_TYPE_SECURITY] = {sizeof(struct rte_flow_action_security)},
23 : : [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID] = {sizeof(struct rte_flow_action_of_set_vlan_vid)},
24 : : [RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = {sizeof(struct rte_flow_action_of_push_vlan)},
25 : : [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP] = {sizeof(struct rte_flow_action_of_set_vlan_pcp)},
26 : : [RTE_FLOW_ACTION_TYPE_METER] = {sizeof(struct rte_flow_action_meter)},
27 : : [RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP] = {sizeof(struct rte_flow_action_vxlan_encap)},
28 : : [RTE_FLOW_ACTION_TYPE_COUNT] = {sizeof(struct rte_flow_action_count)},
29 : : };
30 : :
31 : : static void
32 : 0 : cnxk_flow_params_count(const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
33 : : uint16_t *n_pattern, uint16_t *n_action)
34 : : {
35 : : int i = 0;
36 : :
37 [ # # ]: 0 : for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++)
38 : 0 : i++;
39 : :
40 : 0 : *n_pattern = ++i;
41 : 0 : plt_rep_dbg("Total patterns is %d", *n_pattern);
42 : :
43 : : i = 0;
44 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++)
45 : 0 : i++;
46 : 0 : *n_action = ++i;
47 : 0 : plt_rep_dbg("Total actions is %d", *n_action);
48 : 0 : }
49 : :
50 : : static void
51 : 0 : populate_attr_data(void *buffer, uint32_t *length, const struct rte_flow_attr *attr)
52 : : {
53 : : uint32_t sz = sizeof(struct rte_flow_attr);
54 : : uint32_t len;
55 : :
56 : 0 : cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_ATTR, sz);
57 : :
58 : 0 : len = *length;
59 : : /* Populate the attribute data */
60 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(buffer, len), attr, sz);
61 : 0 : len += sz;
62 : :
63 : 0 : *length = len;
64 : 0 : }
65 : :
66 : : static uint16_t
67 : 0 : prepare_pattern_data(const struct rte_flow_item *pattern, uint16_t nb_pattern,
68 : : uint64_t *pattern_data)
69 : : {
70 : : cnxk_pattern_hdr_t hdr;
71 : : uint16_t len = 0;
72 : : int i = 0;
73 : :
74 [ # # ]: 0 : for (i = 0; i < nb_pattern; i++) {
75 : : /* Populate the pattern type hdr */
76 : : memset(&hdr, 0, sizeof(cnxk_pattern_hdr_t));
77 : 0 : hdr.type = pattern->type;
78 [ # # ]: 0 : if (pattern->spec) {
79 : 0 : hdr.spec_sz = term[pattern->type].item_size;
80 : : hdr.last_sz = 0;
81 : 0 : hdr.mask_sz = term[pattern->type].item_size;
82 : : }
83 : :
84 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(pattern_data, len), &hdr, sizeof(cnxk_pattern_hdr_t));
85 : 0 : len += sizeof(cnxk_pattern_hdr_t);
86 : :
87 : : /* Copy pattern spec data */
88 [ # # ]: 0 : if (pattern->spec) {
89 : 0 : rte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->spec,
90 [ # # ]: 0 : term[pattern->type].item_size);
91 : 0 : len += term[pattern->type].item_size;
92 : : }
93 : :
94 : : /* Copy pattern last data */
95 [ # # ]: 0 : if (pattern->last) {
96 : 0 : rte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->last,
97 [ # # ]: 0 : term[pattern->type].item_size);
98 : 0 : len += term[pattern->type].item_size;
99 : : }
100 : :
101 : : /* Copy pattern mask data */
102 [ # # ]: 0 : if (pattern->mask) {
103 : 0 : rte_memcpy(RTE_PTR_ADD(pattern_data, len), pattern->mask,
104 [ # # ]: 0 : term[pattern->type].item_size);
105 : 0 : len += term[pattern->type].item_size;
106 : : }
107 : 0 : pattern++;
108 : : }
109 : :
110 : 0 : return len;
111 : : }
112 : :
113 : : static void
114 : 0 : populate_pattern_data(void *buffer, uint32_t *length, const struct rte_flow_item *pattern,
115 : : uint16_t nb_pattern)
116 : : {
117 : : uint64_t pattern_data[BUFSIZ];
118 : : uint32_t len;
119 : : uint32_t sz;
120 : :
121 : : memset(pattern_data, 0, BUFSIZ * sizeof(uint64_t));
122 : : /* Prepare pattern_data */
123 : 0 : sz = prepare_pattern_data(pattern, nb_pattern, pattern_data);
124 : :
125 : 0 : cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_PATTERN, sz);
126 : :
127 : 0 : len = *length;
128 : : /* Populate the pattern data */
129 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(buffer, len), pattern_data, sz);
130 : 0 : len += sz;
131 : :
132 : 0 : *length = len;
133 : 0 : }
134 : :
135 : : static uint16_t
136 : 0 : populate_rss_action_conf(const struct rte_flow_action_rss *conf, void *rss_action_conf)
137 : : {
138 : : int len, sz;
139 : :
140 : : len = sizeof(struct rte_flow_action_rss) - sizeof(conf->key) - sizeof(conf->queue);
141 : :
142 [ # # ]: 0 : if (rss_action_conf)
143 : : rte_memcpy(rss_action_conf, conf, len);
144 : :
145 [ # # ]: 0 : if (conf->key) {
146 : 0 : sz = conf->key_len;
147 [ # # ]: 0 : if (rss_action_conf)
148 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(rss_action_conf, len), conf->key, sz);
149 : 0 : len += sz;
150 : : }
151 : :
152 [ # # # # ]: 0 : if (conf->queue) {
153 : 0 : sz = conf->queue_num * sizeof(conf->queue);
154 [ # # ]: 0 : if (rss_action_conf)
155 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(rss_action_conf, len), conf->queue, sz);
156 : 0 : len += sz;
157 : : }
158 : :
159 : 0 : return len;
160 : : }
161 : :
162 : : static uint16_t
163 : 0 : populate_vxlan_encap_action_conf(const struct rte_flow_action_vxlan_encap *vxlan_conf,
164 : : void *vxlan_encap_action_data)
165 : : {
166 : : const struct rte_flow_item *pattern;
167 : 0 : uint64_t nb_patterns = 0;
168 : : uint16_t len, sz;
169 : :
170 : 0 : pattern = vxlan_conf->definition;
171 [ # # ]: 0 : for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++)
172 : 0 : nb_patterns++;
173 : :
174 : : len = sizeof(uint64_t);
175 : : rte_memcpy(vxlan_encap_action_data, &nb_patterns, len);
176 : 0 : pattern = vxlan_conf->definition;
177 : : /* Prepare pattern_data */
178 : 0 : sz = prepare_pattern_data(pattern, nb_patterns, RTE_PTR_ADD(vxlan_encap_action_data, len));
179 : :
180 : 0 : len += sz;
181 [ # # ]: 0 : if (len > BUFSIZ) {
182 : 0 : plt_err("Incomplete item definition loaded, len %d", len);
183 : 0 : return 0;
184 : : }
185 : :
186 : : return len;
187 : : }
188 : :
189 : : static uint16_t
190 : 0 : prepare_action_data(const struct rte_flow_action *action, uint16_t nb_action, uint64_t *action_data)
191 : : {
192 : : void *action_conf_data = NULL;
193 : : cnxk_action_hdr_t hdr;
194 : : uint16_t len = 0, sz = 0;
195 : : int i = 0;
196 : :
197 [ # # ]: 0 : for (i = 0; i < nb_action; i++) {
198 [ # # ]: 0 : if (action->conf) {
199 [ # # # ]: 0 : switch (action->type) {
200 [ # # ]: 0 : case RTE_FLOW_ACTION_TYPE_RSS:
201 : : sz = populate_rss_action_conf(action->conf, NULL);
202 : 0 : action_conf_data = plt_zmalloc(sz, 0);
203 [ # # ]: 0 : if (populate_rss_action_conf(action->conf, action_conf_data) !=
204 : : sz) {
205 : 0 : plt_err("Populating RSS action config failed");
206 : 0 : return 0;
207 : : }
208 : : break;
209 : 0 : case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
210 : 0 : action_conf_data = plt_zmalloc(BUFSIZ, 0);
211 : 0 : sz = populate_vxlan_encap_action_conf(action->conf,
212 : : action_conf_data);
213 [ # # ]: 0 : if (!sz) {
214 : 0 : plt_err("Populating vxlan action config failed");
215 : 0 : return 0;
216 : : }
217 : : break;
218 : 0 : default:
219 : 0 : sz = action_info[action->type].conf_size;
220 : 0 : action_conf_data = plt_zmalloc(sz, 0);
221 [ # # ]: 0 : rte_memcpy(action_conf_data, action->conf, sz);
222 : : break;
223 : : };
224 : : }
225 : :
226 : : /* Populate the action type hdr */
227 : : memset(&hdr, 0, sizeof(cnxk_action_hdr_t));
228 : 0 : hdr.type = action->type;
229 : 0 : hdr.conf_sz = sz;
230 : :
231 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(action_data, len), &hdr, sizeof(cnxk_action_hdr_t));
232 : 0 : len += sizeof(cnxk_action_hdr_t);
233 : :
234 : : /* Copy action conf data */
235 [ # # ]: 0 : if (action_conf_data) {
236 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(action_data, len), action_conf_data, sz);
237 : 0 : len += sz;
238 : 0 : plt_free(action_conf_data);
239 : : action_conf_data = NULL;
240 : : }
241 : :
242 : 0 : action++;
243 : : }
244 : :
245 : : return len;
246 : : }
247 : :
248 : : static void
249 : 0 : populate_action_data(void *buffer, uint32_t *length, const struct rte_flow_action *action,
250 : : uint16_t nb_action)
251 : : {
252 : : uint64_t action_data[BUFSIZ];
253 : : uint32_t len;
254 : : uint32_t sz;
255 : :
256 : : memset(action_data, 0, BUFSIZ * sizeof(uint64_t));
257 : : /* Prepare action_data */
258 : 0 : sz = prepare_action_data(action, nb_action, action_data);
259 : :
260 : 0 : cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_ACTION, sz);
261 : :
262 : 0 : len = *length;
263 : : /* Populate the action data */
264 [ # # ]: 0 : rte_memcpy(RTE_PTR_ADD(buffer, len), action_data, sz);
265 : 0 : len += sz;
266 : :
267 : 0 : *length = len;
268 : 0 : }
269 : :
270 : : static int
271 : 0 : process_flow_destroy(struct cnxk_rep_dev *rep_dev, void *flow, cnxk_rep_msg_ack_data_t *adata)
272 : : {
273 : : cnxk_rep_msg_flow_destroy_meta_t msg_fd_meta;
274 : 0 : uint32_t len = 0, rc;
275 : : void *buffer;
276 : : size_t size;
277 : :
278 : : /* If representor not representing any active VF, return 0 */
279 [ # # ]: 0 : if (!rep_dev->is_vf_active)
280 : : return 0;
281 : :
282 : : size = MAX_BUFFER_SIZE;
283 : 0 : buffer = plt_zmalloc(size, 0);
284 [ # # ]: 0 : if (!buffer) {
285 : 0 : plt_err("Failed to allocate mem");
286 : : rc = -ENOMEM;
287 : 0 : goto fail;
288 : : }
289 : :
290 : 0 : cnxk_rep_msg_populate_header(buffer, &len);
291 : :
292 : 0 : msg_fd_meta.portid = rep_dev->rep_id;
293 : 0 : msg_fd_meta.flow = (uint64_t)flow;
294 : 0 : plt_rep_dbg("Flow Destroy: flow 0x%" PRIu64 ", portid %d", msg_fd_meta.flow,
295 : : msg_fd_meta.portid);
296 : 0 : cnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fd_meta,
297 : : sizeof(cnxk_rep_msg_flow_destroy_meta_t),
298 : : CNXK_REP_MSG_FLOW_DESTROY);
299 : 0 : cnxk_rep_msg_populate_msg_end(buffer, &len);
300 : :
301 : 0 : rc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);
302 [ # # ]: 0 : if (rc) {
303 : 0 : plt_err("Failed to process the message, err %d", rc);
304 : 0 : goto fail;
305 : : }
306 : :
307 : : return 0;
308 : 0 : fail:
309 : 0 : return rc;
310 : : }
311 : :
312 : : static int
313 : 0 : copy_flow_dump_file(FILE *target)
314 : : {
315 : : FILE *source = NULL;
316 : : int pos;
317 : : char ch;
318 : :
319 : 0 : source = fopen(DEFAULT_DUMP_FILE_NAME, "r");
320 [ # # ]: 0 : if (source == NULL) {
321 : 0 : plt_err("Failed to read default dump file: %s, err %d", DEFAULT_DUMP_FILE_NAME,
322 : : errno);
323 : 0 : return errno;
324 : : }
325 : :
326 : 0 : fseek(source, 0L, SEEK_END);
327 : 0 : pos = ftell(source);
328 : 0 : fseek(source, 0L, SEEK_SET);
329 [ # # ]: 0 : while (pos--) {
330 : 0 : ch = fgetc(source);
331 : 0 : fputc(ch, target);
332 : : }
333 : :
334 : 0 : fclose(source);
335 : :
336 : : /* Remove the default file after reading */
337 : 0 : remove(DEFAULT_DUMP_FILE_NAME);
338 : :
339 : 0 : return 0;
340 : : }
341 : :
342 : : static int
343 : 0 : process_flow_dump(struct cnxk_rep_dev *rep_dev, struct rte_flow *flow, FILE *file,
344 : : cnxk_rep_msg_ack_data_t *adata)
345 : : {
346 : : cnxk_rep_msg_flow_dump_meta_t msg_fp_meta;
347 : 0 : uint32_t len = 0, rc;
348 : : void *buffer;
349 : : size_t size;
350 : :
351 : : size = MAX_BUFFER_SIZE;
352 : 0 : buffer = plt_zmalloc(size, 0);
353 [ # # ]: 0 : if (!buffer) {
354 : 0 : plt_err("Failed to allocate mem");
355 : : rc = -ENOMEM;
356 : 0 : goto fail;
357 : : }
358 : :
359 : 0 : cnxk_rep_msg_populate_header(buffer, &len);
360 : :
361 : 0 : msg_fp_meta.portid = rep_dev->rep_id;
362 : 0 : msg_fp_meta.flow = (uint64_t)flow;
363 : 0 : msg_fp_meta.is_stdout = (file == stdout) ? 1 : 0;
364 : :
365 : 0 : plt_rep_dbg("Flow Dump: flow 0x%" PRIu64 ", portid %d stdout %d", msg_fp_meta.flow,
366 : : msg_fp_meta.portid, msg_fp_meta.is_stdout);
367 : 0 : cnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fp_meta,
368 : : sizeof(cnxk_rep_msg_flow_dump_meta_t),
369 : : CNXK_REP_MSG_FLOW_DUMP);
370 : 0 : cnxk_rep_msg_populate_msg_end(buffer, &len);
371 : :
372 : 0 : rc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);
373 [ # # ]: 0 : if (rc) {
374 : 0 : plt_err("Failed to process the message, err %d", rc);
375 : 0 : goto fail;
376 : : }
377 : :
378 : : /* Copy contents from default file to user file */
379 [ # # ]: 0 : if (file != stdout)
380 : 0 : copy_flow_dump_file(file);
381 : :
382 : : return 0;
383 : 0 : fail:
384 : 0 : return rc;
385 : : }
386 : :
387 : : static int
388 : 0 : process_flow_flush(struct cnxk_rep_dev *rep_dev, cnxk_rep_msg_ack_data_t *adata)
389 : : {
390 : : cnxk_rep_msg_flow_flush_meta_t msg_ff_meta;
391 : 0 : uint32_t len = 0, rc;
392 : : void *buffer;
393 : : size_t size;
394 : :
395 : : size = MAX_BUFFER_SIZE;
396 : 0 : buffer = plt_zmalloc(size, 0);
397 [ # # ]: 0 : if (!buffer) {
398 : 0 : plt_err("Failed to allocate mem");
399 : : rc = -ENOMEM;
400 : 0 : goto fail;
401 : : }
402 : :
403 : 0 : cnxk_rep_msg_populate_header(buffer, &len);
404 : :
405 : 0 : msg_ff_meta.portid = rep_dev->rep_id;
406 : 0 : plt_rep_dbg("Flow Flush: portid %d", msg_ff_meta.portid);
407 : 0 : cnxk_rep_msg_populate_command_meta(buffer, &len, &msg_ff_meta,
408 : : sizeof(cnxk_rep_msg_flow_flush_meta_t),
409 : : CNXK_REP_MSG_FLOW_FLUSH);
410 : 0 : cnxk_rep_msg_populate_msg_end(buffer, &len);
411 : :
412 : 0 : rc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);
413 [ # # ]: 0 : if (rc) {
414 : 0 : plt_err("Failed to process the message, err %d", rc);
415 : 0 : goto fail;
416 : : }
417 : :
418 : : return 0;
419 : 0 : fail:
420 : 0 : return rc;
421 : : }
422 : :
423 : : static int
424 : 0 : process_flow_query(struct cnxk_rep_dev *rep_dev, struct rte_flow *flow,
425 : : const struct rte_flow_action *action, void *data, cnxk_rep_msg_ack_data_t *adata)
426 : : {
427 : : cnxk_rep_msg_flow_query_meta_t *msg_fq_meta;
428 : : struct rte_flow_query_count *query = data;
429 : 0 : uint32_t len = 0, rc, sz, total_sz;
430 : : uint64_t action_data[BUFSIZ];
431 : : void *buffer;
432 : : size_t size;
433 : :
434 : : size = MAX_BUFFER_SIZE;
435 : 0 : buffer = plt_zmalloc(size, 0);
436 [ # # ]: 0 : if (!buffer) {
437 : 0 : plt_err("Failed to allocate mem");
438 : : rc = -ENOMEM;
439 : 0 : goto fail;
440 : : }
441 : :
442 : 0 : cnxk_rep_msg_populate_header(buffer, &len);
443 : :
444 : : memset(action_data, 0, BUFSIZ * sizeof(uint64_t));
445 : 0 : sz = prepare_action_data(action, 1, action_data);
446 : 0 : total_sz = sz + sizeof(cnxk_rep_msg_flow_query_meta_t);
447 : :
448 : 0 : msg_fq_meta = plt_zmalloc(total_sz, 0);
449 [ # # ]: 0 : if (!msg_fq_meta) {
450 : 0 : plt_err("Failed to allocate memory");
451 : : rc = -ENOMEM;
452 : 0 : goto fail;
453 : : }
454 : :
455 : 0 : msg_fq_meta->portid = rep_dev->rep_id;
456 : 0 : msg_fq_meta->reset = query->reset;
457 : : ;
458 : 0 : msg_fq_meta->flow = (uint64_t)flow;
459 : : /* Populate the action data */
460 [ # # ]: 0 : rte_memcpy(msg_fq_meta->action_data, action_data, sz);
461 : 0 : msg_fq_meta->action_data_sz = sz;
462 : :
463 : 0 : plt_rep_dbg("Flow query: flow 0x%" PRIu64 ", portid %d, action type %d total sz %d "
464 : : "action sz %d", msg_fq_meta->flow, msg_fq_meta->portid, action->type, total_sz,
465 : : sz);
466 : 0 : cnxk_rep_msg_populate_command_meta(buffer, &len, msg_fq_meta, total_sz,
467 : : CNXK_REP_MSG_FLOW_QUERY);
468 : 0 : cnxk_rep_msg_populate_msg_end(buffer, &len);
469 : :
470 : 0 : rc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);
471 [ # # ]: 0 : if (rc) {
472 : 0 : plt_err("Failed to process the message, err %d", rc);
473 : 0 : goto free;
474 : : }
475 : :
476 : 0 : rte_free(msg_fq_meta);
477 : :
478 : 0 : return 0;
479 : :
480 : : free:
481 : 0 : rte_free(msg_fq_meta);
482 : 0 : fail:
483 : 0 : return rc;
484 : : }
485 : :
486 : : static int
487 : 0 : process_flow_rule(struct cnxk_rep_dev *rep_dev, const struct rte_flow_attr *attr,
488 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
489 : : cnxk_rep_msg_ack_data_t *adata, cnxk_rep_msg_t msg)
490 : : {
491 : : cnxk_rep_msg_flow_create_meta_t msg_fc_meta;
492 : : uint16_t n_pattern, n_action;
493 : 0 : uint32_t len = 0, rc = 0;
494 : : void *buffer;
495 : : size_t size;
496 : :
497 : : size = MAX_BUFFER_SIZE;
498 : 0 : buffer = plt_zmalloc(size, 0);
499 [ # # ]: 0 : if (!buffer) {
500 : 0 : plt_err("Failed to allocate mem");
501 : : rc = -ENOMEM;
502 : 0 : goto fail;
503 : : }
504 : :
505 : : /* Get no of actions and patterns */
506 : 0 : cnxk_flow_params_count(pattern, actions, &n_pattern, &n_action);
507 : :
508 : : /* Adding the header */
509 : 0 : cnxk_rep_msg_populate_header(buffer, &len);
510 : :
511 : : /* Representor port identified as rep_xport queue */
512 : 0 : msg_fc_meta.portid = rep_dev->rep_id;
513 : 0 : msg_fc_meta.nb_pattern = n_pattern;
514 : 0 : msg_fc_meta.nb_action = n_action;
515 : :
516 : 0 : cnxk_rep_msg_populate_command_meta(buffer, &len, &msg_fc_meta,
517 : : sizeof(cnxk_rep_msg_flow_create_meta_t), msg);
518 : :
519 : : /* Populate flow create parameters data */
520 : 0 : populate_attr_data(buffer, &len, attr);
521 : 0 : populate_pattern_data(buffer, &len, pattern, n_pattern);
522 : 0 : populate_action_data(buffer, &len, actions, n_action);
523 : :
524 : 0 : cnxk_rep_msg_populate_msg_end(buffer, &len);
525 : :
526 : 0 : rc = cnxk_rep_msg_send_process(rep_dev, buffer, len, adata);
527 [ # # ]: 0 : if (rc) {
528 : 0 : plt_err("Failed to process the message, err %d", rc);
529 : 0 : goto fail;
530 : : }
531 : :
532 : : return 0;
533 : 0 : fail:
534 : 0 : return rc;
535 : : }
536 : :
537 : : static struct rte_flow *
538 : 0 : cnxk_rep_flow_create_native(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
539 : : const struct rte_flow_item pattern[],
540 : : const struct rte_flow_action actions[], struct rte_flow_error *error)
541 : : {
542 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
543 : : struct roc_npc_flow *flow;
544 : : uint16_t new_entry;
545 : : int rc;
546 : :
547 : 0 : flow = cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, true);
548 [ # # ]: 0 : if (!flow) {
549 : 0 : plt_err("Fail to create flow");
550 : 0 : goto fail;
551 : : }
552 : :
553 : : /* Shifting the rules with higher priority than exception path rules */
554 : 0 : new_entry = (uint16_t)flow->mcam_id;
555 : 0 : rc = cnxk_eswitch_flow_rule_shift(rep_dev->hw_func, &new_entry);
556 [ # # ]: 0 : if (rc) {
557 : 0 : plt_err("Failed to shift the flow rule entry, err %d", rc);
558 : 0 : goto fail;
559 : : }
560 : :
561 : 0 : flow->mcam_id = new_entry;
562 : :
563 : 0 : return (struct rte_flow *)flow;
564 : : fail:
565 : : return NULL;
566 : : }
567 : :
568 : : static struct rte_flow *
569 [ # # ]: 0 : cnxk_rep_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
570 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
571 : : struct rte_flow_error *error)
572 : : {
573 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
574 : : struct rte_flow *flow = NULL;
575 : : cnxk_rep_msg_ack_data_t adata;
576 : : int rc = 0;
577 : :
578 : : /* If representor not representing any active VF, return 0 */
579 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
580 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
581 : : "Represented VF not active yet");
582 : 0 : return 0;
583 : : }
584 : :
585 [ # # ]: 0 : if (rep_dev->native_repte)
586 : 0 : return cnxk_rep_flow_create_native(eth_dev, attr, pattern, actions, error);
587 : :
588 : 0 : rc = process_flow_rule(rep_dev, attr, pattern, actions, &adata, CNXK_REP_MSG_FLOW_CREATE);
589 [ # # # # ]: 0 : if (!rc || adata.u.sval < 0) {
590 [ # # ]: 0 : if (adata.u.sval < 0) {
591 : 0 : rc = (int)adata.u.sval;
592 : 0 : rte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
593 : : NULL, "Failed to validate flow");
594 : 0 : goto fail;
595 : : }
596 : :
597 : : flow = adata.u.data;
598 [ # # ]: 0 : if (!flow) {
599 : 0 : rte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
600 : : NULL, "Failed to create flow");
601 : 0 : goto fail;
602 : : }
603 : : } else {
604 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
605 : : "Failed to create flow");
606 : 0 : goto fail;
607 : : }
608 : 0 : plt_rep_dbg("Flow %p created successfully", adata.u.data);
609 : :
610 : 0 : return flow;
611 : : fail:
612 : : return NULL;
613 : : }
614 : :
615 : : static int
616 [ # # ]: 0 : cnxk_rep_flow_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
617 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
618 : : struct rte_flow_error *error)
619 : : {
620 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
621 : : cnxk_rep_msg_ack_data_t adata;
622 : : int rc = 0;
623 : :
624 : : /* If representor not representing any active VF, return 0 */
625 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
626 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
627 : : "Represented VF not active yet");
628 : 0 : return 0;
629 : : }
630 : :
631 [ # # ]: 0 : if (rep_dev->native_repte)
632 : 0 : return cnxk_flow_validate_common(eth_dev, attr, pattern, actions, error, true);
633 : :
634 : 0 : rc = process_flow_rule(rep_dev, attr, pattern, actions, &adata, CNXK_REP_MSG_FLOW_VALIDATE);
635 [ # # # # ]: 0 : if (!rc || adata.u.sval < 0) {
636 [ # # ]: 0 : if (adata.u.sval < 0) {
637 : 0 : rc = (int)adata.u.sval;
638 : 0 : rte_flow_error_set(error, adata.u.sval, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
639 : : NULL, "Failed to validate flow");
640 : 0 : goto fail;
641 : : }
642 : : } else {
643 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
644 : : "Failed to validate flow");
645 : : }
646 : :
647 : 0 : plt_rep_dbg("Flow %p validated successfully", adata.u.data);
648 : :
649 : : fail:
650 : : return rc;
651 : : }
652 : :
653 : : static int
654 [ # # ]: 0 : cnxk_rep_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
655 : : struct rte_flow_error *error)
656 : : {
657 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
658 : : cnxk_rep_msg_ack_data_t adata;
659 : : int rc;
660 : :
661 : : /* If representor not representing any active VF, return 0 */
662 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
663 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
664 : : "Represented VF not active yet");
665 : 0 : return 0;
666 : : }
667 : :
668 [ # # ]: 0 : if (rep_dev->native_repte)
669 : 0 : return cnxk_flow_destroy_common(eth_dev, (struct roc_npc_flow *)flow, error, true);
670 : :
671 : 0 : rc = process_flow_destroy(rep_dev, flow, &adata);
672 [ # # # # ]: 0 : if (rc || adata.u.sval < 0) {
673 [ # # ]: 0 : if (adata.u.sval < 0)
674 : 0 : rc = adata.u.sval;
675 : :
676 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
677 : : "Failed to destroy flow");
678 : 0 : goto fail;
679 : : }
680 : :
681 : : return 0;
682 : : fail:
683 : 0 : return rc;
684 : : }
685 : :
686 : : static int
687 [ # # ]: 0 : cnxk_rep_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
688 : : const struct rte_flow_action *action, void *data, struct rte_flow_error *error)
689 : : {
690 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
691 : : cnxk_rep_msg_ack_data_t adata;
692 : : int rc;
693 : :
694 : : /* If representor not representing any active VF, return 0 */
695 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
696 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
697 : : "Represented VF not active yet");
698 : 0 : return 0;
699 : : }
700 : :
701 [ # # ]: 0 : if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
702 : : rc = -ENOTSUP;
703 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
704 : : "Only COUNT is supported in query");
705 : 0 : goto fail;
706 : : }
707 : :
708 [ # # ]: 0 : if (rep_dev->native_repte)
709 : 0 : return cnxk_flow_query_common(eth_dev, flow, action, data, error, true);
710 : :
711 : 0 : rc = process_flow_query(rep_dev, flow, action, data, &adata);
712 [ # # # # ]: 0 : if (rc || adata.u.sval < 0) {
713 [ # # ]: 0 : if (adata.u.sval < 0)
714 : 0 : rc = adata.u.sval;
715 : :
716 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
717 : : "Failed to query the flow");
718 : 0 : goto fail;
719 : : }
720 : :
721 [ # # ]: 0 : rte_memcpy(data, adata.u.data, adata.size);
722 : :
723 : : return 0;
724 : : fail:
725 : : return rc;
726 : : }
727 : :
728 : : static int
729 [ # # ]: 0 : cnxk_rep_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
730 : : {
731 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
732 : : cnxk_rep_msg_ack_data_t adata;
733 : : int rc;
734 : :
735 : : /* If representor not representing any active VF, return 0 */
736 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
737 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
738 : : "Represented VF not active yet");
739 : 0 : return 0;
740 : : }
741 : :
742 [ # # ]: 0 : if (rep_dev->native_repte)
743 : 0 : return cnxk_flow_flush_common(eth_dev, error, true);
744 : :
745 : 0 : rc = process_flow_flush(rep_dev, &adata);
746 [ # # # # ]: 0 : if (rc || adata.u.sval < 0) {
747 [ # # ]: 0 : if (adata.u.sval < 0)
748 : 0 : rc = adata.u.sval;
749 : :
750 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
751 : : "Failed to destroy flow");
752 : 0 : goto fail;
753 : : }
754 : :
755 : : return 0;
756 : : fail:
757 : 0 : return rc;
758 : : }
759 : :
760 : : static int
761 [ # # ]: 0 : cnxk_rep_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow, FILE *file,
762 : : struct rte_flow_error *error)
763 : : {
764 : : struct cnxk_rep_dev *rep_dev = cnxk_rep_pmd_priv(eth_dev);
765 : : cnxk_rep_msg_ack_data_t adata;
766 : : int rc;
767 : :
768 : : /* If representor not representing any active VF, return 0 */
769 [ # # ]: 0 : if (!rep_dev->is_vf_active) {
770 : 0 : rte_flow_error_set(error, -EAGAIN, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
771 : : "Represented VF not active yet");
772 : 0 : return 0;
773 : : }
774 : :
775 [ # # ]: 0 : if (rep_dev->native_repte)
776 : 0 : return cnxk_flow_dev_dump_common(eth_dev, flow, file, error, true);
777 : :
778 : 0 : rc = process_flow_dump(rep_dev, flow, file, &adata);
779 [ # # # # ]: 0 : if (rc || adata.u.sval < 0) {
780 [ # # ]: 0 : if (adata.u.sval < 0)
781 : 0 : rc = adata.u.sval;
782 : :
783 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
784 : : "Failed to destroy flow");
785 : 0 : goto fail;
786 : : }
787 : :
788 : : return 0;
789 : : fail:
790 : 0 : return rc;
791 : : }
792 : :
793 : : static int
794 : 0 : cnxk_rep_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused, int enable __rte_unused,
795 : : struct rte_flow_error *error)
796 : : {
797 : : /* If we support, we need to un-install the default mcam
798 : : * entry for this port.
799 : : */
800 : :
801 : 0 : rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
802 : : "Flow isolation not supported");
803 : :
804 : 0 : return -rte_errno;
805 : : }
806 : :
807 : : struct rte_flow_ops cnxk_rep_flow_ops = {
808 : : .validate = cnxk_rep_flow_validate,
809 : : .create = cnxk_rep_flow_create,
810 : : .destroy = cnxk_rep_flow_destroy,
811 : : .query = cnxk_rep_flow_query,
812 : : .flush = cnxk_rep_flow_flush,
813 : : .isolate = cnxk_rep_flow_isolate,
814 : : .dev_dump = cnxk_rep_flow_dev_dump,
815 : : };
|