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=35099a383e0bf3f356084a5ea2dc909c19d41f31;hpb=778472331e05fbb76ea1b60e7a0dfc101722d2e4;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 35099a383e..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,103 +61,105 @@ 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, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error) +bnxt_ulp_flow_create(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) { - struct ulp_rte_hdr_bitmap hdr_bitmap; - struct ulp_rte_hdr_field hdr_field[BNXT_ULP_PROTO_HDR_MAX]; - struct ulp_rte_act_bitmap act_bitmap; - struct ulp_rte_act_prop act_prop; - enum ulp_direction_type dir = ULP_DIR_INGRESS; + struct bnxt_ulp_mapper_create_parms mapper_cparms = { 0 }; + struct ulp_rte_parser_params params; + struct bnxt_ulp_context *ulp_ctx; uint32_t class_id, act_tmpl; - uint32_t app_priority; - int ret; - struct bnxt_ulp_context *ulp_ctx = NULL; - uint32_t vnic; - uint8_t svif; struct rte_flow *flow_id; uint32_t fid; + 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; } - /* clear the header bitmap and field structure */ - memset(&hdr_bitmap, 0, sizeof(struct ulp_rte_hdr_bitmap)); - memset(hdr_field, 0, sizeof(hdr_field)); - memset(&act_bitmap, 0, sizeof(act_bitmap)); - memset(&act_prop, 0, sizeof(act_prop)); - - svif = bnxt_get_svif(dev->data->port_id, false); - BNXT_TF_DBG(ERR, "SVIF for port[%d][port]=0x%08x\n", - dev->data->port_id, svif); - - hdr_field[BNXT_ULP_HDR_FIELD_SVIF_INDEX].size = sizeof(svif); - hdr_field[BNXT_ULP_HDR_FIELD_SVIF_INDEX].spec[0] = svif; - hdr_field[BNXT_ULP_HDR_FIELD_SVIF_INDEX].mask[0] = -1; - ULP_BITMAP_SET(hdr_bitmap.bits, BNXT_ULP_HDR_BIT_SVIF); - - /* - * VNIC is being pushed as 32bit and the pop will take care of - * proper size - */ - vnic = (uint32_t)bnxt_get_vnic_id(dev->data->port_id); - vnic = htonl(vnic); - rte_memcpy(&act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VNIC], - &vnic, BNXT_ULP_ACT_PROP_SZ_VNIC); + /* Initialize the parser params */ + memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); + params.ulp_ctx = ulp_ctx; + + /* 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_SVIF_FLAG, + BNXT_ULP_INVALID_SVIF_VAL); /* Parse the rte flow pattern */ - ret = bnxt_ulp_rte_parser_hdr_parse(pattern, - &hdr_bitmap, - hdr_field); + ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; /* Parse the rte flow action */ - ret = bnxt_ulp_rte_parser_act_parse(actions, - &act_bitmap, - &act_prop); + ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; - if (attr->egress) - dir = ULP_DIR_EGRESS; - - ret = ulp_matcher_pattern_match(dir, &hdr_bitmap, hdr_field, - &act_bitmap, &class_id); + /* 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; - ret = ulp_matcher_action_match(dir, &act_bitmap, &act_tmpl); + ret = ulp_matcher_action_match(¶ms, &act_tmpl); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; - app_priority = attr->priority; - /* call the ulp mapper to create the flow in the hardware */ - ret = ulp_mapper_flow_create(ulp_ctx, - app_priority, - &hdr_bitmap, - hdr_field, - &act_bitmap, - &act_prop, - class_id, - act_tmpl, - &fid); + mapper_cparms.app_priority = attr->priority; + mapper_cparms.hdr_bitmap = ¶ms.hdr_bitmap; + mapper_cparms.hdr_field = params.hdr_field; + mapper_cparms.comp_fld = params.comp_fld; + mapper_cparms.act = ¶ms.act_bitmap; + mapper_cparms.act_prop = ¶ms.act_prop; + mapper_cparms.class_tid = class_id; + mapper_cparms.act_tid = act_tmpl; + 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); if (!ret) { flow_id = (struct rte_flow *)((uintptr_t)fid); return flow_id; @@ -169,57 +173,58 @@ parse_error: /* Function to validate the rte flow. */ static int -bnxt_ulp_flow_validate(struct rte_eth_dev *dev __rte_unused, +bnxt_ulp_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], struct rte_flow_error *error) { - struct ulp_rte_hdr_bitmap hdr_bitmap; - struct ulp_rte_hdr_field hdr_field[BNXT_ULP_PROTO_HDR_MAX]; - struct ulp_rte_act_bitmap act_bitmap; - struct ulp_rte_act_prop act_prop; - enum ulp_direction_type dir = ULP_DIR_INGRESS; + 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; } - /* clear the header bitmap and field structure */ - memset(&hdr_bitmap, 0, sizeof(struct ulp_rte_hdr_bitmap)); - memset(hdr_field, 0, sizeof(hdr_field)); - memset(&act_bitmap, 0, sizeof(act_bitmap)); - memset(&act_prop, 0, sizeof(act_prop)); + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); + if (!ulp_ctx) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + goto parse_error; + } + + /* Initialize the parser params */ + memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); + params.ulp_ctx = ulp_ctx; + + /* Set the flow attributes */ + bnxt_ulp_set_dir_attributes(¶ms, attr); /* Parse the rte flow pattern */ - ret = bnxt_ulp_rte_parser_hdr_parse(pattern, - &hdr_bitmap, - hdr_field); + ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; /* Parse the rte flow action */ - ret = bnxt_ulp_rte_parser_act_parse(actions, - &act_bitmap, - &act_prop); + ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; - if (attr->egress) - dir = ULP_DIR_EGRESS; + /* 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(dir, &hdr_bitmap, hdr_field, - &act_bitmap, &class_id); + ret = ulp_matcher_pattern_match(¶ms, &class_id); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; - ret = ulp_matcher_action_match(dir, &act_bitmap, &act_tmpl); + ret = ulp_matcher_action_match(¶ms, &act_tmpl); if (ret != BNXT_TF_RC_SUCCESS) goto parse_error; @@ -233,40 +238,142 @@ 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) { int ret = 0; struct bnxt_ulp_context *ulp_ctx; - uint32_t fid; + uint32_t flow_id; + uint16_t func_id; 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; + + 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; } - fid = (uint32_t)(uintptr_t)flow; + if (ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) == + false) { + BNXT_TF_DBG(ERR, "Incorrect device params\n"); + 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, 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; +} + +/* Function to destroy the rte flows. */ +static int32_t +bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, + struct rte_flow_error *error) +{ + struct bnxt_ulp_context *ulp_ctx; + int32_t ret = 0; + uint16_t func_id; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (!ulp_ctx) { + return ret; + } - ret = ulp_mapper_flow_destroy(ulp_ctx, fid); + /* Free the resources for the last device */ + 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)) { + 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, + rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to destroy flow."); - + "Failed to flush flow."); 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 = NULL, - .query = NULL, + .flush = bnxt_ulp_flow_flush, + .query = bnxt_ulp_flow_query, .isolate = NULL };