From: Kishore Padmanabha Date: Wed, 15 Apr 2020 08:19:07 +0000 (+0530) Subject: net/bnxt: support flow API flush X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=edc6ca0cf94135f539f168bc5afa838bff25e890;p=dpdk.git net/bnxt: support flow API flush This patch does the following 1. Gets the ulp session information from eth_dev 2. Fetches the rte_flow table associated with this session 3. Iterates through all the flows in the flow table 4. Calls ulp_mapper_resources_free which releases the key & action tables associated with each flow Signed-off-by: Kishore Padmanabha Signed-off-by: Venkat Duvvuru Reviewed-by: Lance Richardson Reviewed-by: Ajit Khaparde --- diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c index 3795c6db60..56e08f233e 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c @@ -517,6 +517,9 @@ bnxt_ulp_deinit(struct bnxt *bp) if (!session) return; + /* clean up regular flows */ + ulp_flow_db_flush_flows(&bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); + /* cleanup the eem table scope */ ulp_eem_tbl_scope_deinit(bp, &bp->ulp_ctx); diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index 35099a383e..49588953c4 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -262,11 +262,42 @@ bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, 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; + struct bnxt *bp; + + 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; + } + bp = eth_dev->data->dev_private; + + /* Free the resources for the last device */ + if (!ulp_ctx_deinit_allowed(bp)) + return 0; + + ret = ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); + if (ret) + rte_flow_error_set(error, ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to flush flow."); + return ret; +} + 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, + .flush = bnxt_ulp_flow_flush, .query = NULL, .isolate = NULL }; diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c index ee703a1a58..aed50785c8 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c +++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c @@ -555,3 +555,72 @@ int32_t ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt, /* all good, return success */ return 0; } + +/** Get the flow database entry iteratively + * + * flow_tbl [in] Ptr to flow table + * fid [in/out] The index to the flow entry + * + * returns 0 on success and negative on failure. + */ +static int32_t +ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_tbl *flowtbl, + uint32_t *fid) +{ + uint32_t lfid = *fid; + uint32_t idx; + uint64_t bs; + + do { + lfid++; + if (lfid >= flowtbl->num_flows) + return -ENOENT; + idx = lfid / ULP_INDEX_BITMAP_SIZE; + while (!(bs = flowtbl->active_flow_tbl[idx])) { + idx++; + if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows) + return -ENOENT; + } + lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs); + if (*fid >= lfid) { + BNXT_TF_DBG(ERR, "Flow Database is corrupt\n"); + return -ENOENT; + } + } while (!ulp_flow_db_active_flow_is_set(flowtbl, lfid)); + + /* all good, return success */ + *fid = lfid; + return 0; +} + +/* + * Flush all flows in the flow database. + * + * ulp_ctxt [in] Ptr to ulp context + * tbl_idx [in] The index to table + * + * returns 0 on success or negative number on failure + */ +int32_t ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx, + uint32_t idx) +{ + uint32_t fid = 0; + struct bnxt_ulp_flow_db *flow_db; + struct bnxt_ulp_flow_tbl *flow_tbl; + + if (!ulp_ctx) { + BNXT_TF_DBG(ERR, "Invalid Argument\n"); + return -EINVAL; + } + + flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); + if (!flow_db) { + BNXT_TF_DBG(ERR, "Flow database not found\n"); + return -EINVAL; + } + flow_tbl = &flow_db->flow_tbl[idx]; + while (!ulp_flow_db_next_entry_get(flow_tbl, &fid)) + (void)ulp_mapper_resources_free(ulp_ctx, fid, idx); + + return 0; +} diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h index eb5effafe7..5435415655 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h +++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h @@ -142,4 +142,15 @@ int32_t ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt, enum bnxt_ulp_flow_db_tables tbl_idx, uint32_t fid); +/* + * Flush all flows in the flow database. + * + * ulp_ctxt [in] Ptr to ulp context + * tbl_idx [in] The index to table + * + * returns 0 on success or negative number on failure + */ +int32_t ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx, + uint32_t idx); + #endif /* _ULP_FLOW_DB_H_ */