1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 Broadcom
7 #include "bnxt_tf_common.h"
8 #include "ulp_rte_parser.h"
9 #include "ulp_matcher.h"
10 #include "ulp_flow_db.h"
11 #include "ulp_mapper.h"
12 #include "ulp_fc_mgr.h"
13 #include "ulp_port_db.h"
14 #include <rte_malloc.h>
17 bnxt_ulp_flow_validate_args(const struct rte_flow_attr *attr,
18 const struct rte_flow_item pattern[],
19 const struct rte_flow_action actions[],
20 struct rte_flow_error *error)
22 /* Perform the validation of the arguments for null */
24 return BNXT_TF_RC_ERROR;
27 rte_flow_error_set(error,
29 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
32 return BNXT_TF_RC_ERROR;
36 rte_flow_error_set(error,
38 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
41 return BNXT_TF_RC_ERROR;
45 rte_flow_error_set(error,
47 RTE_FLOW_ERROR_TYPE_ATTR,
50 return BNXT_TF_RC_ERROR;
53 if (attr->egress && attr->ingress) {
54 rte_flow_error_set(error,
56 RTE_FLOW_ERROR_TYPE_ATTR,
58 "EGRESS AND INGRESS UNSUPPORTED");
59 return BNXT_TF_RC_ERROR;
61 return BNXT_TF_RC_SUCCESS;
65 bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params,
66 const struct rte_flow_attr *attr)
68 /* Set the flow attributes */
70 params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS;
72 params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
74 params->dir_attr |= BNXT_ULP_FLOW_ATTR_TRANSFER;
77 /* Function to create the rte flow. */
78 static struct rte_flow *
79 bnxt_ulp_flow_create(struct rte_eth_dev *dev,
80 const struct rte_flow_attr *attr,
81 const struct rte_flow_item pattern[],
82 const struct rte_flow_action actions[],
83 struct rte_flow_error *error)
85 struct bnxt_ulp_mapper_create_parms mapper_cparms = { 0 };
86 struct ulp_rte_parser_params params;
87 struct bnxt_ulp_context *ulp_ctx;
88 uint32_t class_id, act_tmpl;
89 struct rte_flow *flow_id;
91 int ret = BNXT_TF_RC_ERROR;
93 if (bnxt_ulp_flow_validate_args(attr,
95 error) == BNXT_TF_RC_ERROR) {
96 BNXT_TF_DBG(ERR, "Invalid arguments being passed\n");
100 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
102 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
106 /* Initialize the parser params */
107 memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
108 params.ulp_ctx = ulp_ctx;
110 /* Set the flow attributes */
111 bnxt_ulp_set_dir_attributes(¶ms, attr);
113 /* copy the device port id and direction for further processing */
114 ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_INCOMING_IF,
116 ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_SVIF_FLAG,
117 BNXT_ULP_INVALID_SVIF_VAL);
119 /* Parse the rte flow pattern */
120 ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms);
121 if (ret != BNXT_TF_RC_SUCCESS)
124 /* Parse the rte flow action */
125 ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms);
126 if (ret != BNXT_TF_RC_SUCCESS)
129 /* Perform the rte flow post process */
130 ret = bnxt_ulp_rte_parser_post_process(¶ms);
131 if (ret != BNXT_TF_RC_SUCCESS)
134 ret = ulp_matcher_pattern_match(¶ms, &class_id);
135 if (ret != BNXT_TF_RC_SUCCESS)
138 ret = ulp_matcher_action_match(¶ms, &act_tmpl);
139 if (ret != BNXT_TF_RC_SUCCESS)
142 mapper_cparms.app_priority = attr->priority;
143 mapper_cparms.hdr_bitmap = ¶ms.hdr_bitmap;
144 mapper_cparms.hdr_field = params.hdr_field;
145 mapper_cparms.comp_fld = params.comp_fld;
146 mapper_cparms.act = ¶ms.act_bitmap;
147 mapper_cparms.act_prop = ¶ms.act_prop;
148 mapper_cparms.class_tid = class_id;
149 mapper_cparms.act_tid = act_tmpl;
150 mapper_cparms.flow_type = BNXT_ULP_FDB_TYPE_REGULAR;
152 /* Get the function id */
153 if (ulp_port_db_port_func_id_get(ulp_ctx,
155 &mapper_cparms.func_id)) {
156 BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
159 mapper_cparms.dir_attr = params.dir_attr;
161 /* Call the ulp mapper to create the flow in the hardware. */
162 ret = ulp_mapper_flow_create(ulp_ctx, &mapper_cparms, &fid);
164 flow_id = (struct rte_flow *)((uintptr_t)fid);
169 rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
170 "Failed to create flow.");
174 /* Function to validate the rte flow. */
176 bnxt_ulp_flow_validate(struct rte_eth_dev *dev,
177 const struct rte_flow_attr *attr,
178 const struct rte_flow_item pattern[],
179 const struct rte_flow_action actions[],
180 struct rte_flow_error *error)
182 struct ulp_rte_parser_params params;
183 uint32_t class_id, act_tmpl;
184 int ret = BNXT_TF_RC_ERROR;
185 struct bnxt_ulp_context *ulp_ctx;
187 if (bnxt_ulp_flow_validate_args(attr,
189 error) == BNXT_TF_RC_ERROR) {
190 BNXT_TF_DBG(ERR, "Invalid arguments being passed\n");
194 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
196 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
200 /* Initialize the parser params */
201 memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
202 params.ulp_ctx = ulp_ctx;
204 /* Set the flow attributes */
205 bnxt_ulp_set_dir_attributes(¶ms, attr);
207 /* Parse the rte flow pattern */
208 ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms);
209 if (ret != BNXT_TF_RC_SUCCESS)
212 /* Parse the rte flow action */
213 ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms);
214 if (ret != BNXT_TF_RC_SUCCESS)
217 /* Perform the rte flow post process */
218 ret = bnxt_ulp_rte_parser_post_process(¶ms);
219 if (ret != BNXT_TF_RC_SUCCESS)
222 ret = ulp_matcher_pattern_match(¶ms, &class_id);
224 if (ret != BNXT_TF_RC_SUCCESS)
227 ret = ulp_matcher_action_match(¶ms, &act_tmpl);
228 if (ret != BNXT_TF_RC_SUCCESS)
231 /* all good return success */
235 rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
236 "Failed to validate flow.");
240 /* Function to destroy the rte flow. */
242 bnxt_ulp_flow_destroy(struct rte_eth_dev *dev,
243 struct rte_flow *flow,
244 struct rte_flow_error *error)
247 struct bnxt_ulp_context *ulp_ctx;
251 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
253 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
255 rte_flow_error_set(error, EINVAL,
256 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
257 "Failed to destroy flow.");
261 flow_id = (uint32_t)(uintptr_t)flow;
263 if (ulp_port_db_port_func_id_get(ulp_ctx,
266 BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
268 rte_flow_error_set(error, EINVAL,
269 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
270 "Failed to destroy flow.");
274 if (ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) ==
276 BNXT_TF_DBG(ERR, "Incorrect device params\n");
278 rte_flow_error_set(error, EINVAL,
279 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
280 "Failed to destroy flow.");
284 ret = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
287 BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
289 rte_flow_error_set(error, -ret,
290 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
291 "Failed to destroy flow.");
297 /* Function to destroy the rte flows. */
299 bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev,
300 struct rte_flow_error *error)
302 struct bnxt_ulp_context *ulp_ctx;
306 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
311 /* Free the resources for the last device */
312 if (ulp_ctx_deinit_allowed(ulp_ctx)) {
313 ret = ulp_flow_db_session_flow_flush(ulp_ctx);
314 } else if (bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx)) {
315 ret = ulp_port_db_port_func_id_get(ulp_ctx,
316 eth_dev->data->port_id,
319 ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id);
321 BNXT_TF_DBG(ERR, "convert port to func id failed\n");
324 rte_flow_error_set(error, ret,
325 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
326 "Failed to flush flow.");
330 /* Function to query the rte flows. */
332 bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev,
333 struct rte_flow *flow,
334 const struct rte_flow_action *action,
336 struct rte_flow_error *error)
339 struct bnxt_ulp_context *ulp_ctx;
340 struct rte_flow_query_count *count;
343 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
345 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
346 rte_flow_error_set(error, EINVAL,
347 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
348 "Failed to query flow.");
352 flow_id = (uint32_t)(uintptr_t)flow;
354 switch (action->type) {
355 case RTE_FLOW_ACTION_TYPE_COUNT:
357 rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count);
359 rte_flow_error_set(error, EINVAL,
360 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
361 "Failed to query flow.");
365 rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
366 NULL, "Unsupported action item");
372 const struct rte_flow_ops bnxt_ulp_rte_flow_ops = {
373 .validate = bnxt_ulp_flow_validate,
374 .create = bnxt_ulp_flow_create,
375 .destroy = bnxt_ulp_flow_destroy,
376 .flush = bnxt_ulp_flow_flush,
377 .query = bnxt_ulp_flow_query,