/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Broadcom
+ * Copyright(c) 2019-2020 Broadcom
* All rights reserved.
*/
#ifndef _HWRM_TF_H_
HWRM_TFT_REG_SET = 822,
HWRM_TFT_TBL_TYPE_SET = 823,
HWRM_TFT_TBL_TYPE_GET = 824,
- TF_SUBTYPE_LAST = HWRM_TFT_TBL_TYPE_GET,
+ HWRM_TFT_TBL_TYPE_GET_BULK = 825,
+ TF_SUBTYPE_LAST = HWRM_TFT_TBL_TYPE_GET_BULK,
} tf_subtype_t;
/* Request and Response compile time checking */
struct tf_tbl_type_set_input;
struct tf_tbl_type_get_input;
struct tf_tbl_type_get_output;
+struct tf_tbl_type_get_bulk_input;
+struct tf_tbl_type_get_bulk_output;
/* Input params for session attach */
typedef struct tf_session_attach_input {
/* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
#define TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX (0x0)
/* When set to 1, indicates the get apply to TX */
#define TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX (0x1)
+ /* When set to 1, indicates the clear entry on read */
+#define TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ (0x2)
/* Type of the object to set */
uint32_t type;
/* Index to get */
uint8_t data[TF_BULK_RECV];
} tf_tbl_type_get_output_t, *ptf_tbl_type_get_output_t;
+/* Input params for table type get */
+typedef struct tf_tbl_type_get_bulk_input {
+ /* Session Id */
+ uint32_t fw_session_id;
+ /* flags */
+ uint16_t flags;
+ /* When set to 0, indicates the get apply to RX */
+#define TF_TBL_TYPE_GET_BULK_INPUT_FLAGS_DIR_RX (0x0)
+ /* When set to 1, indicates the get apply to TX */
+#define TF_TBL_TYPE_GET_BULK_INPUT_FLAGS_DIR_TX (0x1)
+ /* When set to 1, indicates the clear entry on read */
+#define TF_TBL_TYPE_GET_BULK_INPUT_FLAGS_CLEAR_ON_READ (0x2)
+ /* Type of the object to set */
+ uint32_t type;
+ /* Starting index to get from */
+ uint32_t start_index;
+ /* Number of entries to get */
+ uint32_t num_entries;
+ /* Host memory where data will be stored */
+ uint64_t host_addr;
+} tf_tbl_type_get_bulk_input_t, *ptf_tbl_type_get_bulk_input_t;
+
+/* Output params for table type get */
+typedef struct tf_tbl_type_get_bulk_output {
+ /* Size of the total data read in bytes */
+ uint16_t size;
+} tf_tbl_type_get_bulk_output_t, *ptf_tbl_type_get_bulk_output_t;
+
#endif /* _HWRM_TF_H_ */
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_COMMON_H_
+#define _TF_COMMON_H_
+
+/* Helper to check the parms */
+#define TF_CHECK_PARMS_SESSION(tfp, parms) do { \
+ if ((parms) == NULL || (tfp) == NULL) { \
+ TFP_DRV_LOG(ERR, "Invalid Argument(s)\n"); \
+ return -EINVAL; \
+ } \
+ if ((tfp)->session == NULL || \
+ (tfp)->session->core_data == NULL) { \
+ TFP_DRV_LOG(ERR, "%s: session error\n", \
+ tf_dir_2_str((parms)->dir)); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
+#define TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms) do { \
+ if ((parms) == NULL || (tfp) == NULL) { \
+ TFP_DRV_LOG(ERR, "Invalid Argument(s)\n"); \
+ return -EINVAL; \
+ } \
+ if ((tfp)->session == NULL || \
+ (tfp)->session->core_data == NULL) { \
+ TFP_DRV_LOG(ERR, "Session error\n"); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
+#define TF_CHECK_PARMS(tfp, parms) do { \
+ if ((parms) == NULL || (tfp) == NULL) { \
+ TFP_DRV_LOG(ERR, "Invalid Argument(s)\n"); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
+#define TF_CHECK_TFP_SESSION(tfp) do { \
+ if ((tfp) == NULL) { \
+ TFP_DRV_LOG(ERR, "Invalid Argument(s)\n"); \
+ return -EINVAL; \
+ } \
+ if ((tfp)->session == NULL || \
+ (tfp)->session->core_data == NULL) { \
+ TFP_DRV_LOG(ERR, "Session error\n"); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
+#endif /* _TF_COMMON_H_ */
#include "bitalloc.h"
#include "bnxt.h"
#include "rand.h"
+#include "tf_common.h"
+#include "hwrm_tf.h"
static inline uint32_t SWAP_WORDS32(uint32_t val32)
{
*/
uint8_t *data;
/**
- * [out] Entry size
+ * [in] Entry size
*/
uint16_t data_sz_in_bytes;
/**
int tf_get_tbl_entry(struct tf *tfp,
struct tf_get_tbl_entry_parms *parms);
+/**
+ * tf_get_bulk_tbl_entry parameter definition
+ */
+struct tf_get_bulk_tbl_entry_parms {
+ /**
+ * [in] Receive or transmit direction
+ */
+ enum tf_dir dir;
+ /**
+ * [in] Type of object to get
+ */
+ enum tf_tbl_type type;
+ /**
+ * [in] Clear hardware entries on reads only
+ * supported for TF_TBL_TYPE_ACT_STATS_64
+ */
+ bool clear_on_read;
+ /**
+ * [in] Starting index to read from
+ */
+ uint32_t starting_idx;
+ /**
+ * [in] Number of sequential entries
+ */
+ uint16_t num_entries;
+ /**
+ * [in] Size of the single entry
+ */
+ uint16_t entry_sz_in_bytes;
+ /**
+ * [out] Host physical address, where the data
+ * will be copied to by the firmware.
+ * Use tfp_calloc() API and mem_pa
+ * variable of the tfp_calloc_parms
+ * structure for the physical address.
+ */
+ uint64_t physical_mem_addr;
+};
+
+/**
+ * Bulk get index table entry
+ *
+ * Used to retrieve a previous set index table entry.
+ *
+ * Reads and compares with the shadow table copy (if enabled) (only
+ * for internal objects).
+ *
+ * Returns success or failure code. Failure will be returned if the
+ * provided data buffer is too small for the data type requested.
+ */
+int tf_get_bulk_tbl_entry(struct tf *tfp,
+ struct tf_get_bulk_tbl_entry_parms *parms);
+
/**
* @page exact_match Exact Match Table
*
return tfp_le_to_cpu_32(parms.tf_resp_code);
}
-#define TF_BYTES_PER_SLICE(tfp) 12
-#define NUM_SLICES(tfp, bytes) \
- (((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp))
-
static int
-tf_msg_get_dma_buf(struct tf_msg_dma_buf *buf, int size)
+tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size)
{
struct tfp_calloc_parms alloc_parms;
int rc;
/* Allocate session */
alloc_parms.nitems = 1;
alloc_parms.size = size;
- alloc_parms.alignment = 0;
+ alloc_parms.alignment = 4096;
rc = tfp_calloc(&alloc_parms);
- if (rc) {
- /* Log error */
- PMD_DRV_LOG(ERR,
- "Failed to allocate tcam dma entry, rc:%d\n",
- rc);
+ if (rc)
return -ENOMEM;
- }
buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
buf->va_addr = alloc_parms.mem_va;
return 0;
}
+int
+tf_msg_get_bulk_tbl_entry(struct tf *tfp,
+ struct tf_get_bulk_tbl_entry_parms *params)
+{
+ int rc;
+ struct tfp_send_msg_parms parms = { 0 };
+ struct tf_tbl_type_get_bulk_input req = { 0 };
+ struct tf_tbl_type_get_bulk_output resp = { 0 };
+ struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+ int data_size = 0;
+
+ /* Populate the request */
+ req.fw_session_id =
+ tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+ req.flags = tfp_cpu_to_le_16((params->dir) |
+ ((params->clear_on_read) ?
+ TF_TBL_TYPE_GET_BULK_INPUT_FLAGS_CLEAR_ON_READ : 0x0));
+ req.type = tfp_cpu_to_le_32(params->type);
+ req.start_index = tfp_cpu_to_le_32(params->starting_idx);
+ req.num_entries = tfp_cpu_to_le_32(params->num_entries);
+
+ data_size = (params->num_entries * params->entry_sz_in_bytes);
+ req.host_addr = tfp_cpu_to_le_64(params->physical_mem_addr);
+
+ MSG_PREP(parms,
+ TF_KONG_MB,
+ HWRM_TF,
+ HWRM_TFT_TBL_TYPE_GET_BULK,
+ req,
+ resp);
+
+ rc = tfp_send_msg_tunneled(tfp, &parms);
+ if (rc)
+ return rc;
+
+ /* Verify that we got enough buffer to return the requested data */
+ if (resp.size < data_size)
+ return -EINVAL;
+
+ return tfp_le_to_cpu_32(parms.tf_resp_code);
+}
+
+#define TF_BYTES_PER_SLICE(tfp) 12
+#define NUM_SLICES(tfp, bytes) \
+ (((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp))
+
int
tf_msg_tcam_entry_set(struct tf *tfp,
struct tf_set_tcam_entry_parms *parms)
} else {
/* use dma buffer */
req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA;
- rc = tf_msg_get_dma_buf(&buf, data_size);
- if (rc != 0)
- return rc;
+ rc = tf_msg_alloc_dma_buf(&buf, data_size);
+ if (rc)
+ goto cleanup;
data = buf.va_addr;
memcpy(&req.dev_data[0], &buf.pa_addr, sizeof(buf.pa_addr));
}
rc = tfp_send_msg_direct(tfp,
&mparms);
if (rc)
- return rc;
+ goto cleanup;
+cleanup:
if (buf.va_addr != NULL)
tfp_free(buf.va_addr);
uint8_t *data,
uint32_t index);
+/**
+ * Sends bulk get message of a Table Type element to the firmware.
+ *
+ * [in] tfp
+ * Pointer to session handle
+ *
+ * [in] parms
+ * Pointer to table get bulk parameters
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
+ */
+int tf_msg_get_bulk_tbl_entry(struct tf *tfp,
+ struct tf_get_bulk_tbl_entry_parms *parms);
+
#endif /* _TF_MSG_H_ */
#define TF_RSVD_METER_INST_END_IDX_TX 0
/* Mirror */
-/* Not yet supported fully in the infra */
-#define TF_RSVD_MIRROR_RX 0
+#define TF_RSVD_MIRROR_RX 1
#define TF_RSVD_MIRROR_BEGIN_IDX_RX 0
#define TF_RSVD_MIRROR_END_IDX_RX 0
-#define TF_RSVD_MIRROR_TX 0
+#define TF_RSVD_MIRROR_TX 1
#define TF_RSVD_MIRROR_BEGIN_IDX_TX 0
#define TF_RSVD_MIRROR_END_IDX_TX 0
#include "bnxt.h"
#include "tf_resources.h"
#include "tf_rm.h"
+#include "tf_common.h"
#define PTU_PTE_VALID 0x1UL
#define PTU_PTE_LAST 0x2UL
if (parms->type != TF_TBL_TYPE_FULL_ACT_RECORD &&
parms->type != TF_TBL_TYPE_ACT_SP_SMAC_IPV4 &&
+ parms->type != TF_TBL_TYPE_MIRROR_CONFIG &&
parms->type != TF_TBL_TYPE_ACT_STATS_64) {
PMD_DRV_LOG(ERR,
"dir:%d, Type not supported, type:%d\n",
return rc;
}
+/**
+ * Internal function to get a Table Entry. Supports all Table Types
+ * except the TF_TBL_TYPE_EXT as that is handled as a table scope.
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+static int
+tf_get_bulk_tbl_entry_internal(struct tf *tfp,
+ struct tf_get_bulk_tbl_entry_parms *parms)
+{
+ int rc;
+ int id;
+ uint32_t index;
+ struct bitalloc *session_pool;
+ struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+
+ /* Lookup the pool using the table type of the element */
+ rc = tf_rm_lookup_tbl_type_pool(tfs,
+ parms->dir,
+ parms->type,
+ &session_pool);
+ /* Error logging handled by tf_rm_lookup_tbl_type_pool */
+ if (rc)
+ return rc;
+
+ index = parms->starting_idx;
+
+ /*
+ * Adjust the returned index/offset as there is no guarantee
+ * that the start is 0 at time of RM allocation
+ */
+ tf_rm_convert_index(tfs,
+ parms->dir,
+ parms->type,
+ TF_RM_CONVERT_RM_BASE,
+ parms->starting_idx,
+ &index);
+
+ /* Verify that the entry has been previously allocated */
+ id = ba_inuse(session_pool, index);
+ if (id != 1) {
+ TFP_DRV_LOG(ERR,
+ "%s, Invalid or not allocated index, type:%d, starting_idx:%d\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ index);
+ return -EINVAL;
+ }
+
+ /* Get the entry */
+ rc = tf_msg_get_bulk_tbl_entry(tfp, parms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s, Bulk get failed, type:%d, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ strerror(-rc));
+ }
+
+ return rc;
+}
+
#if (TF_SHADOW == 1)
/**
* Allocate Tbl entry from the Shadow DB. Shadow DB is searched for
parms->type != TF_TBL_TYPE_ACT_ENCAP_8B &&
parms->type != TF_TBL_TYPE_ACT_ENCAP_16B &&
parms->type != TF_TBL_TYPE_ACT_ENCAP_64B &&
+ parms->type != TF_TBL_TYPE_MIRROR_CONFIG &&
parms->type != TF_TBL_TYPE_ACT_STATS_64) {
PMD_DRV_LOG(ERR,
"dir:%d, Type not supported, type:%d\n",
return rc;
}
+/* API defined in tf_core.h */
+int
+tf_get_bulk_tbl_entry(struct tf *tfp,
+ struct tf_get_bulk_tbl_entry_parms *parms)
+{
+ int rc = 0;
+
+ TF_CHECK_PARMS_SESSION(tfp, parms);
+
+ if (parms->type == TF_TBL_TYPE_EXT) {
+ /* Not supported, yet */
+ TFP_DRV_LOG(ERR,
+ "%s, External table type not supported\n",
+ tf_dir_2_str(parms->dir));
+
+ rc = -EOPNOTSUPP;
+ } else {
+ /* Internal table type processing */
+ rc = tf_get_bulk_tbl_entry_internal(tfp, parms);
+ if (rc)
+ TFP_DRV_LOG(ERR,
+ "%s, Bulk get failed, type:%d, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ strerror(-rc));
+ }
+
+ return rc;
+}
+
/* API defined in tf_core.h */
int
tf_alloc_tbl_scope(struct tf *tfp,