#include <rte_flow_driver.h>
#include <rte_tailq.h>
+#include "bnxt.h"
#include "bnxt_ulp.h"
#include "bnxt_tf_common.h"
-#include "bnxt.h"
#include "tf_core.h"
#include "tf_ext_flow_handle.h"
#include "ulp_template_db_enum.h"
#include "ulp_template_struct.h"
#include "ulp_mark_mgr.h"
+#include "ulp_fc_mgr.h"
#include "ulp_flow_db.h"
#include "ulp_mapper.h"
#include "ulp_port_db.h"
return rc;
}
- params.shadow_copy = false;
+ params.shadow_copy = true;
params.device_type = TF_DEVICE_TYPE_WH;
resources = ¶ms.resources;
/** RX **/
/* Identifiers */
- resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_L2_CTXT] = 16;
+ resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_L2_CTXT_HIGH] = 200;
+ resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_L2_CTXT_LOW] = 20;
resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
/* Table Types */
resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 720;
resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 720;
+ resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_MODIFY_IPV4] = 8;
+
+ /* ENCAP */
+ resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_ENCAP_8B] = 16;
+ resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_ENCAP_16B] = 16;
/* TCAMs */
- resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM] = 16;
+ resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
+ 200;
+ resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
+ 20;
resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 416;
/* EM */
resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
+ /* EEM */
+ resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
+
/** TX **/
/* Identifiers */
- resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT] = 8;
+ resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT_HIGH] = 200;
+ resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT_LOW] = 20;
resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
/* Table Types */
resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 16;
resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 16;
+ resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_MODIFY_IPV4] = 8;
/* ENCAP */
resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_ENCAP_64B] = 16;
+ resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_ENCAP_16B] = 16;
/* TCAMs */
- resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM] = 8;
+ resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
+ 200;
+ resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
+ 20;
resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
/* EM */
- resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 8;
+ resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
/* EEM */
- resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
+ /* SP */
+ resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = 128;
+
rc = tf_open_session(&bp->tfp, ¶ms);
if (rc) {
BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
ulp_eem_tbl_scope_init(struct bnxt *bp)
{
struct tf_alloc_tbl_scope_parms params = {0};
+ uint32_t dev_id;
+ struct bnxt_ulp_device_params *dparms;
int rc;
+ /* Get the dev specific number of flows that needed to be supported. */
+ if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
+ BNXT_TF_DBG(ERR, "Invalid device id\n");
+ return -EINVAL;
+ }
+
+ dparms = bnxt_ulp_device_params_get(dev_id);
+ if (!dparms) {
+ BNXT_TF_DBG(ERR, "could not fetch the device params\n");
+ return -ENODEV;
+ }
+
+ if (dparms->flow_mem_type != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
+ BNXT_TF_DBG(INFO, "Table Scope alloc is not required\n");
+ return 0;
+ }
+
bnxt_init_tbl_scope_parms(bp, ¶ms);
rc = tf_alloc_tbl_scope(&bp->tfp, ¶ms);
struct tf_free_tbl_scope_parms params = {0};
struct tf *tfp;
int32_t rc = 0;
+ struct bnxt_ulp_device_params *dparms;
+ uint32_t dev_id;
if (!ulp_ctx || !ulp_ctx->cfg_data)
return -EINVAL;
return -EINVAL;
}
+ /* Get the dev specific number of flows that needed to be supported. */
+ if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
+ BNXT_TF_DBG(ERR, "Invalid device id\n");
+ return -EINVAL;
+ }
+
+ dparms = bnxt_ulp_device_params_get(dev_id);
+ if (!dparms) {
+ BNXT_TF_DBG(ERR, "could not fetch the device params\n");
+ return -ENODEV;
+ }
+
+ if (dparms->flow_mem_type != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
+ BNXT_TF_DBG(INFO, "Table Scope free is not required\n");
+ return 0;
+ }
+
rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, ¶ms.tbl_scope_id);
if (rc) {
BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
bp->ulp_ctx->cfg_data = ulp_data;
session->cfg_data = ulp_data;
ulp_data->ref_cnt++;
+ ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
/* Open the ulp session. */
rc = ulp_ctx_session_open(bp, session);
(void)ulp_ctx_deinit(bp, session);
return rc;
}
+
bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session->g_tfp);
return rc;
}
}
}
+/*
+ * Internal api to enable NAT feature.
+ * Set set_flag to 1 to set the value or zero to reset the value.
+ * returns 0 on success.
+ */
+static int32_t
+bnxt_ulp_global_cfg_update(struct bnxt *bp,
+ enum tf_dir dir,
+ enum tf_global_config_type type,
+ uint32_t offset,
+ uint32_t value,
+ uint32_t set_flag)
+{
+ uint32_t global_cfg = 0;
+ int rc;
+ struct tf_global_cfg_parms parms;
+
+ /* Initialize the params */
+ parms.dir = dir,
+ parms.type = type,
+ parms.offset = offset,
+ parms.config = (uint8_t *)&global_cfg,
+ parms.config_sz_in_bytes = sizeof(global_cfg);
+
+ rc = tf_get_global_cfg(&bp->tfp, &parms);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
+ type, rc);
+ return rc;
+ }
+
+ if (set_flag)
+ global_cfg |= value;
+ else
+ global_cfg &= ~value;
+
+ /* SET the register RE_CFA_REG_ACT_TECT */
+ rc = tf_set_global_cfg(&bp->tfp, &parms);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
+ type, rc);
+ return rc;
+ }
+ return rc;
+}
+
/*
* When a port is initialized by dpdk. This functions is called
* and this function initializes the ULP context and rest of the
bool init;
int rc;
+ if (!BNXT_TRUFLOW_EN(bp))
+ return 0;
+
if (bp->ulp_ctx) {
- BNXT_TF_DBG(ERR, "ulp ctx already allocated\n");
+ BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n");
return -EINVAL;
}
rc = ulp_dparms_init(bp, bp->ulp_ctx);
/* create the port database */
- rc = ulp_port_db_init(bp->ulp_ctx);
+ rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
if (rc) {
BNXT_TF_DBG(ERR, "Failed to create the port database\n");
goto jump_to_error;
goto jump_to_error;
}
+ rc = ulp_fc_mgr_init(bp->ulp_ctx);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
+ goto jump_to_error;
+ }
+
+ /*
+ * Enable NAT feature. Set the global configuration register
+ * Tunnel encap to enable NAT with the reuse of existing inner
+ * L2 header smac and dmac
+ */
+ rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
+ TF_TUNNEL_ENCAP_NAT,
+ (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
+ BNXT_ULP_NAT_INNER_L2_HEADER_DMAC), 1);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to set rx global configuration\n");
+ goto jump_to_error;
+ }
+
+ rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
+ TF_TUNNEL_ENCAP_NAT,
+ (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
+ BNXT_ULP_NAT_INNER_L2_HEADER_DMAC), 1);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to set tx global configuration\n");
+ goto jump_to_error;
+ }
+
return rc;
jump_to_error:
struct rte_pci_device *pci_dev;
struct rte_pci_addr *pci_addr;
+ if (!BNXT_TRUFLOW_EN(bp))
+ return;
+
/* Get the session first */
pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
pci_addr = &pci_dev->addr;
if (!session)
return;
+ /* clean up default flows */
+ bnxt_ulp_destroy_df_rules(bp, true);
+
/* clean up regular flows */
ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);
/* cleanup the ulp mapper */
ulp_mapper_deinit(bp->ulp_ctx);
+ /* Delete the Flow Counter Manager */
+ ulp_fc_mgr_deinit(bp->ulp_ctx);
+
/* Delete the Port database */
ulp_port_db_deinit(bp->ulp_ctx);
+ /* Disable NAT feature */
+ (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
+ TF_TUNNEL_ENCAP_NAT,
+ (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
+ BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),
+ 0);
+
+ (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
+ TF_TUNNEL_ENCAP_NAT,
+ (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
+ BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),
+ 0);
+
/* Delete the ulp context and tf session */
ulp_ctx_detach(bp, session);
struct bnxt_ulp_context *
bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev *dev)
{
- struct bnxt *bp;
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+ if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
+ struct bnxt_vf_representor *vfr = dev->data->dev_private;
+
+ bp = vfr->parent_dev->data->dev_private;
+ }
- bp = (struct bnxt *)dev->data->dev_private;
if (!bp) {
BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
return NULL;
return ulp_ctx->cfg_data->port_db;
}
+
+/* Function to set the flow counter info into the context */
+int32_t
+bnxt_ulp_cntxt_ptr2_fc_info_set(struct bnxt_ulp_context *ulp_ctx,
+ struct bnxt_ulp_fc_info *ulp_fc_info)
+{
+ if (!ulp_ctx || !ulp_ctx->cfg_data) {
+ BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
+ return -EINVAL;
+ }
+
+ ulp_ctx->cfg_data->fc_info = ulp_fc_info;
+
+ return 0;
+}
+
+/* Function to retrieve the flow counter info from the context. */
+struct bnxt_ulp_fc_info *
+bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx)
+{
+ if (!ulp_ctx || !ulp_ctx->cfg_data)
+ return NULL;
+
+ return ulp_ctx->cfg_data->fc_info;
+}
+
+/* Function to get the ulp flags from the ulp context. */
+int32_t
+bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,
+ uint32_t *flags)
+{
+ if (!ulp_ctx || !ulp_ctx->cfg_data)
+ return -1;
+
+ *flags = ulp_ctx->cfg_data->ulp_flags;
+ return 0;
+}