X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_ulp%2Fbnxt_ulp_flow.c;h=c7b29824e4393031e69dd98166f64a3f1292392e;hb=bd885ab120e2335f978a28ee0aa4303017390e15;hp=138b0b73dc57e0f33c8bb042f9ae74b1b3b96aa8;hpb=45e8e1d406b7a5ecd2698f9977e63fcdc4acb145;p=dpdk.git diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index 138b0b73dc..c7b29824e4 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -9,6 +9,8 @@ #include "ulp_matcher.h" #include "ulp_flow_db.h" #include "ulp_mapper.h" +#include "ulp_fc_mgr.h" +#include "ulp_port_db.h" #include static int32_t @@ -59,6 +61,19 @@ bnxt_ulp_flow_validate_args(const struct rte_flow_attr *attr, return BNXT_TF_RC_SUCCESS; } +static inline void +bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params, + const struct rte_flow_attr *attr) +{ + /* Set the flow attributes */ + if (attr->egress) + params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS; + if (attr->ingress) + params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS; + if (attr->transfer) + params->dir_attr |= BNXT_ULP_FLOW_ATTR_TRANSFER; +} + /* Function to create the rte flow. */ static struct rte_flow * bnxt_ulp_flow_create(struct rte_eth_dev *dev, @@ -73,32 +88,31 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, uint32_t class_id, act_tmpl; struct rte_flow *flow_id; uint32_t fid; - int ret; + int ret = BNXT_TF_RC_ERROR; if (bnxt_ulp_flow_validate_args(attr, pattern, actions, error) == BNXT_TF_RC_ERROR) { BNXT_TF_DBG(ERR, "Invalid arguments being passed\n"); - return NULL; + goto parse_error; } ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); if (!ulp_ctx) { BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); - return NULL; + goto parse_error; } /* Initialize the parser params */ memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); params.ulp_ctx = ulp_ctx; - if (attr->egress) - params.dir = ULP_DIR_EGRESS; + /* Set the flow attributes */ + bnxt_ulp_set_dir_attributes(¶ms, attr); /* copy the device port id and direction for further processing */ ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_INCOMING_IF, dev->data->port_id); - ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, params.dir); ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_SVIF_FLAG, BNXT_ULP_INVALID_SVIF_VAL); @@ -112,6 +126,11 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; + /* Perform the rte flow post process */ + ret = bnxt_ulp_rte_parser_post_process(¶ms); + if (ret != BNXT_TF_RC_SUCCESS) + goto parse_error; + ret = ulp_matcher_pattern_match(¶ms, &class_id); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; @@ -128,9 +147,16 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, mapper_cparms.act_prop = ¶ms.act_prop; mapper_cparms.class_tid = class_id; mapper_cparms.act_tid = act_tmpl; - mapper_cparms.func_id = bnxt_get_fw_func_id(dev->data->port_id, - BNXT_ULP_INTF_TYPE_INVALID); - mapper_cparms.dir = params.dir; + mapper_cparms.flow_type = BNXT_ULP_FDB_TYPE_REGULAR; + + /* Get the function id */ + if (ulp_port_db_port_func_id_get(ulp_ctx, + dev->data->port_id, + &mapper_cparms.func_id)) { + BNXT_TF_DBG(ERR, "conversion of port to func id failed\n"); + goto parse_error; + } + mapper_cparms.dir_attr = params.dir_attr; /* Call the ulp mapper to create the flow in the hardware. */ ret = ulp_mapper_flow_create(ulp_ctx, &mapper_cparms, &fid); @@ -155,28 +181,28 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev, { struct ulp_rte_parser_params params; uint32_t class_id, act_tmpl; - int ret; + int ret = BNXT_TF_RC_ERROR; struct bnxt_ulp_context *ulp_ctx; if (bnxt_ulp_flow_validate_args(attr, pattern, actions, error) == BNXT_TF_RC_ERROR) { BNXT_TF_DBG(ERR, "Invalid arguments being passed\n"); - return -EINVAL; + goto parse_error; } ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); if (!ulp_ctx) { BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); - return -EINVAL; + goto parse_error; } /* Initialize the parser params */ memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); params.ulp_ctx = ulp_ctx; - if (attr->egress) - params.dir = ULP_DIR_EGRESS; + /* Set the flow attributes */ + bnxt_ulp_set_dir_attributes(¶ms, attr); /* Parse the rte flow pattern */ ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms); @@ -188,6 +214,11 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev, if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; + /* Perform the rte flow post process */ + ret = bnxt_ulp_rte_parser_post_process(¶ms); + if (ret != BNXT_TF_RC_SUCCESS) + goto parse_error; + ret = ulp_matcher_pattern_match(¶ms, &class_id); if (ret != BNXT_TF_RC_SUCCESS) @@ -207,7 +238,7 @@ parse_error: } /* Function to destroy the rte flow. */ -static int +int bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error) @@ -220,30 +251,45 @@ bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); if (!ulp_ctx) { BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to destroy flow."); + if (error) + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to destroy flow."); return -EINVAL; } flow_id = (uint32_t)(uintptr_t)flow; - func_id = bnxt_get_fw_func_id(dev->data->port_id, - BNXT_ULP_INTF_TYPE_INVALID); + + if (ulp_port_db_port_func_id_get(ulp_ctx, + dev->data->port_id, + &func_id)) { + BNXT_TF_DBG(ERR, "conversion of port to func id failed\n"); + if (error) + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to destroy flow."); + return -EINVAL; + } if (ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) == false) { BNXT_TF_DBG(ERR, "Incorrect device params\n"); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to destroy flow."); + if (error) + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to destroy flow."); return -EINVAL; } - ret = ulp_mapper_flow_destroy(ulp_ctx, flow_id); - if (ret) - rte_flow_error_set(error, -ret, - RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to destroy flow."); + ret = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, + flow_id); + if (ret) { + BNXT_TF_DBG(ERR, "Failed to destroy flow.\n"); + if (error) + rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to destroy flow."); + } return ret; } @@ -255,26 +301,24 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, { struct bnxt_ulp_context *ulp_ctx; int32_t ret = 0; - struct bnxt *bp; uint16_t func_id; ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); if (!ulp_ctx) { - BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to flush flow."); - return -EINVAL; + return ret; } - bp = eth_dev->data->dev_private; /* Free the resources for the last device */ - if (ulp_ctx_deinit_allowed(bp)) { + if (ulp_ctx_deinit_allowed(ulp_ctx)) { ret = ulp_flow_db_session_flow_flush(ulp_ctx); } else if (bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx)) { - func_id = bnxt_get_fw_func_id(eth_dev->data->port_id, - BNXT_ULP_INTF_TYPE_INVALID); - ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id); + ret = ulp_port_db_port_func_id_get(ulp_ctx, + eth_dev->data->port_id, + &func_id); + if (!ret) + ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id); + else + BNXT_TF_DBG(ERR, "convert port to func id failed\n"); } if (ret) rte_flow_error_set(error, ret, @@ -283,11 +327,53 @@ bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, return ret; } +/* Function to query the rte flows. */ +static int32_t +bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, + struct rte_flow *flow, + const struct rte_flow_action *action, + void *data, + struct rte_flow_error *error) +{ + int rc = 0; + struct bnxt_ulp_context *ulp_ctx; + struct rte_flow_query_count *count; + uint32_t flow_id; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (!ulp_ctx) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to query flow."); + return -EINVAL; + } + + flow_id = (uint32_t)(uintptr_t)flow; + + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_COUNT: + count = data; + rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count); + if (rc) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to query flow."); + } + break; + default: + rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, + NULL, "Unsupported action item"); + } + + return rc; +} + const struct rte_flow_ops bnxt_ulp_rte_flow_ops = { .validate = bnxt_ulp_flow_validate, .create = bnxt_ulp_flow_create, .destroy = bnxt_ulp_flow_destroy, .flush = bnxt_ulp_flow_flush, - .query = NULL, + .query = bnxt_ulp_flow_query, .isolate = NULL };