net/bnxt: support bulk table get and mirror
- Add new bulk table type get using FW to DMA the data back to host. - Add flag to allow records to be cleared if possible - Set mirror using tf_alloc_tbl_entry Signed-off-by: Shahaji Bhosle <sbhosle@broadcom.com> Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com> Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
This commit is contained in:
parent
8187694b15
commit
8c37258d78
@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2019 Broadcom
|
||||
* Copyright(c) 2019-2020 Broadcom
|
||||
* All rights reserved.
|
||||
*/
|
||||
#ifndef _HWRM_TF_H_
|
||||
@ -27,7 +27,8 @@ typedef enum tf_subtype {
|
||||
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 */
|
||||
@ -81,6 +82,8 @@ struct tf_session_sram_resc_flush_input;
|
||||
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 */
|
||||
@ -902,6 +905,8 @@ typedef struct tf_tbl_type_get_input {
|
||||
#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 */
|
||||
@ -916,4 +921,32 @@ typedef struct tf_tbl_type_get_output {
|
||||
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_ */
|
||||
|
54
drivers/net/bnxt/tf_core/tf_common.h
Normal file
54
drivers/net/bnxt/tf_core/tf_common.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* 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_ */
|
@ -16,6 +16,8 @@
|
||||
#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)
|
||||
{
|
||||
|
@ -1165,7 +1165,7 @@ struct tf_get_tbl_entry_parms {
|
||||
*/
|
||||
uint8_t *data;
|
||||
/**
|
||||
* [out] Entry size
|
||||
* [in] Entry size
|
||||
*/
|
||||
uint16_t data_sz_in_bytes;
|
||||
/**
|
||||
@ -1188,6 +1188,59 @@ struct tf_get_tbl_entry_parms {
|
||||
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
|
||||
*
|
||||
|
@ -1216,12 +1216,8 @@ tf_msg_get_tbl_entry(struct tf *tfp,
|
||||
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;
|
||||
@ -1229,15 +1225,10 @@ tf_msg_get_dma_buf(struct tf_msg_dma_buf *buf, int size)
|
||||
/* 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;
|
||||
@ -1245,6 +1236,52 @@ tf_msg_get_dma_buf(struct tf_msg_dma_buf *buf, int size)
|
||||
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)
|
||||
@ -1282,9 +1319,9 @@ tf_msg_tcam_entry_set(struct tf *tfp,
|
||||
} 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));
|
||||
}
|
||||
@ -1303,8 +1340,9 @@ tf_msg_tcam_entry_set(struct tf *tfp,
|
||||
rc = tfp_send_msg_direct(tfp,
|
||||
&mparms);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
if (buf.va_addr != NULL)
|
||||
tfp_free(buf.va_addr);
|
||||
|
||||
|
@ -267,4 +267,19 @@ int tf_msg_get_tbl_entry(struct tf *tfp,
|
||||
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_ */
|
||||
|
@ -149,11 +149,10 @@
|
||||
#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
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#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
|
||||
@ -794,6 +795,7 @@ tf_set_tbl_entry_internal(struct tf *tfp,
|
||||
|
||||
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",
|
||||
@ -915,6 +917,76 @@ tf_get_tbl_entry_internal(struct tf *tfp,
|
||||
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
|
||||
@ -1182,6 +1254,7 @@ tf_alloc_tbl_entry_pool_internal(struct tf *tfp,
|
||||
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",
|
||||
@ -1663,6 +1736,36 @@ tf_get_tbl_entry(struct tf *tfp,
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user