1
2
3
4
5
6#include "bnxt_tf_common.h"
7#include "ulp_template_struct.h"
8#include "ulp_template_db_enum.h"
9#include "ulp_template_db_field.h"
10#include "ulp_utils.h"
11#include "ulp_port_db.h"
12#include "ulp_flow_db.h"
13#include "ulp_mapper.h"
14
15struct bnxt_ulp_def_param_handler {
16 int32_t (*vfr_func)(struct bnxt_ulp_context *ulp_ctx,
17 struct ulp_tlv_param *param,
18 struct bnxt_ulp_mapper_create_parms *mapper_params);
19};
20
21static int32_t
22ulp_set_svif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
23 uint32_t ifindex, uint8_t svif_type,
24 struct bnxt_ulp_mapper_create_parms *mapper_params)
25{
26 uint16_t svif;
27 uint8_t idx;
28 int rc;
29
30 rc = ulp_port_db_svif_get(ulp_ctx, ifindex, svif_type, &svif);
31 if (rc)
32 return rc;
33
34 if (svif_type == BNXT_ULP_PHY_PORT_SVIF)
35 idx = BNXT_ULP_CF_IDX_PHY_PORT_SVIF;
36 else if (svif_type == BNXT_ULP_DRV_FUNC_SVIF)
37 idx = BNXT_ULP_CF_IDX_DRV_FUNC_SVIF;
38 else
39 idx = BNXT_ULP_CF_IDX_VF_FUNC_SVIF;
40
41 ULP_COMP_FLD_IDX_WR(mapper_params, idx, svif);
42
43 return 0;
44}
45
46static int32_t
47ulp_set_spif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
48 uint32_t ifindex, uint8_t spif_type,
49 struct bnxt_ulp_mapper_create_parms *mapper_params)
50{
51 uint16_t spif;
52 uint8_t idx;
53 int rc;
54
55 rc = ulp_port_db_spif_get(ulp_ctx, ifindex, spif_type, &spif);
56 if (rc)
57 return rc;
58
59 if (spif_type == BNXT_ULP_PHY_PORT_SPIF)
60 idx = BNXT_ULP_CF_IDX_PHY_PORT_SPIF;
61 else if (spif_type == BNXT_ULP_DRV_FUNC_SPIF)
62 idx = BNXT_ULP_CF_IDX_DRV_FUNC_SPIF;
63 else
64 idx = BNXT_ULP_CF_IDX_VF_FUNC_SPIF;
65
66 ULP_COMP_FLD_IDX_WR(mapper_params, idx, spif);
67
68 return 0;
69}
70
71static int32_t
72ulp_set_parif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
73 uint32_t ifindex, uint8_t parif_type,
74 struct bnxt_ulp_mapper_create_parms *mapper_params)
75{
76 uint16_t parif;
77 uint8_t idx;
78 int rc;
79
80 rc = ulp_port_db_parif_get(ulp_ctx, ifindex, parif_type, &parif);
81 if (rc)
82 return rc;
83
84 if (parif_type == BNXT_ULP_PHY_PORT_PARIF)
85 idx = BNXT_ULP_CF_IDX_PHY_PORT_PARIF;
86 else if (parif_type == BNXT_ULP_DRV_FUNC_PARIF)
87 idx = BNXT_ULP_CF_IDX_DRV_FUNC_PARIF;
88 else
89 idx = BNXT_ULP_CF_IDX_VF_FUNC_PARIF;
90
91 ULP_COMP_FLD_IDX_WR(mapper_params, idx, parif);
92
93 return 0;
94}
95
96static int32_t
97ulp_set_vport_in_comp_fld(struct bnxt_ulp_context *ulp_ctx, uint32_t ifindex,
98 struct bnxt_ulp_mapper_create_parms *mapper_params)
99{
100 uint16_t vport;
101 int rc;
102
103 rc = ulp_port_db_vport_get(ulp_ctx, ifindex, &vport);
104 if (rc)
105 return rc;
106
107 ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_PHY_PORT_VPORT,
108 vport);
109 return 0;
110}
111
112static int32_t
113ulp_set_vnic_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
114 uint32_t ifindex, uint8_t vnic_type,
115 struct bnxt_ulp_mapper_create_parms *mapper_params)
116{
117 uint16_t vnic;
118 uint8_t idx;
119 int rc;
120
121 rc = ulp_port_db_default_vnic_get(ulp_ctx, ifindex, vnic_type, &vnic);
122 if (rc)
123 return rc;
124
125 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC)
126 idx = BNXT_ULP_CF_IDX_DRV_FUNC_VNIC;
127 else
128 idx = BNXT_ULP_CF_IDX_VF_FUNC_VNIC;
129
130 ULP_COMP_FLD_IDX_WR(mapper_params, idx, vnic);
131
132 return 0;
133}
134
135static int32_t
136ulp_set_vlan_in_act_prop(uint16_t port_id,
137 struct bnxt_ulp_mapper_create_parms *mapper_params)
138{
139 struct ulp_rte_act_prop *act_prop = mapper_params->act_prop;
140
141 if (ULP_BITMAP_ISSET(mapper_params->act->bits,
142 BNXT_ULP_ACTION_BIT_SET_VLAN_VID)) {
143 BNXT_TF_DBG(ERR,
144 "VLAN already set, multiple VLANs unsupported\n");
145 return BNXT_TF_RC_ERROR;
146 }
147
148 port_id = rte_cpu_to_be_16(port_id);
149
150 ULP_BITMAP_SET(mapper_params->act->bits,
151 BNXT_ULP_ACTION_BIT_SET_VLAN_VID);
152
153 memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG],
154 &port_id, sizeof(port_id));
155
156 return 0;
157}
158
159static int32_t
160ulp_set_mark_in_act_prop(uint16_t port_id,
161 struct bnxt_ulp_mapper_create_parms *mapper_params)
162{
163 if (ULP_BITMAP_ISSET(mapper_params->act->bits,
164 BNXT_ULP_ACTION_BIT_MARK)) {
165 BNXT_TF_DBG(ERR,
166 "MARK already set, multiple MARKs unsupported\n");
167 return BNXT_TF_RC_ERROR;
168 }
169
170 ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_DEV_PORT_ID,
171 port_id);
172
173 return 0;
174}
175
176static int32_t
177ulp_df_dev_port_handler(struct bnxt_ulp_context *ulp_ctx,
178 struct ulp_tlv_param *param,
179 struct bnxt_ulp_mapper_create_parms *mapper_params)
180{
181 uint16_t port_id;
182 uint32_t ifindex;
183 int rc;
184
185 port_id = param->value[0] | param->value[1];
186
187 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctx, port_id, &ifindex);
188 if (rc) {
189 BNXT_TF_DBG(ERR,
190 "Invalid port id\n");
191 return BNXT_TF_RC_ERROR;
192 }
193
194
195 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SVIF,
196 mapper_params);
197 if (rc)
198 return rc;
199
200
201 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SVIF,
202 mapper_params);
203 if (rc)
204 return rc;
205
206
207 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_SVIF,
208 mapper_params);
209 if (rc)
210 return rc;
211
212
213 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SPIF,
214 mapper_params);
215 if (rc)
216 return rc;
217
218
219 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
220 mapper_params);
221 if (rc)
222 return rc;
223
224
225 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
226 mapper_params);
227 if (rc)
228 return rc;
229
230
231 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
232 BNXT_ULP_PHY_PORT_PARIF, mapper_params);
233 if (rc)
234 return rc;
235
236
237 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
238 BNXT_ULP_DRV_FUNC_PARIF, mapper_params);
239 if (rc)
240 return rc;
241
242
243 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_PARIF,
244 mapper_params);
245 if (rc)
246 return rc;
247
248
249 rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, true, mapper_params);
250 if (rc)
251 return rc;
252
253
254 rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, false, mapper_params);
255 if (rc)
256 return rc;
257
258
259 rc = ulp_set_vport_in_comp_fld(ulp_ctx, ifindex, mapper_params);
260 if (rc)
261 return rc;
262
263
264 rc = ulp_set_vlan_in_act_prop(port_id, mapper_params);
265 if (rc)
266 return rc;
267
268
269 rc = ulp_set_mark_in_act_prop(port_id, mapper_params);
270 if (rc)
271 return rc;
272
273 return 0;
274}
275
276struct bnxt_ulp_def_param_handler ulp_def_handler_tbl[] = {
277 [BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID] = {
278 .vfr_func = ulp_df_dev_port_handler }
279};
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295int32_t
296ulp_default_flow_create(struct rte_eth_dev *eth_dev,
297 struct ulp_tlv_param *param_list,
298 uint32_t ulp_class_tid,
299 uint32_t *flow_id)
300{
301 struct ulp_rte_hdr_field hdr_field[BNXT_ULP_PROTO_HDR_MAX];
302 uint32_t comp_fld[BNXT_ULP_CF_IDX_LAST];
303 struct bnxt_ulp_mapper_create_parms mapper_params = { 0 };
304 struct ulp_rte_act_prop act_prop;
305 struct ulp_rte_act_bitmap act = { 0 };
306 struct bnxt_ulp_context *ulp_ctx;
307 uint32_t type, ulp_flags = 0, fid;
308 int rc = 0;
309
310 memset(&mapper_params, 0, sizeof(mapper_params));
311 memset(hdr_field, 0, sizeof(hdr_field));
312 memset(comp_fld, 0, sizeof(comp_fld));
313 memset(&act_prop, 0, sizeof(act_prop));
314
315 mapper_params.hdr_field = hdr_field;
316 mapper_params.act = &act;
317 mapper_params.act_prop = &act_prop;
318 mapper_params.comp_fld = comp_fld;
319 mapper_params.class_tid = ulp_class_tid;
320 mapper_params.flow_type = BNXT_ULP_FDB_TYPE_DEFAULT;
321
322 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
323 if (!ulp_ctx) {
324 BNXT_TF_DBG(ERR, "ULP context is not initialized. "
325 "Failed to create default flow.\n");
326 return -EINVAL;
327 }
328
329
330 if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(ulp_ctx, &ulp_flags)) {
331 BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
332 return -EINVAL;
333 }
334 if (ULP_VF_REP_IS_ENABLED(ulp_flags))
335 ULP_COMP_FLD_IDX_WR(&mapper_params,
336 BNXT_ULP_CF_IDX_VFR_MODE, 1);
337
338 type = param_list->type;
339 while (type != BNXT_ULP_DF_PARAM_TYPE_LAST) {
340 if (ulp_def_handler_tbl[type].vfr_func) {
341 rc = ulp_def_handler_tbl[type].vfr_func(ulp_ctx,
342 param_list,
343 &mapper_params);
344 if (rc) {
345 BNXT_TF_DBG(ERR,
346 "Failed to create default flow.\n");
347 return rc;
348 }
349 }
350
351 param_list++;
352 type = param_list->type;
353 }
354
355
356 if (ulp_port_db_port_func_id_get(ulp_ctx,
357 eth_dev->data->port_id,
358 &mapper_params.func_id)) {
359 BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
360 goto err1;
361 }
362
363
364 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
365 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
366 goto err1;
367 }
368
369 rc = ulp_flow_db_fid_alloc(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT,
370 mapper_params.func_id, &fid);
371 if (rc) {
372 BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
373 goto err2;
374 }
375
376 mapper_params.flow_id = fid;
377 rc = ulp_mapper_flow_create(ulp_ctx, &mapper_params);
378 if (rc)
379 goto err3;
380
381 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
382 *flow_id = fid;
383 return 0;
384
385err3:
386 ulp_flow_db_fid_free(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT, fid);
387err2:
388 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
389err1:
390 BNXT_TF_DBG(ERR, "Failed to create default flow.\n");
391 return rc;
392}
393
394
395
396
397
398
399
400
401
402
403
404
405
406int32_t
407ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
408{
409 struct bnxt_ulp_context *ulp_ctx;
410 int rc = 0;
411
412 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
413 if (!ulp_ctx) {
414 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
415 return -EINVAL;
416 }
417
418 if (!flow_id) {
419 BNXT_TF_DBG(DEBUG, "invalid flow id zero\n");
420 return rc;
421 }
422
423 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
424 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
425 return -EINVAL;
426 }
427 rc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT,
428 flow_id);
429 if (rc)
430 BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
431 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
432
433 return rc;
434}
435
436void
437bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)
438{
439 struct bnxt_ulp_df_rule_info *info;
440 uint16_t port_id;
441
442 if (!BNXT_TRUFLOW_EN(bp) ||
443 BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
444 return;
445
446 if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
447 return;
448
449
450 if (!global) {
451 port_id = bp->eth_dev->data->port_id;
452 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
453 if (!info->valid)
454 return;
455
456 ulp_default_flow_destroy(bp->eth_dev,
457 info->port_to_app_flow_id);
458 ulp_default_flow_destroy(bp->eth_dev,
459 info->app_to_port_flow_id);
460 memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
461 return;
462 }
463
464
465 for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
466 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
467 if (!info->valid)
468 continue;
469
470 ulp_default_flow_destroy(bp->eth_dev,
471 info->port_to_app_flow_id);
472 ulp_default_flow_destroy(bp->eth_dev,
473 info->app_to_port_flow_id);
474 memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
475 }
476}
477
478static int32_t
479bnxt_create_port_app_df_rule(struct bnxt *bp, uint8_t flow_type,
480 uint32_t *flow_id)
481{
482 uint16_t port_id = bp->eth_dev->data->port_id;
483 struct ulp_tlv_param param_list[] = {
484 {
485 .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
486 .length = 2,
487 .value = {(port_id >> 8) & 0xff, port_id & 0xff}
488 },
489 {
490 .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
491 .length = 0,
492 .value = {0}
493 }
494 };
495
496 return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
497 flow_id);
498}
499
500int32_t
501bnxt_ulp_create_df_rules(struct bnxt *bp)
502{
503 struct bnxt_ulp_df_rule_info *info;
504 uint16_t port_id;
505 int rc;
506
507 if (!BNXT_TRUFLOW_EN(bp) ||
508 BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev) || !bp->ulp_ctx)
509 return 0;
510
511 port_id = bp->eth_dev->data->port_id;
512 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
513 rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_PORT_TO_VS,
514 &info->port_to_app_flow_id);
515 if (rc) {
516 BNXT_TF_DBG(ERR,
517 "Failed to create port to app default rule\n");
518 return rc;
519 }
520
521 bp->tx_cfa_action = 0;
522 rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_VS_TO_PORT,
523 &info->app_to_port_flow_id);
524 if (rc) {
525 BNXT_TF_DBG(ERR,
526 "Failed to create app to port default rule\n");
527 goto port_to_app_free;
528 }
529
530 rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
531 info->app_to_port_flow_id,
532 &bp->tx_cfa_action);
533 if (rc)
534 goto app_to_port_free;
535
536 info->valid = true;
537 return 0;
538
539app_to_port_free:
540 ulp_default_flow_destroy(bp->eth_dev, info->app_to_port_flow_id);
541port_to_app_free:
542 ulp_default_flow_destroy(bp->eth_dev, info->port_to_app_flow_id);
543 info->valid = false;
544
545 return rc;
546}
547
548static int32_t
549bnxt_create_port_vfr_default_rule(struct bnxt *bp,
550 uint8_t flow_type,
551 uint16_t vfr_port_id,
552 uint32_t *flow_id)
553{
554 struct ulp_tlv_param param_list[] = {
555 {
556 .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
557 .length = 2,
558 .value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}
559 },
560 {
561 .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
562 .length = 0,
563 .value = {0}
564 }
565 };
566 return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
567 flow_id);
568}
569
570int32_t
571bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev)
572{
573 struct bnxt_ulp_vfr_rule_info *info;
574 struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
575 struct rte_eth_dev *parent_dev = vfr->parent_dev;
576 struct bnxt *bp = parent_dev->data->dev_private;
577 uint16_t vfr_port_id = vfr_ethdev->data->port_id;
578 uint16_t port_id;
579 int rc;
580
581 if (!bp || !BNXT_TRUFLOW_EN(bp))
582 return 0;
583
584 port_id = vfr_ethdev->data->port_id;
585 info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx, port_id);
586
587 if (!info) {
588 BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
589 return -EINVAL;
590 }
591
592 if (info->valid) {
593 BNXT_TF_DBG(ERR, "VFR already allocated\n");
594 return -EINVAL;
595 }
596
597 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
598 rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VFREP_TO_VF,
599 vfr_port_id,
600 &info->rep2vf_flow_id);
601 if (rc) {
602 BNXT_TF_DBG(ERR, "Failed to create VFREP to VF default rule\n");
603 goto error;
604 }
605 rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VF_TO_VFREP,
606 vfr_port_id,
607 &info->vf2rep_flow_id);
608 if (rc) {
609 BNXT_TF_DBG(ERR, "Failed to create VF to VFREP default rule\n");
610 goto error;
611 }
612 rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
613 info->rep2vf_flow_id,
614 &vfr->vfr_tx_cfa_action);
615 if (rc) {
616 BNXT_TF_DBG(ERR, "Failed to get the tx cfa action\n");
617 goto error;
618 }
619
620
621 info->valid = true;
622 info->parent_port_id = bp->eth_dev->data->port_id;
623 return 0;
624
625error:
626 if (info->rep2vf_flow_id)
627 ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
628 if (info->vf2rep_flow_id)
629 ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
630 return rc;
631}
632
633int32_t
634bnxt_ulp_delete_vfr_default_rules(struct bnxt_representor *vfr)
635{
636 struct bnxt_ulp_vfr_rule_info *info;
637 struct rte_eth_dev *parent_dev = vfr->parent_dev;
638 struct bnxt *bp = parent_dev->data->dev_private;
639
640 if (!bp || !BNXT_TRUFLOW_EN(bp))
641 return 0;
642 info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx,
643 vfr->dpdk_port_id);
644 if (!info) {
645 BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
646 return -EINVAL;
647 }
648
649 if (!info->valid) {
650 BNXT_TF_DBG(ERR, "VFR already freed\n");
651 return -EINVAL;
652 }
653 ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
654 ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
655 vfr->vfr_tx_cfa_action = 0;
656 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
657 return 0;
658}
659