net/bnxt: support TruFlow core TCAM
- Add TruFlow TCAM public API functions - Add TCAM support functions as well as public APIs. Signed-off-by: Shahaji Bhosle <sbhosle@broadcom.com> Signed-off-by: Jay Ding <jay.ding@broadcom.com> Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com> Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
This commit is contained in:
parent
6cf2f95d4d
commit
82fa189de8
@ -440,3 +440,166 @@ int tf_free_identifier(struct tf *tfp,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tf_alloc_tcam_entry(struct tf *tfp,
|
||||
struct tf_alloc_tcam_entry_parms *parms)
|
||||
{
|
||||
int rc;
|
||||
int index;
|
||||
struct tf_session *tfs;
|
||||
struct bitalloc *session_pool;
|
||||
|
||||
if (parms == NULL || tfp == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (tfp->session == NULL || tfp->session->core_data == NULL) {
|
||||
PMD_DRV_LOG(ERR, "%s: session error\n",
|
||||
tf_dir_2_str(parms->dir));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tfs = (struct tf_session *)(tfp->session->core_data);
|
||||
|
||||
rc = tf_rm_lookup_tcam_type_pool(tfs,
|
||||
parms->dir,
|
||||
parms->tcam_tbl_type,
|
||||
&session_pool);
|
||||
/* Error logging handled by tf_rm_lookup_tcam_type_pool */
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
index = ba_alloc(session_pool);
|
||||
if (index == BA_FAIL) {
|
||||
PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
|
||||
tf_dir_2_str(parms->dir),
|
||||
tf_tcam_tbl_2_str(parms->tcam_tbl_type));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
parms->idx = index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tf_set_tcam_entry(struct tf *tfp,
|
||||
struct tf_set_tcam_entry_parms *parms)
|
||||
{
|
||||
int rc;
|
||||
int id;
|
||||
struct tf_session *tfs;
|
||||
struct bitalloc *session_pool;
|
||||
|
||||
if (tfp == NULL || parms == NULL) {
|
||||
PMD_DRV_LOG(ERR, "Invalid parameters\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tfp->session == NULL || tfp->session->core_data == NULL) {
|
||||
PMD_DRV_LOG(ERR,
|
||||
"%s, Session info invalid\n",
|
||||
tf_dir_2_str(parms->dir));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tfs = (struct tf_session *)(tfp->session->core_data);
|
||||
|
||||
/*
|
||||
* Each tcam send msg function should check for key sizes range
|
||||
*/
|
||||
|
||||
rc = tf_rm_lookup_tcam_type_pool(tfs,
|
||||
parms->dir,
|
||||
parms->tcam_tbl_type,
|
||||
&session_pool);
|
||||
/* Error logging handled by tf_rm_lookup_tcam_type_pool */
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
/* Verify that the entry has been previously allocated */
|
||||
id = ba_inuse(session_pool, parms->idx);
|
||||
if (id != 1) {
|
||||
PMD_DRV_LOG(ERR,
|
||||
"%s: %s: Invalid or not allocated index, idx:%d\n",
|
||||
tf_dir_2_str(parms->dir),
|
||||
tf_tcam_tbl_2_str(parms->tcam_tbl_type),
|
||||
parms->idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = tf_msg_tcam_entry_set(tfp, parms);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tf_get_tcam_entry(struct tf *tfp __rte_unused,
|
||||
struct tf_get_tcam_entry_parms *parms __rte_unused)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
if (tfp == NULL || parms == NULL) {
|
||||
PMD_DRV_LOG(ERR, "Invalid parameters\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tfp->session == NULL || tfp->session->core_data == NULL) {
|
||||
PMD_DRV_LOG(ERR,
|
||||
"%s, Session info invalid\n",
|
||||
tf_dir_2_str(parms->dir));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tf_free_tcam_entry(struct tf *tfp,
|
||||
struct tf_free_tcam_entry_parms *parms)
|
||||
{
|
||||
int rc;
|
||||
struct tf_session *tfs;
|
||||
struct bitalloc *session_pool;
|
||||
|
||||
if (parms == NULL || tfp == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (tfp->session == NULL || tfp->session->core_data == NULL) {
|
||||
PMD_DRV_LOG(ERR, "%s: Session error\n",
|
||||
tf_dir_2_str(parms->dir));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tfs = (struct tf_session *)(tfp->session->core_data);
|
||||
|
||||
rc = tf_rm_lookup_tcam_type_pool(tfs,
|
||||
parms->dir,
|
||||
parms->tcam_tbl_type,
|
||||
&session_pool);
|
||||
/* Error logging handled by tf_rm_lookup_tcam_type_pool */
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = ba_inuse(session_pool, (int)parms->idx);
|
||||
if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
|
||||
PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
|
||||
tf_dir_2_str(parms->dir),
|
||||
tf_tcam_tbl_2_str(parms->tcam_tbl_type),
|
||||
parms->idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ba_free(session_pool, (int)parms->idx);
|
||||
|
||||
rc = tf_msg_tcam_entry_free(tfp, parms);
|
||||
if (rc) {
|
||||
/* Log error */
|
||||
PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
|
||||
tf_dir_2_str(parms->dir),
|
||||
tf_tcam_tbl_2_str(parms->tcam_tbl_type),
|
||||
parms->idx);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -471,6 +471,233 @@ enum tf_tcam_tbl_type {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @page tcam TCAM Access
|
||||
*
|
||||
* @ref tf_alloc_tcam_entry
|
||||
*
|
||||
* @ref tf_set_tcam_entry
|
||||
*
|
||||
* @ref tf_get_tcam_entry
|
||||
*
|
||||
* @ref tf_free_tcam_entry
|
||||
*/
|
||||
|
||||
/** tf_alloc_tcam_entry parameter definition
|
||||
*/
|
||||
struct tf_alloc_tcam_entry_parms {
|
||||
/**
|
||||
* [in] receive or transmit direction
|
||||
*/
|
||||
enum tf_dir dir;
|
||||
/**
|
||||
* [in] TCAM table type
|
||||
*/
|
||||
enum tf_tcam_tbl_type tcam_tbl_type;
|
||||
/**
|
||||
* [in] Enable search for matching entry
|
||||
*/
|
||||
uint8_t search_enable;
|
||||
/**
|
||||
* [in] Key data to match on (if search)
|
||||
*/
|
||||
uint8_t *key;
|
||||
/**
|
||||
* [in] key size in bits (if search)
|
||||
*/
|
||||
uint16_t key_sz_in_bits;
|
||||
/**
|
||||
* [in] Mask data to match on (if search)
|
||||
*/
|
||||
uint8_t *mask;
|
||||
/**
|
||||
* [in] Priority of entry requested (definition TBD)
|
||||
*/
|
||||
uint32_t priority;
|
||||
/**
|
||||
* [out] If search, set if matching entry found
|
||||
*/
|
||||
uint8_t hit;
|
||||
/**
|
||||
* [out] Current refcnt after allocation
|
||||
*/
|
||||
uint16_t ref_cnt;
|
||||
/**
|
||||
* [out] Idx allocated
|
||||
*
|
||||
*/
|
||||
uint16_t idx;
|
||||
};
|
||||
|
||||
/** allocate TCAM entry
|
||||
*
|
||||
* Allocate a TCAM entry - one of these types:
|
||||
*
|
||||
* L2 Context
|
||||
* Profile TCAM
|
||||
* WC TCAM
|
||||
* VEB TCAM
|
||||
*
|
||||
* This function allocates a TCAM table record. This function
|
||||
* will attempt to allocate a TCAM table entry from the session
|
||||
* owned TCAM entries or search a shadow copy of the TCAM table for a
|
||||
* matching entry if search is enabled. Key, mask and result must match for
|
||||
* hit to be set. Only TruFlow core data is accessed.
|
||||
* A hash table to entry mapping is maintained for search purposes. If
|
||||
* search is not enabled, the first available free entry is returned based
|
||||
* on priority and alloc_cnt is set to 1. If search is enabled and a matching
|
||||
* entry to entry_data is found, hit is set to TRUE and alloc_cnt is set to 1.
|
||||
* RefCnt is also returned.
|
||||
*
|
||||
* Also returns success or failure code.
|
||||
*/
|
||||
int tf_alloc_tcam_entry(struct tf *tfp,
|
||||
struct tf_alloc_tcam_entry_parms *parms);
|
||||
|
||||
/** tf_set_tcam_entry parameter definition
|
||||
*/
|
||||
struct tf_set_tcam_entry_parms {
|
||||
/**
|
||||
* [in] receive or transmit direction
|
||||
*/
|
||||
enum tf_dir dir;
|
||||
/**
|
||||
* [in] TCAM table type
|
||||
*/
|
||||
enum tf_tcam_tbl_type tcam_tbl_type;
|
||||
/**
|
||||
* [in] base index of the entry to program
|
||||
*/
|
||||
uint16_t idx;
|
||||
/**
|
||||
* [in] struct containing key
|
||||
*/
|
||||
uint8_t *key;
|
||||
/**
|
||||
* [in] struct containing mask fields
|
||||
*/
|
||||
uint8_t *mask;
|
||||
/**
|
||||
* [in] key size in bits (if search)
|
||||
*/
|
||||
uint16_t key_sz_in_bits;
|
||||
/**
|
||||
* [in] struct containing result
|
||||
*/
|
||||
uint8_t *result;
|
||||
/**
|
||||
* [in] struct containing result size in bits
|
||||
*/
|
||||
uint16_t result_sz_in_bits;
|
||||
};
|
||||
|
||||
/** set TCAM entry
|
||||
*
|
||||
* Program a TCAM table entry for a TruFlow session.
|
||||
*
|
||||
* If the entry has not been allocated, an error will be returned.
|
||||
*
|
||||
* Returns success or failure code.
|
||||
*/
|
||||
int tf_set_tcam_entry(struct tf *tfp,
|
||||
struct tf_set_tcam_entry_parms *parms);
|
||||
|
||||
/** tf_get_tcam_entry parameter definition
|
||||
*/
|
||||
struct tf_get_tcam_entry_parms {
|
||||
/**
|
||||
* [in] receive or transmit direction
|
||||
*/
|
||||
enum tf_dir dir;
|
||||
/**
|
||||
* [in] TCAM table type
|
||||
*/
|
||||
enum tf_tcam_tbl_type tcam_tbl_type;
|
||||
/**
|
||||
* [in] index of the entry to get
|
||||
*/
|
||||
uint16_t idx;
|
||||
/**
|
||||
* [out] struct containing key
|
||||
*/
|
||||
uint8_t *key;
|
||||
/**
|
||||
* [out] struct containing mask fields
|
||||
*/
|
||||
uint8_t *mask;
|
||||
/**
|
||||
* [out] key size in bits
|
||||
*/
|
||||
uint16_t key_sz_in_bits;
|
||||
/**
|
||||
* [out] struct containing result
|
||||
*/
|
||||
uint8_t *result;
|
||||
/**
|
||||
* [out] struct containing result size in bits
|
||||
*/
|
||||
uint16_t result_sz_in_bits;
|
||||
};
|
||||
|
||||
/** get TCAM entry
|
||||
*
|
||||
* Program a TCAM table entry for a TruFlow session.
|
||||
*
|
||||
* If the entry has not been allocated, an error will be returned.
|
||||
*
|
||||
* Returns success or failure code.
|
||||
*/
|
||||
int tf_get_tcam_entry(struct tf *tfp,
|
||||
struct tf_get_tcam_entry_parms *parms);
|
||||
|
||||
/** tf_free_tcam_entry parameter definition
|
||||
*/
|
||||
struct tf_free_tcam_entry_parms {
|
||||
/**
|
||||
* [in] receive or transmit direction
|
||||
*/
|
||||
enum tf_dir dir;
|
||||
/**
|
||||
* [in] TCAM table type
|
||||
*/
|
||||
enum tf_tcam_tbl_type tcam_tbl_type;
|
||||
/**
|
||||
* [in] Index to free
|
||||
*/
|
||||
uint16_t idx;
|
||||
/**
|
||||
* [out] reference count after free
|
||||
*/
|
||||
uint16_t ref_cnt;
|
||||
};
|
||||
|
||||
/** free TCAM entry
|
||||
*
|
||||
* Free TCAM entry.
|
||||
*
|
||||
* Firmware checks to ensure the TCAM entries are owned by the TruFlow
|
||||
* session. TCAM entry will be invalidated. All-ones mask.
|
||||
* writes to hw.
|
||||
*
|
||||
* WCTCAM profile id of 0 must be used to invalidate an entry.
|
||||
*
|
||||
* Returns success or failure code.
|
||||
*/
|
||||
int tf_free_tcam_entry(struct tf *tfp,
|
||||
struct tf_free_tcam_entry_parms *parms);
|
||||
|
||||
/**
|
||||
* @page table Table Access
|
||||
*
|
||||
* @ref tf_alloc_tbl_entry
|
||||
*
|
||||
* @ref tf_free_tbl_entry
|
||||
*
|
||||
* @ref tf_set_tbl_entry
|
||||
*
|
||||
* @ref tf_get_tbl_entry
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumeration of TruFlow table types. A table type is used to identify a
|
||||
* resource object.
|
||||
|
@ -106,6 +106,39 @@ struct tf_msg_dma_buf {
|
||||
uint64_t pa_addr;
|
||||
};
|
||||
|
||||
static int
|
||||
tf_tcam_tbl_2_hwrm(enum tf_tcam_tbl_type tcam_type,
|
||||
uint32_t *hwrm_type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (tcam_type) {
|
||||
case TF_TCAM_TBL_TYPE_L2_CTXT_TCAM:
|
||||
*hwrm_type = TF_DEV_DATA_TYPE_TF_L2_CTX_ENTRY;
|
||||
break;
|
||||
case TF_TCAM_TBL_TYPE_PROF_TCAM:
|
||||
*hwrm_type = TF_DEV_DATA_TYPE_TF_PROF_TCAM_ENTRY;
|
||||
break;
|
||||
case TF_TCAM_TBL_TYPE_WC_TCAM:
|
||||
*hwrm_type = TF_DEV_DATA_TYPE_TF_WC_ENTRY;
|
||||
break;
|
||||
case TF_TCAM_TBL_TYPE_VEB_TCAM:
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
case TF_TCAM_TBL_TYPE_SP_TCAM:
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
case TF_TCAM_TBL_TYPE_CT_RULE_TCAM:
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
default:
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends session open request to TF Firmware
|
||||
*/
|
||||
@ -835,3 +868,129 @@ tf_msg_session_sram_resc_flush(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)
|
||||
{
|
||||
struct tfp_calloc_parms alloc_parms;
|
||||
int rc;
|
||||
|
||||
/* Allocate session */
|
||||
alloc_parms.nitems = 1;
|
||||
alloc_parms.size = size;
|
||||
alloc_parms.alignment = 0;
|
||||
rc = tfp_calloc(&alloc_parms);
|
||||
if (rc) {
|
||||
/* Log error */
|
||||
PMD_DRV_LOG(ERR,
|
||||
"Failed to allocate tcam dma entry, rc:%d\n",
|
||||
rc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buf->pa_addr = (uintptr_t)alloc_parms.mem_pa;
|
||||
buf->va_addr = alloc_parms.mem_va;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tf_msg_tcam_entry_set(struct tf *tfp,
|
||||
struct tf_set_tcam_entry_parms *parms)
|
||||
{
|
||||
int rc;
|
||||
struct tfp_send_msg_parms mparms = { 0 };
|
||||
struct hwrm_tf_tcam_set_input req = { 0 };
|
||||
struct hwrm_tf_tcam_set_output resp = { 0 };
|
||||
uint16_t key_bytes =
|
||||
TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits);
|
||||
uint16_t result_bytes =
|
||||
TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits);
|
||||
struct tf_msg_dma_buf buf = { 0 };
|
||||
uint8_t *data = NULL;
|
||||
int data_size = 0;
|
||||
|
||||
rc = tf_tcam_tbl_2_hwrm(parms->tcam_tbl_type, &req.type);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
req.idx = tfp_cpu_to_le_16(parms->idx);
|
||||
if (parms->dir == TF_DIR_TX)
|
||||
req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX;
|
||||
|
||||
req.key_size = key_bytes;
|
||||
req.mask_offset = key_bytes;
|
||||
/* Result follows after key and mask, thus multiply by 2 */
|
||||
req.result_offset = 2 * key_bytes;
|
||||
req.result_size = result_bytes;
|
||||
data_size = 2 * req.key_size + req.result_size;
|
||||
|
||||
if (data_size <= TF_PCI_BUF_SIZE_MAX) {
|
||||
/* use pci buffer */
|
||||
data = &req.dev_data[0];
|
||||
} 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;
|
||||
data = buf.va_addr;
|
||||
memcpy(&req.dev_data[0], &buf.pa_addr, sizeof(buf.pa_addr));
|
||||
}
|
||||
|
||||
memcpy(&data[0], parms->key, key_bytes);
|
||||
memcpy(&data[key_bytes], parms->mask, key_bytes);
|
||||
memcpy(&data[req.result_offset], parms->result, result_bytes);
|
||||
|
||||
mparms.tf_type = HWRM_TF_TCAM_SET;
|
||||
mparms.req_data = (uint32_t *)&req;
|
||||
mparms.req_size = sizeof(req);
|
||||
mparms.resp_data = (uint32_t *)&resp;
|
||||
mparms.resp_size = sizeof(resp);
|
||||
mparms.mailbox = TF_KONG_MB;
|
||||
|
||||
rc = tfp_send_msg_direct(tfp,
|
||||
&mparms);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (buf.va_addr != NULL)
|
||||
tfp_free(buf.va_addr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tf_msg_tcam_entry_free(struct tf *tfp,
|
||||
struct tf_free_tcam_entry_parms *in_parms)
|
||||
{
|
||||
int rc;
|
||||
struct hwrm_tf_tcam_free_input req = { 0 };
|
||||
struct hwrm_tf_tcam_free_output resp = { 0 };
|
||||
struct tfp_send_msg_parms parms = { 0 };
|
||||
|
||||
/* Populate the request */
|
||||
rc = tf_tcam_tbl_2_hwrm(in_parms->tcam_tbl_type, &req.type);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
req.count = 1;
|
||||
req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx);
|
||||
if (in_parms->dir == TF_DIR_TX)
|
||||
req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX;
|
||||
|
||||
parms.tf_type = HWRM_TF_TCAM_FREE;
|
||||
parms.req_data = (uint32_t *)&req;
|
||||
parms.req_size = sizeof(req);
|
||||
parms.resp_data = (uint32_t *)&resp;
|
||||
parms.resp_size = sizeof(resp);
|
||||
parms.mailbox = TF_KONG_MB;
|
||||
|
||||
rc = tfp_send_msg_direct(tfp,
|
||||
&parms);
|
||||
return rc;
|
||||
}
|
||||
|
@ -120,4 +120,34 @@ int tf_msg_session_sram_resc_flush(struct tf *tfp,
|
||||
enum tf_dir dir,
|
||||
struct tf_rm_entry *sram_entry);
|
||||
|
||||
/**
|
||||
* Sends tcam entry 'set' to the Firmware.
|
||||
*
|
||||
* [in] tfp
|
||||
* Pointer to session handle
|
||||
*
|
||||
* [in] parms
|
||||
* Pointer to set parameters
|
||||
*
|
||||
* Returns:
|
||||
* 0 on Success else internal Truflow error
|
||||
*/
|
||||
int tf_msg_tcam_entry_set(struct tf *tfp,
|
||||
struct tf_set_tcam_entry_parms *parms);
|
||||
|
||||
/**
|
||||
* Sends tcam entry 'free' to the Firmware.
|
||||
*
|
||||
* [in] tfp
|
||||
* Pointer to session handle
|
||||
*
|
||||
* [in] parms
|
||||
* Pointer to free parameters
|
||||
*
|
||||
* Returns:
|
||||
* 0 on Success else internal Truflow error
|
||||
*/
|
||||
int tf_msg_tcam_entry_free(struct tf *tfp,
|
||||
struct tf_free_tcam_entry_parms *parms);
|
||||
|
||||
#endif /* _TF_MSG_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user