#include "ulp_template_db.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_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)
{
/* 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(DEBUG, "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.
*
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->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->gfid_entries;
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);
/* 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");
-
+ BNXT_TF_DBG(DEBUG, "Failed to allocate memory for mark mgr\n");
return -ENOMEM;
}
idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl);
if (is_gfid) {
- if (!mtbl->gfid_tbl[idx].valid)
+ if (idx >= mtbl->gfid_num_entries ||
+ ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->gfid_tbl[idx]))
return -EINVAL;
BNXT_TF_DBG(DEBUG, "Get GFID[0x%0x] = 0x%0x\n",
*mark = mtbl->gfid_tbl[idx].mark_id;
} else {
- if (!mtbl->gfid_tbl[idx].valid)
+ if (idx >= mtbl->lfid_num_entries ||
+ ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->lfid_tbl[idx]))
return -EINVAL;
BNXT_TF_DBG(DEBUG, "Get LFID[0x%0x] = 0x%0x\n",
*
* 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
*
*/
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;
+ }
+ mtbl->lfid_tbl[fid].mark_id = mark;
+ ULP_MARK_DB_ENTRY_SET_VALID(&mtbl->lfid_tbl[fid]);
+ }
+
+ return 0;
}
/*
*
* 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;
}