X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_ulp%2Fbnxt_ulp.c;h=469ad3615260720487ec7b172019e72a5bdf4df5;hb=98487d729b4a;hp=56e08f233e1d6bb6987db3c9b6d09d61b0d45a8d;hpb=edc6ca0cf94135f539f168bc5afa838bff25e890;p=dpdk.git diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c index 56e08f233e..469ad36152 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c @@ -15,10 +15,13 @@ #include "tf_core.h" #include "tf_ext_flow_handle.h" -#include "ulp_template_db.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" /* Linked list of all TF sessions. */ STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list = @@ -42,7 +45,7 @@ ulp_ctx_deinit_allowed(void *ptr) if (!bp) return 0; - if (&bp->tfp == bp->ulp_ctx.g_tfp) + if (&bp->tfp == bp->ulp_ctx->g_tfp) return 1; return 0; @@ -66,6 +69,7 @@ ulp_ctx_session_open(struct bnxt *bp, struct rte_eth_dev *ethdev = bp->eth_dev; int32_t rc = 0; struct tf_open_session_parms params; + struct tf_session_resources *resources; memset(¶ms, 0, sizeof(params)); @@ -77,6 +81,60 @@ ulp_ctx_session_open(struct bnxt *bp, return rc; } + params.shadow_copy = false; + 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_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; + + /* 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_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_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; + + /* 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_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; + + /* EEM */ + 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", @@ -101,7 +159,7 @@ ulp_ctx_session_close(struct bnxt *bp, tf_close_session(&bp->tfp); session->session_opened = 0; session->g_tfp = NULL; - bp->ulp_ctx.g_tfp = NULL; + bp->ulp_ctx->g_tfp = NULL; } static void @@ -112,13 +170,19 @@ bnxt_init_tbl_scope_parms(struct bnxt *bp, uint32_t dev_id; int rc; - rc = bnxt_ulp_cntxt_dev_id_get(&bp->ulp_ctx, &dev_id); + rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id); if (rc) /* TBD: For now, just use default. */ dparms = 0; else dparms = bnxt_ulp_device_params_get(dev_id); + /* + * Set the flush timer for EEM entries. The value is in 100ms intervals, + * so 100 is 10s. + */ + params->hw_flow_cache_flush_timer = 100; + if (!dparms) { params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY; params->rx_max_action_entry_sz_in_bits = @@ -138,14 +202,14 @@ bnxt_init_tbl_scope_parms(struct bnxt *bp, params->rx_max_action_entry_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY; params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM; - params->rx_num_flows_in_k = dparms->num_flows / (1024); + params->rx_num_flows_in_k = dparms->flow_db_num_entries / 1024; params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID; params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY; params->tx_max_action_entry_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY; params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM; - params->tx_num_flows_in_k = dparms->num_flows / (1024); + params->tx_num_flows_in_k = dparms->flow_db_num_entries / 1024; params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID; } } @@ -155,8 +219,27 @@ static int32_t 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); @@ -166,7 +249,7 @@ ulp_eem_tbl_scope_init(struct bnxt *bp) return rc; } - rc = bnxt_ulp_cntxt_tbl_scope_id_set(&bp->ulp_ctx, params.tbl_scope_id); + rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id); if (rc) { BNXT_TF_DBG(ERR, "Unable to set table scope id\n"); return rc; @@ -182,6 +265,8 @@ ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx) 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; @@ -196,6 +281,23 @@ ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx) 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"); @@ -226,7 +328,7 @@ ulp_ctx_deinit(struct bnxt *bp, /* Free the contents */ if (session->cfg_data) { rte_free(session->cfg_data); - bp->ulp_ctx.cfg_data = NULL; + bp->ulp_ctx->cfg_data = NULL; session->cfg_data = NULL; } return 0; @@ -254,7 +356,7 @@ ulp_ctx_init(struct bnxt *bp, } /* Increment the ulp context data reference count usage. */ - bp->ulp_ctx.cfg_data = ulp_data; + bp->ulp_ctx->cfg_data = ulp_data; session->cfg_data = ulp_data; ulp_data->ref_cnt++; @@ -264,10 +366,68 @@ ulp_ctx_init(struct bnxt *bp, (void)ulp_ctx_deinit(bp, session); return rc; } - bnxt_ulp_cntxt_tfp_set(&bp->ulp_ctx, session->g_tfp); + bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session->g_tfp); return rc; } +/* The function to initialize ulp dparms with devargs */ +static int32_t +ulp_dparms_init(struct bnxt *bp, + struct bnxt_ulp_context *ulp_ctx) +{ + struct bnxt_ulp_device_params *dparms; + uint32_t dev_id; + + if (!bp->max_num_kflows) + return -EINVAL; + + if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) { + BNXT_TF_DBG(DEBUG, "Failed to get device id\n"); + return -EINVAL; + } + + dparms = bnxt_ulp_device_params_get(dev_id); + if (!dparms) { + BNXT_TF_DBG(DEBUG, "Failed to get device parms\n"); + return -EINVAL; + } + + /* num_flows = max_num_kflows * 1024 */ + dparms->flow_db_num_entries = bp->max_num_kflows * 1024; + /* GFID = 2 * num_flows */ + dparms->mark_db_gfid_entries = dparms->flow_db_num_entries * 2; + BNXT_TF_DBG(DEBUG, "Set the number of flows = %"PRIu64"\n", + dparms->flow_db_num_entries); + + return 0; +} + +/* The function to initialize bp flags with truflow features */ +static int32_t +ulp_dparms_dev_port_intf_update(struct bnxt *bp, + struct bnxt_ulp_context *ulp_ctx) +{ + struct bnxt_ulp_device_params *dparms; + uint32_t dev_id; + + if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) { + BNXT_TF_DBG(DEBUG, "Failed to get device id\n"); + return -EINVAL; + } + + dparms = bnxt_ulp_device_params_get(dev_id); + if (!dparms) { + BNXT_TF_DBG(DEBUG, "Failed to get device parms\n"); + return -EINVAL; + } + + /* Update the bp flag with gfid flag */ + if (dparms->flow_mem_type == BNXT_ULP_FLOW_MEM_TYPE_EXT) + bp->flags |= BNXT_FLAG_GFID_ENABLE; + + return 0; +} + static int32_t ulp_ctx_attach(struct bnxt_ulp_context *ulp_ctx, struct bnxt_ulp_session_state *session) @@ -296,7 +456,7 @@ ulp_ctx_detach(struct bnxt *bp, BNXT_TF_DBG(ERR, "Invalid Arguments\n"); return -EINVAL; } - ulp_ctx = &bp->ulp_ctx; + ulp_ctx = bp->ulp_ctx; if (!ulp_ctx->cfg_data) return 0; @@ -433,6 +593,11 @@ bnxt_ulp_init(struct bnxt *bp) bool init; int rc; + if (bp->ulp_ctx) { + BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n"); + return -EINVAL; + } + /* * Multiple uplink ports can be associated with a single vswitch. * Make sure only the port that is started first will initialize @@ -444,15 +609,46 @@ bnxt_ulp_init(struct bnxt *bp) return -EINVAL; } + bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx", + sizeof(struct bnxt_ulp_context), 0); + if (!bp->ulp_ctx) { + BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n"); + ulp_session_deinit(session); + return -ENOMEM; + } + /* * If ULP is already initialized for a specific domain then simply * assign the ulp context to this rte_eth_dev. */ if (init) { - rc = ulp_ctx_attach(&bp->ulp_ctx, session); + rc = ulp_ctx_attach(bp->ulp_ctx, session); if (rc) { BNXT_TF_DBG(ERR, "Failed to attach the ulp context\n"); + ulp_session_deinit(session); + rte_free(bp->ulp_ctx); + return rc; + } + + /* Update bnxt driver flags */ + rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx); + if (rc) { + BNXT_TF_DBG(ERR, "Failed to update driver flags\n"); + ulp_ctx_detach(bp, session); + ulp_session_deinit(session); + rte_free(bp->ulp_ctx); + return rc; + } + + /* update the port database */ + rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev); + if (rc) { + BNXT_TF_DBG(ERR, + "Failed to update port database\n"); + ulp_ctx_detach(bp, session); + ulp_session_deinit(session); + rte_free(bp->ulp_ctx); } return rc; } @@ -464,15 +660,39 @@ bnxt_ulp_init(struct bnxt *bp) goto jump_to_error; } + /* Initialize ulp dparms with values devargs passed */ + rc = ulp_dparms_init(bp, bp->ulp_ctx); + + /* create the port database */ + 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; + } + + /* Update bnxt driver flags */ + rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx); + if (rc) { + BNXT_TF_DBG(ERR, "Failed to update driver flags\n"); + goto jump_to_error; + } + + /* update the port database */ + rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev); + if (rc) { + BNXT_TF_DBG(ERR, "Failed to update port database\n"); + goto jump_to_error; + } + /* Create the Mark database. */ - rc = ulp_mark_db_init(&bp->ulp_ctx); + rc = ulp_mark_db_init(bp->ulp_ctx); if (rc) { BNXT_TF_DBG(ERR, "Failed to create the mark database\n"); goto jump_to_error; } /* Create the flow database. */ - rc = ulp_flow_db_init(&bp->ulp_ctx); + rc = ulp_flow_db_init(bp->ulp_ctx); if (rc) { BNXT_TF_DBG(ERR, "Failed to create the flow database\n"); goto jump_to_error; @@ -485,6 +705,18 @@ bnxt_ulp_init(struct bnxt *bp) goto jump_to_error; } + rc = ulp_mapper_init(bp->ulp_ctx); + if (rc) { + BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n"); + 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; + } + return rc; jump_to_error: @@ -518,22 +750,33 @@ bnxt_ulp_deinit(struct bnxt *bp) return; /* clean up regular flows */ - ulp_flow_db_flush_flows(&bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE); + 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); + ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx); /* cleanup the flow database */ - ulp_flow_db_deinit(&bp->ulp_ctx); + ulp_flow_db_deinit(bp->ulp_ctx); /* Delete the Mark database */ - ulp_mark_db_deinit(&bp->ulp_ctx); + ulp_mark_db_deinit(bp->ulp_ctx); + + /* 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); /* Delete the ulp context and tf session */ ulp_ctx_detach(bp, session); /* Finally delete the bnxt session*/ ulp_session_deinit(session); + + rte_free(bp->ulp_ctx); } /* Function to set the Mark DB into the context */ @@ -659,10 +902,8 @@ int32_t bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx, struct bnxt_ulp_flow_db *flow_db) { - if (!ulp_ctx || !ulp_ctx->cfg_data) { - BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + if (!ulp_ctx || !ulp_ctx->cfg_data) return -EINVAL; - } ulp_ctx->cfg_data->flow_db = flow_db; return 0; @@ -672,10 +913,8 @@ bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx, struct bnxt_ulp_flow_db * bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx) { - if (!ulp_ctx || !ulp_ctx->cfg_data) { - BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + if (!ulp_ctx || !ulp_ctx->cfg_data) return NULL; - } return ulp_ctx->cfg_data->flow_db; } @@ -691,5 +930,76 @@ bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev *dev) BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n"); return NULL; } - return &bp->ulp_ctx; + return bp->ulp_ctx; +} + +int32_t +bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx, + void *mapper_data) +{ + if (!ulp_ctx || !ulp_ctx->cfg_data) { + BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + return -EINVAL; + } + + ulp_ctx->cfg_data->mapper_data = mapper_data; + return 0; +} + +void * +bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx) +{ + if (!ulp_ctx || !ulp_ctx->cfg_data) { + BNXT_TF_DBG(ERR, "Invalid ulp context data\n"); + return NULL; + } + + return ulp_ctx->cfg_data->mapper_data; +} + +/* Function to set the port database to the ulp context. */ +int32_t +bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx, + struct bnxt_ulp_port_db *port_db) +{ + if (!ulp_ctx || !ulp_ctx->cfg_data) + return -EINVAL; + + ulp_ctx->cfg_data->port_db = port_db; + return 0; +} + +/* Function to get the port database from the ulp context. */ +struct bnxt_ulp_port_db * +bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx) +{ + if (!ulp_ctx || !ulp_ctx->cfg_data) + 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; }