From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9A66E45C9F; Thu, 7 Nov 2024 14:47:52 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EC48D42FB5; Thu, 7 Nov 2024 14:47:43 +0100 (CET) Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) by mails.dpdk.org (Postfix) with ESMTP id 5245242FBD for ; Thu, 7 Nov 2024 14:47:42 +0100 (CET) Received: by mail-pl1-f193.google.com with SMTP id d9443c01a7336-20c8c50fdd9so15036595ad.0 for ; Thu, 07 Nov 2024 05:47:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1730987261; x=1731592061; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cNLgXJ3UWp5JxrAF62EkDOXCBLigwfxdu+ItVzQcfZE=; b=dM3NSlk/o7BF6zkcV5e77ukfxTuQ1K+q7/bYAg4lI992DCphe+ZZ+U+oY8k0/gFmPx gTo0ocpL8dDFmlYy4TuJM6IFuhhmXv2FsM7BRBnr9Gppkv1nmzqtY/dGI+IRdL5aLdrz hw8Sy7vPN6EUpFpmUKBt+D15RvbdhV/o5zBfE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730987261; x=1731592061; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cNLgXJ3UWp5JxrAF62EkDOXCBLigwfxdu+ItVzQcfZE=; b=hOwfXGEaMNrznJHRxWrF6ak7VpU6s2vFPwxcTjH5SEf0uSnqGFupX8PKx7yC0Jmb7X og2UZoCgAGcgRN89KR4evjpFY9wZx3OI+/FMRASMNug8u4K+KeOw8v/7Yg2X48BMobWi e5aMR9AfR5F0YIOo0CWVDk6ztKQlTQTcQlkB6KgGMkIyffdcjznFAktQvim1yW6my0lq CkMnoSlNh+c94MPELLhn63yEu3y2XWuxPpEkJr0WHoVC3MyUVlfV9m0P/f2VkuHxiAuA 6Sdnvqiw7Z1yxFZy4CP40F6Yxy6tRayrIdp6coZuFwNRTwrCud/eeKyTHSn2zpPoA2xe GSyg== X-Gm-Message-State: AOJu0YxOEixBtRQeGbZGvYbT2yA95hjMX0w2dCA4O1JNDlgXca1GN6HB MEcYI5ZQf8fXD2u5NpnAqp/SEPS8oMdBVZ6RM61C110a/bZUx6aFLMdhhZ+by5cxJ2JNicNlX6o tDyyMiZJlrz6UcnNaL7ki7J2YTeQhdZ6+U/UPtPk/r0gHAww0tuC9oWuuXn7UOE342PGOZyQD2R ZazKGc6OSnB4LWEeQpnMFZcaTVo/GvpfcT8woCBMkxK4nG X-Google-Smtp-Source: AGHT+IEfiHVGgt49VgREbvhg/AXU3UUOFRJEdrERub8C0IsOXTE0NmJUJSuAHYYCP5ggUrVJHBk6SA== X-Received: by 2002:a17:902:db02:b0:20c:e169:eb7b with SMTP id d9443c01a7336-21175aceb9emr53537135ad.14.1730987260352; Thu, 07 Nov 2024 05:47:40 -0800 (PST) Received: from dhcp-10-123-154-23.dhcp.broadcom.net ([192.19.234.250]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e9a5f52969sm1409878a91.2.2024.11.07.05.47.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 05:47:39 -0800 (PST) From: Sriharsha Basavapatna To: dev@dpdk.org Cc: Peter Spreadborough , Sriharsha Basavapatna , Jay Ding , Shahaji Bhosle , Ajit Khaparde Subject: [PATCH v8 47/47] net/bnxt: tf_ulp: add stats cache for thor2 Date: Thu, 7 Nov 2024 19:22:54 +0530 Message-Id: <20241107135254.1611676-48-sriharsha.basavapatna@broadcom.com> X-Mailer: git-send-email 2.39.0.189.g4dbebc36b0 In-Reply-To: <20241107135254.1611676-1-sriharsha.basavapatna@broadcom.com> References: <20241107135254.1611676-1-sriharsha.basavapatna@broadcom.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Peter Spreadborough This change adds a stats cache for Thor2 flows using counters. Flow stats will be harvested periodically in the background and stats reads by the application will be returned stats from the cache and not by initiating a read from HW. This change also adds read-clear functionality for counter resets and restructures the stats collection while loop to guarantee full coverage of entries added or removed during the collection period. Signed-off-by: Peter Spreadborough Signed-off-by: Sriharsha Basavapatna Reviewed-by: Jay Ding Reviewed-by: Shahaji Bhosle Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/tf_core/v3/tfc_act.c | 88 ++-- drivers/net/bnxt/tf_core/v3/tfc_em.c | 14 +- drivers/net/bnxt/tf_core/v3/tfc_em.h | 5 + drivers/net/bnxt/tf_ulp/bnxt_ulp.h | 2 + drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c | 16 +- drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c | 10 + drivers/net/bnxt/tf_ulp/bnxt_ulp_utils.h | 26 ++ drivers/net/bnxt/tf_ulp/meson.build | 4 +- drivers/net/bnxt/tf_ulp/ulp_fc_mgr_tfc.c | 13 + drivers/net/bnxt/tf_ulp/ulp_flow_db.c | 4 + drivers/net/bnxt/tf_ulp/ulp_mapper.c | 73 ++++ drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c | 526 +++++++++++++++++++++++ drivers/net/bnxt/tf_ulp/ulp_sc_mgr.h | 142 ++++++ drivers/net/bnxt/tf_ulp/ulp_sc_mgr_tfc.c | 60 +++ 14 files changed, 947 insertions(+), 36 deletions(-) create mode 100644 drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c create mode 100644 drivers/net/bnxt/tf_ulp/ulp_sc_mgr.h create mode 100644 drivers/net/bnxt/tf_ulp/ulp_sc_mgr_tfc.c diff --git a/drivers/net/bnxt/tf_core/v3/tfc_act.c b/drivers/net/bnxt/tf_core/v3/tfc_act.c index bc8faf0c79..3e215f4881 100644 --- a/drivers/net/bnxt/tf_core/v3/tfc_act.c +++ b/drivers/net/bnxt/tf_core/v3/tfc_act.c @@ -505,7 +505,47 @@ static int tfc_act_get_only(struct tfc *tfcp, return rc; } +int tfc_act_get_clear_response(struct cfa_bld_mpcinfo *mpc_info, + struct bnxt_mpc_mbuf *mpc_msg_out, + uint8_t *rx_msg, + uint16_t *data_sz_words) +{ + int i; + int rc; + uint8_t discard_data[TFC_ACT_DISCARD_DATA_SIZE]; + struct cfa_mpc_data_obj fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_MAX_FLD] = { {0} }; + + /* Process response */ + for (i = 0; i < CFA_BLD_MPC_READ_CLR_CMP_MAX_FLD; i++) + fields_cmp[i].field_id = INVALID_U16; + + fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].field_id = + CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD; + + rc = mpc_info->mpcops->cfa_bld_mpc_parse_cache_read_clr(rx_msg, + mpc_msg_out->msg_size, + discard_data, + *data_sz_words * + TFC_MPC_BYTES_PER_WORD, + fields_cmp); + + if (unlikely(rc)) { + PMD_DRV_LOG_LINE(ERR, "Action read clear parse failed: %d", rc); + return -1; + } + + if (fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val != CFA_BLD_MPC_OK) { + PMD_DRV_LOG_LINE(ERR, "Action read clear failed with status code:%d", + (uint32_t)fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val); + rc = ((int)fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val) * -1; + return rc; + } + + return 0; +} + static int tfc_act_get_clear(struct tfc *tfcp, + struct tfc_mpc_batch_info_t *batch_info, const struct tfc_cmm_info *cmm_info, uint8_t *data, uint16_t *data_sz_words, @@ -519,8 +559,6 @@ static int tfc_act_get_clear(struct tfc *tfcp, int i; uint32_t buff_len; struct cfa_mpc_data_obj fields_cmd[CFA_BLD_MPC_READ_CLR_CMD_MAX_FLD] = { {0} }; - struct cfa_mpc_data_obj fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_MAX_FLD] = { {0} }; - uint8_t discard_data[TFC_ACT_DISCARD_DATA_SIZE]; uint32_t entry_offset; uint64_t host_address; struct bnxt_mpc_mbuf mpc_msg_in; @@ -631,37 +669,24 @@ static int tfc_act_get_clear(struct tfc *tfcp, &mpc_msg_out, &msg_count, TFC_MPC_TABLE_READ_CLEAR, - NULL); + batch_info); if (unlikely(rc)) { PMD_DRV_LOG_LINE(ERR, "read clear MPC send failed: %d", rc); goto cleanup; } - /* Process response */ - for (i = 0; i < CFA_BLD_MPC_READ_CLR_CMP_MAX_FLD; i++) - fields_cmp[i].field_id = INVALID_U16; - - fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].field_id = - CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD; - - rc = mpc_info->mpcops->cfa_bld_mpc_parse_cache_read_clr(rx_msg, - mpc_msg_out.msg_size, - discard_data, - *data_sz_words * - TFC_MPC_BYTES_PER_WORD, - fields_cmp); - - if (unlikely(rc)) { - PMD_DRV_LOG_LINE(ERR, "Action read clear parse failed: %d", rc); - goto cleanup; - } - - if (fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val != CFA_BLD_MPC_OK) { - PMD_DRV_LOG_LINE(ERR, "Action read clear failed with status code:%d", - (uint32_t)fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val); - rc = ((int)fields_cmp[CFA_BLD_MPC_READ_CLR_CMP_STATUS_FLD].val) * -1; - goto cleanup; + if ((batch_info && !batch_info->enabled) || !batch_info) { + rc = tfc_act_get_clear_response(mpc_info, + &mpc_msg_out, + rx_msg, + data_sz_words); + if (rc) { + PMD_DRV_LOG_LINE(ERR, "Action response failed: %d", rc); + goto cleanup; + } + } else { + batch_info->comp_info[batch_info->count - 1].read_words = *data_sz_words; } return 0; @@ -682,11 +707,6 @@ int tfc_act_get(struct tfc *tfcp, * clear via the clr flag. */ if (clr && clr->clr) { - if (unlikely(batch_info && batch_info->enabled)) { - PMD_DRV_LOG_LINE(ERR, "Not supported in batching mode"); - return -EINVAL; - } - /* Clear offset and size have to be two bytes aligned */ if (clr->offset_in_byte % 2 || clr->sz_in_byte % 2) { PMD_DRV_LOG_LINE(ERR, @@ -695,7 +715,9 @@ int tfc_act_get(struct tfc *tfcp, return -EINVAL; } - return tfc_act_get_clear(tfcp, cmm_info, + return tfc_act_get_clear(tfcp, + batch_info, + cmm_info, data, data_sz_words, clr->offset_in_byte / 2, clr->sz_in_byte / 2); diff --git a/drivers/net/bnxt/tf_core/v3/tfc_em.c b/drivers/net/bnxt/tf_core/v3/tfc_em.c index cafab913b4..a70e35b6b1 100644 --- a/drivers/net/bnxt/tf_core/v3/tfc_em.c +++ b/drivers/net/bnxt/tf_core/v3/tfc_em.c @@ -926,6 +926,11 @@ int tfc_mpc_batch_end(struct tfc *tfcp, if (unlikely(!batch_info->enabled)) return -EBUSY; + if (unlikely(!batch_info->count)) { + batch_info->enabled = false; + return 0; + } + tfo_mpcinfo_get(tfcp->tfo, &mpc_info); if (unlikely(mpc_info->mpcops == NULL)) { @@ -933,7 +938,8 @@ int tfc_mpc_batch_end(struct tfc *tfcp, return -EINVAL; } - rte_delay_us_block(BNXT_MPC_RX_US_DELAY * 4); + if (batch_info->count < (BNXT_MPC_COMP_MAX_COUNT / 4)) + rte_delay_us_block(BNXT_MPC_RX_US_DELAY * 4); for (i = 0; i < batch_info->count; i++) { rc = tfc_mpc_process_completions(&rx_msg[TFC_MPC_HEADER_SIZE_BYTES], @@ -981,6 +987,12 @@ int tfc_mpc_batch_end(struct tfc *tfcp, break; case TFC_MPC_TABLE_READ_CLEAR: + rc = tfc_act_get_clear_response(mpc_info, + &batch_info->comp_info[i].out_msg, + rx_msg, + &batch_info->comp_info[i].read_words); + break; + default: PMD_DRV_LOG_LINE(ERR, "MPC Batch not supported for type: %d", batch_info->comp_info[i].type); diff --git a/drivers/net/bnxt/tf_core/v3/tfc_em.h b/drivers/net/bnxt/tf_core/v3/tfc_em.h index 90d977be82..837678cea1 100644 --- a/drivers/net/bnxt/tf_core/v3/tfc_em.h +++ b/drivers/net/bnxt/tf_core/v3/tfc_em.h @@ -164,6 +164,11 @@ int tfc_act_get_only_response(struct cfa_bld_mpcinfo *mpc_info, uint8_t *rx_msg, uint16_t *data_sz_words); +int tfc_act_get_clear_response(struct cfa_bld_mpcinfo *mpc_info, + struct bnxt_mpc_mbuf *mpc_msg_out, + uint8_t *rx_msg, + uint16_t *data_sz_words); + int tfc_mpc_send(struct bnxt *bp, struct bnxt_mpc_mbuf *in_msg, struct bnxt_mpc_mbuf *out_msg, diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h index a35f79f167..83fb205f68 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h @@ -162,6 +162,8 @@ struct bnxt_ulp_data { uint64_t feature_bits; uint64_t default_class_bits; uint64_t default_act_bits; + struct ulp_fc_tfc_stats_cache_entry *stats_cache; + struct bnxt_ulp_sc_info *sc_info; }; enum bnxt_ulp_tfo_type { diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index 334eda99ce..2c22582e1c 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -670,6 +670,7 @@ bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, struct bnxt_ulp_context *ulp_ctx; struct rte_flow_action_rss *rss_conf; struct rte_flow_query_count *count; + enum bnxt_ulp_device_id dev_id; uint32_t flow_id; ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); @@ -681,6 +682,15 @@ bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, return -EINVAL; } + rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); + if (rc) { + BNXT_DRV_DBG(ERR, "Can't identify the device\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to query flow."); + return -EINVAL; + } + flow_id = (uint32_t)(uintptr_t)flow; switch (action->type) { @@ -696,7 +706,11 @@ bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, break; case RTE_FLOW_ACTION_TYPE_COUNT: count = data; - rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count); + if (dev_id == BNXT_ULP_DEVICE_ID_THOR2) + rc = ulp_sc_mgr_query_count_get(ulp_ctx, flow_id, count); + else + rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count); + if (unlikely(rc)) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c index d83f3df884..6d7ec0ffec 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c @@ -26,6 +26,7 @@ #include "ulp_template_struct.h" #include "ulp_mark_mgr.h" #include "ulp_fc_mgr.h" +#include "ulp_sc_mgr.h" #include "ulp_flow_db.h" #include "ulp_mapper.h" #include "ulp_matcher.h" @@ -888,6 +889,9 @@ ulp_tfc_deinit(struct bnxt *bp, BNXT_DRV_DBG(ERR, "Failed to close HA (%d)\n", rc); } + /* Delete the Stats Counter Manager */ + ulp_sc_mgr_deinit(bp->ulp_ctx); + /* cleanup the flow database */ ulp_flow_db_deinit(bp->ulp_ctx); @@ -1044,6 +1048,12 @@ ulp_tfc_init(struct bnxt *bp, goto jump_to_error; } + rc = ulp_sc_mgr_init(bp->ulp_ctx); + if (rc) { + BNXT_DRV_DBG(ERR, "Failed to initialize ulp stats cache mgr\n"); + goto jump_to_error; + } + rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); if (rc) { BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n"); diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_utils.h b/drivers/net/bnxt/tf_ulp/bnxt_ulp_utils.h index 5ca99780e2..418e0eecae 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_utils.h +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_utils.h @@ -25,6 +25,7 @@ #include "ulp_template_struct.h" #include "ulp_mark_mgr.h" #include "ulp_fc_mgr.h" +#include "ulp_sc_mgr.h" #include "ulp_flow_db.h" #include "ulp_mapper.h" #include "ulp_matcher.h" @@ -739,6 +740,31 @@ bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx) return ulp_ctx->cfg_data->fc_info; } +/* Function to set the flow counter info into the context */ +static inline int32_t +bnxt_ulp_cntxt_ptr2_sc_info_set(struct bnxt_ulp_context *ulp_ctx, + struct bnxt_ulp_sc_info *ulp_sc_info) +{ + if (unlikely(!ulp_ctx || !ulp_ctx->cfg_data)) { + BNXT_DRV_DBG(ERR, "Invalid ulp context data\n"); + return -EINVAL; + } + + ulp_ctx->cfg_data->sc_info = ulp_sc_info; + + return 0; +} + +/* Function to retrieve the flow counter info from the context. */ +static inline struct bnxt_ulp_sc_info * +bnxt_ulp_cntxt_ptr2_sc_info_get(struct bnxt_ulp_context *ulp_ctx) +{ + if (unlikely(!ulp_ctx || !ulp_ctx->cfg_data)) + return NULL; + + return ulp_ctx->cfg_data->sc_info; +} + /* Function to get the ulp flags from the ulp context. */ static inline int32_t bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx, diff --git a/drivers/net/bnxt/tf_ulp/meson.build b/drivers/net/bnxt/tf_ulp/meson.build index e19d51ee01..db6f65539d 100644 --- a/drivers/net/bnxt/tf_ulp/meson.build +++ b/drivers/net/bnxt/tf_ulp/meson.build @@ -31,6 +31,8 @@ sources += files( 'bnxt_ulp_tfc.c', 'ulp_fc_mgr_tfc.c', 'ulp_fc_mgr_tf.c', - 'ulp_alloc_tbl.c') + 'ulp_alloc_tbl.c', + 'ulp_sc_mgr.c', + 'ulp_sc_mgr_tfc.c') subdir('generic_templates') diff --git a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr_tfc.c b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr_tfc.c index 4a93dd1a33..e73fdcd1c7 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_fc_mgr_tfc.c +++ b/drivers/net/bnxt/tf_ulp/ulp_fc_mgr_tfc.c @@ -30,6 +30,19 @@ #define ULP_TFC_CNTR_ALIGN 32 #define ULP_TFC_ACT_WORD_SZ 32 +struct ulp_fc_tfc_stats_cache_entry { + uint32_t flags; + uint64_t timestamp; + uint8_t tsid; + uint32_t record_size; + uint32_t offset; + uint8_t dir; + uint64_t packet_count; + uint64_t byte_count; + uint16_t tcp_flags; + uint32_t tcp_timestamp; +}; + static int32_t ulp_fc_tfc_update_accum_stats(__rte_unused struct bnxt_ulp_context *ctxt, __rte_unused struct bnxt_ulp_fc_info *fc_info, diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c index d5e8bcfacd..d6fd653b4a 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c +++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c @@ -13,6 +13,7 @@ #include "ulp_mapper.h" #include "ulp_flow_db.h" #include "ulp_fc_mgr.h" +#include "ulp_sc_mgr.h" #include "ulp_tun.h" #ifdef TF_FLOW_SCALE_QUERY #include "tf_resources.h" @@ -634,6 +635,9 @@ ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt, if (!ulp_fc_mgr_thread_isstarted(ulp_ctxt)) ulp_fc_mgr_thread_start(ulp_ctxt); + + if (!ulp_sc_mgr_thread_isstarted(ulp_ctxt)) + ulp_sc_mgr_thread_start(ulp_ctxt); } /* all good, return success */ diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c index 721e8f4992..2429ac2f1a 100644 --- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c +++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c @@ -2950,6 +2950,72 @@ ulp_mapper_vnic_tbl_process(struct bnxt_ulp_mapper_parms *parms, return rc; } +static int32_t +ulp_mapper_stats_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms, + struct bnxt_ulp_mapper_tbl_info *tbl) +{ + struct ulp_flow_db_res_params fid_parms; + uint64_t counter_handle; + struct ulp_blob data; + uint16_t data_len = 0; + uint8_t *tmp_data; + int32_t rc = 0; + + /* Initialize the blob data */ + if (unlikely(ulp_blob_init(&data, tbl->result_bit_size, + BNXT_ULP_BYTE_ORDER_BE))) { + BNXT_DRV_DBG(ERR, "Failed initial ulp_global table blob\n"); + return -EINVAL; + } + + /* read the arguments from the result table */ + rc = ulp_mapper_tbl_result_build(parms, tbl, &data, + "ULP Global Result"); + if (unlikely(rc)) { + BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); + return rc; + } + + tmp_data = ulp_blob_data_get(&data, &data_len); + counter_handle = *(uint64_t *)tmp_data; + counter_handle = tfp_be_to_cpu_64(counter_handle); + + memset(&fid_parms, 0, sizeof(fid_parms)); + fid_parms.direction = tbl->direction; + fid_parms.resource_func = tbl->resource_func; + fid_parms.resource_type = tbl->resource_type; + fid_parms.resource_sub_type = tbl->resource_sub_type; + fid_parms.resource_hndl = counter_handle; + fid_parms.critical_resource = tbl->critical_resource; + rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); + if (unlikely(rc)) { + BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", + rc); + return rc; + } + + rc = ulp_sc_mgr_entry_alloc(parms, counter_handle, tbl); + if (unlikely(rc)) { + BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", + rc); + return rc; + } +#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG +#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER + BNXT_DRV_DBG(DEBUG, "flow id =0x%x\n", parms->flow_id); +#endif +#endif + return rc; +} + +static int32_t +ulp_mapper_stats_cache_tbl_res_free(struct bnxt_ulp_context *ulp, + uint32_t fid) +{ + ulp_sc_mgr_entry_free(ulp, fid); + return 0; +} + /* Free the vnic resource */ static int32_t ulp_mapper_vnic_tbl_res_free(struct bnxt_ulp_context *ulp __rte_unused, @@ -4148,6 +4214,9 @@ ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, void *error) case BNXT_ULP_RESOURCE_FUNC_ALLOCATOR_TABLE: rc = ulp_mapper_allocator_tbl_process(parms, tbl); break; + case BNXT_ULP_RESOURCE_FUNC_STATS_CACHE: + rc = ulp_mapper_stats_cache_tbl_process(parms, tbl); + break; default: BNXT_DRV_DBG(ERR, "Unexpected mapper resource %d\n", tbl->resource_func); @@ -4286,6 +4355,10 @@ ulp_mapper_resource_free(struct bnxt_ulp_context *ulp, res->direction, res->resource_hndl); break; + case BNXT_ULP_RESOURCE_FUNC_STATS_CACHE: + rc = ulp_mapper_stats_cache_tbl_res_free(ulp, + fid); + break; default: break; } diff --git a/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c new file mode 100644 index 0000000000..13069126f0 --- /dev/null +++ b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.c @@ -0,0 +1,526 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2021 Broadcom + * All rights reserved. + */ + +#include +#include +#include +#include +#include "bnxt.h" +#include "bnxt_ulp.h" +#include "bnxt_ulp_utils.h" +#include "bnxt_ulp_tfc.h" +#include "bnxt_tf_common.h" +#include "ulp_sc_mgr.h" +#include "ulp_flow_db.h" +#include "ulp_template_db_enum.h" +#include "ulp_template_struct.h" +#include "tfc.h" +#include "tfc_debug.h" +#include "tfc_action_handle.h" + +#define ULP_TFC_CNTR_READ_BYTES 32 +#define ULP_TFC_CNTR_ALIGN 32 +#define ULP_TFC_ACT_WORD_SZ 32 + +static const struct bnxt_ulp_sc_core_ops * +bnxt_ulp_sc_ops_get(struct bnxt_ulp_context *ctxt) +{ + int32_t rc; + enum bnxt_ulp_device_id dev_id; + const struct bnxt_ulp_sc_core_ops *func_ops; + + rc = bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id); + if (rc) + return NULL; + + switch (dev_id) { + case BNXT_ULP_DEVICE_ID_THOR2: + func_ops = &ulp_sc_tfc_core_ops; + break; + case BNXT_ULP_DEVICE_ID_THOR: + case BNXT_ULP_DEVICE_ID_STINGRAY: + case BNXT_ULP_DEVICE_ID_WH_PLUS: + default: + func_ops = NULL; + break; + } + return func_ops; +} + +int32_t ulp_sc_mgr_init(struct bnxt_ulp_context *ctxt) +{ + const struct bnxt_ulp_sc_core_ops *sc_ops; + struct bnxt_ulp_device_params *dparms; + struct bnxt_ulp_sc_info *ulp_sc_info; + uint32_t stats_cache_tbl_sz; + uint32_t dev_id; + int rc; + + if (!ctxt) { + BNXT_DRV_DBG(DEBUG, "Invalid ULP CTXT\n"); + return -EINVAL; + } + + if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) { + BNXT_DRV_DBG(DEBUG, "Failed to get device id\n"); + return -EINVAL; + } + + dparms = bnxt_ulp_device_params_get(dev_id); + if (!dparms) { + BNXT_DRV_DBG(DEBUG, "Failed to device parms\n"); + return -EINVAL; + } + + sc_ops = bnxt_ulp_sc_ops_get(ctxt); + if (sc_ops == NULL) { + BNXT_DRV_DBG(DEBUG, "Failed to get the counter ops\n"); + return -EINVAL; + } + + ulp_sc_info = rte_zmalloc("ulp_sc_info", sizeof(*ulp_sc_info), 0); + if (!ulp_sc_info) { + rc = -ENOMEM; + goto error; + } + + ulp_sc_info->sc_ops = sc_ops; + ulp_sc_info->flags = 0; + + rc = pthread_mutex_init(&ulp_sc_info->sc_lock, NULL); + if (rc) { + BNXT_DRV_DBG(ERR, "Failed to initialize sc mutex\n"); + goto error; + } + + /* Add the SC info tbl to the ulp context. */ + bnxt_ulp_cntxt_ptr2_sc_info_set(ctxt, ulp_sc_info); + + ulp_sc_info->num_counters = dparms->ext_flow_db_num_entries; + if (!ulp_sc_info->num_counters) { + /* No need for software counters, call fw directly */ + BNXT_DRV_DBG(DEBUG, "Sw flow counter support not enabled\n"); + return 0; + } + + /* + * Size is determined by the number of flows + 10% to cover IDs + * used for resources. + */ + stats_cache_tbl_sz = sizeof(struct ulp_sc_tfc_stats_cache_entry) * + (ulp_sc_info->num_counters + + (ulp_sc_info->num_counters / 10)); + + ulp_sc_info->stats_cache_tbl = rte_zmalloc("ulp_stats_cache_tbl", + stats_cache_tbl_sz, 0); + if (!ulp_sc_info->stats_cache_tbl) { + rc = -ENOMEM; + goto error; + } + + ulp_sc_info->read_data = rte_zmalloc("ulp_stats_cache_read_data", + ULP_SC_BATCH_SIZE * ULP_SC_PAGE_SIZE, + ULP_SC_PAGE_SIZE); + if (!ulp_sc_info->read_data) { + rte_free(ulp_sc_info->stats_cache_tbl); + rc = -ENOMEM; + goto error; + } + + rc = ulp_sc_mgr_thread_start(ctxt); + if (rc) + BNXT_DRV_DBG(DEBUG, "Stats counter thread start failed\n"); + + error: + return rc; +} + +/* + * Release all resources in the Flow Counter Manager for this ulp context + * + * ctxt [in] The ulp context for the Flow Counter manager + * + */ +int32_t +ulp_sc_mgr_deinit(struct bnxt_ulp_context *ctxt) +{ + struct bnxt_ulp_sc_info *ulp_sc_info; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + + if (!ulp_sc_info) + return -EINVAL; + + pthread_mutex_lock(&ulp_sc_info->sc_lock); + + ulp_sc_mgr_thread_cancel(ctxt); + + pthread_mutex_destroy(&ulp_sc_info->sc_lock); + + if (ulp_sc_info->stats_cache_tbl) + rte_free(ulp_sc_info->stats_cache_tbl); + + if (ulp_sc_info->read_data) + rte_free(ulp_sc_info->read_data); + + rte_free(ulp_sc_info); + + /* Safe to ignore on deinit */ + (void)bnxt_ulp_cntxt_ptr2_sc_info_set(ctxt, NULL); + + return 0; +} + +#define ULP_SC_PERIOD_S 1 +#define ULP_SC_PERIOD_MS (ULP_SC_PERIOD_S * 1000) + +static uint32_t ulp_stats_cache_main_loop(void *arg) +{ + struct ulp_sc_tfc_stats_cache_entry *count; + const struct bnxt_ulp_sc_core_ops *sc_ops; + struct ulp_sc_tfc_stats_cache_entry *sce; + struct ulp_sc_tfc_stats_cache_entry *sce_end; + struct tfc_mpc_batch_info_t batch_info; + struct bnxt_ulp_sc_info *ulp_sc_info; + struct bnxt_ulp_context *ctxt = NULL; + uint16_t words = (ULP_TFC_CNTR_READ_BYTES + ULP_TFC_ACT_WORD_SZ - 1) / ULP_TFC_ACT_WORD_SZ; + uint32_t batch_size; + struct tfc *tfcp = NULL; + uint32_t batch; + uint32_t delay = ULP_SC_PERIOD_MS; + uint64_t start; + uint64_t stop; + uint64_t hz; + uint8_t *data; + int rc; + static uint32_t loop; + uint64_t cycles = 0; + uint64_t cpms = 0; + + while (!ctxt) { + ctxt = bnxt_ulp_cntxt_entry_acquire(arg); + + if (ctxt) + break; + + BNXT_DRV_DBG(INFO, "could not get the ulp context lock\n"); + rte_delay_us_block(1000); + } + + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + if (!ulp_sc_info) { + bnxt_ulp_cntxt_entry_release(); + goto terminate; + } + + sc_ops = ulp_sc_info->sc_ops; + + hz = rte_get_timer_hz(); + cpms = hz / 1000; + + while (true) { + bnxt_ulp_cntxt_entry_release(); + ctxt = NULL; + rte_delay_ms(delay); + + while (!ctxt) { + ctxt = bnxt_ulp_cntxt_entry_acquire(arg); + + if (ctxt) + break; + + BNXT_DRV_DBG(INFO, "could not get the ulp context lock\n"); + rte_delay_us_block(1); + } + + start = rte_get_timer_cycles(); + sce = ulp_sc_info->stats_cache_tbl; + sce_end = sce + (ulp_sc_info->num_counters + (ulp_sc_info->num_counters / 10)); + + while (ulp_sc_info->num_entries && (sce < sce_end)) { + data = ulp_sc_info->read_data; + + rc = tfc_mpc_batch_start(&batch_info); + if (rc) { + PMD_DRV_LOG_LINE(ERR, + "MPC batch start failed rc:%d loop:%d", + rc, loop); + break; + } + + if (bnxt_ulp_cntxt_acquire_fdb_lock(ctxt)) + break; + + rc = pthread_mutex_lock(&ulp_sc_info->sc_lock); + if (rc) { + PMD_DRV_LOG_LINE(ERR, + "Failed to get SC lock, terminating main loop rc:%d loop:%d", + rc, loop); + goto terminate; + } + + for (batch = 0; (batch < ULP_SC_BATCH_SIZE) && (sce < sce_end);) { + if (!(sce->flags & ULP_SC_ENTRY_FLAG_VALID)) { + sce++; + continue; + } + + tfcp = bnxt_ulp_cntxt_tfcp_get(sce->ctxt); + if (tfcp == NULL) { + bnxt_ulp_cntxt_entry_release(); + goto terminate; + } + + + /* Store the entry pointer to use for counter update */ + batch_info.em_hdl[batch_info.count] = (uint64_t)sce; + + rc = sc_ops->ulp_stats_cache_update(tfcp, + sce->dir, + data, + sce->handle, + &words, + &batch_info, + sce->reset); + if (rc) { + /* Abort this batch */ + PMD_DRV_LOG_LINE(ERR, + "loop:%d read_counter() failed:%d", + loop, rc); + break; + } + + if (sce->reset) + sce->reset = false; + + /* Next */ + batch++; + sce++; + data += ULP_SC_PAGE_SIZE; + } + + batch_size = batch_info.count; + rc = tfc_mpc_batch_end(tfcp, &batch_info); + + pthread_mutex_unlock(&ulp_sc_info->sc_lock); + bnxt_ulp_cntxt_release_fdb_lock(ctxt); + + if (rc) { + PMD_DRV_LOG_LINE(ERR, + "MPC batch end failed rc:%d loop:%d", + rc, loop); + batch_info.enabled = false; + break; + } + + /* Process counts */ + data = ulp_sc_info->read_data; + + for (batch = 0; batch < batch_size; batch++) { + /* Check for error in completion */ + if (batch_info.result[batch]) { + PMD_DRV_LOG_LINE(ERR, + "batch:%d result:%d", + batch, batch_info.result[batch]); + } else { + count = (struct ulp_sc_tfc_stats_cache_entry *) + ((uintptr_t)batch_info.em_hdl[batch]); + memcpy(&count->packet_count, data, ULP_TFC_ACT_WORD_SZ); + } + + data += ULP_SC_PAGE_SIZE; + } + } + + loop++; + stop = rte_get_timer_cycles(); + cycles = stop - start; + if (cycles > (hz * ULP_SC_PERIOD_S)) { + PMD_DRV_LOG_LINE(ERR, + "Stats collection time exceeded %dmS Cycles:%" PRIu64, + ULP_SC_PERIOD_MS, cycles); + delay = ULP_SC_PERIOD_MS; + } else { + delay = ULP_SC_PERIOD_MS - (cycles / cpms); + + if (delay > ULP_SC_PERIOD_MS) { + PMD_DRV_LOG_LINE(ERR, + "Stats collection delay:%dmS exceedes %dmS", + delay, ULP_SC_PERIOD_MS); + delay = ULP_SC_PERIOD_MS; + } + } + } + + terminate: + return 0; +} + +/* + * Check if the alarm thread that walks through the flows is started + * + * ctxt [in] The ulp context for the flow counter manager + * + */ +bool ulp_sc_mgr_thread_isstarted(struct bnxt_ulp_context *ctxt) +{ + struct bnxt_ulp_sc_info *ulp_sc_info; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + + if (ulp_sc_info) + return !!(ulp_sc_info->flags & ULP_FLAG_SC_THREAD); + + return false; +} + +/* + * Setup the Flow counter timer thread that will fetch/accumulate raw counter + * data from the chip's internal flow counters + * + * ctxt [in] The ulp context for the flow counter manager + * + */ +int32_t +ulp_sc_mgr_thread_start(struct bnxt_ulp_context *ctxt) +{ + struct bnxt_ulp_sc_info *ulp_sc_info; + int rc; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + + if (ulp_sc_info && !(ulp_sc_info->flags & ULP_FLAG_SC_THREAD)) { + rc = rte_thread_create(&ulp_sc_info->tid, + NULL, + &ulp_stats_cache_main_loop, + (void *)ctxt->cfg_data); + if (rc) + return rc; + + ulp_sc_info->flags |= ULP_FLAG_SC_THREAD; + } + + return 0; +} + +/* + * Cancel the alarm handler + * + * ctxt [in] The ulp context for the flow counter manager + * + */ +void ulp_sc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt) +{ + struct bnxt_ulp_sc_info *ulp_sc_info; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + if (!ulp_sc_info) + return; + + ulp_sc_info->flags &= ~ULP_FLAG_SC_THREAD; +} + +/* + * Fill the rte_flow_query_count 'data' argument passed + * in the rte_flow_query() with the values obtained and + * accumulated locally. + * + * ctxt [in] The ulp context for the flow counter manager + * + * flow_id [in] The HW flow ID + * + * count [out] The rte_flow_query_count 'data' that is set + * + */ +int ulp_sc_mgr_query_count_get(struct bnxt_ulp_context *ctxt, + uint32_t flow_id, + struct rte_flow_query_count *count) +{ + struct ulp_sc_tfc_stats_cache_entry *sce; + struct bnxt_ulp_sc_info *ulp_sc_info; + int rc = 0; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ctxt); + if (!ulp_sc_info) + return -ENODEV; + + sce = ulp_sc_info->stats_cache_tbl; + sce += flow_id; + + /* If entry is not valid return an error */ + if (!(sce->flags & ULP_SC_ENTRY_FLAG_VALID)) + return -EBUSY; + + count->hits = sce->packet_count; + count->hits_set = 1; + count->bytes = sce->byte_count; + count->bytes_set = 1; + + if (count->reset) + sce->reset = true; + + return rc; +} + + +int ulp_sc_mgr_entry_alloc(struct bnxt_ulp_mapper_parms *parms, + uint64_t counter_handle, + struct bnxt_ulp_mapper_tbl_info *tbl) +{ + struct ulp_sc_tfc_stats_cache_entry *sce; + struct bnxt_ulp_sc_info *ulp_sc_info; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(parms->ulp_ctx); + if (!ulp_sc_info) + return -ENODEV; + + pthread_mutex_lock(&ulp_sc_info->sc_lock); + + sce = ulp_sc_info->stats_cache_tbl; + sce += parms->flow_id; + + /* If entry is not free return an error */ + if (sce->flags & ULP_SC_ENTRY_FLAG_VALID) { + pthread_mutex_unlock(&ulp_sc_info->sc_lock); + return -EBUSY; + } + + memset(sce, 0, sizeof(*sce)); + sce->ctxt = parms->ulp_ctx; + sce->flags |= ULP_SC_ENTRY_FLAG_VALID; + sce->handle = counter_handle; + sce->dir = tbl->direction; + ulp_sc_info->num_entries++; + pthread_mutex_unlock(&ulp_sc_info->sc_lock); + + return 0; +} + +void ulp_sc_mgr_entry_free(struct bnxt_ulp_context *ulp, + uint32_t fid) +{ + struct ulp_sc_tfc_stats_cache_entry *sce; + struct bnxt_ulp_sc_info *ulp_sc_info; + + ulp_sc_info = bnxt_ulp_cntxt_ptr2_sc_info_get(ulp); + if (!ulp_sc_info) + return; + + pthread_mutex_lock(&ulp_sc_info->sc_lock); + + sce = ulp_sc_info->stats_cache_tbl; + sce += fid; + + if (!(sce->flags & ULP_SC_ENTRY_FLAG_VALID)) { + pthread_mutex_unlock(&ulp_sc_info->sc_lock); + return; + } + + sce->flags = 0; + ulp_sc_info->num_entries--; + + pthread_mutex_unlock(&ulp_sc_info->sc_lock); +} diff --git a/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.h b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.h new file mode 100644 index 0000000000..85524ce371 --- /dev/null +++ b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2023 Broadcom + * All rights reserved. + */ + +#ifndef _ULP_SC_MGR_H_ +#define _ULP_SC_MGR_H_ + +#include "pthread.h" +#include "bnxt_ulp.h" +#include "ulp_flow_db.h" + +#define ULP_FLAG_SC_THREAD BIT(0) + +#define ULP_SC_ENTRY_FLAG_VALID BIT(0) + +#define ULP_SC_BATCH_SIZE 64 +#define ULP_SC_PAGE_SIZE 4096 + +struct ulp_sc_tfc_stats_cache_entry { + struct bnxt_ulp_context *ctxt; + uint32_t flags; + uint64_t timestamp; + uint64_t handle; + uint8_t dir; + uint64_t packet_count; + uint64_t byte_count; + uint64_t count_fields1; + uint64_t count_fields2; + bool reset; +}; + +struct bnxt_ulp_sc_info { + struct ulp_sc_tfc_stats_cache_entry *stats_cache_tbl; + uint8_t *read_data; + uint32_t flags; + uint32_t num_entries; + pthread_mutex_t sc_lock; + uint32_t num_counters; + rte_thread_t tid; + const struct bnxt_ulp_sc_core_ops *sc_ops; +}; + +struct bnxt_ulp_sc_core_ops { + int32_t + (*ulp_stats_cache_update)(struct tfc *tfcp, + int dir, + uint8_t *data, + uint64_t handle, + uint16_t *words, + struct tfc_mpc_batch_info_t *batch_info, + bool reset); +}; + +/* + * Allocate all resources in the stats cache manager for this ulp context + * + * ctxt [in] The ulp context for the stats cache manager + */ +int32_t +ulp_sc_mgr_init(struct bnxt_ulp_context *ctxt); + +/* + * Release all resources in the stats cache manager for this ulp context + * + * ctxt [in] The ulp context for the stats cache manager + */ +int32_t +ulp_sc_mgr_deinit(struct bnxt_ulp_context *ctxt); + +/* + * Setup the stats cache timer thread that will fetch/accumulate raw counter + * data from the chip's internal stats caches + * + * ctxt [in] The ulp context for the stats cache manager + */ +int32_t +ulp_sc_mgr_thread_start(struct bnxt_ulp_context *ctxt); + +/* + * Alarm handler that will issue the TF-Core API to fetch + * data from the chip's internal stats caches + * + * ctxt [in] The ulp context for the stats cache manager + */ +void +ulp_sc_mgr_alarm_cb(void *arg); + +/* + * Cancel the alarm handler + * + * ctxt [in] The ulp context for the stats cache manager + * + */ +void ulp_sc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt); + +/* + * Check if the thread that walks through the flows is started + * + * ctxt [in] The ulp context for the stats cache manager + * + */ +bool ulp_sc_mgr_thread_isstarted(struct bnxt_ulp_context *ctxt); + +/* + * Get the current counts for the given flow id + * + * ctxt [in] The ulp context for the stats cache manager + * flow_id [in] The flow identifier + * count [out] structure in which the updated counts are passed + * back to the caller. + * + */ +int ulp_sc_mgr_query_count_get(struct bnxt_ulp_context *ctxt, + uint32_t flow_id, + struct rte_flow_query_count *count); + +/* + * Allocate a cache entry for flow + * + * parms [in] Various fields used to identify the flow + * counter_handle [in] This is the action table entry identifier. + * tbl [in] Various fields used to identify the flow + * + */ +int ulp_sc_mgr_entry_alloc(struct bnxt_ulp_mapper_parms *parms, + uint64_t counter_handle, + struct bnxt_ulp_mapper_tbl_info *tbl); + +/* + * Free cache entry + * + * ulp [in] The ulp context for the stats cache manager + * fid [in] The flow identifier + * + */ +void ulp_sc_mgr_entry_free(struct bnxt_ulp_context *ulp, + uint32_t fid); + +extern const struct bnxt_ulp_sc_core_ops ulp_sc_tfc_core_ops; + +#endif /* _ULP_SC_MGR_H_ */ diff --git a/drivers/net/bnxt/tf_ulp/ulp_sc_mgr_tfc.c b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr_tfc.c new file mode 100644 index 0000000000..a8141980d8 --- /dev/null +++ b/drivers/net/bnxt/tf_ulp/ulp_sc_mgr_tfc.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2021 Broadcom + * All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "bnxt.h" +#include "bnxt_ulp.h" +#include "bnxt_ulp_utils.h" +#include "bnxt_ulp_tfc.h" +#include "bnxt_tf_common.h" +#include "ulp_sc_mgr.h" +#include "ulp_flow_db.h" +#include "ulp_template_db_enum.h" +#include "ulp_template_struct.h" +#include "tfc.h" +#include "tfc_debug.h" +#include "tfc_action_handle.h" + +static int32_t +ulp_sc_tfc_stats_cache_update(struct tfc *tfcp, + int dir, + uint8_t *data, + uint64_t handle, + uint16_t *words, + struct tfc_mpc_batch_info_t *batch_info, + bool reset) +{ + struct tfc_cmm_info cmm_info; + struct tfc_cmm_clr cmm_clr; + int rc; + + cmm_info.dir = dir; + cmm_info.rsubtype = CFA_RSUBTYPE_CMM_ACT; + cmm_info.act_handle = handle; + cmm_clr.clr = reset; + + if (reset) { + cmm_clr.offset_in_byte = 0; + cmm_clr.sz_in_byte = 16; + } + + rc = tfc_act_get(tfcp, + batch_info, + &cmm_info, + &cmm_clr, + data, + words); + + return rc; +} + + +const struct bnxt_ulp_sc_core_ops ulp_sc_tfc_core_ops = { + .ulp_stats_cache_update = ulp_sc_tfc_stats_cache_update +}; -- 2.39.3