From 539931eab3a5f81adaaac583e792ac1e4237db20 Mon Sep 17 00:00:00 2001 From: Peter Spreadborough Date: Sun, 30 May 2021 14:28:37 +0530 Subject: [PATCH] net/bnxt: support EM with FKB Main TF changes to support EM insert with FKB. Flexible Key builder is required to create Wild Card and Exact Match keys for TCAM lookups. Signed-off-by: Peter Spreadborough Signed-off-by: Randy Schacher Signed-off-by: Venkat Duvvuru Reviewed-by: Farah Smith Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/tf_core/meson.build | 1 + drivers/net/bnxt/tf_core/tf_device_p58.c | 14 +- drivers/net/bnxt/tf_core/tf_em.h | 32 +++++ .../net/bnxt/tf_core/tf_em_hash_internal.c | 123 ++++++++++++++++++ drivers/net/bnxt/tf_core/tf_em_internal.c | 3 +- drivers/net/bnxt/tf_core/tf_msg.c | 96 ++++++++++++++ drivers/net/bnxt/tf_core/tf_msg.h | 35 +++++ 7 files changed, 295 insertions(+), 9 deletions(-) create mode 100644 drivers/net/bnxt/tf_core/tf_em_hash_internal.c diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build index d7e8f664fd..373ee0413b 100644 --- a/drivers/net/bnxt/tf_core/meson.build +++ b/drivers/net/bnxt/tf_core/meson.build @@ -30,5 +30,6 @@ sources += files( 'll.c', 'tf_global_cfg.c', 'tf_em_host.c', + 'tf_em_hash_internal.c', 'tf_shadow_identifier.c', 'tf_hash.c') diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c index 7dd806000c..6cef1d5ba5 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.c +++ b/drivers/net/bnxt/tf_core/tf_device_p58.c @@ -256,14 +256,14 @@ const struct tf_dev_ops tf_dev_ops_p58 = { .tf_dev_alloc_search_tcam = tf_tcam_alloc_search, .tf_dev_set_tcam = tf_tcam_set, .tf_dev_get_tcam = NULL, - .tf_dev_insert_int_em_entry = tf_em_insert_int_entry, - .tf_dev_delete_int_em_entry = tf_em_delete_int_entry, - .tf_dev_insert_ext_em_entry = tf_em_insert_ext_entry, - .tf_dev_delete_ext_em_entry = tf_em_delete_ext_entry, - .tf_dev_alloc_tbl_scope = tf_em_ext_common_alloc, - .tf_dev_map_tbl_scope = tf_em_ext_map_tbl_scope, + .tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry, + .tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry, + .tf_dev_insert_ext_em_entry = NULL, + .tf_dev_delete_ext_em_entry = NULL, + .tf_dev_alloc_tbl_scope = NULL, + .tf_dev_map_tbl_scope = NULL, .tf_dev_map_parif = tf_dev_p58_map_parif, - .tf_dev_free_tbl_scope = tf_em_ext_common_free, + .tf_dev_free_tbl_scope = NULL, .tf_dev_set_if_tbl = tf_if_tbl_set, .tf_dev_get_if_tbl = tf_if_tbl_get, .tf_dev_set_global_cfg = tf_global_cfg_set, diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h index b5c3acb09a..5a67ca3509 100644 --- a/drivers/net/bnxt/tf_core/tf_em.h +++ b/drivers/net/bnxt/tf_core/tf_em.h @@ -197,6 +197,38 @@ int tf_em_insert_int_entry(struct tf *tfp, int tf_em_delete_int_entry(struct tf *tfp, struct tf_delete_em_entry_parms *parms); +/** + * Insert record in to internal EM table + * + * [in] tfp + * Pointer to TruFlow handle + * + * [in] parms + * Pointer to input parameters + * + * Returns: + * 0 - Success + * -EINVAL - Parameter error + */ +int tf_em_hash_insert_int_entry(struct tf *tfp, + struct tf_insert_em_entry_parms *parms); + +/** + * Delete record from internal EM table + * + * [in] tfp + * Pointer to TruFlow handle + * + * [in] parms + * Pointer to input parameters + * + * Returns: + * 0 - Success + * -EINVAL - Parameter error + */ +int tf_em_hash_delete_int_entry(struct tf *tfp, + struct tf_delete_em_entry_parms *parms); + /** * Insert record in to external EEM table * diff --git a/drivers/net/bnxt/tf_core/tf_em_hash_internal.c b/drivers/net/bnxt/tf_core/tf_em_hash_internal.c new file mode 100644 index 0000000000..09183b42f0 --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_em_hash_internal.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Broadcom + * All rights reserved. + */ + +#include +#include +#include +#include + +#include "tf_core.h" +#include "tf_util.h" +#include "tf_common.h" +#include "tf_em.h" +#include "tf_msg.h" +#include "tfp.h" +#include "tf_ext_flow_handle.h" + +#include "bnxt.h" + +/** + * EM Pool + */ +extern struct stack em_pool[TF_DIR_MAX]; + +/** + * Insert EM internal entry API + * + * returns: + * 0 - Success + */ +int +tf_em_hash_insert_int_entry(struct tf *tfp, + struct tf_insert_em_entry_parms *parms) +{ + int rc; + uint32_t gfid; + uint16_t rptr_index = 0; + uint8_t rptr_entry = 0; + uint8_t num_of_entries = 0; + struct stack *pool = &em_pool[parms->dir]; + uint32_t index; + uint32_t key0_hash; + uint32_t key1_hash; + uint64_t big_hash; + + rc = stack_pop(pool, &index); + if (rc) { + PMD_DRV_LOG(ERR, + "%s, EM entry index allocation failed\n", + tf_dir_2_str(parms->dir)); + return rc; + } + + big_hash = hcapi_cfa_key_hash((uint64_t *)parms->key, + (TF_HW_EM_KEY_MAX_SIZE + 4) * 8); + key0_hash = (uint32_t)(big_hash >> 32); + key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF); + + rptr_index = index; + rc = tf_msg_hash_insert_em_internal_entry(tfp, + parms, + key0_hash, + key1_hash, + &rptr_index, + &rptr_entry, + &num_of_entries); + if (rc) { + /* Free the allocated index before returning */ + stack_push(pool, index); + return -1; + } + + PMD_DRV_LOG + (DEBUG, + "%s, Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n", + tf_dir_2_str(parms->dir), + index, + rptr_index, + rptr_entry, + num_of_entries); + + TF_SET_GFID(gfid, + ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) | + rptr_entry), + 0); /* N/A for internal table */ + + TF_SET_FLOW_ID(parms->flow_id, + gfid, + TF_GFID_TABLE_INTERNAL, + parms->dir); + + TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle, + (uint32_t)num_of_entries, + 0, + 0, + rptr_index, + rptr_entry, + 0); + return 0; +} + +/** Delete EM internal entry API + * + * returns: + * 0 + * -EINVAL + */ +int +tf_em_hash_delete_int_entry(struct tf *tfp, + struct tf_delete_em_entry_parms *parms) +{ + int rc = 0; + struct stack *pool = &em_pool[parms->dir]; + + rc = tf_msg_delete_em_entry(tfp, parms); + + /* Return resource to pool */ + if (rc == 0) + stack_push(pool, parms->index); + + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c index bdffd801b3..0864218469 100644 --- a/drivers/net/bnxt/tf_core/tf_em_internal.c +++ b/drivers/net/bnxt/tf_core/tf_em_internal.c @@ -30,11 +30,10 @@ static void *em_db[TF_DIR_MAX]; */ static uint8_t init; - /** * EM Pool */ -static struct stack em_pool[TF_DIR_MAX]; +struct stack em_pool[TF_DIR_MAX]; /** * Create EM Tbl pool of memory indexes. diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index be30d4a09f..39d7e3eace 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -25,6 +25,7 @@ */ #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16 #define TF_MSG_EM_INSERT_KEY_SIZE 64 +#define TF_MSG_EM_INSERT_RECORD_SIZE 80 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88 /* Compile check - Catch any msg changes that we depend on, like the @@ -706,6 +707,101 @@ tf_msg_insert_em_internal_entry(struct tf *tfp, return 0; } +int +tf_msg_hash_insert_em_internal_entry(struct tf *tfp, + struct tf_insert_em_entry_parms *em_parms, + uint32_t key0_hash, + uint32_t key1_hash, + uint16_t *rptr_index, + uint8_t *rptr_entry, + uint8_t *num_of_entries) +{ + int rc; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_em_hash_insert_input req = { 0 }; + struct hwrm_tf_em_hash_insert_output resp = { 0 }; + uint16_t flags; + uint8_t fw_session_id; + uint8_t msg_record_size; + struct tf_dev_info *dev; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + + /* Check for key size conformity */ + msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8; + + if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, + "%s: Record size to large, rc:%s\n", + tf_dir_2_str(em_parms->dir), + strerror(-rc)); + return rc; + } + + tfp_memcpy((char *)req.em_record, + em_parms->em_record, + msg_record_size); + + flags = (em_parms->dir == TF_DIR_TX ? + HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : + HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); + req.flags = tfp_cpu_to_le_16(flags); + req.em_record_size_bits = em_parms->em_record_sz_in_bits; + req.em_record_idx = *rptr_index; + req.key0_hash = key0_hash; + req.key1_hash = key1_hash; + + parms.tf_type = HWRM_TF_EM_HASH_INSERT; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tfp, + &parms); + if (rc) + return rc; + + *rptr_entry = resp.rptr_entry; + *rptr_index = resp.rptr_index; + *num_of_entries = resp.num_of_entries; + + return 0; +} + int tf_msg_delete_em_entry(struct tf *tfp, struct tf_delete_em_entry_parms *em_parms) diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h index 25e29a554f..1d82ce5049 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.h +++ b/drivers/net/bnxt/tf_core/tf_msg.h @@ -225,6 +225,41 @@ int tf_msg_insert_em_internal_entry(struct tf *tfp, uint16_t *rptr_index, uint8_t *rptr_entry, uint8_t *num_of_entries); +/** + * Sends EM hash internal insert request to Firmware + * + * [in] tfp + * Pointer to TF handle + * + * [in] params + * Pointer to em insert parameter list + * + * [in] key0_hash + * CRC32 hash of key + * + * [in] key1_hash + * Lookup3 hash of key + * + * [in] rptr_index + * Record ptr index + * + * [in] rptr_entry + * Record ptr entry + * + * [in] num_of_entries + * Number of entries to insert + * + * Returns: + * 0 on Success else internal Truflow error + */ +int +tf_msg_hash_insert_em_internal_entry(struct tf *tfp, + struct tf_insert_em_entry_parms *em_parms, + uint32_t key0_hash, + uint32_t key1_hash, + uint16_t *rptr_index, + uint8_t *rptr_entry, + uint8_t *num_of_entries); /** * Sends EM internal delete request to Firmware * -- 2.20.1