X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_ulp%2Fulp_mark_mgr.c;h=271520e1d3787e21fc58129a0f5ba6310af1527b;hb=f787952d13d20b7eceaf6d1742ea591239b63ba1;hp=566668eece9b8875da0118c23ab758cf2cd7fea5;hpb=05a11d7dff9f1c6371ea2a5c697b7797272cb4e5;p=dpdk.git diff --git a/drivers/net/bnxt/tf_ulp/ulp_mark_mgr.c b/drivers/net/bnxt/tf_ulp/ulp_mark_mgr.c index 566668eece..271520e1d3 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mark_mgr.c +++ b/drivers/net/bnxt/tf_ulp/ulp_mark_mgr.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2014-2020 Broadcom + * Copyright(c) 2014-2021 Broadcom * All rights reserved. */ @@ -11,9 +11,20 @@ #include "tf_ext_flow_handle.h" #include "ulp_mark_mgr.h" #include "bnxt_tf_common.h" -#include "ulp_template_db.h" +#include "ulp_template_db_enum.h" #include "ulp_template_struct.h" +#define ULP_MARK_DB_ENTRY_SET_VALID(mark_info) ((mark_info)->flags |=\ + BNXT_ULP_MARK_VALID) +#define ULP_MARK_DB_ENTRY_IS_INVALID(mark_info) (!((mark_info)->flags &\ + BNXT_ULP_MARK_VALID)) +#define ULP_MARK_DB_ENTRY_SET_VFR_ID(mark_info) ((mark_info)->flags |=\ + BNXT_ULP_MARK_VFR_ID) +#define ULP_MARK_DB_ENTRY_IS_VFR_ID(mark_info) ((mark_info)->flags &\ + BNXT_ULP_MARK_VFR_ID) +#define ULP_MARK_DB_ENTRY_IS_GLOBAL_HW_FID(mark_info) ((mark_info)->flags &\ + BNXT_ULP_MARK_GLOBAL_HW_FID) + static inline uint32_t ulp_mark_db_idx_get(bool is_gfid, uint32_t fid, struct bnxt_ulp_mark_tbl *mtbl) { @@ -25,52 +36,14 @@ ulp_mark_db_idx_get(bool is_gfid, uint32_t fid, struct bnxt_ulp_mark_tbl *mtbl) /* Need to truncate anything beyond supported flows */ idx &= mtbl->gfid_mask; - if (hashtype) idx |= mtbl->gfid_type_bit; } else { idx = fid; } - return idx; } -static int32_t -ulp_mark_db_mark_set(struct bnxt_ulp_context *ctxt, - bool is_gfid, - uint32_t fid, - uint32_t mark) -{ - struct bnxt_ulp_mark_tbl *mtbl; - uint32_t idx = 0; - - if (!ctxt) { - BNXT_TF_DBG(ERR, "Invalid ulp context\n"); - return -EINVAL; - } - - mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt); - if (!mtbl) { - BNXT_TF_DBG(ERR, "Unable to get Mark DB\n"); - return -EINVAL; - } - - idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl); - - if (is_gfid) { - BNXT_TF_DBG(ERR, "Set GFID[0x%0x] = 0x%0x\n", idx, mark); - - mtbl->gfid_tbl[idx].mark_id = mark; - mtbl->gfid_tbl[idx].valid = true; - } else { - /* For the LFID, the FID is used as the index */ - mtbl->lfid_tbl[fid].mark_id = mark; - mtbl->lfid_tbl[fid].valid = true; - } - - return 0; -} - /* * Allocate and Initialize all Mark Manager resources for this ulp context. * @@ -100,53 +73,65 @@ ulp_mark_db_init(struct bnxt_ulp_context *ctxt) return -EINVAL; } + if (!dparms->mark_db_lfid_entries || !dparms->mark_db_gfid_entries) { + BNXT_TF_DBG(DEBUG, "mark Table is not allocated\n"); + bnxt_ulp_cntxt_ptr2_mark_db_set(ctxt, NULL); + return 0; + } + mark_tbl = rte_zmalloc("ulp_rx_mark_tbl_ptr", sizeof(struct bnxt_ulp_mark_tbl), 0); if (!mark_tbl) goto mem_error; - /* Need to allocate 2 * Num flows to account for hash type bit. */ + /* Need to allocate 2 * Num flows to account for hash type bit.*/ + mark_tbl->lfid_num_entries = dparms->mark_db_lfid_entries; mark_tbl->lfid_tbl = rte_zmalloc("ulp_rx_em_flow_mark_table", - dparms->lfid_entries * - sizeof(struct bnxt_lfid_mark_info), + mark_tbl->lfid_num_entries * + sizeof(struct bnxt_lfid_mark_info), 0); - if (!mark_tbl->lfid_tbl) goto mem_error; - /* Need to allocate 2 * Num flows to account for hash type bit. */ + /* Need to allocate 2 * Num flows to account for hash type bit */ + mark_tbl->gfid_num_entries = dparms->mark_db_gfid_entries; + if (!mark_tbl->gfid_num_entries) + goto gfid_not_required; + mark_tbl->gfid_tbl = rte_zmalloc("ulp_rx_eem_flow_mark_table", - 2 * dparms->num_flows * - sizeof(struct bnxt_gfid_mark_info), + mark_tbl->gfid_num_entries * + sizeof(struct bnxt_gfid_mark_info), 0); if (!mark_tbl->gfid_tbl) goto mem_error; /* - * TBD: This needs to be generalized for better mark handling * These values are used to compress the FID to the allowable index - * space. The FID from hw may be the full hash. + * space. The FID from hw may be the full hash which may be a big + * value to allocate and so allocate only needed hash values. + * gfid mask is the number of flow entries for the each left/right + * hash The gfid type bit is used to get to the higher or lower hash + * entries. */ - mark_tbl->gfid_max = dparms->gfid_entries - 1; - mark_tbl->gfid_mask = (dparms->gfid_entries / 2) - 1; - mark_tbl->gfid_type_bit = (dparms->gfid_entries / 2); + mark_tbl->gfid_mask = (mark_tbl->gfid_num_entries / 2) - 1; + mark_tbl->gfid_type_bit = (mark_tbl->gfid_num_entries / 2); BNXT_TF_DBG(DEBUG, "GFID Max = 0x%08x\nGFID MASK = 0x%08x\n", - mark_tbl->gfid_max, + mark_tbl->gfid_num_entries - 1, mark_tbl->gfid_mask); +gfid_not_required: /* Add the mark tbl to the ulp context. */ bnxt_ulp_cntxt_ptr2_mark_db_set(ctxt, mark_tbl); - return 0; mem_error: - rte_free(mark_tbl->gfid_tbl); - rte_free(mark_tbl->lfid_tbl); - rte_free(mark_tbl); - BNXT_TF_DBG(DEBUG, - "Failed to allocate memory for mark mgr\n"); - + if (mark_tbl) { + rte_free(mark_tbl->gfid_tbl); + rte_free(mark_tbl->lfid_tbl); + rte_free(mark_tbl); + } + BNXT_TF_DBG(DEBUG, "Failed to allocate memory for mark mgr\n"); return -ENOMEM; } @@ -176,7 +161,7 @@ ulp_mark_db_deinit(struct bnxt_ulp_context *ctxt) } /* - * Adds a Mark to the Mark Manager + * Get a Mark from the Mark Manager * * ctxt [in] The ulp context for the mark manager * @@ -184,16 +169,108 @@ ulp_mark_db_deinit(struct bnxt_ulp_context *ctxt) * * fid [in] The flow id that is returned by HW in BD * + * vfr_flag [out].it indicatesif mark is vfr_id or mark id + * + * mark [out] The mark that is associated with the FID + * + */ +int32_t +ulp_mark_db_mark_get(struct bnxt_ulp_context *ctxt, + bool is_gfid, + uint32_t fid, + uint32_t *vfr_flag, + uint32_t *mark) +{ + struct bnxt_ulp_mark_tbl *mtbl; + uint32_t idx = 0; + + if (!ctxt || !mark) + return -EINVAL; + + mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt); + if (!mtbl) + return -EINVAL; + + idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl); + + if (is_gfid) { + if (idx >= mtbl->gfid_num_entries || + ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->gfid_tbl[idx])) + return -EINVAL; + + *vfr_flag = ULP_MARK_DB_ENTRY_IS_VFR_ID(&mtbl->gfid_tbl[idx]); + *mark = mtbl->gfid_tbl[idx].mark_id; + } else { + if (idx >= mtbl->lfid_num_entries || + ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->lfid_tbl[idx])) + return -EINVAL; + + *vfr_flag = ULP_MARK_DB_ENTRY_IS_VFR_ID(&mtbl->lfid_tbl[idx]); + *mark = mtbl->lfid_tbl[idx].mark_id; + } + + return 0; +} + +/* + * Adds a Mark to the Mark Manager + * + * ctxt [in] The ulp context for the mark manager + * + * mark_flag [in] mark flags. + * + * fid [in] The flow id that is returned by HW in BD + * * mark [in] The mark to be associated with the FID * */ int32_t ulp_mark_db_mark_add(struct bnxt_ulp_context *ctxt, - bool is_gfid, - uint32_t gfid, + uint32_t mark_flag, + uint32_t fid, uint32_t mark) { - return ulp_mark_db_mark_set(ctxt, is_gfid, gfid, mark); + struct bnxt_ulp_mark_tbl *mtbl; + uint32_t idx = 0; + bool is_gfid; + + if (!ctxt) { + BNXT_TF_DBG(ERR, "Invalid ulp context\n"); + return -EINVAL; + } + + mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt); + if (!mtbl) { + BNXT_TF_DBG(ERR, "Unable to get Mark DB\n"); + return -EINVAL; + } + + is_gfid = (mark_flag & BNXT_ULP_MARK_GLOBAL_HW_FID); + if (is_gfid) { + idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl); + if (idx >= mtbl->gfid_num_entries) { + BNXT_TF_DBG(ERR, "Mark index greater than allocated\n"); + return -EINVAL; + } + BNXT_TF_DBG(DEBUG, "Set GFID[0x%0x] = 0x%0x\n", idx, mark); + mtbl->gfid_tbl[idx].mark_id = mark; + ULP_MARK_DB_ENTRY_SET_VALID(&mtbl->gfid_tbl[idx]); + + } else { + /* For the LFID, the FID is used as the index */ + if (fid >= mtbl->lfid_num_entries) { + BNXT_TF_DBG(ERR, "Mark index greater than allocated\n"); + return -EINVAL; + } + BNXT_TF_DBG(DEBUG, "Set LFID[0x%0x] = 0x%0x\n", fid, mark); + mtbl->lfid_tbl[fid].mark_id = mark; + ULP_MARK_DB_ENTRY_SET_VALID(&mtbl->lfid_tbl[fid]); + + if (mark_flag & BNXT_ULP_MARK_VFR_ID) + ULP_MARK_DB_ENTRY_SET_VFR_ID(&mtbl->lfid_tbl[fid]); + } + + return 0; } /* @@ -201,18 +278,51 @@ ulp_mark_db_mark_add(struct bnxt_ulp_context *ctxt, * * ctxt [in] The ulp context for the mark manager * - * is_gfid [in] The type of fid (GFID or LFID) + * mark_flag [in] mark flags. * * fid [in] The flow id that is returned by HW in BD * - * mark [in] The mark to be associated with the FID - * */ int32_t ulp_mark_db_mark_del(struct bnxt_ulp_context *ctxt, - bool is_gfid, - uint32_t gfid, - uint32_t mark __rte_unused) + uint32_t mark_flag, + uint32_t fid) { - return ulp_mark_db_mark_set(ctxt, is_gfid, gfid, ULP_MARK_INVALID); + struct bnxt_ulp_mark_tbl *mtbl; + uint32_t idx = 0; + bool is_gfid; + + if (!ctxt) { + BNXT_TF_DBG(ERR, "Invalid ulp context\n"); + return -EINVAL; + } + + mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt); + if (!mtbl) { + BNXT_TF_DBG(ERR, "Unable to get Mark DB\n"); + return -EINVAL; + } + + is_gfid = (mark_flag & BNXT_ULP_MARK_GLOBAL_HW_FID); + if (is_gfid) { + idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl); + if (idx >= mtbl->gfid_num_entries) { + BNXT_TF_DBG(ERR, "Mark index greater than allocated\n"); + return -EINVAL; + } + BNXT_TF_DBG(DEBUG, "Reset GFID[0x%0x]\n", idx); + memset(&mtbl->gfid_tbl[idx], 0, + sizeof(struct bnxt_gfid_mark_info)); + + } else { + /* For the LFID, the FID is used as the index */ + if (fid >= mtbl->lfid_num_entries) { + BNXT_TF_DBG(ERR, "Mark index greater than allocated\n"); + return -EINVAL; + } + memset(&mtbl->lfid_tbl[fid], 0, + sizeof(struct bnxt_lfid_mark_info)); + } + + return 0; }