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 <peter.spreadborough@broadcom.com>
Signed-off-by: Randy Schacher <stuart.schacher@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Farah Smith <farah.smith@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
'll.c',
'tf_global_cfg.c',
'tf_em_host.c',
+ 'tf_em_hash_internal.c',
'tf_shadow_identifier.c',
'tf_hash.c')
.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,
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
*
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2021 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+
+#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;
+}
*/
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.
*/
#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
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)
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
*