'tf_core/tf_msg.c',
'tf_core/rand.c',
'tf_core/stack.c',
- 'tf_core/tf_em.c',
+ 'tf_core/tf_em_common.c',
+ 'tf_core/tf_em_host.c',
+ 'tf_core/tf_em_internal.c',
+ 'tf_core/tf_em_system.c',
'tf_core/tf_rm.c',
'tf_core/tf_tbl.c',
'tf_core/tfp.c',
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_rm.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tfp.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_msg.c
-SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_tbl.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_internal.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_host.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_em_system.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_session.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_core/tf_device_p4.c
#define CFA_RESOURCE_TYPE_P45_SP_TCAM 0x1fUL
/* VEB TCAM */
#define CFA_RESOURCE_TYPE_P45_VEB_TCAM 0x20UL
-#define CFA_RESOURCE_TYPE_P45_LAST CFA_RESOURCE_TYPE_P45_VEB_TCAM
+/* Table Scope */
+#define CFA_RESOURCE_TYPE_P45_TBL_SCOPE 0x21UL
+#define CFA_RESOURCE_TYPE_P45_LAST CFA_RESOURCE_TYPE_P45_TBL_SCOPE
/* Multicast Group */
#define CFA_RESOURCE_TYPE_P4_MIRROR 0x1eUL
/* Source Property TCAM */
#define CFA_RESOURCE_TYPE_P4_SP_TCAM 0x1fUL
-#define CFA_RESOURCE_TYPE_P4_LAST CFA_RESOURCE_TYPE_P4_SP_TCAM
+/* Table Scope */
+#define CFA_RESOURCE_TYPE_P4_TBL_SCOPE 0x20UL
+#define CFA_RESOURCE_TYPE_P4_LAST CFA_RESOURCE_TYPE_P4_TBL_SCOPE
#endif /* _CFA_RESOURCE_TYPES_H_ */
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2020 Broadcom
+ * Copyright(c) 2019 Broadcom
* All rights reserved.
*/
#ifndef _HWRM_TF_H_
} tf_type_t;
typedef enum tf_subtype {
- HWRM_TFT_SESSION_ATTACH = 712,
- HWRM_TFT_SESSION_HW_RESC_QCAPS = 721,
- HWRM_TFT_SESSION_HW_RESC_ALLOC = 722,
- HWRM_TFT_SESSION_HW_RESC_FREE = 723,
- HWRM_TFT_SESSION_HW_RESC_FLUSH = 724,
- HWRM_TFT_SESSION_SRAM_RESC_QCAPS = 725,
- HWRM_TFT_SESSION_SRAM_RESC_ALLOC = 726,
- HWRM_TFT_SESSION_SRAM_RESC_FREE = 727,
- HWRM_TFT_SESSION_SRAM_RESC_FLUSH = 728,
- HWRM_TFT_TBL_SCOPE_CFG = 731,
HWRM_TFT_REG_GET = 821,
HWRM_TFT_REG_SET = 822,
- HWRM_TFT_TBL_TYPE_SET = 823,
- HWRM_TFT_TBL_TYPE_GET = 824,
HWRM_TFT_TBL_TYPE_BULK_GET = 825,
TF_SUBTYPE_LAST = HWRM_TFT_TBL_TYPE_BULK_GET,
} tf_subtype_t;
#define TF_BITS2BYTES(x) (((x) + 7) >> 3)
#define TF_BITS2BYTES_WORD_ALIGN(x) ((((x) + 31) >> 5) * 4)
-struct tf_session_attach_input;
-struct tf_session_hw_resc_qcaps_input;
-struct tf_session_hw_resc_qcaps_output;
-struct tf_session_hw_resc_alloc_input;
-struct tf_session_hw_resc_alloc_output;
-struct tf_session_hw_resc_free_input;
-struct tf_session_hw_resc_flush_input;
-struct tf_session_sram_resc_qcaps_input;
-struct tf_session_sram_resc_qcaps_output;
-struct tf_session_sram_resc_alloc_input;
-struct tf_session_sram_resc_alloc_output;
-struct tf_session_sram_resc_free_input;
-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_bulk_get_input;
struct tf_tbl_type_bulk_get_output;
-/* Input params for session attach */
-typedef struct tf_session_attach_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* Session Name */
- char session_name[TF_SESSION_NAME_MAX];
-} tf_session_attach_input_t, *ptf_session_attach_input_t;
-
-/* Input params for session resource HW qcaps */
-typedef struct tf_session_hw_resc_qcaps_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_QCAPS_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_QCAPS_INPUT_FLAGS_DIR_TX (0x1)
-} tf_session_hw_resc_qcaps_input_t, *ptf_session_hw_resc_qcaps_input_t;
-
-/* Output params for session resource HW qcaps */
-typedef struct tf_session_hw_resc_qcaps_output {
- /* Control Flags */
- uint32_t flags;
- /* When set to 0, indicates Static partitioning */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_STATIC (0x0)
- /* When set to 1, indicates Strategy 1 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_1 (0x1)
- /* When set to 1, indicates Strategy 2 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_2 (0x2)
- /* When set to 1, indicates Strategy 3 */
-#define TF_SESSION_HW_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_3 (0x3)
- /* Unused */
- uint8_t unused[4];
- /* Minimum guaranteed number of L2 Ctx */
- uint16_t l2_ctx_tcam_entries_min;
- /* Maximum non-guaranteed number of L2 Ctx */
- uint16_t l2_ctx_tcam_entries_max;
- /* Minimum guaranteed number of profile functions */
- uint16_t prof_func_min;
- /* Maximum non-guaranteed number of profile functions */
- uint16_t prof_func_max;
- /* Minimum guaranteed number of profile TCAM entries */
- uint16_t prof_tcam_entries_min;
- /* Maximum non-guaranteed number of profile TCAM entries */
- uint16_t prof_tcam_entries_max;
- /* Minimum guaranteed number of EM profile ID */
- uint16_t em_prof_id_min;
- /* Maximum non-guaranteed number of EM profile ID */
- uint16_t em_prof_id_max;
- /* Minimum guaranteed number of EM records entries */
- uint16_t em_record_entries_min;
- /* Maximum non-guaranteed number of EM record entries */
- uint16_t em_record_entries_max;
- /* Minimum guaranteed number of WC TCAM profile ID */
- uint16_t wc_tcam_prof_id_min;
- /* Maximum non-guaranteed number of WC TCAM profile ID */
- uint16_t wc_tcam_prof_id_max;
- /* Minimum guaranteed number of WC TCAM entries */
- uint16_t wc_tcam_entries_min;
- /* Maximum non-guaranteed number of WC TCAM entries */
- uint16_t wc_tcam_entries_max;
- /* Minimum guaranteed number of meter profiles */
- uint16_t meter_profiles_min;
- /* Maximum non-guaranteed number of meter profiles */
- uint16_t meter_profiles_max;
- /* Minimum guaranteed number of meter instances */
- uint16_t meter_inst_min;
- /* Maximum non-guaranteed number of meter instances */
- uint16_t meter_inst_max;
- /* Minimum guaranteed number of mirrors */
- uint16_t mirrors_min;
- /* Maximum non-guaranteed number of mirrors */
- uint16_t mirrors_max;
- /* Minimum guaranteed number of UPAR */
- uint16_t upar_min;
- /* Maximum non-guaranteed number of UPAR */
- uint16_t upar_max;
- /* Minimum guaranteed number of SP TCAM entries */
- uint16_t sp_tcam_entries_min;
- /* Maximum non-guaranteed number of SP TCAM entries */
- uint16_t sp_tcam_entries_max;
- /* Minimum guaranteed number of L2 Functions */
- uint16_t l2_func_min;
- /* Maximum non-guaranteed number of L2 Functions */
- uint16_t l2_func_max;
- /* Minimum guaranteed number of flexible key templates */
- uint16_t flex_key_templ_min;
- /* Maximum non-guaranteed number of flexible key templates */
- uint16_t flex_key_templ_max;
- /* Minimum guaranteed number of table Scopes */
- uint16_t tbl_scope_min;
- /* Maximum non-guaranteed number of table Scopes */
- uint16_t tbl_scope_max;
- /* Minimum guaranteed number of epoch0 entries */
- uint16_t epoch0_entries_min;
- /* Maximum non-guaranteed number of epoch0 entries */
- uint16_t epoch0_entries_max;
- /* Minimum guaranteed number of epoch1 entries */
- uint16_t epoch1_entries_min;
- /* Maximum non-guaranteed number of epoch1 entries */
- uint16_t epoch1_entries_max;
- /* Minimum guaranteed number of metadata */
- uint16_t metadata_min;
- /* Maximum non-guaranteed number of metadata */
- uint16_t metadata_max;
- /* Minimum guaranteed number of CT states */
- uint16_t ct_state_min;
- /* Maximum non-guaranteed number of CT states */
- uint16_t ct_state_max;
- /* Minimum guaranteed number of range profiles */
- uint16_t range_prof_min;
- /* Maximum non-guaranteed number range profiles */
- uint16_t range_prof_max;
- /* Minimum guaranteed number of range entries */
- uint16_t range_entries_min;
- /* Maximum non-guaranteed number of range entries */
- uint16_t range_entries_max;
- /* Minimum guaranteed number of LAG table entries */
- uint16_t lag_tbl_entries_min;
- /* Maximum non-guaranteed number of LAG table entries */
- uint16_t lag_tbl_entries_max;
-} tf_session_hw_resc_qcaps_output_t, *ptf_session_hw_resc_qcaps_output_t;
-
-/* Input params for session resource HW alloc */
-typedef struct tf_session_hw_resc_alloc_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_ALLOC_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_ALLOC_INPUT_FLAGS_DIR_TX (0x1)
- /* Unused */
- uint8_t unused[2];
- /* Number of L2 CTX TCAM entries to be allocated */
- uint16_t num_l2_ctx_tcam_entries;
- /* Number of profile functions to be allocated */
- uint16_t num_prof_func_entries;
- /* Number of profile TCAM entries to be allocated */
- uint16_t num_prof_tcam_entries;
- /* Number of EM profile ids to be allocated */
- uint16_t num_em_prof_id;
- /* Number of EM records entries to be allocated */
- uint16_t num_em_record_entries;
- /* Number of WC profiles ids to be allocated */
- uint16_t num_wc_tcam_prof_id;
- /* Number of WC TCAM entries to be allocated */
- uint16_t num_wc_tcam_entries;
- /* Number of meter profiles to be allocated */
- uint16_t num_meter_profiles;
- /* Number of meter instances to be allocated */
- uint16_t num_meter_inst;
- /* Number of mirrors to be allocated */
- uint16_t num_mirrors;
- /* Number of UPAR to be allocated */
- uint16_t num_upar;
- /* Number of SP TCAM entries to be allocated */
- uint16_t num_sp_tcam_entries;
- /* Number of L2 functions to be allocated */
- uint16_t num_l2_func;
- /* Number of flexible key templates to be allocated */
- uint16_t num_flex_key_templ;
- /* Number of table scopes to be allocated */
- uint16_t num_tbl_scope;
- /* Number of epoch0 entries to be allocated */
- uint16_t num_epoch0_entries;
- /* Number of epoch1 entries to be allocated */
- uint16_t num_epoch1_entries;
- /* Number of metadata to be allocated */
- uint16_t num_metadata;
- /* Number of CT states to be allocated */
- uint16_t num_ct_state;
- /* Number of range profiles to be allocated */
- uint16_t num_range_prof;
- /* Number of range Entries to be allocated */
- uint16_t num_range_entries;
- /* Number of LAG table entries to be allocated */
- uint16_t num_lag_tbl_entries;
-} tf_session_hw_resc_alloc_input_t, *ptf_session_hw_resc_alloc_input_t;
-
-/* Output params for session resource HW alloc */
-typedef struct tf_session_hw_resc_alloc_output {
- /* Starting index of L2 CTX TCAM entries allocated to the session */
- uint16_t l2_ctx_tcam_entries_start;
- /* Number of L2 CTX TCAM entries allocated */
- uint16_t l2_ctx_tcam_entries_stride;
- /* Starting index of profile functions allocated to the session */
- uint16_t prof_func_start;
- /* Number of profile functions allocated */
- uint16_t prof_func_stride;
- /* Starting index of profile TCAM entries allocated to the session */
- uint16_t prof_tcam_entries_start;
- /* Number of profile TCAM entries allocated */
- uint16_t prof_tcam_entries_stride;
- /* Starting index of EM profile ids allocated to the session */
- uint16_t em_prof_id_start;
- /* Number of EM profile ids allocated */
- uint16_t em_prof_id_stride;
- /* Starting index of EM record entries allocated to the session */
- uint16_t em_record_entries_start;
- /* Number of EM record entries allocated */
- uint16_t em_record_entries_stride;
- /* Starting index of WC TCAM profiles ids allocated to the session */
- uint16_t wc_tcam_prof_id_start;
- /* Number of WC TCAM profile ids allocated */
- uint16_t wc_tcam_prof_id_stride;
- /* Starting index of WC TCAM entries allocated to the session */
- uint16_t wc_tcam_entries_start;
- /* Number of WC TCAM allocated */
- uint16_t wc_tcam_entries_stride;
- /* Starting index of meter profiles allocated to the session */
- uint16_t meter_profiles_start;
- /* Number of meter profiles allocated */
- uint16_t meter_profiles_stride;
- /* Starting index of meter instance allocated to the session */
- uint16_t meter_inst_start;
- /* Number of meter instance allocated */
- uint16_t meter_inst_stride;
- /* Starting index of mirrors allocated to the session */
- uint16_t mirrors_start;
- /* Number of mirrors allocated */
- uint16_t mirrors_stride;
- /* Starting index of UPAR allocated to the session */
- uint16_t upar_start;
- /* Number of UPAR allocated */
- uint16_t upar_stride;
- /* Starting index of SP TCAM entries allocated to the session */
- uint16_t sp_tcam_entries_start;
- /* Number of SP TCAM entries allocated */
- uint16_t sp_tcam_entries_stride;
- /* Starting index of L2 functions allocated to the session */
- uint16_t l2_func_start;
- /* Number of L2 functions allocated */
- uint16_t l2_func_stride;
- /* Starting index of flexible key templates allocated to the session */
- uint16_t flex_key_templ_start;
- /* Number of flexible key templates allocated */
- uint16_t flex_key_templ_stride;
- /* Starting index of table scopes allocated to the session */
- uint16_t tbl_scope_start;
- /* Number of table scopes allocated */
- uint16_t tbl_scope_stride;
- /* Starting index of epoch0 entries allocated to the session */
- uint16_t epoch0_entries_start;
- /* Number of epoch0 entries allocated */
- uint16_t epoch0_entries_stride;
- /* Starting index of epoch1 entries allocated to the session */
- uint16_t epoch1_entries_start;
- /* Number of epoch1 entries allocated */
- uint16_t epoch1_entries_stride;
- /* Starting index of metadata allocated to the session */
- uint16_t metadata_start;
- /* Number of metadata allocated */
- uint16_t metadata_stride;
- /* Starting index of CT states allocated to the session */
- uint16_t ct_state_start;
- /* Number of CT states allocated */
- uint16_t ct_state_stride;
- /* Starting index of range profiles allocated to the session */
- uint16_t range_prof_start;
- /* Number range profiles allocated */
- uint16_t range_prof_stride;
- /* Starting index of range entries allocated to the session */
- uint16_t range_entries_start;
- /* Number of range entries allocated */
- uint16_t range_entries_stride;
- /* Starting index of LAG table entries allocated to the session */
- uint16_t lag_tbl_entries_start;
- /* Number of LAG table entries allocated */
- uint16_t lag_tbl_entries_stride;
-} tf_session_hw_resc_alloc_output_t, *ptf_session_hw_resc_alloc_output_t;
-
-/* Input params for session resource HW free */
-typedef struct tf_session_hw_resc_free_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_HW_RESC_FREE_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_HW_RESC_FREE_INPUT_FLAGS_DIR_TX (0x1)
- /* Unused */
- uint8_t unused[2];
- /* Starting index of L2 CTX TCAM entries allocated to the session */
- uint16_t l2_ctx_tcam_entries_start;
- /* Number of L2 CTX TCAM entries allocated */
- uint16_t l2_ctx_tcam_entries_stride;
- /* Starting index of profile functions allocated to the session */
- uint16_t prof_func_start;
- /* Number of profile functions allocated */
- uint16_t prof_func_stride;
- /* Starting index of profile TCAM entries allocated to the session */
- uint16_t prof_tcam_entries_start;
- /* Number of profile TCAM entries allocated */
- uint16_t prof_tcam_entries_stride;
- /* Starting index of EM profile ids allocated to the session */
- uint16_t em_prof_id_start;
- /* Number of EM profile ids allocated */
- uint16_t em_prof_id_stride;
- /* Starting index of EM record entries allocated to the session */
- uint16_t em_record_entries_start;
- /* Number of EM record entries allocated */
- uint16_t em_record_entries_stride;
- /* Starting index of WC TCAM profiles ids allocated to the session */
- uint16_t wc_tcam_prof_id_start;
- /* Number of WC TCAM profile ids allocated */
- uint16_t wc_tcam_prof_id_stride;
- /* Starting index of WC TCAM entries allocated to the session */
- uint16_t wc_tcam_entries_start;
- /* Number of WC TCAM allocated */
- uint16_t wc_tcam_entries_stride;
- /* Starting index of meter profiles allocated to the session */
- uint16_t meter_profiles_start;
- /* Number of meter profiles allocated */
- uint16_t meter_profiles_stride;
- /* Starting index of meter instance allocated to the session */
- uint16_t meter_inst_start;
- /* Number of meter instance allocated */
- uint16_t meter_inst_stride;
- /* Starting index of mirrors allocated to the session */
- uint16_t mirrors_start;
- /* Number of mirrors allocated */
- uint16_t mirrors_stride;
- /* Starting index of UPAR allocated to the session */
- uint16_t upar_start;
- /* Number of UPAR allocated */
- uint16_t upar_stride;
- /* Starting index of SP TCAM entries allocated to the session */
- uint16_t sp_tcam_entries_start;
- /* Number of SP TCAM entries allocated */
- uint16_t sp_tcam_entries_stride;
- /* Starting index of L2 functions allocated to the session */
- uint16_t l2_func_start;
- /* Number of L2 functions allocated */
- uint16_t l2_func_stride;
- /* Starting index of flexible key templates allocated to the session */
- uint16_t flex_key_templ_start;
- /* Number of flexible key templates allocated */
- uint16_t flex_key_templ_stride;
- /* Starting index of table scopes allocated to the session */
- uint16_t tbl_scope_start;
- /* Number of table scopes allocated */
- uint16_t tbl_scope_stride;
- /* Starting index of epoch0 entries allocated to the session */
- uint16_t epoch0_entries_start;
- /* Number of epoch0 entries allocated */
- uint16_t epoch0_entries_stride;
- /* Starting index of epoch1 entries allocated to the session */
- uint16_t epoch1_entries_start;
- /* Number of epoch1 entries allocated */
- uint16_t epoch1_entries_stride;
- /* Starting index of metadata allocated to the session */
- uint16_t metadata_start;
- /* Number of metadata allocated */
- uint16_t metadata_stride;
- /* Starting index of CT states allocated to the session */
- uint16_t ct_state_start;
- /* Number of CT states allocated */
- uint16_t ct_state_stride;
- /* Starting index of range profiles allocated to the session */
- uint16_t range_prof_start;
- /* Number range profiles allocated */
- uint16_t range_prof_stride;
- /* Starting index of range entries allocated to the session */
- uint16_t range_entries_start;
- /* Number of range entries allocated */
- uint16_t range_entries_stride;
- /* Starting index of LAG table entries allocated to the session */
- uint16_t lag_tbl_entries_start;
- /* Number of LAG table entries allocated */
- uint16_t lag_tbl_entries_stride;
-} tf_session_hw_resc_free_input_t, *ptf_session_hw_resc_free_input_t;
-
-/* Input params for session resource HW flush */
-typedef struct tf_session_hw_resc_flush_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the flush apply to RX */
-#define TF_SESSION_HW_RESC_FLUSH_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the flush apply to TX */
-#define TF_SESSION_HW_RESC_FLUSH_INPUT_FLAGS_DIR_TX (0x1)
- /* Unused */
- uint8_t unused[2];
- /* Starting index of L2 CTX TCAM entries allocated to the session */
- uint16_t l2_ctx_tcam_entries_start;
- /* Number of L2 CTX TCAM entries allocated */
- uint16_t l2_ctx_tcam_entries_stride;
- /* Starting index of profile functions allocated to the session */
- uint16_t prof_func_start;
- /* Number of profile functions allocated */
- uint16_t prof_func_stride;
- /* Starting index of profile TCAM entries allocated to the session */
- uint16_t prof_tcam_entries_start;
- /* Number of profile TCAM entries allocated */
- uint16_t prof_tcam_entries_stride;
- /* Starting index of EM profile ids allocated to the session */
- uint16_t em_prof_id_start;
- /* Number of EM profile ids allocated */
- uint16_t em_prof_id_stride;
- /* Starting index of EM record entries allocated to the session */
- uint16_t em_record_entries_start;
- /* Number of EM record entries allocated */
- uint16_t em_record_entries_stride;
- /* Starting index of WC TCAM profiles ids allocated to the session */
- uint16_t wc_tcam_prof_id_start;
- /* Number of WC TCAM profile ids allocated */
- uint16_t wc_tcam_prof_id_stride;
- /* Starting index of WC TCAM entries allocated to the session */
- uint16_t wc_tcam_entries_start;
- /* Number of WC TCAM allocated */
- uint16_t wc_tcam_entries_stride;
- /* Starting index of meter profiles allocated to the session */
- uint16_t meter_profiles_start;
- /* Number of meter profiles allocated */
- uint16_t meter_profiles_stride;
- /* Starting index of meter instance allocated to the session */
- uint16_t meter_inst_start;
- /* Number of meter instance allocated */
- uint16_t meter_inst_stride;
- /* Starting index of mirrors allocated to the session */
- uint16_t mirrors_start;
- /* Number of mirrors allocated */
- uint16_t mirrors_stride;
- /* Starting index of UPAR allocated to the session */
- uint16_t upar_start;
- /* Number of UPAR allocated */
- uint16_t upar_stride;
- /* Starting index of SP TCAM entries allocated to the session */
- uint16_t sp_tcam_entries_start;
- /* Number of SP TCAM entries allocated */
- uint16_t sp_tcam_entries_stride;
- /* Starting index of L2 functions allocated to the session */
- uint16_t l2_func_start;
- /* Number of L2 functions allocated */
- uint16_t l2_func_stride;
- /* Starting index of flexible key templates allocated to the session */
- uint16_t flex_key_templ_start;
- /* Number of flexible key templates allocated */
- uint16_t flex_key_templ_stride;
- /* Starting index of table scopes allocated to the session */
- uint16_t tbl_scope_start;
- /* Number of table scopes allocated */
- uint16_t tbl_scope_stride;
- /* Starting index of epoch0 entries allocated to the session */
- uint16_t epoch0_entries_start;
- /* Number of epoch0 entries allocated */
- uint16_t epoch0_entries_stride;
- /* Starting index of epoch1 entries allocated to the session */
- uint16_t epoch1_entries_start;
- /* Number of epoch1 entries allocated */
- uint16_t epoch1_entries_stride;
- /* Starting index of metadata allocated to the session */
- uint16_t metadata_start;
- /* Number of metadata allocated */
- uint16_t metadata_stride;
- /* Starting index of CT states allocated to the session */
- uint16_t ct_state_start;
- /* Number of CT states allocated */
- uint16_t ct_state_stride;
- /* Starting index of range profiles allocated to the session */
- uint16_t range_prof_start;
- /* Number range profiles allocated */
- uint16_t range_prof_stride;
- /* Starting index of range entries allocated to the session */
- uint16_t range_entries_start;
- /* Number of range entries allocated */
- uint16_t range_entries_stride;
- /* Starting index of LAG table entries allocated to the session */
- uint16_t lag_tbl_entries_start;
- /* Number of LAG table entries allocated */
- uint16_t lag_tbl_entries_stride;
-} tf_session_hw_resc_flush_input_t, *ptf_session_hw_resc_flush_input_t;
-
-/* Input params for session resource SRAM qcaps */
-typedef struct tf_session_sram_resc_qcaps_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_QCAPS_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_QCAPS_INPUT_FLAGS_DIR_TX (0x1)
-} tf_session_sram_resc_qcaps_input_t, *ptf_session_sram_resc_qcaps_input_t;
-
-/* Output params for session resource SRAM qcaps */
-typedef struct tf_session_sram_resc_qcaps_output {
- /* Flags */
- uint32_t flags;
- /* When set to 0, indicates Static partitioning */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_STATIC (0x0)
- /* When set to 1, indicates Strategy 1 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_1 (0x1)
- /* When set to 1, indicates Strategy 2 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_2 (0x2)
- /* When set to 1, indicates Strategy 3 */
-#define TF_SESSION_SRAM_RESC_QCAPS_OUTPUT_FLAGS_SESS_RES_STRATEGY_3 (0x3)
- /* Minimum guaranteed number of Full Action */
- uint16_t full_action_min;
- /* Maximum non-guaranteed number of Full Action */
- uint16_t full_action_max;
- /* Minimum guaranteed number of MCG */
- uint16_t mcg_min;
- /* Maximum non-guaranteed number of MCG */
- uint16_t mcg_max;
- /* Minimum guaranteed number of Encap 8B */
- uint16_t encap_8b_min;
- /* Maximum non-guaranteed number of Encap 8B */
- uint16_t encap_8b_max;
- /* Minimum guaranteed number of Encap 16B */
- uint16_t encap_16b_min;
- /* Maximum non-guaranteed number of Encap 16B */
- uint16_t encap_16b_max;
- /* Minimum guaranteed number of Encap 64B */
- uint16_t encap_64b_min;
- /* Maximum non-guaranteed number of Encap 64B */
- uint16_t encap_64b_max;
- /* Minimum guaranteed number of SP SMAC */
- uint16_t sp_smac_min;
- /* Maximum non-guaranteed number of SP SMAC */
- uint16_t sp_smac_max;
- /* Minimum guaranteed number of SP SMAC IPv4 */
- uint16_t sp_smac_ipv4_min;
- /* Maximum non-guaranteed number of SP SMAC IPv4 */
- uint16_t sp_smac_ipv4_max;
- /* Minimum guaranteed number of SP SMAC IPv6 */
- uint16_t sp_smac_ipv6_min;
- /* Maximum non-guaranteed number of SP SMAC IPv6 */
- uint16_t sp_smac_ipv6_max;
- /* Minimum guaranteed number of Counter 64B */
- uint16_t counter_64b_min;
- /* Maximum non-guaranteed number of Counter 64B */
- uint16_t counter_64b_max;
- /* Minimum guaranteed number of NAT SPORT */
- uint16_t nat_sport_min;
- /* Maximum non-guaranteed number of NAT SPORT */
- uint16_t nat_sport_max;
- /* Minimum guaranteed number of NAT DPORT */
- uint16_t nat_dport_min;
- /* Maximum non-guaranteed number of NAT DPORT */
- uint16_t nat_dport_max;
- /* Minimum guaranteed number of NAT S_IPV4 */
- uint16_t nat_s_ipv4_min;
- /* Maximum non-guaranteed number of NAT S_IPV4 */
- uint16_t nat_s_ipv4_max;
- /* Minimum guaranteed number of NAT D_IPV4 */
- uint16_t nat_d_ipv4_min;
- /* Maximum non-guaranteed number of NAT D_IPV4 */
- uint16_t nat_d_ipv4_max;
-} tf_session_sram_resc_qcaps_output_t, *ptf_session_sram_resc_qcaps_output_t;
-
-/* Input params for session resource SRAM alloc */
-typedef struct tf_session_sram_resc_alloc_input {
- /* FW Session Id */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_ALLOC_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_ALLOC_INPUT_FLAGS_DIR_TX (0x1)
- /* Unused */
- uint8_t unused[2];
- /* Number of full action SRAM entries to be allocated */
- uint16_t num_full_action;
- /* Number of multicast groups to be allocated */
- uint16_t num_mcg;
- /* Number of Encap 8B entries to be allocated */
- uint16_t num_encap_8b;
- /* Number of Encap 16B entries to be allocated */
- uint16_t num_encap_16b;
- /* Number of Encap 64B entries to be allocated */
- uint16_t num_encap_64b;
- /* Number of SP SMAC entries to be allocated */
- uint16_t num_sp_smac;
- /* Number of SP SMAC IPv4 entries to be allocated */
- uint16_t num_sp_smac_ipv4;
- /* Number of SP SMAC IPv6 entries to be allocated */
- uint16_t num_sp_smac_ipv6;
- /* Number of Counter 64B entries to be allocated */
- uint16_t num_counter_64b;
- /* Number of NAT source ports to be allocated */
- uint16_t num_nat_sport;
- /* Number of NAT destination ports to be allocated */
- uint16_t num_nat_dport;
- /* Number of NAT source iPV4 addresses to be allocated */
- uint16_t num_nat_s_ipv4;
- /* Number of NAT destination IPV4 addresses to be allocated */
- uint16_t num_nat_d_ipv4;
-} tf_session_sram_resc_alloc_input_t, *ptf_session_sram_resc_alloc_input_t;
-
-/* Output params for session resource SRAM alloc */
-typedef struct tf_session_sram_resc_alloc_output {
- /* Unused */
- uint8_t unused[2];
- /* Starting index of full action SRAM entries allocated to the session */
- uint16_t full_action_start;
- /* Number of full action SRAM entries allocated */
- uint16_t full_action_stride;
- /* Starting index of multicast groups allocated to this session */
- uint16_t mcg_start;
- /* Number of multicast groups allocated */
- uint16_t mcg_stride;
- /* Starting index of encap 8B entries allocated to the session */
- uint16_t encap_8b_start;
- /* Number of encap 8B entries allocated */
- uint16_t encap_8b_stride;
- /* Starting index of encap 16B entries allocated to the session */
- uint16_t encap_16b_start;
- /* Number of encap 16B entries allocated */
- uint16_t encap_16b_stride;
- /* Starting index of encap 64B entries allocated to the session */
- uint16_t encap_64b_start;
- /* Number of encap 64B entries allocated */
- uint16_t encap_64b_stride;
- /* Starting index of SP SMAC entries allocated to the session */
- uint16_t sp_smac_start;
- /* Number of SP SMAC entries allocated */
- uint16_t sp_smac_stride;
- /* Starting index of SP SMAC IPv4 entries allocated to the session */
- uint16_t sp_smac_ipv4_start;
- /* Number of SP SMAC IPv4 entries allocated */
- uint16_t sp_smac_ipv4_stride;
- /* Starting index of SP SMAC IPv6 entries allocated to the session */
- uint16_t sp_smac_ipv6_start;
- /* Number of SP SMAC IPv6 entries allocated */
- uint16_t sp_smac_ipv6_stride;
- /* Starting index of Counter 64B entries allocated to the session */
- uint16_t counter_64b_start;
- /* Number of Counter 64B entries allocated */
- uint16_t counter_64b_stride;
- /* Starting index of NAT source ports allocated to the session */
- uint16_t nat_sport_start;
- /* Number of NAT source ports allocated */
- uint16_t nat_sport_stride;
- /* Starting index of NAT destination ports allocated to the session */
- uint16_t nat_dport_start;
- /* Number of NAT destination ports allocated */
- uint16_t nat_dport_stride;
- /* Starting index of NAT source IPV4 addresses allocated to the session */
- uint16_t nat_s_ipv4_start;
- /* Number of NAT source IPV4 addresses allocated */
- uint16_t nat_s_ipv4_stride;
- /*
- * Starting index of NAT destination IPV4 addresses allocated to the
- * session
- */
- uint16_t nat_d_ipv4_start;
- /* Number of NAT destination IPV4 addresses allocated */
- uint16_t nat_d_ipv4_stride;
-} tf_session_sram_resc_alloc_output_t, *ptf_session_sram_resc_alloc_output_t;
-
-/* Input params for session resource SRAM free */
-typedef struct tf_session_sram_resc_free_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the query apply to RX */
-#define TF_SESSION_SRAM_RESC_FREE_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the query apply to TX */
-#define TF_SESSION_SRAM_RESC_FREE_INPUT_FLAGS_DIR_TX (0x1)
- /* Starting index of full action SRAM entries allocated to the session */
- uint16_t full_action_start;
- /* Number of full action SRAM entries allocated */
- uint16_t full_action_stride;
- /* Starting index of multicast groups allocated to this session */
- uint16_t mcg_start;
- /* Number of multicast groups allocated */
- uint16_t mcg_stride;
- /* Starting index of encap 8B entries allocated to the session */
- uint16_t encap_8b_start;
- /* Number of encap 8B entries allocated */
- uint16_t encap_8b_stride;
- /* Starting index of encap 16B entries allocated to the session */
- uint16_t encap_16b_start;
- /* Number of encap 16B entries allocated */
- uint16_t encap_16b_stride;
- /* Starting index of encap 64B entries allocated to the session */
- uint16_t encap_64b_start;
- /* Number of encap 64B entries allocated */
- uint16_t encap_64b_stride;
- /* Starting index of SP SMAC entries allocated to the session */
- uint16_t sp_smac_start;
- /* Number of SP SMAC entries allocated */
- uint16_t sp_smac_stride;
- /* Starting index of SP SMAC IPv4 entries allocated to the session */
- uint16_t sp_smac_ipv4_start;
- /* Number of SP SMAC IPv4 entries allocated */
- uint16_t sp_smac_ipv4_stride;
- /* Starting index of SP SMAC IPv6 entries allocated to the session */
- uint16_t sp_smac_ipv6_start;
- /* Number of SP SMAC IPv6 entries allocated */
- uint16_t sp_smac_ipv6_stride;
- /* Starting index of Counter 64B entries allocated to the session */
- uint16_t counter_64b_start;
- /* Number of Counter 64B entries allocated */
- uint16_t counter_64b_stride;
- /* Starting index of NAT source ports allocated to the session */
- uint16_t nat_sport_start;
- /* Number of NAT source ports allocated */
- uint16_t nat_sport_stride;
- /* Starting index of NAT destination ports allocated to the session */
- uint16_t nat_dport_start;
- /* Number of NAT destination ports allocated */
- uint16_t nat_dport_stride;
- /* Starting index of NAT source IPV4 addresses allocated to the session */
- uint16_t nat_s_ipv4_start;
- /* Number of NAT source IPV4 addresses allocated */
- uint16_t nat_s_ipv4_stride;
- /*
- * Starting index of NAT destination IPV4 addresses allocated to the
- * session
- */
- uint16_t nat_d_ipv4_start;
- /* Number of NAT destination IPV4 addresses allocated */
- uint16_t nat_d_ipv4_stride;
-} tf_session_sram_resc_free_input_t, *ptf_session_sram_resc_free_input_t;
-
-/* Input params for session resource SRAM flush */
-typedef struct tf_session_sram_resc_flush_input {
- /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent */
- uint32_t fw_session_id;
- /* flags */
- uint16_t flags;
- /* When set to 0, indicates the flush apply to RX */
-#define TF_SESSION_SRAM_RESC_FLUSH_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the flush apply to TX */
-#define TF_SESSION_SRAM_RESC_FLUSH_INPUT_FLAGS_DIR_TX (0x1)
- /* Starting index of full action SRAM entries allocated to the session */
- uint16_t full_action_start;
- /* Number of full action SRAM entries allocated */
- uint16_t full_action_stride;
- /* Starting index of multicast groups allocated to this session */
- uint16_t mcg_start;
- /* Number of multicast groups allocated */
- uint16_t mcg_stride;
- /* Starting index of encap 8B entries allocated to the session */
- uint16_t encap_8b_start;
- /* Number of encap 8B entries allocated */
- uint16_t encap_8b_stride;
- /* Starting index of encap 16B entries allocated to the session */
- uint16_t encap_16b_start;
- /* Number of encap 16B entries allocated */
- uint16_t encap_16b_stride;
- /* Starting index of encap 64B entries allocated to the session */
- uint16_t encap_64b_start;
- /* Number of encap 64B entries allocated */
- uint16_t encap_64b_stride;
- /* Starting index of SP SMAC entries allocated to the session */
- uint16_t sp_smac_start;
- /* Number of SP SMAC entries allocated */
- uint16_t sp_smac_stride;
- /* Starting index of SP SMAC IPv4 entries allocated to the session */
- uint16_t sp_smac_ipv4_start;
- /* Number of SP SMAC IPv4 entries allocated */
- uint16_t sp_smac_ipv4_stride;
- /* Starting index of SP SMAC IPv6 entries allocated to the session */
- uint16_t sp_smac_ipv6_start;
- /* Number of SP SMAC IPv6 entries allocated */
- uint16_t sp_smac_ipv6_stride;
- /* Starting index of Counter 64B entries allocated to the session */
- uint16_t counter_64b_start;
- /* Number of Counter 64B entries allocated */
- uint16_t counter_64b_stride;
- /* Starting index of NAT source ports allocated to the session */
- uint16_t nat_sport_start;
- /* Number of NAT source ports allocated */
- uint16_t nat_sport_stride;
- /* Starting index of NAT destination ports allocated to the session */
- uint16_t nat_dport_start;
- /* Number of NAT destination ports allocated */
- uint16_t nat_dport_stride;
- /* Starting index of NAT source IPV4 addresses allocated to the session */
- uint16_t nat_s_ipv4_start;
- /* Number of NAT source IPV4 addresses allocated */
- uint16_t nat_s_ipv4_stride;
- /*
- * Starting index of NAT destination IPV4 addresses allocated to the
- * session
- */
- uint16_t nat_d_ipv4_start;
- /* Number of NAT destination IPV4 addresses allocated */
- uint16_t nat_d_ipv4_stride;
-} tf_session_sram_resc_flush_input_t, *ptf_session_sram_resc_flush_input_t;
-
-/* Input params for table type set */
-typedef struct tf_tbl_type_set_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_SET_INPUT_FLAGS_DIR_RX (0x0)
- /* When set to 1, indicates the get apply to TX */
-#define TF_TBL_TYPE_SET_INPUT_FLAGS_DIR_TX (0x1)
- /* Type of the object to set */
- uint32_t type;
- /* Size of the data to set in bytes */
- uint16_t size;
- /* Data to set */
- uint8_t data[TF_BULK_SEND];
- /* Index to set */
- uint32_t index;
-} tf_tbl_type_set_input_t, *ptf_tbl_type_set_input_t;
-
-/* Input params for table type get */
-typedef struct tf_tbl_type_get_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_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)
- /* Type of the object to set */
- uint32_t type;
- /* Index to get */
- uint32_t index;
-} tf_tbl_type_get_input_t, *ptf_tbl_type_get_input_t;
-
-/* Output params for table type get */
-typedef struct tf_tbl_type_get_output {
- /* Size of the data read in bytes */
- uint16_t size;
- /* Data read */
- 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_bulk_get_input {
return rc;
}
- rc = dev->ops->tf_dev_insert_em_entry(tfp, parms);
+ if (parms->mem == TF_MEM_EXTERNAL &&
+ dev->ops->tf_dev_insert_ext_em_entry != NULL)
+ rc = dev->ops->tf_dev_insert_ext_em_entry(tfp, parms);
+ else if (parms->mem == TF_MEM_INTERNAL &&
+ dev->ops->tf_dev_insert_int_em_entry != NULL)
+ rc = dev->ops->tf_dev_insert_int_em_entry(tfp, parms);
+ else
+ return -EINVAL;
+
if (rc) {
TFP_DRV_LOG(ERR,
"%s: EM insert failed, rc:%s\n",
return rc;
}
- return -EINVAL;
+ return 0;
}
/** Delete EM hash entry API
return rc;
}
- rc = dev->ops->tf_dev_delete_em_entry(tfp, parms);
+ if (parms->mem == TF_MEM_EXTERNAL)
+ rc = dev->ops->tf_dev_delete_ext_em_entry(tfp, parms);
+ else if (parms->mem == TF_MEM_INTERNAL)
+ rc = dev->ops->tf_dev_delete_int_em_entry(tfp, parms);
+ else
+ return -EINVAL;
+
if (rc) {
TFP_DRV_LOG(ERR,
"%s: EM delete failed, rc:%s\n",
return rc;
}
+
+/* API defined in tf_core.h */
+int
+tf_alloc_tbl_scope(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms)
+{
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ int rc;
+
+ TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup session, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup device, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ if (dev->ops->tf_dev_alloc_tbl_scope != NULL) {
+ rc = dev->ops->tf_dev_alloc_tbl_scope(tfp, parms);
+ } else {
+ TFP_DRV_LOG(ERR,
+ "Alloc table scope not supported by device\n");
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+/* API defined in tf_core.h */
+int
+tf_free_tbl_scope(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms)
+{
+ struct tf_session *tfs;
+ struct tf_dev_info *dev;
+ int rc;
+
+ TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup session, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Retrieve the device information */
+ rc = tf_session_get_device(tfs, &dev);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to lookup device, rc:%s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ if (dev->ops->tf_dev_free_tbl_scope) {
+ rc = dev->ops->tf_dev_free_tbl_scope(tfp, parms);
+ } else {
+ TFP_DRV_LOG(ERR,
+ "Free table scope not supported by device\n");
+ return -EINVAL;
+ }
+
+ return rc;
+}
#include "tf_device.h"
#include "tf_device_p4.h"
#include "tfp.h"
+#include "tf_em.h"
struct tf;
struct tf_ident_cfg_parms ident_cfg;
struct tf_tbl_cfg_parms tbl_cfg;
struct tf_tcam_cfg_parms tcam_cfg;
-
- dev_handle->type = TF_DEVICE_TYPE_WH;
- /* Initial function initialization */
- dev_handle->ops = &tf_dev_ops_p4_init;
+ struct tf_em_cfg_parms em_cfg;
dev_handle->type = TF_DEVICE_TYPE_WH;
/* Initial function initialization */
goto fail;
}
+ /*
+ * EEM
+ */
+ em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
+ em_cfg.cfg = tf_em_ext_p4;
+ em_cfg.resources = resources;
+ em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST;
+
+ rc = tf_em_ext_common_bind(tfp, &em_cfg);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "EEM initialization failure\n");
+ goto fail;
+ }
+
+ /*
+ * EM
+ */
+ em_cfg.num_elements = TF_EM_TBL_TYPE_MAX;
+ em_cfg.cfg = tf_em_int_p4;
+ em_cfg.resources = resources;
+ em_cfg.mem_type = 0; /* Not used by EM */
+
+ rc = tf_em_int_bind(tfp, &em_cfg);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "EM initialization failure\n");
+ goto fail;
+ }
+
/* Final function initialization */
dev_handle->ops = &tf_dev_ops_p4;
fail = true;
}
+ rc = tf_em_ext_common_unbind(tfp);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Device unbind failed, EEM\n");
+ fail = true;
+ }
+
+ rc = tf_em_int_unbind(tfp);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Device unbind failed, EM\n");
+ fail = true;
+ }
+
if (fail)
return -1;
struct tf_session;
/**
- *
+ * Device module types
*/
enum tf_device_module_type {
+ /**
+ * Identifier module
+ */
TF_DEVICE_MODULE_TYPE_IDENTIFIER,
+ /**
+ * Table type module
+ */
TF_DEVICE_MODULE_TYPE_TABLE,
+ /**
+ * TCAM module
+ */
TF_DEVICE_MODULE_TYPE_TCAM,
+ /**
+ * EM module
+ */
TF_DEVICE_MODULE_TYPE_EM,
TF_DEVICE_MODULE_TYPE_MAX
};
* 0 - Success
* -EINVAL - Error
*/
- int (*tf_dev_insert_em_entry)(struct tf *tfp,
- struct tf_insert_em_entry_parms *parms);
+ int (*tf_dev_insert_int_em_entry)(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms);
/**
* Delete EM hash entry API
* 0 - Success
* -EINVAL - Error
*/
- int (*tf_dev_delete_em_entry)(struct tf *tfp,
- struct tf_delete_em_entry_parms *parms);
+ int (*tf_dev_delete_int_em_entry)(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms);
+
+ /**
+ * Insert EEM hash entry API
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to E/EM insert parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+ int (*tf_dev_insert_ext_em_entry)(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms);
+
+ /**
+ * Delete EEM hash entry API
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to E/EM delete parameters
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+ int (*tf_dev_delete_ext_em_entry)(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms);
+
+ /**
+ * Allocate EEM table scope
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to table scope alloc parameters
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+ int (*tf_dev_alloc_tbl_scope)(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms);
+
+ /**
+ * Free EEM table scope
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] parms
+ * Pointer to table scope free parameters
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+ int (*tf_dev_free_tbl_scope)(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms);
};
/**
.tf_dev_alloc_search_tcam = NULL,
.tf_dev_set_tcam = NULL,
.tf_dev_get_tcam = NULL,
+ .tf_dev_insert_int_em_entry = NULL,
+ .tf_dev_delete_int_em_entry = NULL,
+ .tf_dev_insert_ext_em_entry = NULL,
+ .tf_dev_delete_ext_em_entry = NULL,
+ .tf_dev_alloc_tbl_scope = NULL,
+ .tf_dev_free_tbl_scope = NULL,
};
/**
.tf_dev_alloc_search_tcam = NULL,
.tf_dev_set_tcam = tf_tcam_set,
.tf_dev_get_tcam = NULL,
- .tf_dev_insert_em_entry = tf_em_insert_entry,
- .tf_dev_delete_em_entry = tf_em_delete_entry,
+ .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_free_tbl_scope = tf_em_ext_common_free,
};
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_MCG },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_8B },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_16B },
- /* CFA_RESOURCE_TYPE_P4_SRAM_ENCAP_32B */
+ /* CFA_RESOURCE_TYPE_P4_ENCAP_32B */
{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_ENCAP_64B },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_SP_MAC },
- /* CFA_RESOURCE_TYPE_P4_SRAM_SP_SMAC_IPV4 */
- { TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
- /* CFA_RESOURCE_TYPE_P4_SRAM_SP_SMAC_IPV6 */
+ { TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_SP_MAC_IPV4 },
+ /* CFA_RESOURCE_TYPE_P4_SP_MAC_IPV6 */
{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_COUNTER_64B },
{ TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_NAT_SPORT },
/* CFA_RESOURCE_TYPE_P4_EXT */
{ TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID }
};
+
+struct tf_rm_element_cfg tf_em_ext_p4[TF_EM_TBL_TYPE_MAX] = {
+ /* CFA_RESOURCE_TYPE_P4_EM_REC */
+ { TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
+ { TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_TBL_SCOPE },
+};
+
+struct tf_rm_element_cfg tf_em_int_p4[TF_EM_TBL_TYPE_MAX] = {
+ { TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_EM_REC },
+ /* CFA_RESOURCE_TYPE_P4_TBL_SCOPE */
+ { TF_RM_ELEM_CFG_NULL, CFA_RESOURCE_TYPE_INVALID },
+};
+
#endif /* _TF_DEVICE_P4_H_ */
+++ /dev/null
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019-2020 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_em.h"
-#include "tf_msg.h"
-#include "tfp.h"
-#include "lookup3.h"
-#include "tf_ext_flow_handle.h"
-
-#include "bnxt.h"
-
-
-static uint32_t tf_em_get_key_mask(int num_entries)
-{
- uint32_t mask = num_entries - 1;
-
- if (num_entries & 0x7FFF)
- return 0;
-
- if (num_entries > (128 * 1024 * 1024))
- return 0;
-
- return mask;
-}
-
-static void tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
- uint8_t *in_key,
- struct cfa_p4_eem_64b_entry *key_entry)
-{
- key_entry->hdr.word1 = result->word1;
-
- if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
- key_entry->hdr.pointer = result->pointer;
- else
- key_entry->hdr.pointer = result->pointer;
-
- memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
-
-#ifdef TF_EEM_DEBUG
- dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
-#endif
-}
-
-/** insert EEM entry API
- *
- * returns:
- * 0
- * TF_ERR - unable to get lock
- *
- * insert callback returns:
- * 0
- * TF_ERR_EM_DUP - key is already in table
- */
-static int tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
- struct tf_insert_em_entry_parms *parms)
-{
- uint32_t mask;
- uint32_t key0_hash;
- uint32_t key1_hash;
- uint32_t key0_index;
- uint32_t key1_index;
- struct cfa_p4_eem_64b_entry key_entry;
- uint32_t index;
- enum hcapi_cfa_em_table_type table_type;
- uint32_t gfid;
- struct hcapi_cfa_hwop op;
- struct hcapi_cfa_key_tbl key_tbl;
- struct hcapi_cfa_key_data key_obj;
- struct hcapi_cfa_key_loc key_loc;
- uint64_t big_hash;
- int rc;
-
- /* Get mask to use on hash */
- mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
-
- if (!mask)
- return -EINVAL;
-
-#ifdef TF_EEM_DEBUG
- dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key");
-#endif
-
- 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);
-
- key0_index = key0_hash & mask;
- key1_index = key1_hash & mask;
-
-#ifdef TF_EEM_DEBUG
- TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash);
- TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash);
-#endif
- /*
- * Use the "result" arg to populate all of the key entry then
- * store the byte swapped "raw" entry in a local copy ready
- * for insertion in to the table.
- */
- tf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,
- ((uint8_t *)parms->key),
- &key_entry);
-
- /*
- * Try to add to Key0 table, if that does not work then
- * try the key1 table.
- */
- index = key0_index;
- op.opcode = HCAPI_CFA_HWOPS_ADD;
- key_tbl.base0 = (uint8_t *)
- &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];
- key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
- key_obj.data = (uint8_t *)&key_entry;
- key_obj.size = TF_EM_KEY_RECORD_SIZE;
-
- rc = hcapi_cfa_key_hw_op(&op,
- &key_tbl,
- &key_obj,
- &key_loc);
-
- if (rc == 0) {
- table_type = TF_KEY0_TABLE;
- } else {
- index = key1_index;
-
- key_tbl.base0 = (uint8_t *)
- &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];
- key_obj.offset =
- (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
-
- rc = hcapi_cfa_key_hw_op(&op,
- &key_tbl,
- &key_obj,
- &key_loc);
- if (rc != 0)
- return rc;
-
- table_type = TF_KEY1_TABLE;
- }
-
- TF_SET_GFID(gfid,
- index,
- table_type);
- TF_SET_FLOW_ID(parms->flow_id,
- gfid,
- TF_GFID_TABLE_EXTERNAL,
- parms->dir);
- TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
- 0,
- 0,
- 0,
- index,
- 0,
- table_type);
-
- return 0;
-}
-
-/**
- * Insert EM internal entry API
- *
- * returns:
- * 0 - Success
- */
-static int tf_insert_em_internal_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 tf_session *session =
- (struct tf_session *)(tfp->session->core_data);
- struct stack *pool = &session->em_pool[parms->dir];
- uint32_t index;
-
- rc = stack_pop(pool, &index);
-
- if (rc != 0) {
- TFP_DRV_LOG(ERR,
- "dir:%d, EM entry index allocation failed\n",
- parms->dir);
- return rc;
- }
-
- rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
- rc = tf_msg_insert_em_internal_entry(tfp,
- parms,
- &rptr_index,
- &rptr_entry,
- &num_of_entries);
- if (rc != 0)
- return -1;
-
- PMD_DRV_LOG(ERR,
- "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
- index * TF_SESSION_EM_ENTRY_SIZE,
- 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,
- num_of_entries,
- 0,
- 0,
- rptr_index,
- rptr_entry,
- 0);
- return 0;
-}
-
-/** Delete EM internal entry API
- *
- * returns:
- * 0
- * -EINVAL
- */
-static int tf_delete_em_internal_entry(struct tf *tfp,
- struct tf_delete_em_entry_parms *parms)
-{
- int rc;
- struct tf_session *session =
- (struct tf_session *)(tfp->session->core_data);
- struct stack *pool = &session->em_pool[parms->dir];
-
- rc = tf_msg_delete_em_entry(tfp, parms);
-
- /* Return resource to pool */
- if (rc == 0)
- stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
-
- return rc;
-}
-
-
-/** delete EEM hash entry API
- *
- * returns:
- * 0
- * -EINVAL - parameter error
- * TF_NO_SESSION - bad session ID
- * TF_ERR_TBL_SCOPE - invalid table scope
- * TF_ERR_TBL_IF - invalid table interface
- *
- * insert callback returns
- * 0
- * TF_NO_EM_MATCH - entry not found
- */
-static int tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
- struct tf_delete_em_entry_parms *parms)
-{
- enum hcapi_cfa_em_table_type hash_type;
- uint32_t index;
- struct hcapi_cfa_hwop op;
- struct hcapi_cfa_key_tbl key_tbl;
- struct hcapi_cfa_key_data key_obj;
- struct hcapi_cfa_key_loc key_loc;
- int rc;
-
- if (parms->flow_handle == 0)
- return -EINVAL;
-
- TF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);
- TF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);
-
- op.opcode = HCAPI_CFA_HWOPS_DEL;
- key_tbl.base0 = (uint8_t *)
- &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[(hash_type == 0 ?
- TF_KEY0_TABLE :
- TF_KEY1_TABLE)];
- key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
- key_obj.data = NULL;
- key_obj.size = TF_EM_KEY_RECORD_SIZE;
-
- rc = hcapi_cfa_key_hw_op(&op,
- &key_tbl,
- &key_obj,
- &key_loc);
-
- if (!rc)
- return rc;
-
- return 0;
-}
-
-/** insert EM hash entry API
- *
- * returns:
- * 0 - Success
- * -EINVAL - Error
- */
-int tf_em_insert_entry(struct tf *tfp,
- struct tf_insert_em_entry_parms *parms)
-{
- struct tf_tbl_scope_cb *tbl_scope_cb;
-
- tbl_scope_cb = tbl_scope_cb_find
- ((struct tf_session *)(tfp->session->core_data),
- parms->tbl_scope_id);
- if (tbl_scope_cb == NULL) {
- TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
- return -EINVAL;
- }
-
- /* Process the EM entry per Table Scope type */
- if (parms->mem == TF_MEM_EXTERNAL)
- /* External EEM */
- return tf_insert_eem_entry
- (tbl_scope_cb, parms);
- else if (parms->mem == TF_MEM_INTERNAL)
- /* Internal EM */
- return tf_insert_em_internal_entry(tfp, parms);
-
- return -EINVAL;
-}
-
-/** Delete EM hash entry API
- *
- * returns:
- * 0 - Success
- * -EINVAL - Error
- */
-int tf_em_delete_entry(struct tf *tfp,
- struct tf_delete_em_entry_parms *parms)
-{
- struct tf_tbl_scope_cb *tbl_scope_cb;
-
- tbl_scope_cb = tbl_scope_cb_find
- ((struct tf_session *)(tfp->session->core_data),
- parms->tbl_scope_id);
- if (tbl_scope_cb == NULL) {
- TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
- return -EINVAL;
- }
- if (parms->mem == TF_MEM_EXTERNAL)
- return tf_delete_eem_entry(tbl_scope_cb, parms);
- else if (parms->mem == TF_MEM_INTERNAL)
- return tf_delete_em_internal_entry(tfp, parms);
-
- return -EINVAL;
-}
#include "tf_core.h"
#include "tf_session.h"
+#define TF_HACK_TBL_SCOPE_BASE 68
#define SUPPORT_CFA_HW_P4 1
#define SUPPORT_CFA_HW_P58 0
#define SUPPORT_CFA_HW_P59 0
#define TF_HW_EM_KEY_MAX_SIZE 52
#define TF_EM_KEY_RECORD_SIZE 64
+#define TF_EM_MAX_MASK 0x7FFF
+#define TF_EM_MAX_ENTRY (128 * 1024 * 1024)
+
/*
* Used to build GFID:
*
uint8_t key[TF_EM_KEY_RECORD_SIZE - sizeof(struct cfa_p4_eem_entry_hdr)];
};
+/** EEM Memory Type
+ *
+ */
+enum tf_mem_type {
+ TF_EEM_MEM_TYPE_INVALID,
+ TF_EEM_MEM_TYPE_HOST,
+ TF_EEM_MEM_TYPE_SYSTEM
+};
+
+/**
+ * tf_em_cfg_parms definition
+ */
+struct tf_em_cfg_parms {
+ /**
+ * [in] Num entries in resource config
+ */
+ uint16_t num_elements;
+ /**
+ * [in] Resource config
+ */
+ struct tf_rm_element_cfg *cfg;
+ /**
+ * Session resource allocations
+ */
+ struct tf_session_resources *resources;
+ /**
+ * [in] Memory type.
+ */
+ enum tf_mem_type mem_type;
+};
+
+/**
+ * @page table Table
+ *
+ * @ref tf_alloc_eem_tbl_scope
+ *
+ * @ref tf_free_eem_tbl_scope_cb
+ *
+ * @ref tbl_scope_cb_find
+ */
+
/**
* Allocates EEM Table scope
*
struct tf_free_tbl_scope_parms *parms);
/**
- * Function to search for table scope control block structure
- * with specified table scope ID.
+ * 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_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_delete_int_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms);
+
+/**
+ * Insert record in to external EEM table
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_insert_ext_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms);
+
+/**
+ * Insert record from external EEM table
*
- * [in] session
- * Session to use for the search of the table scope control block
- * [in] tbl_scope_id
- * Table scope ID to search for
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
*
* Returns:
- * Pointer to the found table scope control block struct or NULL if
- * table scope control block struct not found
+ * 0 - Success
+ * -EINVAL - Parameter error
*/
-struct tf_tbl_scope_cb *tbl_scope_cb_find(struct tf_session *session,
- uint32_t tbl_scope_id);
+int tf_em_delete_ext_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms);
-void *tf_em_get_table_page(struct tf_tbl_scope_cb *tbl_scope_cb,
- enum tf_dir dir,
- uint32_t offset,
- enum hcapi_cfa_em_table_type table_type);
+/**
+ * Insert record in to external system EEM table
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_insert_ext_sys_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms);
+
+/**
+ * Delete record from external system EEM table
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_delete_ext_sys_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms);
-int tf_em_insert_entry(struct tf *tfp,
- struct tf_insert_em_entry_parms *parms);
+/**
+ * Bind internal EM device interface
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_int_bind(struct tf *tfp,
+ struct tf_em_cfg_parms *parms);
-int tf_em_delete_entry(struct tf *tfp,
- struct tf_delete_em_entry_parms *parms);
+/**
+ * Unbind internal EM device interface
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_int_unbind(struct tf *tfp);
+
+/**
+ * Common bind for EEM device interface. Used for both host and
+ * system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_common_bind(struct tf *tfp,
+ struct tf_em_cfg_parms *parms);
+
+/**
+ * Common unbind for EEM device interface. Used for both host and
+ * system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_common_unbind(struct tf *tfp);
+
+/**
+ * Alloc for external EEM using host memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_host_alloc(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms);
+
+/**
+ * Free for external EEM using host memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_host_free(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Alloc for external EEM using system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_system_alloc(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms);
+
+/**
+ * Free for external EEM using system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_system_free(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Common free for external EEM using host or system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_common_free(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms);
+
+/**
+ * Common alloc for external EEM using host or system memory
+ *
+ * [in] tfp
+ * Pointer to TruFlow handle
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+int tf_em_ext_common_alloc(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms);
#endif /* _TF_EM_H_ */
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <sys/param.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_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "tf_device.h"
+#include "tf_ext_flow_handle.h"
+#include "cfa_resource_types.h"
+
+#include "bnxt.h"
+
+
+/**
+ * EM DBs.
+ */
+void *eem_db[TF_DIR_MAX];
+
+/**
+ * Init flag, set on bind and cleared on unbind
+ */
+static uint8_t init;
+
+/**
+ * Host or system
+ */
+static enum tf_mem_type mem_type;
+
+/* API defined in tf_em.h */
+struct tf_tbl_scope_cb *
+tbl_scope_cb_find(struct tf_session *session,
+ uint32_t tbl_scope_id)
+{
+ int i;
+ struct tf_rm_is_allocated_parms parms;
+ int allocated;
+
+ /* Check that id is valid */
+ parms.rm_db = eem_db[TF_DIR_RX];
+ parms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+ parms.index = tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+ parms.allocated = &allocated;
+
+ i = tf_rm_is_allocated(&parms);
+
+ if (i < 0 || !allocated)
+ return NULL;
+
+ for (i = 0; i < TF_NUM_TBL_SCOPE; i++) {
+ if (session->tbl_scopes[i].tbl_scope_id == tbl_scope_id)
+ return &session->tbl_scopes[i];
+ }
+
+ return NULL;
+}
+
+int
+tf_create_tbl_pool_external(enum tf_dir dir,
+ struct tf_tbl_scope_cb *tbl_scope_cb,
+ uint32_t num_entries,
+ uint32_t entry_sz_bytes)
+{
+ struct tfp_calloc_parms parms;
+ uint32_t i;
+ int32_t j;
+ int rc = 0;
+ struct stack *pool = &tbl_scope_cb->ext_act_pool[dir];
+
+ parms.nitems = num_entries;
+ parms.size = sizeof(uint32_t);
+ parms.alignment = 0;
+
+ if (tfp_calloc(&parms) != 0) {
+ TFP_DRV_LOG(ERR, "%s: TBL: external pool failure %s\n",
+ tf_dir_2_str(dir), strerror(ENOMEM));
+ return -ENOMEM;
+ }
+
+ /* Create empty stack
+ */
+ rc = stack_init(num_entries, parms.mem_va, pool);
+
+ if (rc != 0) {
+ TFP_DRV_LOG(ERR, "%s: TBL: stack init failure %s\n",
+ tf_dir_2_str(dir), strerror(-rc));
+ goto cleanup;
+ }
+
+ /* Save the malloced memory address so that it can
+ * be freed when the table scope is freed.
+ */
+ tbl_scope_cb->ext_act_pool_mem[dir] = (uint32_t *)parms.mem_va;
+
+ /* Fill pool with indexes in reverse
+ */
+ j = (num_entries - 1) * entry_sz_bytes;
+
+ for (i = 0; i < num_entries; i++) {
+ rc = stack_push(pool, j);
+ if (rc != 0) {
+ TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
+ tf_dir_2_str(dir), strerror(-rc));
+ goto cleanup;
+ }
+
+ if (j < 0) {
+ TFP_DRV_LOG(ERR, "%d TBL: invalid offset (%d)\n",
+ dir, j);
+ goto cleanup;
+ }
+ j -= entry_sz_bytes;
+ }
+
+ if (!stack_is_full(pool)) {
+ rc = -EINVAL;
+ TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
+ tf_dir_2_str(dir), strerror(-rc));
+ goto cleanup;
+ }
+ return 0;
+cleanup:
+ tfp_free((void *)parms.mem_va);
+ return rc;
+}
+
+/**
+ * Destroy External Tbl pool of memory indexes.
+ *
+ * [in] dir
+ * direction
+ * [in] tbl_scope_cb
+ * pointer to the table scope
+ */
+void
+tf_destroy_tbl_pool_external(enum tf_dir dir,
+ struct tf_tbl_scope_cb *tbl_scope_cb)
+{
+ uint32_t *ext_act_pool_mem =
+ tbl_scope_cb->ext_act_pool_mem[dir];
+
+ tfp_free(ext_act_pool_mem);
+}
+
+uint32_t
+tf_em_get_key_mask(int num_entries)
+{
+ uint32_t mask = num_entries - 1;
+
+ if (num_entries & TF_EM_MAX_MASK)
+ return 0;
+
+ if (num_entries > TF_EM_MAX_ENTRY)
+ return 0;
+
+ return mask;
+}
+
+void
+tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
+ uint8_t *in_key,
+ struct cfa_p4_eem_64b_entry *key_entry)
+{
+ key_entry->hdr.word1 = result->word1;
+
+ if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
+ key_entry->hdr.pointer = result->pointer;
+ else
+ key_entry->hdr.pointer = result->pointer;
+
+ memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
+
+#ifdef TF_EEM_DEBUG
+ dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
+#endif
+}
+
+int
+tf_em_ext_common_bind(struct tf *tfp,
+ struct tf_em_cfg_parms *parms)
+{
+ int rc;
+ int i;
+ struct tf_rm_create_db_parms db_cfg = { 0 };
+
+ TF_CHECK_PARMS2(tfp, parms);
+
+ if (init) {
+ TFP_DRV_LOG(ERR,
+ "Identifier already initialized\n");
+ return -EINVAL;
+ }
+
+ db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
+ db_cfg.num_elements = parms->num_elements;
+ db_cfg.cfg = parms->cfg;
+
+ for (i = 0; i < TF_DIR_MAX; i++) {
+ db_cfg.dir = i;
+ db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
+ db_cfg.rm_db = &eem_db[i];
+ rc = tf_rm_create_db(tfp, &db_cfg);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: EM DB creation failed\n",
+ tf_dir_2_str(i));
+
+ return rc;
+ }
+ }
+
+ mem_type = parms->mem_type;
+ init = 1;
+
+ return 0;
+}
+
+int
+tf_em_ext_common_unbind(struct tf *tfp)
+{
+ int rc;
+ int i;
+ struct tf_rm_free_db_parms fparms = { 0 };
+
+ TF_CHECK_PARMS1(tfp);
+
+ /* Bail if nothing has been initialized done silent as to
+ * allow for creation cleanup.
+ */
+ if (!init) {
+ TFP_DRV_LOG(ERR,
+ "No EM DBs created\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < TF_DIR_MAX; i++) {
+ fparms.dir = i;
+ fparms.rm_db = eem_db[i];
+ rc = tf_rm_free_db(tfp, &fparms);
+ if (rc)
+ return rc;
+
+ eem_db[i] = NULL;
+ }
+
+ init = 0;
+
+ return 0;
+}
+
+int
+tf_em_ext_common_alloc(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms)
+{
+ if (mem_type == TF_EEM_MEM_TYPE_HOST)
+ return tf_em_ext_host_alloc(tfp, parms);
+ else
+ return tf_em_ext_system_alloc(tfp, parms);
+}
+
+int
+tf_em_ext_common_free(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms)
+{
+ if (mem_type == TF_EEM_MEM_TYPE_HOST)
+ return tf_em_ext_host_free(tfp, parms);
+ else
+ return tf_em_ext_system_free(tfp, parms);
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _TF_EM_COMMON_H_
+#define _TF_EM_COMMON_H_
+
+#include "tf_core.h"
+#include "tf_session.h"
+
+
+/**
+ * Function to search for table scope control block structure
+ * with specified table scope ID.
+ *
+ * [in] session
+ * Session to use for the search of the table scope control block
+ * [in] tbl_scope_id
+ * Table scope ID to search for
+ *
+ * Returns:
+ * Pointer to the found table scope control block struct or NULL if
+ * table scope control block struct not found
+ */
+struct tf_tbl_scope_cb *tbl_scope_cb_find(struct tf_session *session,
+ uint32_t tbl_scope_id);
+
+/**
+ * Create and initialize a stack to use for action entries
+ *
+ * [in] dir
+ * Direction
+ * [in] tbl_scope_id
+ * Table scope ID
+ * [in] num_entries
+ * Number of EEM entries
+ * [in] entry_sz_bytes
+ * Size of the entry
+ *
+ * Returns:
+ * 0 - Success
+ * -ENOMEM - Out of memory
+ * -EINVAL - Failure
+ */
+int tf_create_tbl_pool_external(enum tf_dir dir,
+ struct tf_tbl_scope_cb *tbl_scope_cb,
+ uint32_t num_entries,
+ uint32_t entry_sz_bytes);
+
+/**
+ * Delete and cleanup action record allocation stack
+ *
+ * [in] dir
+ * Direction
+ * [in] tbl_scope_id
+ * Table scope ID
+ *
+ */
+void tf_destroy_tbl_pool_external(enum tf_dir dir,
+ struct tf_tbl_scope_cb *tbl_scope_cb);
+
+/**
+ * Get hash mask for current EEM table size
+ *
+ * [in] num_entries
+ * Number of EEM entries
+ */
+uint32_t tf_em_get_key_mask(int num_entries);
+
+/**
+ * Populate key_entry
+ *
+ * [in] result
+ * Entry data
+ * [in] in_key
+ * Key data
+ * [out] key_entry
+ * Completed key record
+ */
+void tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
+ uint8_t *in_key,
+ struct cfa_p4_eem_64b_entry *key_entry);
+
+/**
+ * Find base page address for offset into specified table type
+ *
+ * [in] tbl_scope_cb
+ * Table scope
+ * [in] dir
+ * Direction
+ * [in] Offset
+ * Offset in to table
+ * [in] table_type
+ * Table type
+ *
+ * Returns:
+ *
+ * 0 - Failure
+ * Void pointer to page base address - Success
+ */
+void *tf_em_get_table_page(struct tf_tbl_scope_cb *tbl_scope_cb,
+ enum tf_dir dir,
+ uint32_t offset,
+ enum hcapi_cfa_em_table_type table_type);
+
+#endif /* _TF_EM_COMMON_H_ */
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <sys/param.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_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "lookup3.h"
+#include "tf_ext_flow_handle.h"
+
+#include "bnxt.h"
+
+
+#define PTU_PTE_VALID 0x1UL
+#define PTU_PTE_LAST 0x2UL
+#define PTU_PTE_NEXT_TO_LAST 0x4UL
+
+/* Number of pointers per page_size */
+#define MAX_PAGE_PTRS(page_size) ((page_size) / sizeof(void *))
+
+#define TF_EM_PG_SZ_4K (1 << 12)
+#define TF_EM_PG_SZ_8K (1 << 13)
+#define TF_EM_PG_SZ_64K (1 << 16)
+#define TF_EM_PG_SZ_256K (1 << 18)
+#define TF_EM_PG_SZ_1M (1 << 20)
+#define TF_EM_PG_SZ_2M (1 << 21)
+#define TF_EM_PG_SZ_4M (1 << 22)
+#define TF_EM_PG_SZ_1G (1 << 30)
+
+#define TF_EM_CTX_ID_INVALID 0xFFFF
+
+#define TF_EM_MIN_ENTRIES (1 << 15) /* 32K */
+#define TF_EM_MAX_ENTRIES (1 << 27) /* 128M */
+
+/**
+ * EM DBs.
+ */
+extern void *eem_db[TF_DIR_MAX];
+
+/**
+ * Function to free a page table
+ *
+ * [in] tp
+ * Pointer to the page table to free
+ */
+static void
+tf_em_free_pg_tbl(struct hcapi_cfa_em_page_tbl *tp)
+{
+ uint32_t i;
+
+ for (i = 0; i < tp->pg_count; i++) {
+ if (!tp->pg_va_tbl[i]) {
+ TFP_DRV_LOG(WARNING,
+ "No mapping for page: %d table: %016" PRIu64 "\n",
+ i,
+ (uint64_t)(uintptr_t)tp);
+ continue;
+ }
+
+ tfp_free(tp->pg_va_tbl[i]);
+ tp->pg_va_tbl[i] = NULL;
+ }
+
+ tp->pg_count = 0;
+ tfp_free(tp->pg_va_tbl);
+ tp->pg_va_tbl = NULL;
+ tfp_free(tp->pg_pa_tbl);
+ tp->pg_pa_tbl = NULL;
+}
+
+/**
+ * Function to free an EM table
+ *
+ * [in] tbl
+ * Pointer to the EM table to free
+ */
+static void
+tf_em_free_page_table(struct hcapi_cfa_em_table *tbl)
+{
+ struct hcapi_cfa_em_page_tbl *tp;
+ int i;
+
+ for (i = 0; i < tbl->num_lvl; i++) {
+ tp = &tbl->pg_tbl[i];
+ TFP_DRV_LOG(INFO,
+ "EEM: Freeing page table: size %u lvl %d cnt %u\n",
+ TF_EM_PAGE_SIZE,
+ i,
+ tp->pg_count);
+
+ tf_em_free_pg_tbl(tp);
+ }
+
+ tbl->l0_addr = NULL;
+ tbl->l0_dma_addr = 0;
+ tbl->num_lvl = 0;
+ tbl->num_data_pages = 0;
+}
+
+/**
+ * Allocation of page tables
+ *
+ * [in] tfp
+ * Pointer to a TruFlow handle
+ *
+ * [in] pg_count
+ * Page count to allocate
+ *
+ * [in] pg_size
+ * Size of each page
+ *
+ * Returns:
+ * 0 - Success
+ * -ENOMEM - Out of memory
+ */
+static int
+tf_em_alloc_pg_tbl(struct hcapi_cfa_em_page_tbl *tp,
+ uint32_t pg_count,
+ uint32_t pg_size)
+{
+ uint32_t i;
+ struct tfp_calloc_parms parms;
+
+ parms.nitems = pg_count;
+ parms.size = sizeof(void *);
+ parms.alignment = 0;
+
+ if (tfp_calloc(&parms) != 0)
+ return -ENOMEM;
+
+ tp->pg_va_tbl = parms.mem_va;
+
+ if (tfp_calloc(&parms) != 0) {
+ tfp_free(tp->pg_va_tbl);
+ return -ENOMEM;
+ }
+
+ tp->pg_pa_tbl = parms.mem_va;
+
+ tp->pg_count = 0;
+ tp->pg_size = pg_size;
+
+ for (i = 0; i < pg_count; i++) {
+ parms.nitems = 1;
+ parms.size = pg_size;
+ parms.alignment = TF_EM_PAGE_ALIGNMENT;
+
+ if (tfp_calloc(&parms) != 0)
+ goto cleanup;
+
+ tp->pg_pa_tbl[i] = (uintptr_t)parms.mem_pa;
+ tp->pg_va_tbl[i] = parms.mem_va;
+
+ memset(tp->pg_va_tbl[i], 0, pg_size);
+ tp->pg_count++;
+ }
+
+ return 0;
+
+cleanup:
+ tf_em_free_pg_tbl(tp);
+ return -ENOMEM;
+}
+
+/**
+ * Allocates EM page tables
+ *
+ * [in] tbl
+ * Table to allocate pages for
+ *
+ * Returns:
+ * 0 - Success
+ * -ENOMEM - Out of memory
+ */
+static int
+tf_em_alloc_page_table(struct hcapi_cfa_em_table *tbl)
+{
+ struct hcapi_cfa_em_page_tbl *tp;
+ int rc = 0;
+ int i;
+ uint32_t j;
+
+ for (i = 0; i < tbl->num_lvl; i++) {
+ tp = &tbl->pg_tbl[i];
+
+ rc = tf_em_alloc_pg_tbl(tp,
+ tbl->page_cnt[i],
+ TF_EM_PAGE_SIZE);
+ if (rc) {
+ TFP_DRV_LOG(WARNING,
+ "Failed to allocate page table: lvl: %d, rc:%s\n",
+ i,
+ strerror(-rc));
+ goto cleanup;
+ }
+
+ for (j = 0; j < tp->pg_count; j++) {
+ TFP_DRV_LOG(INFO,
+ "EEM: Allocated page table: size %u lvl %d cnt"
+ " %u VA:%p PA:%p\n",
+ TF_EM_PAGE_SIZE,
+ i,
+ tp->pg_count,
+ (void *)(uintptr_t)tp->pg_va_tbl[j],
+ (void *)(uintptr_t)tp->pg_pa_tbl[j]);
+ }
+ }
+ return rc;
+
+cleanup:
+ tf_em_free_page_table(tbl);
+ return rc;
+}
+
+/**
+ * Links EM page tables
+ *
+ * [in] tp
+ * Pointer to page table
+ *
+ * [in] tp_next
+ * Pointer to the next page table
+ *
+ * [in] set_pte_last
+ * Flag controlling if the page table is last
+ */
+static void
+tf_em_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
+ struct hcapi_cfa_em_page_tbl *tp_next,
+ bool set_pte_last)
+{
+ uint64_t *pg_pa = tp_next->pg_pa_tbl;
+ uint64_t *pg_va;
+ uint64_t valid;
+ uint32_t k = 0;
+ uint32_t i;
+ uint32_t j;
+
+ for (i = 0; i < tp->pg_count; i++) {
+ pg_va = tp->pg_va_tbl[i];
+
+ for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
+ if (k == tp_next->pg_count - 2 && set_pte_last)
+ valid = PTU_PTE_NEXT_TO_LAST | PTU_PTE_VALID;
+ else if (k == tp_next->pg_count - 1 && set_pte_last)
+ valid = PTU_PTE_LAST | PTU_PTE_VALID;
+ else
+ valid = PTU_PTE_VALID;
+
+ pg_va[j] = tfp_cpu_to_le_64(pg_pa[k] | valid);
+ if (++k >= tp_next->pg_count)
+ return;
+ }
+ }
+}
+
+/**
+ * Setup a EM page table
+ *
+ * [in] tbl
+ * Pointer to EM page table
+ */
+static void
+tf_em_setup_page_table(struct hcapi_cfa_em_table *tbl)
+{
+ struct hcapi_cfa_em_page_tbl *tp_next;
+ struct hcapi_cfa_em_page_tbl *tp;
+ bool set_pte_last = 0;
+ int i;
+
+ for (i = 0; i < tbl->num_lvl - 1; i++) {
+ tp = &tbl->pg_tbl[i];
+ tp_next = &tbl->pg_tbl[i + 1];
+ if (i == tbl->num_lvl - 2)
+ set_pte_last = 1;
+ tf_em_link_page_table(tp, tp_next, set_pte_last);
+ }
+
+ tbl->l0_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_va_tbl[0];
+ tbl->l0_dma_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_pa_tbl[0];
+}
+
+/**
+ * Given the page size, size of each data item (entry size),
+ * and the total number of entries needed, determine the number
+ * of page table levels and the number of data pages required.
+ *
+ * [in] page_size
+ * Page size
+ *
+ * [in] entry_size
+ * Entry size
+ *
+ * [in] num_entries
+ * Number of entries needed
+ *
+ * [out] num_data_pages
+ * Number of pages required
+ *
+ * Returns:
+ * Success - Number of EM page levels required
+ * -ENOMEM - Out of memory
+ */
+static int
+tf_em_size_page_tbl_lvl(uint32_t page_size,
+ uint32_t entry_size,
+ uint32_t num_entries,
+ uint64_t *num_data_pages)
+{
+ uint64_t lvl_data_size = page_size;
+ int lvl = TF_PT_LVL_0;
+ uint64_t data_size;
+
+ *num_data_pages = 0;
+ data_size = (uint64_t)num_entries * entry_size;
+
+ while (lvl_data_size < data_size) {
+ lvl++;
+
+ if (lvl == TF_PT_LVL_1)
+ lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
+ page_size;
+ else if (lvl == TF_PT_LVL_2)
+ lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
+ MAX_PAGE_PTRS(page_size) * page_size;
+ else
+ return -ENOMEM;
+ }
+
+ *num_data_pages = roundup(data_size, page_size) / page_size;
+
+ return lvl;
+}
+
+/**
+ * Return the number of page table pages needed to
+ * reference the given number of next level pages.
+ *
+ * [in] num_pages
+ * Number of EM pages
+ *
+ * [in] page_size
+ * Size of each EM page
+ *
+ * Returns:
+ * Number of EM page table pages
+ */
+static uint32_t
+tf_em_page_tbl_pgcnt(uint32_t num_pages,
+ uint32_t page_size)
+{
+ return roundup(num_pages, MAX_PAGE_PTRS(page_size)) /
+ MAX_PAGE_PTRS(page_size);
+ return 0;
+}
+
+/**
+ * Given the number of data pages, page_size and the maximum
+ * number of page table levels (already determined), size
+ * the number of page table pages required at each level.
+ *
+ * [in] max_lvl
+ * Max number of levels
+ *
+ * [in] num_data_pages
+ * Number of EM data pages
+ *
+ * [in] page_size
+ * Size of an EM page
+ *
+ * [out] *page_cnt
+ * EM page count
+ */
+static void
+tf_em_size_page_tbls(int max_lvl,
+ uint64_t num_data_pages,
+ uint32_t page_size,
+ uint32_t *page_cnt)
+{
+ if (max_lvl == TF_PT_LVL_0) {
+ page_cnt[TF_PT_LVL_0] = num_data_pages;
+ } else if (max_lvl == TF_PT_LVL_1) {
+ page_cnt[TF_PT_LVL_1] = num_data_pages;
+ page_cnt[TF_PT_LVL_0] =
+ tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
+ } else if (max_lvl == TF_PT_LVL_2) {
+ page_cnt[TF_PT_LVL_2] = num_data_pages;
+ page_cnt[TF_PT_LVL_1] =
+ tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);
+ page_cnt[TF_PT_LVL_0] =
+ tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
+ } else {
+ return;
+ }
+}
+
+/**
+ * Size the EM table based on capabilities
+ *
+ * [in] tbl
+ * EM table to size
+ *
+ * Returns:
+ * 0 - Success
+ * - EINVAL - Parameter error
+ * - ENOMEM - Out of memory
+ */
+static int
+tf_em_size_table(struct hcapi_cfa_em_table *tbl)
+{
+ uint64_t num_data_pages;
+ uint32_t *page_cnt;
+ int max_lvl;
+ uint32_t num_entries;
+ uint32_t cnt = TF_EM_MIN_ENTRIES;
+
+ /* Ignore entry if both size and number are zero */
+ if (!tbl->entry_size && !tbl->num_entries)
+ return 0;
+
+ /* If only one is set then error */
+ if (!tbl->entry_size || !tbl->num_entries)
+ return -EINVAL;
+
+ /* Determine number of page table levels and the number
+ * of data pages needed to process the given eem table.
+ */
+ if (tbl->type == TF_RECORD_TABLE) {
+ /*
+ * For action records just a memory size is provided. Work
+ * backwards to resolve to number of entries
+ */
+ num_entries = tbl->num_entries / tbl->entry_size;
+ if (num_entries < TF_EM_MIN_ENTRIES) {
+ num_entries = TF_EM_MIN_ENTRIES;
+ } else {
+ while (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)
+ cnt *= 2;
+ num_entries = cnt;
+ }
+ } else {
+ num_entries = tbl->num_entries;
+ }
+
+ max_lvl = tf_em_size_page_tbl_lvl(TF_EM_PAGE_SIZE,
+ tbl->entry_size,
+ tbl->num_entries,
+ &num_data_pages);
+ if (max_lvl < 0) {
+ TFP_DRV_LOG(WARNING, "EEM: Failed to size page table levels\n");
+ TFP_DRV_LOG(WARNING,
+ "table: %d data-sz: %016" PRIu64 " page-sz: %u\n",
+ tbl->type, (uint64_t)num_entries * tbl->entry_size,
+ TF_EM_PAGE_SIZE);
+ return -ENOMEM;
+ }
+
+ tbl->num_lvl = max_lvl + 1;
+ tbl->num_data_pages = num_data_pages;
+
+ /* Determine the number of pages needed at each level */
+ page_cnt = tbl->page_cnt;
+ memset(page_cnt, 0, sizeof(tbl->page_cnt));
+ tf_em_size_page_tbls(max_lvl, num_data_pages, TF_EM_PAGE_SIZE,
+ page_cnt);
+
+ TFP_DRV_LOG(INFO, "EEM: Sized page table: %d\n", tbl->type);
+ TFP_DRV_LOG(INFO,
+ "EEM: lvls: %d sz: %016" PRIu64 " pgs: %016" PRIu64 " l0: %u l1: %u l2: %u\n",
+ max_lvl + 1,
+ (uint64_t)num_data_pages * TF_EM_PAGE_SIZE,
+ num_data_pages,
+ page_cnt[TF_PT_LVL_0],
+ page_cnt[TF_PT_LVL_1],
+ page_cnt[TF_PT_LVL_2]);
+
+ return 0;
+}
+
+/**
+ * Unregisters EM Ctx in Firmware
+ *
+ * [in] tfp
+ * Pointer to a TruFlow handle
+ *
+ * [in] tbl_scope_cb
+ * Pointer to a table scope control block
+ *
+ * [in] dir
+ * Receive or transmit direction
+ */
+static void
+tf_em_ctx_unreg(struct tf *tfp,
+ struct tf_tbl_scope_cb *tbl_scope_cb,
+ int dir)
+{
+ struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
+ struct hcapi_cfa_em_table *tbl;
+ int i;
+
+ for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
+ tbl = &ctxp->em_tables[i];
+
+ if (tbl->num_entries != 0 && tbl->entry_size != 0) {
+ tf_msg_em_mem_unrgtr(tfp, &tbl->ctx_id);
+ tf_em_free_page_table(tbl);
+ }
+ }
+}
+
+/**
+ * Registers EM Ctx in Firmware
+ *
+ * [in] tfp
+ * Pointer to a TruFlow handle
+ *
+ * [in] tbl_scope_cb
+ * Pointer to a table scope control block
+ *
+ * [in] dir
+ * Receive or transmit direction
+ *
+ * Returns:
+ * 0 - Success
+ * -ENOMEM - Out of Memory
+ */
+static int
+tf_em_ctx_reg(struct tf *tfp,
+ struct tf_tbl_scope_cb *tbl_scope_cb,
+ int dir)
+{
+ struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir];
+ struct hcapi_cfa_em_table *tbl;
+ int rc;
+ int i;
+
+ for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
+ tbl = &ctxp->em_tables[i];
+
+ if (tbl->num_entries && tbl->entry_size) {
+ rc = tf_em_size_table(tbl);
+
+ if (rc)
+ goto cleanup;
+
+ rc = tf_em_alloc_page_table(tbl);
+ if (rc)
+ goto cleanup;
+
+ tf_em_setup_page_table(tbl);
+ rc = tf_msg_em_mem_rgtr(tfp,
+ tbl->num_lvl - 1,
+ TF_EM_PAGE_SIZE_ENUM,
+ tbl->l0_dma_addr,
+ &tbl->ctx_id);
+ if (rc)
+ goto cleanup;
+ }
+ }
+ return rc;
+
+cleanup:
+ tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
+ return rc;
+}
+
+
+/**
+ * Validates EM number of entries requested
+ *
+ * [in] tbl_scope_cb
+ * Pointer to table scope control block to be populated
+ *
+ * [in] parms
+ * Pointer to input parameters
+ *
+ * Returns:
+ * 0 - Success
+ * -EINVAL - Parameter error
+ */
+static int
+tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,
+ struct tf_alloc_tbl_scope_parms *parms)
+{
+ uint32_t cnt;
+
+ if (parms->rx_mem_size_in_mb != 0) {
+ uint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);
+ uint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)
+ + 1);
+ uint32_t num_entries = (parms->rx_mem_size_in_mb *
+ TF_MEGABYTE) / (key_b + action_b);
+
+ if (num_entries < TF_EM_MIN_ENTRIES) {
+ TFP_DRV_LOG(ERR, "EEM: Insufficient memory requested:"
+ "%uMB\n",
+ parms->rx_mem_size_in_mb);
+ return -EINVAL;
+ }
+
+ cnt = TF_EM_MIN_ENTRIES;
+ while (num_entries > cnt &&
+ cnt <= TF_EM_MAX_ENTRIES)
+ cnt *= 2;
+
+ if (cnt > TF_EM_MAX_ENTRIES) {
+ TFP_DRV_LOG(ERR, "EEM: Invalid number of Tx requested: "
+ "%u\n",
+ (parms->tx_num_flows_in_k * TF_KILOBYTE));
+ return -EINVAL;
+ }
+
+ parms->rx_num_flows_in_k = cnt / TF_KILOBYTE;
+ } else {
+ if ((parms->rx_num_flows_in_k * TF_KILOBYTE) <
+ TF_EM_MIN_ENTRIES ||
+ (parms->rx_num_flows_in_k * TF_KILOBYTE) >
+ tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Invalid number of Rx flows "
+ "requested:%u max:%u\n",
+ parms->rx_num_flows_in_k * TF_KILOBYTE,
+ tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);
+ return -EINVAL;
+ }
+
+ /* must be a power-of-2 supported value
+ * in the range 32K - 128M
+ */
+ cnt = TF_EM_MIN_ENTRIES;
+ while ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&
+ cnt <= TF_EM_MAX_ENTRIES)
+ cnt *= 2;
+
+ if (cnt > TF_EM_MAX_ENTRIES) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Invalid number of Rx requested: %u\n",
+ (parms->rx_num_flows_in_k * TF_KILOBYTE));
+ return -EINVAL;
+ }
+ }
+
+ if (parms->tx_mem_size_in_mb != 0) {
+ uint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);
+ uint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)
+ + 1);
+ uint32_t num_entries = (parms->tx_mem_size_in_mb *
+ (TF_KILOBYTE * TF_KILOBYTE)) /
+ (key_b + action_b);
+
+ if (num_entries < TF_EM_MIN_ENTRIES) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Insufficient memory requested:%uMB\n",
+ parms->rx_mem_size_in_mb);
+ return -EINVAL;
+ }
+
+ cnt = TF_EM_MIN_ENTRIES;
+ while (num_entries > cnt &&
+ cnt <= TF_EM_MAX_ENTRIES)
+ cnt *= 2;
+
+ if (cnt > TF_EM_MAX_ENTRIES) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Invalid number of Tx requested: %u\n",
+ (parms->tx_num_flows_in_k * TF_KILOBYTE));
+ return -EINVAL;
+ }
+
+ parms->tx_num_flows_in_k = cnt / TF_KILOBYTE;
+ } else {
+ if ((parms->tx_num_flows_in_k * TF_KILOBYTE) <
+ TF_EM_MIN_ENTRIES ||
+ (parms->tx_num_flows_in_k * TF_KILOBYTE) >
+ tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Invalid number of Tx flows "
+ "requested:%u max:%u\n",
+ (parms->tx_num_flows_in_k * TF_KILOBYTE),
+ tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);
+ return -EINVAL;
+ }
+
+ cnt = TF_EM_MIN_ENTRIES;
+ while ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&
+ cnt <= TF_EM_MAX_ENTRIES)
+ cnt *= 2;
+
+ if (cnt > TF_EM_MAX_ENTRIES) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Invalid number of Tx requested: %u\n",
+ (parms->tx_num_flows_in_k * TF_KILOBYTE));
+ return -EINVAL;
+ }
+ }
+
+ if (parms->rx_num_flows_in_k != 0 &&
+ (parms->rx_max_key_sz_in_bits / 8 == 0)) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Rx key size required: %u\n",
+ (parms->rx_max_key_sz_in_bits));
+ return -EINVAL;
+ }
+
+ if (parms->tx_num_flows_in_k != 0 &&
+ (parms->tx_max_key_sz_in_bits / 8 == 0)) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Tx key size required: %u\n",
+ (parms->tx_max_key_sz_in_bits));
+ return -EINVAL;
+ }
+ /* Rx */
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =
+ parms->rx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =
+ parms->rx_max_key_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =
+ parms->rx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =
+ parms->rx_max_key_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries =
+ parms->rx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size =
+ parms->rx_max_action_entry_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries = 0;
+
+ /* Tx */
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =
+ parms->tx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =
+ parms->tx_max_key_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =
+ parms->tx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =
+ parms->tx_max_key_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries =
+ parms->tx_num_flows_in_k * TF_KILOBYTE;
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size =
+ parms->tx_max_action_entry_sz_in_bits / 8;
+
+ tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries = 0;
+
+ return 0;
+}
+
+/** insert EEM entry API
+ *
+ * returns:
+ * 0
+ * TF_ERR - unable to get lock
+ *
+ * insert callback returns:
+ * 0
+ * TF_ERR_EM_DUP - key is already in table
+ */
+static int
+tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
+ struct tf_insert_em_entry_parms *parms)
+{
+ uint32_t mask;
+ uint32_t key0_hash;
+ uint32_t key1_hash;
+ uint32_t key0_index;
+ uint32_t key1_index;
+ struct cfa_p4_eem_64b_entry key_entry;
+ uint32_t index;
+ enum hcapi_cfa_em_table_type table_type;
+ uint32_t gfid;
+ struct hcapi_cfa_hwop op;
+ struct hcapi_cfa_key_tbl key_tbl;
+ struct hcapi_cfa_key_data key_obj;
+ struct hcapi_cfa_key_loc key_loc;
+ uint64_t big_hash;
+ int rc;
+
+ /* Get mask to use on hash */
+ mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
+
+ if (!mask)
+ return -EINVAL;
+
+#ifdef TF_EEM_DEBUG
+ dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key");
+#endif
+
+ 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);
+
+ key0_index = key0_hash & mask;
+ key1_index = key1_hash & mask;
+
+#ifdef TF_EEM_DEBUG
+ TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash);
+ TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash);
+#endif
+ /*
+ * Use the "result" arg to populate all of the key entry then
+ * store the byte swapped "raw" entry in a local copy ready
+ * for insertion in to the table.
+ */
+ tf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,
+ ((uint8_t *)parms->key),
+ &key_entry);
+
+ /*
+ * Try to add to Key0 table, if that does not work then
+ * try the key1 table.
+ */
+ index = key0_index;
+ op.opcode = HCAPI_CFA_HWOPS_ADD;
+ key_tbl.base0 = (uint8_t *)
+ &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];
+ key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+ key_obj.data = (uint8_t *)&key_entry;
+ key_obj.size = TF_EM_KEY_RECORD_SIZE;
+
+ rc = hcapi_cfa_key_hw_op(&op,
+ &key_tbl,
+ &key_obj,
+ &key_loc);
+
+ if (rc == 0) {
+ table_type = TF_KEY0_TABLE;
+ } else {
+ index = key1_index;
+
+ key_tbl.base0 = (uint8_t *)
+ &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];
+ key_obj.offset =
+ (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+
+ rc = hcapi_cfa_key_hw_op(&op,
+ &key_tbl,
+ &key_obj,
+ &key_loc);
+ if (rc != 0)
+ return rc;
+
+ table_type = TF_KEY1_TABLE;
+ }
+
+ TF_SET_GFID(gfid,
+ index,
+ table_type);
+ TF_SET_FLOW_ID(parms->flow_id,
+ gfid,
+ TF_GFID_TABLE_EXTERNAL,
+ parms->dir);
+ TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
+ 0,
+ 0,
+ 0,
+ index,
+ 0,
+ table_type);
+
+ return 0;
+}
+
+/** delete EEM hash entry API
+ *
+ * returns:
+ * 0
+ * -EINVAL - parameter error
+ * TF_NO_SESSION - bad session ID
+ * TF_ERR_TBL_SCOPE - invalid table scope
+ * TF_ERR_TBL_IF - invalid table interface
+ *
+ * insert callback returns
+ * 0
+ * TF_NO_EM_MATCH - entry not found
+ */
+static int
+tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
+ struct tf_delete_em_entry_parms *parms)
+{
+ enum hcapi_cfa_em_table_type hash_type;
+ uint32_t index;
+ struct hcapi_cfa_hwop op;
+ struct hcapi_cfa_key_tbl key_tbl;
+ struct hcapi_cfa_key_data key_obj;
+ struct hcapi_cfa_key_loc key_loc;
+ int rc;
+
+ if (parms->flow_handle == 0)
+ return -EINVAL;
+
+ TF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);
+ TF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);
+
+ op.opcode = HCAPI_CFA_HWOPS_DEL;
+ key_tbl.base0 = (uint8_t *)
+ &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[(hash_type == 0 ?
+ TF_KEY0_TABLE :
+ TF_KEY1_TABLE)];
+ key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
+ key_obj.data = NULL;
+ key_obj.size = TF_EM_KEY_RECORD_SIZE;
+
+ rc = hcapi_cfa_key_hw_op(&op,
+ &key_tbl,
+ &key_obj,
+ &key_loc);
+
+ if (!rc)
+ return rc;
+
+ return 0;
+}
+
+/** insert EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int
+tf_em_insert_ext_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms)
+{
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+
+ tbl_scope_cb =
+ tbl_scope_cb_find((struct tf_session *)(tfp->session->core_data),
+ parms->tbl_scope_id);
+ if (tbl_scope_cb == NULL) {
+ TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+ return -EINVAL;
+ }
+
+ return tf_insert_eem_entry(tbl_scope_cb, parms);
+}
+
+/** Delete EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int
+tf_em_delete_ext_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms)
+{
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+
+ tbl_scope_cb =
+ tbl_scope_cb_find((struct tf_session *)(tfp->session->core_data),
+ parms->tbl_scope_id);
+ if (tbl_scope_cb == NULL) {
+ TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+ return -EINVAL;
+ }
+
+ return tf_delete_eem_entry(tbl_scope_cb, parms);
+}
+
+int
+tf_em_ext_host_alloc(struct tf *tfp,
+ struct tf_alloc_tbl_scope_parms *parms)
+{
+ int rc;
+ enum tf_dir dir;
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+ struct hcapi_cfa_em_table *em_tables;
+ struct tf_session *session;
+ struct tf_free_tbl_scope_parms free_parms;
+ struct tf_rm_allocate_parms aparms = { 0 };
+ struct tf_rm_free_parms fparms = { 0 };
+
+ session = (struct tf_session *)tfp->session->core_data;
+
+ /* Get Table Scope control block from the session pool */
+ aparms.rm_db = eem_db[TF_DIR_RX];
+ aparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+ aparms.index = (uint32_t *)&parms->tbl_scope_id;
+ rc = tf_rm_allocate(&aparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to allocate table scope\n");
+ return rc;
+ }
+
+ parms->tbl_scope_id -= TF_HACK_TBL_SCOPE_BASE;
+ tbl_scope_cb = &session->tbl_scopes[parms->tbl_scope_id];
+ tbl_scope_cb->index = parms->tbl_scope_id;
+ tbl_scope_cb->tbl_scope_id = parms->tbl_scope_id;
+
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ rc = tf_msg_em_qcaps(tfp,
+ dir,
+ &tbl_scope_cb->em_caps[dir]);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Unable to query for EEM capability,"
+ " rc:%s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+ }
+
+ /*
+ * Validate and setup table sizes
+ */
+ if (tf_em_validate_num_entries(tbl_scope_cb, parms))
+ goto cleanup;
+
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ /*
+ * Allocate tables and signal configuration to FW
+ */
+ rc = tf_em_ctx_reg(tfp, tbl_scope_cb, dir);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Unable to register for EEM ctx,"
+ " rc:%s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+
+ em_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;
+ rc = tf_msg_em_cfg(tfp,
+ em_tables[TF_KEY0_TABLE].num_entries,
+ em_tables[TF_KEY0_TABLE].ctx_id,
+ em_tables[TF_KEY1_TABLE].ctx_id,
+ em_tables[TF_RECORD_TABLE].ctx_id,
+ em_tables[TF_EFC_TABLE].ctx_id,
+ parms->hw_flow_cache_flush_timer,
+ dir);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "TBL: Unable to configure EEM in firmware"
+ " rc:%s\n",
+ strerror(-rc));
+ goto cleanup_full;
+ }
+
+ rc = tf_msg_em_op(tfp,
+ dir,
+ HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_ENABLE);
+
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "EEM: Unable to enable EEM in firmware"
+ " rc:%s\n",
+ strerror(-rc));
+ goto cleanup_full;
+ }
+
+ /* Allocate the pool of offsets of the external memory.
+ * Initially, this is a single fixed size pool for all external
+ * actions related to a single table scope.
+ */
+ rc = tf_create_tbl_pool_external(dir,
+ tbl_scope_cb,
+ em_tables[TF_RECORD_TABLE].num_entries,
+ em_tables[TF_RECORD_TABLE].entry_size);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s TBL: Unable to allocate idx pools %s\n",
+ tf_dir_2_str(dir),
+ strerror(-rc));
+ goto cleanup_full;
+ }
+ }
+
+ return 0;
+
+cleanup_full:
+ free_parms.tbl_scope_id = parms->tbl_scope_id;
+ tf_em_ext_host_free(tfp, &free_parms);
+ return -EINVAL;
+
+cleanup:
+ /* Free Table control block */
+ fparms.rm_db = eem_db[TF_DIR_RX];
+ fparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+ fparms.index = parms->tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+ tf_rm_free(&fparms);
+ return -EINVAL;
+}
+
+int
+tf_em_ext_host_free(struct tf *tfp,
+ struct tf_free_tbl_scope_parms *parms)
+{
+ int rc = 0;
+ enum tf_dir dir;
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+ struct tf_session *session;
+ struct tf_rm_free_parms aparms = { 0 };
+
+ session = (struct tf_session *)(tfp->session->core_data);
+
+ tbl_scope_cb = tbl_scope_cb_find(session,
+ parms->tbl_scope_id);
+
+ if (tbl_scope_cb == NULL) {
+ TFP_DRV_LOG(ERR, "Table scope error\n");
+ return -EINVAL;
+ }
+
+ /* Free Table control block */
+ aparms.rm_db = eem_db[TF_DIR_RX];
+ aparms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
+ aparms.index = parms->tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
+ rc = tf_rm_free(&aparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "Failed to free table scope\n");
+ }
+
+ /* free table scope locks */
+ for (dir = 0; dir < TF_DIR_MAX; dir++) {
+ /* Free associated external pools
+ */
+ tf_destroy_tbl_pool_external(dir,
+ tbl_scope_cb);
+ tf_msg_em_op(tfp,
+ dir,
+ HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);
+
+ /* free table scope and all associated resources */
+ tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
+ }
+
+ return rc;
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 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 DBs.
+ */
+static void *em_db[TF_DIR_MAX];
+
+/**
+ * Init flag, set on bind and cleared on unbind
+ */
+static uint8_t init;
+
+/**
+ * Create EM Tbl pool of memory indexes.
+ *
+ * [in] session
+ * Pointer to session
+ * [in] dir
+ * direction
+ * [in] num_entries
+ * number of entries to write
+ *
+ * Return:
+ * 0 - Success, entry allocated - no search support
+ * -ENOMEM -EINVAL -EOPNOTSUPP
+ * - Failure, entry not allocated, out of resources
+ */
+static int
+tf_create_em_pool(struct tf_session *session,
+ enum tf_dir dir,
+ uint32_t num_entries)
+{
+ struct tfp_calloc_parms parms;
+ uint32_t i, j;
+ int rc = 0;
+ struct stack *pool = &session->em_pool[dir];
+
+ parms.nitems = num_entries;
+ parms.size = sizeof(uint32_t);
+ parms.alignment = 0;
+
+ rc = tfp_calloc(&parms);
+
+ if (rc) {
+ TFP_DRV_LOG(ERR, "EM pool allocation failure %s\n",
+ strerror(-rc));
+ return rc;
+ }
+
+ /* Create empty stack
+ */
+ rc = stack_init(num_entries, (uint32_t *)parms.mem_va, pool);
+
+ if (rc) {
+ TFP_DRV_LOG(ERR, "EM pool stack init failure %s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+
+ /* Fill pool with indexes
+ */
+ j = num_entries - 1;
+
+ for (i = 0; i < num_entries; i++) {
+ rc = stack_push(pool, j);
+ if (rc) {
+ TFP_DRV_LOG(ERR, "EM pool stack push failure %s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+ j--;
+ }
+
+ if (!stack_is_full(pool)) {
+ rc = -EINVAL;
+ TFP_DRV_LOG(ERR, "EM pool stack failure %s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+
+ return 0;
+cleanup:
+ tfp_free((void *)parms.mem_va);
+ return rc;
+}
+
+/**
+ * Create EM Tbl pool of memory indexes.
+ *
+ * [in] session
+ * Pointer to session
+ * [in] dir
+ * direction
+ *
+ * Return:
+ */
+static void
+tf_free_em_pool(struct tf_session *session,
+ enum tf_dir dir)
+{
+ struct stack *pool = &session->em_pool[dir];
+ uint32_t *ptr;
+
+ ptr = stack_items(pool);
+
+ if (ptr != NULL)
+ tfp_free(ptr);
+}
+
+/**
+ * Insert EM internal entry API
+ *
+ * returns:
+ * 0 - Success
+ */
+int
+tf_em_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 tf_session *session =
+ (struct tf_session *)(tfp->session->core_data);
+ struct stack *pool = &session->em_pool[parms->dir];
+ uint32_t index;
+
+ rc = stack_pop(pool, &index);
+
+ if (rc) {
+ PMD_DRV_LOG
+ (ERR,
+ "dir:%d, EM entry index allocation failed\n",
+ parms->dir);
+ return rc;
+ }
+
+ rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
+ rc = tf_msg_insert_em_internal_entry(tfp,
+ parms,
+ &rptr_index,
+ &rptr_entry,
+ &num_of_entries);
+ if (rc)
+ return -1;
+
+ PMD_DRV_LOG
+ (ERR,
+ "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
+ index * TF_SESSION_EM_ENTRY_SIZE,
+ 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_delete_int_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms)
+{
+ int rc = 0;
+ struct tf_session *session =
+ (struct tf_session *)(tfp->session->core_data);
+ struct stack *pool = &session->em_pool[parms->dir];
+
+ rc = tf_msg_delete_em_entry(tfp, parms);
+
+ /* Return resource to pool */
+ if (rc == 0)
+ stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
+
+ return rc;
+}
+
+int
+tf_em_int_bind(struct tf *tfp,
+ struct tf_em_cfg_parms *parms)
+{
+ int rc;
+ int i;
+ struct tf_rm_create_db_parms db_cfg = { 0 };
+ struct tf_session *session;
+
+ TF_CHECK_PARMS2(tfp, parms);
+
+ if (init) {
+ TFP_DRV_LOG(ERR,
+ "Identifier already initialized\n");
+ return -EINVAL;
+ }
+
+ session = (struct tf_session *)tfp->session->core_data;
+
+ for (i = 0; i < TF_DIR_MAX; i++) {
+ tf_create_em_pool(session,
+ i,
+ TF_SESSION_EM_POOL_SIZE);
+ }
+
+ /*
+ * I'm not sure that this code is needed.
+ * leaving for now until resolved
+ */
+ if (parms->num_elements) {
+ db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
+ db_cfg.num_elements = parms->num_elements;
+ db_cfg.cfg = parms->cfg;
+
+ for (i = 0; i < TF_DIR_MAX; i++) {
+ db_cfg.dir = i;
+ db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
+ db_cfg.rm_db = &em_db[i];
+ rc = tf_rm_create_db(tfp, &db_cfg);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: EM DB creation failed\n",
+ tf_dir_2_str(i));
+
+ return rc;
+ }
+ }
+ }
+
+ init = 1;
+ return 0;
+}
+
+int
+tf_em_int_unbind(struct tf *tfp)
+{
+ int rc;
+ int i;
+ struct tf_rm_free_db_parms fparms = { 0 };
+ struct tf_session *session;
+
+ TF_CHECK_PARMS1(tfp);
+
+ /* Bail if nothing has been initialized done silent as to
+ * allow for creation cleanup.
+ */
+ if (!init) {
+ TFP_DRV_LOG(ERR,
+ "No EM DBs created\n");
+ return -EINVAL;
+ }
+
+ session = (struct tf_session *)tfp->session->core_data;
+
+ for (i = 0; i < TF_DIR_MAX; i++)
+ tf_free_em_pool(session, i);
+
+ for (i = 0; i < TF_DIR_MAX; i++) {
+ fparms.dir = i;
+ fparms.rm_db = em_db[i];
+ if (em_db[i] != NULL) {
+ rc = tf_rm_free_db(tfp, &fparms);
+ if (rc)
+ return rc;
+ }
+
+ em_db[i] = NULL;
+ }
+
+ init = 0;
+
+ return 0;
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 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_em.h"
+#include "tf_em_common.h"
+#include "tf_msg.h"
+#include "tfp.h"
+#include "lookup3.h"
+#include "tf_ext_flow_handle.h"
+
+#include "bnxt.h"
+
+
+/** insert EEM entry API
+ *
+ * returns:
+ * 0
+ * TF_ERR - unable to get lock
+ *
+ * insert callback returns:
+ * 0
+ * TF_ERR_EM_DUP - key is already in table
+ */
+static int
+tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,
+ struct tf_insert_em_entry_parms *parms __rte_unused)
+{
+ return 0;
+}
+
+/** delete EEM hash entry API
+ *
+ * returns:
+ * 0
+ * -EINVAL - parameter error
+ * TF_NO_SESSION - bad session ID
+ * TF_ERR_TBL_SCOPE - invalid table scope
+ * TF_ERR_TBL_IF - invalid table interface
+ *
+ * insert callback returns
+ * 0
+ * TF_NO_EM_MATCH - entry not found
+ */
+static int
+tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb __rte_unused,
+ struct tf_delete_em_entry_parms *parms __rte_unused)
+{
+ return 0;
+}
+
+/** insert EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int
+tf_em_insert_ext_sys_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *parms)
+{
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+
+ tbl_scope_cb = tbl_scope_cb_find
+ ((struct tf_session *)(tfp->session->core_data),
+ parms->tbl_scope_id);
+ if (tbl_scope_cb == NULL) {
+ TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+ return -EINVAL;
+ }
+
+ return tf_insert_eem_entry
+ (tbl_scope_cb, parms);
+}
+
+/** Delete EM hash entry API
+ *
+ * returns:
+ * 0 - Success
+ * -EINVAL - Error
+ */
+int
+tf_em_delete_ext_sys_entry(struct tf *tfp,
+ struct tf_delete_em_entry_parms *parms)
+{
+ struct tf_tbl_scope_cb *tbl_scope_cb;
+
+ tbl_scope_cb = tbl_scope_cb_find
+ ((struct tf_session *)(tfp->session->core_data),
+ parms->tbl_scope_id);
+ if (tbl_scope_cb == NULL) {
+ TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
+ return -EINVAL;
+ }
+
+ return tf_delete_eem_entry(tbl_scope_cb, parms);
+}
+
+int
+tf_em_ext_system_alloc(struct tf *tfp __rte_unused,
+ struct tf_alloc_tbl_scope_parms *parms __rte_unused)
+{
+ return 0;
+}
+
+int
+tf_em_ext_system_free(struct tf *tfp __rte_unused,
+ struct tf_free_tbl_scope_parms *parms __rte_unused)
+{
+ return 0;
+}
#include "hwrm_tf.h"
#include "tf_em.h"
-/**
- * Endian converts min and max values from the HW response to the query
- */
-#define TF_HW_RESP_TO_QUERY(query, index, response, element) do { \
- (query)->hw_query[index].min = \
- tfp_le_to_cpu_16(response. element ## _min); \
- (query)->hw_query[index].max = \
- tfp_le_to_cpu_16(response. element ## _max); \
-} while (0)
-
-/**
- * Endian converts the number of entries from the alloc to the request
- */
-#define TF_HW_ALLOC_TO_REQ(alloc, index, request, element) \
- (request. num_ ## element = tfp_cpu_to_le_16((alloc)->hw_num[index]))
-
-/**
- * Endian converts the start and stride value from the free to the request
- */
-#define TF_HW_FREE_TO_REQ(hw_entry, index, request, element) do { \
- request.element ## _start = \
- tfp_cpu_to_le_16(hw_entry[index].start); \
- request.element ## _stride = \
- tfp_cpu_to_le_16(hw_entry[index].stride); \
-} while (0)
-
-/**
- * Endian converts the start and stride from the HW response to the
- * alloc
- */
-#define TF_HW_RESP_TO_ALLOC(hw_entry, index, response, element) do { \
- hw_entry[index].start = \
- tfp_le_to_cpu_16(response.element ## _start); \
- hw_entry[index].stride = \
- tfp_le_to_cpu_16(response.element ## _stride); \
-} while (0)
-
-/**
- * Endian converts min and max values from the SRAM response to the
- * query
- */
-#define TF_SRAM_RESP_TO_QUERY(query, index, response, element) do { \
- (query)->sram_query[index].min = \
- tfp_le_to_cpu_16(response.element ## _min); \
- (query)->sram_query[index].max = \
- tfp_le_to_cpu_16(response.element ## _max); \
-} while (0)
-
-/**
- * Endian converts the number of entries from the action (alloc) to
- * the request
- */
-#define TF_SRAM_ALLOC_TO_REQ(action, index, request, element) \
- (request. num_ ## element = tfp_cpu_to_le_16((action)->sram_num[index]))
-
-/**
- * Endian converts the start and stride value from the free to the request
- */
-#define TF_SRAM_FREE_TO_REQ(sram_entry, index, request, element) do { \
- request.element ## _start = \
- tfp_cpu_to_le_16(sram_entry[index].start); \
- request.element ## _stride = \
- tfp_cpu_to_le_16(sram_entry[index].stride); \
-} while (0)
-
-/**
- * Endian converts the start and stride from the HW response to the
- * alloc
- */
-#define TF_SRAM_RESP_TO_ALLOC(sram_entry, index, response, element) do { \
- sram_entry[index].start = \
- tfp_le_to_cpu_16(response.element ## _start); \
- sram_entry[index].stride = \
- tfp_le_to_cpu_16(response.element ## _stride); \
-} while (0)
-
/**
* This is the MAX data we can transport across regular HWRM
*/
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;
-}
-
/**
* Allocates a DMA buffer that can be used for message transfer.
*
tfp_free(buf->va_addr);
}
-/**
- * NEW HWRM direct messages
- */
+/* HWRM Direct messages */
-/**
- * Sends session open request to TF Firmware
- */
int
tf_msg_session_open(struct tf *tfp,
char *ctrl_chan_name,
return rc;
}
-/**
- * Sends session attach request to TF Firmware
- */
int
tf_msg_session_attach(struct tf *tfp __rte_unused,
char *ctrl_chan_name __rte_unused,
return -1;
}
-/**
- * Sends session close request to TF Firmware
- */
int
tf_msg_session_close(struct tf *tfp)
{
return rc;
}
-/**
- * Sends session query config request to TF Firmware
- */
int
tf_msg_session_qcfg(struct tf *tfp)
{
int rc;
- struct hwrm_tf_session_qcfg_input req = { 0 };
+ struct hwrm_tf_session_qcfg_input req = { 0 };
struct hwrm_tf_session_qcfg_output resp = { 0 };
struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
struct tfp_send_msg_parms parms = { 0 };
return rc;
}
-/**
- * Sends session HW resource query capability request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_qcaps(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_hw_query *query)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_hw_resc_qcaps_input req = { 0 };
- struct tf_session_hw_resc_qcaps_output resp = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- memset(query, 0, sizeof(*query));
-
- /* 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(dir);
-
- MSG_PREP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_HW_RESC_QCAPS,
- req,
- resp);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- /* Process the response */
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
- l2_ctx_tcam_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_FUNC, resp,
- prof_func);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_PROF_TCAM, resp,
- prof_tcam_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
- em_prof_id);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EM_REC, resp,
- em_record_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
- wc_tcam_prof_id);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_WC_TCAM, resp,
- wc_tcam_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_PROF, resp,
- meter_profiles);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METER_INST,
- resp, meter_inst);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_MIRROR, resp,
- mirrors);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_UPAR, resp,
- upar);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_SP_TCAM, resp,
- sp_tcam_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_L2_FUNC, resp,
- l2_func);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_FKB, resp,
- flex_key_templ);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
- tbl_scope);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH0, resp,
- epoch0_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_EPOCH1, resp,
- epoch1_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_METADATA, resp,
- metadata);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_CT_STATE, resp,
- ct_state);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_PROF, resp,
- range_prof);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
- range_entries);
- TF_HW_RESP_TO_QUERY(query, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
- lag_tbl_entries);
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource allocation request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_alloc(struct tf *tfp __rte_unused,
- enum tf_dir dir,
- struct tf_rm_hw_alloc *hw_alloc __rte_unused,
- struct tf_rm_entry *hw_entry __rte_unused)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_hw_resc_alloc_input req = { 0 };
- struct tf_session_hw_resc_alloc_output resp = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- memset(hw_entry, 0, sizeof(*hw_entry));
-
- /* 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(dir);
-
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
- l2_ctx_tcam_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_FUNC, req,
- prof_func_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_PROF_TCAM, req,
- prof_tcam_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_PROF_ID, req,
- em_prof_id);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EM_REC, req,
- em_record_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
- wc_tcam_prof_id);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_WC_TCAM, req,
- wc_tcam_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_PROF, req,
- meter_profiles);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METER_INST, req,
- meter_inst);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_MIRROR, req,
- mirrors);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_UPAR, req,
- upar);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_SP_TCAM, req,
- sp_tcam_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_L2_FUNC, req,
- l2_func);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_FKB, req,
- flex_key_templ);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_TBL_SCOPE, req,
- tbl_scope);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH0, req,
- epoch0_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_EPOCH1, req,
- epoch1_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_METADATA, req,
- metadata);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_CT_STATE, req,
- ct_state);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_PROF, req,
- range_prof);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
- range_entries);
- TF_HW_ALLOC_TO_REQ(hw_alloc, TF_RESC_TYPE_HW_LAG_ENTRY, req,
- lag_tbl_entries);
-
- MSG_PREP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_HW_RESC_ALLOC,
- req,
- resp);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- /* Process the response */
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, resp,
- l2_ctx_tcam_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, resp,
- prof_func);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, resp,
- prof_tcam_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, resp,
- em_prof_id);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EM_REC, resp,
- em_record_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, resp,
- wc_tcam_prof_id);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, resp,
- wc_tcam_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_PROF, resp,
- meter_profiles);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METER_INST, resp,
- meter_inst);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_MIRROR, resp,
- mirrors);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_UPAR, resp,
- upar);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, resp,
- sp_tcam_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, resp,
- l2_func);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_FKB, resp,
- flex_key_templ);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, resp,
- tbl_scope);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH0, resp,
- epoch0_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_EPOCH1, resp,
- epoch1_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_METADATA, resp,
- metadata);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_CT_STATE, resp,
- ct_state);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, resp,
- range_prof);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, resp,
- range_entries);
- TF_HW_RESP_TO_ALLOC(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, resp,
- lag_tbl_entries);
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource free request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_free(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *hw_entry)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_hw_resc_free_input req = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- memset(hw_entry, 0, sizeof(*hw_entry));
-
- /* 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(dir);
-
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
- l2_ctx_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
- prof_func);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
- prof_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
- em_prof_id);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
- em_record_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
- wc_tcam_prof_id);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
- wc_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
- meter_profiles);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
- meter_inst);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
- mirrors);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
- upar);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
- sp_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
- l2_func);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
- flex_key_templ);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
- tbl_scope);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
- epoch0_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
- epoch1_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
- metadata);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
- ct_state);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
- range_prof);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
- range_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
- lag_tbl_entries);
-
- MSG_PREP_NO_RESP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_HW_RESC_FREE,
- req);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session HW resource flush request to TF Firmware
- */
-int
-tf_msg_session_hw_resc_flush(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *hw_entry)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_hw_resc_free_input req = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- /* 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(dir);
-
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_CTXT_TCAM, req,
- l2_ctx_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_FUNC, req,
- prof_func);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_PROF_TCAM, req,
- prof_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_PROF_ID, req,
- em_prof_id);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EM_REC, req,
- em_record_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM_PROF_ID, req,
- wc_tcam_prof_id);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_WC_TCAM, req,
- wc_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_PROF, req,
- meter_profiles);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METER_INST, req,
- meter_inst);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_MIRROR, req,
- mirrors);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_UPAR, req,
- upar);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_SP_TCAM, req,
- sp_tcam_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_L2_FUNC, req,
- l2_func);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_FKB, req,
- flex_key_templ);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_TBL_SCOPE, req,
- tbl_scope);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH0, req,
- epoch0_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_EPOCH1, req,
- epoch1_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_METADATA, req,
- metadata);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_CT_STATE, req,
- ct_state);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_PROF, req,
- range_prof);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_RANGE_ENTRY, req,
- range_entries);
- TF_HW_FREE_TO_REQ(hw_entry, TF_RESC_TYPE_HW_LAG_ENTRY, req,
- lag_tbl_entries);
-
- MSG_PREP_NO_RESP(parms,
- TF_KONG_MB,
- TF_TYPE_TRUFLOW,
- HWRM_TFT_SESSION_HW_RESC_FLUSH,
- req);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource query capability request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_qcaps(struct tf *tfp __rte_unused,
- enum tf_dir dir,
- struct tf_rm_sram_query *query __rte_unused)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_sram_resc_qcaps_input req = { 0 };
- struct tf_session_sram_resc_qcaps_output resp = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- /* 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(dir);
-
- MSG_PREP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_SRAM_RESC_QCAPS,
- req,
- resp);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- /* Process the response */
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_FULL_ACTION, resp,
- full_action);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_MCG, resp,
- mcg);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
- encap_8b);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
- encap_16b);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
- encap_64b);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
- sp_smac);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, resp,
- sp_smac_ipv4);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, resp,
- sp_smac_ipv6);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
- counter_64b);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
- nat_sport);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
- nat_dport);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
- nat_s_ipv4);
- TF_SRAM_RESP_TO_QUERY(query, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
- nat_d_ipv4);
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource allocation request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_alloc(struct tf *tfp __rte_unused,
- enum tf_dir dir,
- struct tf_rm_sram_alloc *sram_alloc __rte_unused,
- struct tf_rm_entry *sram_entry __rte_unused)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_sram_resc_alloc_input req = { 0 };
- struct tf_session_sram_resc_alloc_output resp;
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- memset(&resp, 0, sizeof(resp));
-
- /* 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(dir);
-
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
- full_action);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_MCG, req,
- mcg);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
- encap_8b);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
- encap_16b);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
- encap_64b);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC, req,
- sp_smac);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
- req, sp_smac_ipv4);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
- req, sp_smac_ipv6);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_COUNTER_64B,
- req, counter_64b);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
- nat_sport);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
- nat_dport);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
- nat_s_ipv4);
- TF_SRAM_ALLOC_TO_REQ(sram_alloc, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
- nat_d_ipv4);
-
- MSG_PREP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_SRAM_RESC_ALLOC,
- req,
- resp);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- /* Process the response */
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION,
- resp, full_action);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_MCG, resp,
- mcg);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, resp,
- encap_8b);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, resp,
- encap_16b);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, resp,
- encap_64b);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, resp,
- sp_smac);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4,
- resp, sp_smac_ipv4);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6,
- resp, sp_smac_ipv6);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, resp,
- counter_64b);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, resp,
- nat_sport);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, resp,
- nat_dport);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, resp,
- nat_s_ipv4);
- TF_SRAM_RESP_TO_ALLOC(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, resp,
- nat_d_ipv4);
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource free request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_free(struct tf *tfp __rte_unused,
- enum tf_dir dir,
- struct tf_rm_entry *sram_entry __rte_unused)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_sram_resc_free_input req = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- /* 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(dir);
-
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
- full_action);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
- mcg);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
- encap_8b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
- encap_16b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
- encap_64b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
- sp_smac);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
- sp_smac_ipv4);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
- sp_smac_ipv6);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
- counter_64b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
- nat_sport);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
- nat_dport);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
- nat_s_ipv4);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
- nat_d_ipv4);
-
- MSG_PREP_NO_RESP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_SESSION_SRAM_RESC_FREE,
- req);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
-/**
- * Sends session SRAM resource flush request to TF Firmware
- */
-int
-tf_msg_session_sram_resc_flush(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *sram_entry)
-{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct tf_session_sram_resc_free_input req = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
-
- /* 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(dir);
-
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_FULL_ACTION, req,
- full_action);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_MCG, req,
- mcg);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_8B, req,
- encap_8b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_16B, req,
- encap_16b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_ENCAP_64B, req,
- encap_64b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC, req,
- sp_smac);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV4, req,
- sp_smac_ipv4);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_SP_SMAC_IPV6, req,
- sp_smac_ipv6);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_COUNTER_64B, req,
- counter_64b);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_SPORT, req,
- nat_sport);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_DPORT, req,
- nat_dport);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_S_IPV4, req,
- nat_s_ipv4);
- TF_SRAM_FREE_TO_REQ(sram_entry, TF_RESC_TYPE_SRAM_NAT_D_IPV4, req,
- nat_d_ipv4);
-
- MSG_PREP_NO_RESP(parms,
- TF_KONG_MB,
- TF_TYPE_TRUFLOW,
- HWRM_TFT_SESSION_SRAM_RESC_FLUSH,
- req);
-
- rc = tfp_send_msg_tunneled(tfp, &parms);
- if (rc)
- return rc;
-
- return tfp_le_to_cpu_32(parms.tf_resp_code);
-}
-
int
tf_msg_session_resc_qcaps(struct tf *tfp,
enum tf_dir dir,
/* Process the response
* Should always get expected number of entries
*/
- if (resp.size != size) {
+ if (tfp_le_to_cpu_32(resp.size) != size) {
TFP_DRV_LOG(ERR,
"%s: QCAPS message size error, rc:%s\n",
tf_dir_2_str(dir),
return -EINVAL;
}
- printf("size: %d\n", resp.size);
+ printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
/* Post process the response */
data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr;
printf("\nQCAPS\n");
for (i = 0; i < size; i++) {
- query[i].type = tfp_cpu_to_le_32(data[i].type);
+ query[i].type = tfp_le_to_cpu_32(data[i].type);
query[i].min = tfp_le_to_cpu_16(data[i].min);
query[i].max = tfp_le_to_cpu_16(data[i].max);
/* Process the response
* Should always get expected number of entries
*/
- if (resp.size != size) {
+ if (tfp_le_to_cpu_32(resp.size) != size) {
TFP_DRV_LOG(ERR,
"%s: Alloc message size error, rc:%s\n",
tf_dir_2_str(dir),
}
printf("\nRESV\n");
- printf("size: %d\n", resp.size);
+ printf("size: %d\n", tfp_le_to_cpu_32(resp.size));
/* Post process the response */
resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr;
for (i = 0; i < size; i++) {
- resv[i].type = tfp_cpu_to_le_32(resv_data[i].type);
- resv[i].start = tfp_cpu_to_le_16(resv_data[i].start);
- resv[i].stride = tfp_cpu_to_le_16(resv_data[i].stride);
+ resv[i].type = tfp_le_to_cpu_32(resv_data[i].type);
+ resv[i].start = tfp_le_to_cpu_16(resv_data[i].start);
+ resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride);
printf("%d type: %d(0x%x) %d %d\n",
i,
return rc;
}
-/**
- * Sends EM mem register request to Firmware
- */
-int tf_msg_em_mem_rgtr(struct tf *tfp,
- int page_lvl,
- int page_size,
- uint64_t dma_addr,
- uint16_t *ctx_id)
+int
+tf_msg_insert_em_internal_entry(struct tf *tfp,
+ struct tf_insert_em_entry_parms *em_parms,
+ uint16_t *rptr_index,
+ uint8_t *rptr_entry,
+ uint8_t *num_of_entries)
{
int rc;
- struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
- struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
+ struct hwrm_tf_em_insert_input req = { 0 };
+ struct hwrm_tf_em_insert_output resp = { 0 };
+ struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+ struct tf_em_64b_entry *em_result =
+ (struct tf_em_64b_entry *)em_parms->em_record;
+ uint32_t flags;
+
+ req.fw_session_id =
+ tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+ tfp_memcpy(req.em_key,
+ em_parms->key,
+ ((em_parms->key_sz_in_bits + 7) / 8));
+
+ 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.strength = (em_result->hdr.word1 &
+ CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
+ CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
+ req.em_key_bitlen = em_parms->key_sz_in_bits;
+ req.action_ptr = em_result->hdr.pointer;
+ req.em_record_idx = *rptr_index;
+
+ parms.tf_type = HWRM_TF_EM_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 = TF_KONG_MB;
+
+ 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)
+{
+ int rc;
+ struct tfp_send_msg_parms parms = { 0 };
+ struct hwrm_tf_em_delete_input req = { 0 };
+ struct hwrm_tf_em_delete_output resp = { 0 };
+ uint32_t flags;
+ struct tf_session *tfs =
+ (struct tf_session *)(tfp->session->core_data);
+
+ req.fw_session_id =
+ tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+
+ flags = (em_parms->dir == TF_DIR_TX ?
+ HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
+ HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
+ req.flags = tfp_cpu_to_le_16(flags);
+ req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
+
+ parms.tf_type = HWRM_TF_EM_DELETE;
+ 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);
+ if (rc)
+ return rc;
+
+ em_parms->index = tfp_le_to_cpu_16(resp.em_index);
+
+ return 0;
+}
+
+int
+tf_msg_em_mem_rgtr(struct tf *tfp,
+ int page_lvl,
+ int page_size,
+ uint64_t dma_addr,
+ uint16_t *ctx_id)
+{
+ int rc;
+ struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 };
+ struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 };
+ struct tfp_send_msg_parms parms = { 0 };
+
+ req.page_level = page_lvl;
+ req.page_size = page_size;
+ req.page_dir = tfp_cpu_to_le_64(dma_addr);
- req.page_level = page_lvl;
- req.page_size = page_size;
- req.page_dir = tfp_cpu_to_le_64(dma_addr);
-
parms.tf_type = HWRM_TF_CTXT_MEM_RGTR;
parms.req_data = (uint32_t *)&req;
parms.req_size = sizeof(req);
return rc;
}
-/**
- * Sends EM mem unregister request to Firmware
- */
-int tf_msg_em_mem_unrgtr(struct tf *tfp,
- uint16_t *ctx_id)
+int
+tf_msg_em_mem_unrgtr(struct tf *tfp,
+ uint16_t *ctx_id)
{
int rc;
struct hwrm_tf_ctxt_mem_unrgtr_input req = {0};
return rc;
}
-/**
- * Sends EM qcaps request to Firmware
- */
-int tf_msg_em_qcaps(struct tf *tfp,
- int dir,
- struct tf_em_caps *em_caps)
+int
+tf_msg_em_qcaps(struct tf *tfp,
+ int dir,
+ struct tf_em_caps *em_caps)
{
int rc;
struct hwrm_tf_ext_em_qcaps_input req = {0};
return rc;
}
-/**
- * Sends EM config request to Firmware
- */
-int tf_msg_em_cfg(struct tf *tfp,
- uint32_t num_entries,
- uint16_t key0_ctx_id,
- uint16_t key1_ctx_id,
- uint16_t record_ctx_id,
- uint16_t efc_ctx_id,
- uint8_t flush_interval,
- int dir)
+int
+tf_msg_em_cfg(struct tf *tfp,
+ uint32_t num_entries,
+ uint16_t key0_ctx_id,
+ uint16_t key1_ctx_id,
+ uint16_t record_ctx_id,
+ uint16_t efc_ctx_id,
+ uint8_t flush_interval,
+ int dir)
{
int rc;
struct hwrm_tf_ext_em_cfg_input req = {0};
return rc;
}
-/**
- * Sends EM internal insert request to Firmware
- */
-int tf_msg_insert_em_internal_entry(struct tf *tfp,
- struct tf_insert_em_entry_parms *em_parms,
- uint16_t *rptr_index,
- uint8_t *rptr_entry,
- uint8_t *num_of_entries)
+int
+tf_msg_em_op(struct tf *tfp,
+ int dir,
+ uint16_t op)
{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct hwrm_tf_em_insert_input req = { 0 };
- struct hwrm_tf_em_insert_output resp = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
- struct tf_em_64b_entry *em_result =
- (struct tf_em_64b_entry *)em_parms->em_record;
+ int rc;
+ struct hwrm_tf_ext_em_op_input req = {0};
+ struct hwrm_tf_ext_em_op_output resp = {0};
uint32_t flags;
+ struct tfp_send_msg_parms parms = { 0 };
- req.fw_session_id =
- tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
- tfp_memcpy(req.em_key,
- em_parms->key,
- ((em_parms->key_sz_in_bits + 7) / 8));
-
- 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.strength =
- (em_result->hdr.word1 & CFA_P4_EEM_ENTRY_STRENGTH_MASK) >>
- CFA_P4_EEM_ENTRY_STRENGTH_SHIFT;
- req.em_key_bitlen = em_parms->key_sz_in_bits;
- req.action_ptr = em_result->hdr.pointer;
- req.em_record_idx = *rptr_index;
+ flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
+ HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
+ req.flags = tfp_cpu_to_le_32(flags);
+ req.op = tfp_cpu_to_le_16(op);
- parms.tf_type = HWRM_TF_EM_INSERT;
+ parms.tf_type = HWRM_TF_EXT_EM_OP;
parms.req_data = (uint32_t *)&req;
parms.req_size = sizeof(req);
parms.resp_data = (uint32_t *)&resp;
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;
+ return rc;
}
-/**
- * Sends EM delete insert request to Firmware
- */
-int tf_msg_delete_em_entry(struct tf *tfp,
- struct tf_delete_em_entry_parms *em_parms)
+int
+tf_msg_tcam_entry_set(struct tf *tfp,
+ struct tf_tcam_set_parms *parms)
{
- int rc;
- struct tfp_send_msg_parms parms = { 0 };
- struct hwrm_tf_em_delete_input req = { 0 };
- struct hwrm_tf_em_delete_output resp = { 0 };
- uint32_t flags;
- struct tf_session *tfs =
- (struct tf_session *)(tfp->session->core_data);
+ 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 };
+ struct tf_msg_dma_buf buf = { 0 };
+ uint8_t *data = NULL;
+ int data_size = 0;
- req.fw_session_id =
- tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id);
+ req.type = parms->hcapi_type;
+ 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;
- flags = (em_parms->dir == TF_DIR_TX ?
- HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX :
- HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX);
- req.flags = tfp_cpu_to_le_16(flags);
- req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle);
+ req.key_size = parms->key_size;
+ req.mask_offset = parms->key_size;
+ /* Result follows after key and mask, thus multiply by 2 */
+ req.result_offset = 2 * parms->key_size;
+ req.result_size = parms->result_size;
+ data_size = 2 * req.key_size + req.result_size;
- parms.tf_type = HWRM_TF_EM_DELETE;
- 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;
+ 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_alloc_dma_buf(&buf, data_size);
+ if (rc)
+ goto cleanup;
+ data = buf.va_addr;
+ tfp_memcpy(&req.dev_data[0],
+ &buf.pa_addr,
+ sizeof(buf.pa_addr));
+ }
+
+ tfp_memcpy(&data[0], parms->key, parms->key_size);
+ tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
+ tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
+
+ 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,
- &parms);
+ &mparms);
if (rc)
- return rc;
+ goto cleanup;
- em_parms->index = tfp_le_to_cpu_16(resp.em_index);
+cleanup:
+ tf_msg_free_dma_buf(&buf);
- return 0;
+ return rc;
}
-/**
- * Sends EM operation request to Firmware
- */
-int tf_msg_em_op(struct tf *tfp,
- int dir,
- uint16_t op)
+int
+tf_msg_tcam_entry_free(struct tf *tfp,
+ struct tf_tcam_free_parms *in_parms)
{
int rc;
- struct hwrm_tf_ext_em_op_input req = {0};
- struct hwrm_tf_ext_em_op_output resp = {0};
- uint32_t flags;
+ struct hwrm_tf_tcam_free_input req = { 0 };
+ struct hwrm_tf_tcam_free_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
- flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX :
- HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX);
- req.flags = tfp_cpu_to_le_32(flags);
- req.op = tfp_cpu_to_le_16(op);
+ req.type = in_parms->hcapi_type;
+ 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_EXT_EM_OP;
+ parms.tf_type = HWRM_TF_TCAM_FREE;
parms.req_data = (uint32_t *)&req;
parms.req_size = sizeof(req);
parms.resp_data = (uint32_t *)&resp;
int
tf_msg_set_tbl_entry(struct tf *tfp,
enum tf_dir dir,
- enum tf_tbl_type type,
+ uint16_t hcapi_type,
uint16_t size,
uint8_t *data,
uint32_t index)
{
int rc;
+ struct hwrm_tf_tbl_type_set_input req = { 0 };
+ struct hwrm_tf_tbl_type_set_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
- struct tf_tbl_type_set_input req = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+ struct tf_session *tfs;
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(dir),
+ strerror(-rc));
+ return rc;
+ }
/* 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(dir);
- req.type = tfp_cpu_to_le_32(type);
+ req.type = tfp_cpu_to_le_32(hcapi_type);
req.size = tfp_cpu_to_le_16(size);
req.index = tfp_cpu_to_le_32(index);
data,
size);
- MSG_PREP_NO_RESP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_TBL_TYPE_SET,
- req);
+ parms.tf_type = HWRM_TF_TBL_TYPE_SET;
+ 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_tunneled(tfp, &parms);
+ rc = tfp_send_msg_direct(tfp,
+ &parms);
if (rc)
return rc;
int
tf_msg_get_tbl_entry(struct tf *tfp,
enum tf_dir dir,
- enum tf_tbl_type type,
+ uint16_t hcapi_type,
uint16_t size,
uint8_t *data,
uint32_t index)
{
int rc;
+ struct hwrm_tf_tbl_type_get_input req = { 0 };
+ struct hwrm_tf_tbl_type_get_output resp = { 0 };
struct tfp_send_msg_parms parms = { 0 };
- struct tf_tbl_type_get_input req = { 0 };
- struct tf_tbl_type_get_output resp = { 0 };
- struct tf_session *tfs = (struct tf_session *)(tfp->session->core_data);
+ struct tf_session *tfs;
+
+ /* Retrieve the session information */
+ rc = tf_session_get_session(tfp, &tfs);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s: Failed to lookup session, rc:%s\n",
+ tf_dir_2_str(dir),
+ strerror(-rc));
+ return rc;
+ }
/* 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(dir);
- req.type = tfp_cpu_to_le_32(type);
+ req.type = tfp_cpu_to_le_32(hcapi_type);
req.index = tfp_cpu_to_le_32(index);
- MSG_PREP(parms,
- TF_KONG_MB,
- HWRM_TF,
- HWRM_TFT_TBL_TYPE_GET,
- req,
- resp);
+ parms.tf_type = HWRM_TF_TBL_TYPE_GET;
+ 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_tunneled(tfp, &parms);
+ rc = tfp_send_msg_direct(tfp,
+ &parms);
if (rc)
return rc;
return tfp_le_to_cpu_32(parms.tf_resp_code);
}
+/* HWRM Tunneled messages */
+
int
tf_msg_bulk_get_tbl_entry(struct tf *tfp,
struct tf_bulk_get_tbl_entry_parms *params)
return tfp_le_to_cpu_32(parms.tf_resp_code);
}
-
-int
-tf_msg_tcam_entry_set(struct tf *tfp,
- struct tf_tcam_set_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 };
- struct tf_msg_dma_buf buf = { 0 };
- uint8_t *data = NULL;
- int data_size = 0;
-
- req.type = parms->type;
-
- 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 = parms->key_size;
- req.mask_offset = parms->key_size;
- /* Result follows after key and mask, thus multiply by 2 */
- req.result_offset = 2 * parms->key_size;
- req.result_size = parms->result_size;
- 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_alloc_dma_buf(&buf, data_size);
- if (rc)
- goto cleanup;
- data = buf.va_addr;
- tfp_memcpy(&req.dev_data[0],
- &buf.pa_addr,
- sizeof(buf.pa_addr));
- }
-
- tfp_memcpy(&data[0], parms->key, parms->key_size);
- tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size);
- tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size);
-
- 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)
- goto cleanup;
-
-cleanup:
- tf_msg_free_dma_buf(&buf);
-
- return rc;
-}
-
-int
-tf_msg_tcam_entry_free(struct tf *tfp,
- struct tf_tcam_free_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->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;
-}
struct tf;
+/* HWRM Direct messages */
+
/**
* Sends session open request to Firmware
*
* Pointer to the fw_session_id that is allocated on firmware side
*
* Returns:
- *
+ * 0 on Success else internal Truflow error
*/
int tf_msg_session_open(struct tf *tfp,
char *ctrl_chan_name,
* time of session open
*
* Returns:
- *
+ * 0 on Success else internal Truflow error
*/
int tf_msg_session_attach(struct tf *tfp,
char *ctrl_channel_name,
* Pointer to session handle
*
* Returns:
- *
+ * 0 on Success else internal Truflow error
*/
int tf_msg_session_close(struct tf *tfp);
/**
* Sends session query config request to TF Firmware
+ *
+ * [in] session
+ * Pointer to session handle
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_session_qcfg(struct tf *tfp);
-/**
- * Sends session HW resource query capability request to TF Firmware
- */
-int tf_msg_session_hw_resc_qcaps(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_hw_query *hw_query);
-
-/**
- * Sends session HW resource allocation request to TF Firmware
- */
-int tf_msg_session_hw_resc_alloc(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_hw_alloc *hw_alloc,
- struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session HW resource free request to TF Firmware
- */
-int tf_msg_session_hw_resc_free(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session HW resource flush request to TF Firmware
- */
-int tf_msg_session_hw_resc_flush(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *hw_entry);
-
-/**
- * Sends session SRAM resource query capability request to TF Firmware
- */
-int tf_msg_session_sram_resc_qcaps(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_sram_query *sram_query);
-
-/**
- * Sends session SRAM resource allocation request to TF Firmware
- */
-int tf_msg_session_sram_resc_alloc(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_sram_alloc *sram_alloc,
- struct tf_rm_entry *sram_entry);
-
-/**
- * Sends session SRAM resource free request to TF Firmware
- */
-int tf_msg_session_sram_resc_free(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *sram_entry);
-
-/**
- * Sends session SRAM resource flush request to TF Firmware
- */
-int tf_msg_session_sram_resc_flush(struct tf *tfp,
- enum tf_dir dir,
- struct tf_rm_entry *sram_entry);
-
/**
* Sends session HW resource query capability request to TF Firmware
*
/**
* Sends session resource flush request to TF Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] dir
+ * Receive or Transmit direction
+ *
+ * [in] size
+ * Number of elements in the req and resv arrays
+ *
+ * [in] resv
+ * Pointer to an array of reserved elements that needs to be flushed
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_session_resc_flush(struct tf *tfp,
enum tf_dir dir,
struct tf_rm_resc_entry *resv);
/**
* Sends EM internal insert request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] params
+ * Pointer to em insert parameter list
+ *
+ * [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_insert_em_internal_entry(struct tf *tfp,
struct tf_insert_em_entry_parms *params,
uint8_t *num_of_entries);
/**
* Sends EM internal delete request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] em_parms
+ * Pointer to em delete parameters
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_delete_em_entry(struct tf *tfp,
struct tf_delete_em_entry_parms *em_parms);
+
/**
* Sends EM mem register request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] page_lvl
+ * Page level
+ *
+ * [in] page_size
+ * Page size
+ *
+ * [in] dma_addr
+ * DMA Address for the memory page
+ *
+ * [in] ctx_id
+ * Context id
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_em_mem_rgtr(struct tf *tfp,
- int page_lvl,
- int page_size,
- uint64_t dma_addr,
- uint16_t *ctx_id);
+ int page_lvl,
+ int page_size,
+ uint64_t dma_addr,
+ uint16_t *ctx_id);
/**
* Sends EM mem unregister request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] ctx_id
+ * Context id
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_em_mem_unrgtr(struct tf *tfp,
- uint16_t *ctx_id);
+ uint16_t *ctx_id);
/**
* Sends EM qcaps request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] dir
+ * Receive or Transmit direction
+ *
+ * [in] em_caps
+ * Pointer to EM capabilities
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_em_qcaps(struct tf *tfp,
int dir,
/**
* Sends EM config request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] num_entries
+ * EM Table, key 0, number of entries to configure
+ *
+ * [in] key0_ctx_id
+ * EM Table, Key 0 context id
+ *
+ * [in] key1_ctx_id
+ * EM Table, Key 1 context id
+ *
+ * [in] record_ctx_id
+ * EM Table, Record context id
+ *
+ * [in] efc_ctx_id
+ * EM Table, EFC Table context id
+ *
+ * [in] flush_interval
+ * Flush pending HW cached flows every 1/10th of value set in
+ * seconds, both idle and active flows are flushed from the HW
+ * cache. If set to 0, this feature will be disabled.
+ *
+ * [in] dir
+ * Receive or Transmit direction
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_em_cfg(struct tf *tfp,
- uint32_t num_entries,
- uint16_t key0_ctx_id,
- uint16_t key1_ctx_id,
- uint16_t record_ctx_id,
- uint16_t efc_ctx_id,
- uint8_t flush_interval,
- int dir);
+ uint32_t num_entries,
+ uint16_t key0_ctx_id,
+ uint16_t key1_ctx_id,
+ uint16_t record_ctx_id,
+ uint16_t efc_ctx_id,
+ uint8_t flush_interval,
+ int dir);
/**
* Sends EM operation request to Firmware
+ *
+ * [in] tfp
+ * Pointer to TF handle
+ *
+ * [in] dir
+ * Receive or Transmit direction
+ *
+ * [in] op
+ * CFA Operator
+ *
+ * Returns:
+ * 0 on Success else internal Truflow error
*/
int tf_msg_em_op(struct tf *tfp,
- int dir,
- uint16_t op);
+ int dir,
+ uint16_t op);
/**
* Sends tcam entry 'set' to the Firmware.
* [in] dir
* Direction location of the element to set
*
- * [in] type
+ * [in] hcapi_type
* Type of the object to set
*
* [in] size
*/
int tf_msg_set_tbl_entry(struct tf *tfp,
enum tf_dir dir,
- enum tf_tbl_type type,
+ uint16_t hcapi_type,
uint16_t size,
uint8_t *data,
uint32_t index);
* [in] dir
* Direction location of the element to get
*
- * [in] type
+ * [in] hcapi_type
* Type of the object to get
*
* [in] size
*/
int tf_msg_get_tbl_entry(struct tf *tfp,
enum tf_dir dir,
- enum tf_tbl_type type,
+ uint16_t hcapi_type,
uint16_t size,
uint8_t *data,
uint32_t index);
+/* HWRM Tunneled messages */
+
/**
* Sends bulk get message of a Table Type element to the firmware.
*
hw_entries = tfs->resc.tx.hw_entry;
/* Query for Session HW Resources */
- rc = tf_msg_session_hw_resc_qcaps(tfp, dir, &hw_query);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, HW qcaps message send failed, rc:%s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- goto cleanup;
- }
+ memset(&hw_query, 0, sizeof(hw_query)); /* RSXX */
rc = tf_rm_check_hw_qcaps_static(&hw_query, dir, &error_flag);
if (rc) {
/* Log error */
hw_alloc.hw_num[i] = hw_query.hw_query[i].max;
/* Allocate Session HW Resources */
- rc = tf_msg_session_hw_resc_alloc(tfp, dir, &hw_alloc, hw_entries);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, HW alloc message send failed, rc:%s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- goto cleanup;
- }
-
/* Perform HW allocation validation as its possible the
* resource availability changed between qcaps and alloc
*/
else
sram_entries = tfs->resc.tx.sram_entry;
- /* Query for Session SRAM Resources */
- rc = tf_msg_session_sram_resc_qcaps(tfp, dir, &sram_query);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, SRAM qcaps message send failed, rc:%s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- goto cleanup;
- }
-
+ memset(&sram_query, 0, sizeof(sram_query)); /* RSXX */
rc = tf_rm_check_sram_qcaps_static(&sram_query, dir, &error_flag);
if (rc) {
/* Log error */
for (i = 0; i < TF_RESC_TYPE_SRAM_MAX; i++)
sram_alloc.sram_num[i] = sram_query.sram_query[i].max;
- /* Allocate Session SRAM Resources */
- rc = tf_msg_session_sram_resc_alloc(tfp,
- dir,
- &sram_alloc,
- sram_entries);
- if (rc) {
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, SRAM alloc message send failed, rc:%s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- goto cleanup;
- }
-
/* Perform SRAM allocation validation as its possible the
* resource availability changed between qcaps and alloc
*/
/* Log the entries to be flushed */
tf_rm_log_hw_flush(i, hw_flush_entries);
- rc = tf_msg_session_hw_resc_flush(tfp,
- i,
- hw_flush_entries);
- if (rc) {
- rc_close = rc;
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, HW flush failed, rc:%s\n",
- tf_dir_2_str(i),
- strerror(-rc));
- }
}
/* Check for any not previously freed SRAM resources
/* Log the entries to be flushed */
tf_rm_log_sram_flush(i, sram_flush_entries);
-
- rc = tf_msg_session_sram_resc_flush(tfp,
- i,
- sram_flush_entries);
- if (rc) {
- rc_close = rc;
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, HW flush failed, rc:%s\n",
- tf_dir_2_str(i),
- strerror(-rc));
- }
- }
-
- rc = tf_msg_session_hw_resc_free(tfp, i, hw_entries);
- if (rc) {
- rc_close = rc;
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, HW free failed, rc:%s\n",
- tf_dir_2_str(i),
- strerror(-rc));
- }
-
- rc = tf_msg_session_sram_resc_free(tfp, i, sram_entries);
- if (rc) {
- rc_close = rc;
- /* Log error */
- TFP_DRV_LOG(ERR,
- "%s, SRAM free failed, rc:%s\n",
- tf_dir_2_str(i),
- strerror(-rc));
}
}
* - EOPNOTSUPP - Operation not supported
*/
static void
-tf_rm_count_hcapi_reservations(struct tf_rm_element_cfg *cfg,
+tf_rm_count_hcapi_reservations(enum tf_dir dir,
+ enum tf_device_module_type type,
+ struct tf_rm_element_cfg *cfg,
uint16_t *reservations,
uint16_t count,
uint16_t *valid_count)
if (cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI &&
reservations[i] > 0)
cnt++;
+
+ /* Only log msg if a type is attempted reserved and
+ * not supported. We ignore EM module as its using a
+ * split configuration array thus it would fail for
+ * this type of check.
+ */
+ if (type != TF_DEVICE_MODULE_TYPE_EM &&
+ cfg[i].cfg_type == TF_RM_ELEM_CFG_NULL &&
+ reservations[i] > 0) {
+ TFP_DRV_LOG(ERR,
+ "%s, %s, %s allocation not supported\n",
+ tf_device_module_type_2_str(type),
+ tf_dir_2_str(dir),
+ tf_device_module_type_subtype_2_str(type, i));
+ printf("%s, %s, %s allocation of %d not supported\n",
+ tf_device_module_type_2_str(type),
+ tf_dir_2_str(dir),
+ tf_device_module_type_subtype_2_str(type, i),
+ reservations[i]);
+ }
}
*valid_count = cnt;
* the DB holds them all as to give a fast lookup. We can also
* remove entries where there are no request for elements.
*/
- tf_rm_count_hcapi_reservations(parms->cfg,
+ tf_rm_count_hcapi_reservations(parms->dir,
+ parms->type,
+ parms->cfg,
parms->alloc_cnt,
parms->num_elements,
&hcapi_items);
db[i].alloc.entry.start = resv[j].start;
db[i].alloc.entry.stride = resv[j].stride;
+ printf("Entry:%d Start:%d Stride:%d\n",
+ i,
+ resv[j].start,
+ resv[j].stride);
+
/* Create pool */
pool_size = (BITALLOC_SIZEOF(resv[j].stride) /
sizeof(struct bitalloc));
}
}
- rm_db->num_entries = i;
+ rm_db->num_entries = parms->num_elements;
rm_db->dir = parms->dir;
rm_db->type = parms->type;
*parms->rm_db = (void *)rm_db;
+ printf("%s: type:%d num_entries:%d\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ i);
+
tfp_free((void *)req);
tfp_free((void *)resv);
#include "stack.h"
#include "tf_common.h"
-#define PTU_PTE_VALID 0x1UL
-#define PTU_PTE_LAST 0x2UL
-#define PTU_PTE_NEXT_TO_LAST 0x4UL
-
-/* Number of pointers per page_size */
-#define MAX_PAGE_PTRS(page_size) ((page_size) / sizeof(void *))
-
-#define TF_EM_PG_SZ_4K (1 << 12)
-#define TF_EM_PG_SZ_8K (1 << 13)
-#define TF_EM_PG_SZ_64K (1 << 16)
-#define TF_EM_PG_SZ_256K (1 << 18)
-#define TF_EM_PG_SZ_1M (1 << 20)
-#define TF_EM_PG_SZ_2M (1 << 21)
-#define TF_EM_PG_SZ_4M (1 << 22)
-#define TF_EM_PG_SZ_1G (1 << 30)
-
-#define TF_EM_CTX_ID_INVALID 0xFFFF
-
-#define TF_EM_MIN_ENTRIES (1 << 15) /* 32K */
-#define TF_EM_MAX_ENTRIES (1 << 27) /* 128M */
-
-/**
- * Function to free a page table
- *
- * [in] tp
- * Pointer to the page table to free
- */
-static void
-tf_em_free_pg_tbl(struct hcapi_cfa_em_page_tbl *tp)
-{
- uint32_t i;
-
- for (i = 0; i < tp->pg_count; i++) {
- if (!tp->pg_va_tbl[i]) {
- TFP_DRV_LOG(WARNING,
- "No mapping for page: %d table: %016" PRIu64 "\n",
- i,
- (uint64_t)(uintptr_t)tp);
- continue;
- }
-
- tfp_free(tp->pg_va_tbl[i]);
- tp->pg_va_tbl[i] = NULL;
- }
-
- tp->pg_count = 0;
- tfp_free(tp->pg_va_tbl);
- tp->pg_va_tbl = NULL;
- tfp_free(tp->pg_pa_tbl);
- tp->pg_pa_tbl = NULL;
-}
-
-/**
- * Function to free an EM table
- *
- * [in] tbl
- * Pointer to the EM table to free
- */
-static void
-tf_em_free_page_table(struct hcapi_cfa_em_table *tbl)
-{
- struct hcapi_cfa_em_page_tbl *tp;
- int i;
-
- for (i = 0; i < tbl->num_lvl; i++) {
- tp = &tbl->pg_tbl[i];
- TFP_DRV_LOG(INFO,
- "EEM: Freeing page table: size %u lvl %d cnt %u\n",
- TF_EM_PAGE_SIZE,
- i,
- tp->pg_count);
-
- tf_em_free_pg_tbl(tp);
- }
-
- tbl->l0_addr = NULL;
- tbl->l0_dma_addr = 0;
- tbl->num_lvl = 0;
- tbl->num_data_pages = 0;
-}
-
-/**
- * Allocation of page tables
- *
- * [in] tfp
- * Pointer to a TruFlow handle
- *
- * [in] pg_count
- * Page count to allocate
- *
- * [in] pg_size
- * Size of each page
- *
- * Returns:
- * 0 - Success
- * -ENOMEM - Out of memory
- */
-static int
-tf_em_alloc_pg_tbl(struct hcapi_cfa_em_page_tbl *tp,
- uint32_t pg_count,
- uint32_t pg_size)
-{
- uint32_t i;
- struct tfp_calloc_parms parms;
-
- parms.nitems = pg_count;
- parms.size = sizeof(void *);
- parms.alignment = 0;
-
- if (tfp_calloc(&parms) != 0)
- return -ENOMEM;
-
- tp->pg_va_tbl = parms.mem_va;
-
- if (tfp_calloc(&parms) != 0) {
- tfp_free(tp->pg_va_tbl);
- return -ENOMEM;
- }
-
- tp->pg_pa_tbl = parms.mem_va;
-
- tp->pg_count = 0;
- tp->pg_size = pg_size;
-
- for (i = 0; i < pg_count; i++) {
- parms.nitems = 1;
- parms.size = pg_size;
- parms.alignment = TF_EM_PAGE_ALIGNMENT;
-
- if (tfp_calloc(&parms) != 0)
- goto cleanup;
-
- tp->pg_pa_tbl[i] = (uintptr_t)parms.mem_pa;
- tp->pg_va_tbl[i] = parms.mem_va;
-
- memset(tp->pg_va_tbl[i], 0, pg_size);
- tp->pg_count++;
- }
-
- return 0;
-
-cleanup:
- tf_em_free_pg_tbl(tp);
- return -ENOMEM;
-}
-
-/**
- * Allocates EM page tables
- *
- * [in] tbl
- * Table to allocate pages for
- *
- * Returns:
- * 0 - Success
- * -ENOMEM - Out of memory
- */
-static int
-tf_em_alloc_page_table(struct hcapi_cfa_em_table *tbl)
-{
- struct hcapi_cfa_em_page_tbl *tp;
- int rc = 0;
- int i;
- uint32_t j;
-
- for (i = 0; i < tbl->num_lvl; i++) {
- tp = &tbl->pg_tbl[i];
-
- rc = tf_em_alloc_pg_tbl(tp,
- tbl->page_cnt[i],
- TF_EM_PAGE_SIZE);
- if (rc) {
- TFP_DRV_LOG(WARNING,
- "Failed to allocate page table: lvl: %d, rc:%s\n",
- i,
- strerror(-rc));
- goto cleanup;
- }
-
- for (j = 0; j < tp->pg_count; j++) {
- TFP_DRV_LOG(INFO,
- "EEM: Allocated page table: size %u lvl %d cnt"
- " %u VA:%p PA:%p\n",
- TF_EM_PAGE_SIZE,
- i,
- tp->pg_count,
- (uint32_t *)tp->pg_va_tbl[j],
- (uint32_t *)(uintptr_t)tp->pg_pa_tbl[j]);
- }
- }
- return rc;
-
-cleanup:
- tf_em_free_page_table(tbl);
- return rc;
-}
-
-/**
- * Links EM page tables
- *
- * [in] tp
- * Pointer to page table
- *
- * [in] tp_next
- * Pointer to the next page table
- *
- * [in] set_pte_last
- * Flag controlling if the page table is last
- */
-static void
-tf_em_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
- struct hcapi_cfa_em_page_tbl *tp_next,
- bool set_pte_last)
-{
- uint64_t *pg_pa = tp_next->pg_pa_tbl;
- uint64_t *pg_va;
- uint64_t valid;
- uint32_t k = 0;
- uint32_t i;
- uint32_t j;
-
- for (i = 0; i < tp->pg_count; i++) {
- pg_va = tp->pg_va_tbl[i];
-
- for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
- if (k == tp_next->pg_count - 2 && set_pte_last)
- valid = PTU_PTE_NEXT_TO_LAST | PTU_PTE_VALID;
- else if (k == tp_next->pg_count - 1 && set_pte_last)
- valid = PTU_PTE_LAST | PTU_PTE_VALID;
- else
- valid = PTU_PTE_VALID;
-
- pg_va[j] = tfp_cpu_to_le_64(pg_pa[k] | valid);
- if (++k >= tp_next->pg_count)
- return;
- }
- }
-}
-
-/**
- * Setup a EM page table
- *
- * [in] tbl
- * Pointer to EM page table
- */
-static void
-tf_em_setup_page_table(struct hcapi_cfa_em_table *tbl)
-{
- struct hcapi_cfa_em_page_tbl *tp_next;
- struct hcapi_cfa_em_page_tbl *tp;
- bool set_pte_last = 0;
- int i;
-
- for (i = 0; i < tbl->num_lvl - 1; i++) {
- tp = &tbl->pg_tbl[i];
- tp_next = &tbl->pg_tbl[i + 1];
- if (i == tbl->num_lvl - 2)
- set_pte_last = 1;
- tf_em_link_page_table(tp, tp_next, set_pte_last);
- }
-
- tbl->l0_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_va_tbl[0];
- tbl->l0_dma_addr = tbl->pg_tbl[TF_PT_LVL_0].pg_pa_tbl[0];
-}
-
-/**
- * Given the page size, size of each data item (entry size),
- * and the total number of entries needed, determine the number
- * of page table levels and the number of data pages required.
- *
- * [in] page_size
- * Page size
- *
- * [in] entry_size
- * Entry size
- *
- * [in] num_entries
- * Number of entries needed
- *
- * [out] num_data_pages
- * Number of pages required
- *
- * Returns:
- * Success - Number of EM page levels required
- * -ENOMEM - Out of memory
- */
-static int
-tf_em_size_page_tbl_lvl(uint32_t page_size,
- uint32_t entry_size,
- uint32_t num_entries,
- uint64_t *num_data_pages)
-{
- uint64_t lvl_data_size = page_size;
- int lvl = TF_PT_LVL_0;
- uint64_t data_size;
-
- *num_data_pages = 0;
- data_size = (uint64_t)num_entries * entry_size;
-
- while (lvl_data_size < data_size) {
- lvl++;
-
- if (lvl == TF_PT_LVL_1)
- lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
- page_size;
- else if (lvl == TF_PT_LVL_2)
- lvl_data_size = (uint64_t)MAX_PAGE_PTRS(page_size) *
- MAX_PAGE_PTRS(page_size) * page_size;
- else
- return -ENOMEM;
- }
-
- *num_data_pages = roundup(data_size, page_size) / page_size;
-
- return lvl;
-}
-
-/**
- * Return the number of page table pages needed to
- * reference the given number of next level pages.
- *
- * [in] num_pages
- * Number of EM pages
- *
- * [in] page_size
- * Size of each EM page
- *
- * Returns:
- * Number of EM page table pages
- */
-static uint32_t
-tf_em_page_tbl_pgcnt(uint32_t num_pages,
- uint32_t page_size)
-{
- return roundup(num_pages, MAX_PAGE_PTRS(page_size)) /
- MAX_PAGE_PTRS(page_size);
- return 0;
-}
-
-/**
- * Given the number of data pages, page_size and the maximum
- * number of page table levels (already determined), size
- * the number of page table pages required at each level.
- *
- * [in] max_lvl
- * Max number of levels
- *
- * [in] num_data_pages
- * Number of EM data pages
- *
- * [in] page_size
- * Size of an EM page
- *
- * [out] *page_cnt
- * EM page count
- */
-static void
-tf_em_size_page_tbls(int max_lvl,
- uint64_t num_data_pages,
- uint32_t page_size,
- uint32_t *page_cnt)
-{
- if (max_lvl == TF_PT_LVL_0) {
- page_cnt[TF_PT_LVL_0] = num_data_pages;
- } else if (max_lvl == TF_PT_LVL_1) {
- page_cnt[TF_PT_LVL_1] = num_data_pages;
- page_cnt[TF_PT_LVL_0] =
- tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
- } else if (max_lvl == TF_PT_LVL_2) {
- page_cnt[TF_PT_LVL_2] = num_data_pages;
- page_cnt[TF_PT_LVL_1] =
- tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_2], page_size);
- page_cnt[TF_PT_LVL_0] =
- tf_em_page_tbl_pgcnt(page_cnt[TF_PT_LVL_1], page_size);
- } else {
- return;
- }
-}
-
-/**
- * Size the EM table based on capabilities
- *
- * [in] tbl
- * EM table to size
- *
- * Returns:
- * 0 - Success
- * - EINVAL - Parameter error
- * - ENOMEM - Out of memory
- */
-static int
-tf_em_size_table(struct hcapi_cfa_em_table *tbl)
-{
- uint64_t num_data_pages;
- uint32_t *page_cnt;
- int max_lvl;
- uint32_t num_entries;
- uint32_t cnt = TF_EM_MIN_ENTRIES;
-
- /* Ignore entry if both size and number are zero */
- if (!tbl->entry_size && !tbl->num_entries)
- return 0;
-
- /* If only one is set then error */
- if (!tbl->entry_size || !tbl->num_entries)
- return -EINVAL;
-
- /* Determine number of page table levels and the number
- * of data pages needed to process the given eem table.
- */
- if (tbl->type == TF_RECORD_TABLE) {
- /*
- * For action records just a memory size is provided. Work
- * backwards to resolve to number of entries
- */
- num_entries = tbl->num_entries / tbl->entry_size;
- if (num_entries < TF_EM_MIN_ENTRIES) {
- num_entries = TF_EM_MIN_ENTRIES;
- } else {
- while (num_entries > cnt && cnt <= TF_EM_MAX_ENTRIES)
- cnt *= 2;
- num_entries = cnt;
- }
- } else {
- num_entries = tbl->num_entries;
- }
-
- max_lvl = tf_em_size_page_tbl_lvl(TF_EM_PAGE_SIZE,
- tbl->entry_size,
- tbl->num_entries,
- &num_data_pages);
- if (max_lvl < 0) {
- TFP_DRV_LOG(WARNING, "EEM: Failed to size page table levels\n");
- TFP_DRV_LOG(WARNING,
- "table: %d data-sz: %016" PRIu64 " page-sz: %u\n",
- tbl->type, (uint64_t)num_entries * tbl->entry_size,
- TF_EM_PAGE_SIZE);
- return -ENOMEM;
- }
-
- tbl->num_lvl = max_lvl + 1;
- tbl->num_data_pages = num_data_pages;
-
- /* Determine the number of pages needed at each level */
- page_cnt = tbl->page_cnt;
- memset(page_cnt, 0, sizeof(tbl->page_cnt));
- tf_em_size_page_tbls(max_lvl, num_data_pages, TF_EM_PAGE_SIZE,
- page_cnt);
-
- TFP_DRV_LOG(INFO, "EEM: Sized page table: %d\n", tbl->type);
- TFP_DRV_LOG(INFO,
- "EEM: lvls: %d sz: %016" PRIu64 " pgs: %016" PRIu64 " l0: %u l1: %u l2: %u\n",
- max_lvl + 1,
- (uint64_t)num_data_pages * TF_EM_PAGE_SIZE,
- num_data_pages,
- page_cnt[TF_PT_LVL_0],
- page_cnt[TF_PT_LVL_1],
- page_cnt[TF_PT_LVL_2]);
-
- return 0;
-}
-
-/**
- * Unregisters EM Ctx in Firmware
- *
- * [in] tfp
- * Pointer to a TruFlow handle
- *
- * [in] tbl_scope_cb
- * Pointer to a table scope control block
- *
- * [in] dir
- * Receive or transmit direction
- */
-static void
-tf_em_ctx_unreg(struct tf *tfp,
- struct tf_tbl_scope_cb *tbl_scope_cb,
- int dir)
-{
- struct hcapi_cfa_em_ctx_mem_info *ctxp =
- &tbl_scope_cb->em_ctx_info[dir];
- struct hcapi_cfa_em_table *tbl;
- int i;
-
- for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
- tbl = &ctxp->em_tables[i];
-
- if (tbl->num_entries != 0 && tbl->entry_size != 0) {
- tf_msg_em_mem_unrgtr(tfp, &tbl->ctx_id);
- tf_em_free_page_table(tbl);
- }
- }
-}
-
-/**
- * Registers EM Ctx in Firmware
- *
- * [in] tfp
- * Pointer to a TruFlow handle
- *
- * [in] tbl_scope_cb
- * Pointer to a table scope control block
- *
- * [in] dir
- * Receive or transmit direction
- *
- * Returns:
- * 0 - Success
- * -ENOMEM - Out of Memory
- */
-static int
-tf_em_ctx_reg(struct tf *tfp,
- struct tf_tbl_scope_cb *tbl_scope_cb,
- int dir)
-{
- struct hcapi_cfa_em_ctx_mem_info *ctxp =
- &tbl_scope_cb->em_ctx_info[dir];
- struct hcapi_cfa_em_table *tbl;
- int rc = 0;
- int i;
-
- for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
- tbl = &ctxp->em_tables[i];
-
- if (tbl->num_entries && tbl->entry_size) {
- rc = tf_em_size_table(tbl);
-
- if (rc)
- goto cleanup;
-
- rc = tf_em_alloc_page_table(tbl);
- if (rc)
- goto cleanup;
-
- tf_em_setup_page_table(tbl);
- rc = tf_msg_em_mem_rgtr(tfp,
- tbl->num_lvl - 1,
- TF_EM_PAGE_SIZE_ENUM,
- tbl->l0_dma_addr,
- &tbl->ctx_id);
- if (rc)
- goto cleanup;
- }
- }
- return rc;
-
-cleanup:
- tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
- return rc;
-}
-
-/**
- * Validates EM number of entries requested
- *
- * [in] tbl_scope_cb
- * Pointer to table scope control block to be populated
- *
- * [in] parms
- * Pointer to input parameters
- *
- * Returns:
- * 0 - Success
- * -EINVAL - Parameter error
- */
-static int
-tf_em_validate_num_entries(struct tf_tbl_scope_cb *tbl_scope_cb,
- struct tf_alloc_tbl_scope_parms *parms)
-{
- uint32_t cnt;
-
- if (parms->rx_mem_size_in_mb != 0) {
- uint32_t key_b = 2 * ((parms->rx_max_key_sz_in_bits / 8) + 1);
- uint32_t action_b = ((parms->rx_max_action_entry_sz_in_bits / 8)
- + 1);
- uint32_t num_entries = (parms->rx_mem_size_in_mb *
- TF_MEGABYTE) / (key_b + action_b);
-
- if (num_entries < TF_EM_MIN_ENTRIES) {
- TFP_DRV_LOG(ERR, "EEM: Insufficient memory requested:"
- "%uMB\n",
- parms->rx_mem_size_in_mb);
- return -EINVAL;
- }
-
- cnt = TF_EM_MIN_ENTRIES;
- while (num_entries > cnt &&
- cnt <= TF_EM_MAX_ENTRIES)
- cnt *= 2;
-
- if (cnt > TF_EM_MAX_ENTRIES) {
- TFP_DRV_LOG(ERR, "EEM: Invalid number of Tx requested: "
- "%u\n",
- (parms->tx_num_flows_in_k * TF_KILOBYTE));
- return -EINVAL;
- }
-
- parms->rx_num_flows_in_k = cnt / TF_KILOBYTE;
- } else {
- if ((parms->rx_num_flows_in_k * TF_KILOBYTE) <
- TF_EM_MIN_ENTRIES ||
- (parms->rx_num_flows_in_k * TF_KILOBYTE) >
- tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported) {
- TFP_DRV_LOG(ERR,
- "EEM: Invalid number of Rx flows "
- "requested:%u max:%u\n",
- parms->rx_num_flows_in_k * TF_KILOBYTE,
- tbl_scope_cb->em_caps[TF_DIR_RX].max_entries_supported);
- return -EINVAL;
- }
-
- /* must be a power-of-2 supported value
- * in the range 32K - 128M
- */
- cnt = TF_EM_MIN_ENTRIES;
- while ((parms->rx_num_flows_in_k * TF_KILOBYTE) != cnt &&
- cnt <= TF_EM_MAX_ENTRIES)
- cnt *= 2;
-
- if (cnt > TF_EM_MAX_ENTRIES) {
- TFP_DRV_LOG(ERR,
- "EEM: Invalid number of Rx requested: %u\n",
- (parms->rx_num_flows_in_k * TF_KILOBYTE));
- return -EINVAL;
- }
- }
-
- if (parms->tx_mem_size_in_mb != 0) {
- uint32_t key_b = 2 * (parms->tx_max_key_sz_in_bits / 8 + 1);
- uint32_t action_b = ((parms->tx_max_action_entry_sz_in_bits / 8)
- + 1);
- uint32_t num_entries = (parms->tx_mem_size_in_mb *
- (TF_KILOBYTE * TF_KILOBYTE)) /
- (key_b + action_b);
-
- if (num_entries < TF_EM_MIN_ENTRIES) {
- TFP_DRV_LOG(ERR,
- "EEM: Insufficient memory requested:%uMB\n",
- parms->rx_mem_size_in_mb);
- return -EINVAL;
- }
-
- cnt = TF_EM_MIN_ENTRIES;
- while (num_entries > cnt &&
- cnt <= TF_EM_MAX_ENTRIES)
- cnt *= 2;
-
- if (cnt > TF_EM_MAX_ENTRIES) {
- TFP_DRV_LOG(ERR,
- "EEM: Invalid number of Tx requested: %u\n",
- (parms->tx_num_flows_in_k * TF_KILOBYTE));
- return -EINVAL;
- }
-
- parms->tx_num_flows_in_k = cnt / TF_KILOBYTE;
- } else {
- if ((parms->tx_num_flows_in_k * TF_KILOBYTE) <
- TF_EM_MIN_ENTRIES ||
- (parms->tx_num_flows_in_k * TF_KILOBYTE) >
- tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported) {
- TFP_DRV_LOG(ERR,
- "EEM: Invalid number of Tx flows "
- "requested:%u max:%u\n",
- (parms->tx_num_flows_in_k * TF_KILOBYTE),
- tbl_scope_cb->em_caps[TF_DIR_TX].max_entries_supported);
- return -EINVAL;
- }
-
- cnt = TF_EM_MIN_ENTRIES;
- while ((parms->tx_num_flows_in_k * TF_KILOBYTE) != cnt &&
- cnt <= TF_EM_MAX_ENTRIES)
- cnt *= 2;
-
- if (cnt > TF_EM_MAX_ENTRIES) {
- TFP_DRV_LOG(ERR,
- "EEM: Invalid number of Tx requested: %u\n",
- (parms->tx_num_flows_in_k * TF_KILOBYTE));
- return -EINVAL;
- }
- }
-
- if (parms->rx_num_flows_in_k != 0 &&
- (parms->rx_max_key_sz_in_bits / 8 == 0)) {
- TFP_DRV_LOG(ERR,
- "EEM: Rx key size required: %u\n",
- (parms->rx_max_key_sz_in_bits));
- return -EINVAL;
- }
-
- if (parms->tx_num_flows_in_k != 0 &&
- (parms->tx_max_key_sz_in_bits / 8 == 0)) {
- TFP_DRV_LOG(ERR,
- "EEM: Tx key size required: %u\n",
- (parms->tx_max_key_sz_in_bits));
- return -EINVAL;
- }
- /* Rx */
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries =
- parms->rx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].entry_size =
- parms->rx_max_key_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].num_entries =
- parms->rx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY1_TABLE].entry_size =
- parms->rx_max_key_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].num_entries =
- parms->rx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_RECORD_TABLE].entry_size =
- parms->rx_max_action_entry_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_EFC_TABLE].num_entries =
- 0;
-
- /* Tx */
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].num_entries =
- parms->tx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY0_TABLE].entry_size =
- parms->tx_max_key_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].num_entries =
- parms->tx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_KEY1_TABLE].entry_size =
- parms->tx_max_key_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].num_entries =
- parms->tx_num_flows_in_k * TF_KILOBYTE;
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_RECORD_TABLE].entry_size =
- parms->tx_max_action_entry_sz_in_bits / 8;
-
- tbl_scope_cb->em_ctx_info[TF_DIR_TX].em_tables[TF_EFC_TABLE].num_entries =
- 0;
-
- return 0;
-}
-
/**
* 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.
}
#endif /* TF_SHADOW */
-/**
- * Create External Tbl pool of memory indexes.
- *
- * [in] dir
- * direction
- * [in] tbl_scope_cb
- * pointer to the table scope
- * [in] num_entries
- * number of entries to write
- * [in] entry_sz_bytes
- * size of each entry
- *
- * Return:
- * 0 - Success, entry allocated - no search support
- * -ENOMEM -EINVAL -EOPNOTSUPP
- * - Failure, entry not allocated, out of resources
- */
-static int
-tf_create_tbl_pool_external(enum tf_dir dir,
- struct tf_tbl_scope_cb *tbl_scope_cb,
- uint32_t num_entries,
- uint32_t entry_sz_bytes)
-{
- struct tfp_calloc_parms parms;
- uint32_t i;
- int32_t j;
- int rc = 0;
- struct stack *pool = &tbl_scope_cb->ext_act_pool[dir];
-
- parms.nitems = num_entries;
- parms.size = sizeof(uint32_t);
- parms.alignment = 0;
-
- if (tfp_calloc(&parms) != 0) {
- TFP_DRV_LOG(ERR, "%s: TBL: external pool failure %s\n",
- tf_dir_2_str(dir), strerror(ENOMEM));
- return -ENOMEM;
- }
-
- /* Create empty stack
- */
- rc = stack_init(num_entries, parms.mem_va, pool);
-
- if (rc != 0) {
- TFP_DRV_LOG(ERR, "%s: TBL: stack init failure %s\n",
- tf_dir_2_str(dir), strerror(-rc));
- goto cleanup;
- }
-
- /* Save the malloced memory address so that it can
- * be freed when the table scope is freed.
- */
- tbl_scope_cb->ext_act_pool_mem[dir] = (uint32_t *)parms.mem_va;
-
- /* Fill pool with indexes in reverse
- */
- j = (num_entries - 1) * entry_sz_bytes;
-
- for (i = 0; i < num_entries; i++) {
- rc = stack_push(pool, j);
- if (rc != 0) {
- TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
- tf_dir_2_str(dir), strerror(-rc));
- goto cleanup;
- }
-
- if (j < 0) {
- TFP_DRV_LOG(ERR, "%d TBL: invalid offset (%d)\n",
- dir, j);
- goto cleanup;
- }
- j -= entry_sz_bytes;
- }
-
- if (!stack_is_full(pool)) {
- rc = -EINVAL;
- TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
- tf_dir_2_str(dir), strerror(-rc));
- goto cleanup;
- }
- return 0;
-cleanup:
- tfp_free((void *)parms.mem_va);
- return rc;
-}
-
-/**
- * Destroy External Tbl pool of memory indexes.
- *
- * [in] dir
- * direction
- * [in] tbl_scope_cb
- * pointer to the table scope
- *
- */
-static void
-tf_destroy_tbl_pool_external(enum tf_dir dir,
- struct tf_tbl_scope_cb *tbl_scope_cb)
-{
- uint32_t *ext_act_pool_mem =
- tbl_scope_cb->ext_act_pool_mem[dir];
-
- tfp_free(ext_act_pool_mem);
-}
-
-/* API defined in tf_em.h */
-struct tf_tbl_scope_cb *
-tbl_scope_cb_find(struct tf_session *session,
- uint32_t tbl_scope_id)
-{
- int i;
-
- /* Check that id is valid */
- i = ba_inuse(session->tbl_scope_pool_rx, tbl_scope_id);
- if (i < 0)
- return NULL;
-
- for (i = 0; i < TF_NUM_TBL_SCOPE; i++) {
- if (session->tbl_scopes[i].tbl_scope_id == tbl_scope_id)
- return &session->tbl_scopes[i];
- }
-
- return NULL;
-}
-
-/* API defined in tf_core.h */
-int
-tf_free_eem_tbl_scope_cb(struct tf *tfp,
- struct tf_free_tbl_scope_parms *parms)
-{
- int rc = 0;
- enum tf_dir dir;
- struct tf_tbl_scope_cb *tbl_scope_cb;
- struct tf_session *session;
-
- session = (struct tf_session *)(tfp->session->core_data);
-
- tbl_scope_cb = tbl_scope_cb_find(session,
- parms->tbl_scope_id);
-
- if (tbl_scope_cb == NULL) {
- TFP_DRV_LOG(ERR, "Table scope error\n");
- return -EINVAL;
- }
-
- /* Free Table control block */
- ba_free(session->tbl_scope_pool_rx, tbl_scope_cb->index);
-
- /* free table scope locks */
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- /* Free associated external pools
- */
- tf_destroy_tbl_pool_external(dir,
- tbl_scope_cb);
- tf_msg_em_op(tfp,
- dir,
- HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);
-
- /* free table scope and all associated resources */
- tf_em_ctx_unreg(tfp, tbl_scope_cb, dir);
- }
-
- return rc;
-}
-
-/* API defined in tf_em.h */
-int
-tf_alloc_eem_tbl_scope(struct tf *tfp,
- struct tf_alloc_tbl_scope_parms *parms)
-{
- int rc;
- enum tf_dir dir;
- struct tf_tbl_scope_cb *tbl_scope_cb;
- struct hcapi_cfa_em_table *em_tables;
- int index;
- struct tf_session *session;
- struct tf_free_tbl_scope_parms free_parms;
-
- session = (struct tf_session *)tfp->session->core_data;
-
- /* Get Table Scope control block from the session pool */
- index = ba_alloc(session->tbl_scope_pool_rx);
- if (index == -1) {
- TFP_DRV_LOG(ERR, "EEM: Unable to allocate table scope "
- "Control Block\n");
- return -ENOMEM;
- }
-
- tbl_scope_cb = &session->tbl_scopes[index];
- tbl_scope_cb->index = index;
- tbl_scope_cb->tbl_scope_id = index;
- parms->tbl_scope_id = index;
-
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- rc = tf_msg_em_qcaps(tfp,
- dir,
- &tbl_scope_cb->em_caps[dir]);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "EEM: Unable to query for EEM capability,"
- " rc:%s\n",
- strerror(-rc));
- goto cleanup;
- }
- }
-
- /*
- * Validate and setup table sizes
- */
- if (tf_em_validate_num_entries(tbl_scope_cb, parms))
- goto cleanup;
-
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- /*
- * Allocate tables and signal configuration to FW
- */
- rc = tf_em_ctx_reg(tfp, tbl_scope_cb, dir);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "EEM: Unable to register for EEM ctx,"
- " rc:%s\n",
- strerror(-rc));
- goto cleanup;
- }
-
- em_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;
- rc = tf_msg_em_cfg(tfp,
- em_tables[TF_KEY0_TABLE].num_entries,
- em_tables[TF_KEY0_TABLE].ctx_id,
- em_tables[TF_KEY1_TABLE].ctx_id,
- em_tables[TF_RECORD_TABLE].ctx_id,
- em_tables[TF_EFC_TABLE].ctx_id,
- parms->hw_flow_cache_flush_timer,
- dir);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "TBL: Unable to configure EEM in firmware"
- " rc:%s\n",
- strerror(-rc));
- goto cleanup_full;
- }
-
- rc = tf_msg_em_op(tfp,
- dir,
- HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_ENABLE);
-
- if (rc) {
- TFP_DRV_LOG(ERR,
- "EEM: Unable to enable EEM in firmware"
- " rc:%s\n",
- strerror(-rc));
- goto cleanup_full;
- }
-
- /* Allocate the pool of offsets of the external memory.
- * Initially, this is a single fixed size pool for all external
- * actions related to a single table scope.
- */
- rc = tf_create_tbl_pool_external(dir,
- tbl_scope_cb,
- em_tables[TF_RECORD_TABLE].num_entries,
- em_tables[TF_RECORD_TABLE].entry_size);
- if (rc) {
- TFP_DRV_LOG(ERR,
- "%s TBL: Unable to allocate idx pools %s\n",
- tf_dir_2_str(dir),
- strerror(-rc));
- goto cleanup_full;
- }
- }
-
- return 0;
-
-cleanup_full:
- free_parms.tbl_scope_id = index;
- tf_free_eem_tbl_scope_cb(tfp, &free_parms);
- return -EINVAL;
-
-cleanup:
- /* Free Table control block */
- ba_free(session->tbl_scope_pool_rx, tbl_scope_cb->index);
- return -EINVAL;
-}
/* API defined in tf_core.h */
int
return rc;
}
-
-/* API defined in tf_core.h */
-int
-tf_alloc_tbl_scope(struct tf *tfp,
- struct tf_alloc_tbl_scope_parms *parms)
-{
- int rc;
-
- TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
-
- rc = tf_alloc_eem_tbl_scope(tfp, parms);
-
- return rc;
-}
-
-/* API defined in tf_core.h */
-int
-tf_free_tbl_scope(struct tf *tfp,
- struct tf_free_tbl_scope_parms *parms)
-{
- int rc;
-
- TF_CHECK_PARMS_SESSION_NO_DIR(tfp, parms);
-
- /* free table scope and all associated resources */
- rc = tf_free_eem_tbl_scope_cb(tfp, parms);
-
- return rc;
-}
-
-static void
-tf_dump_link_page_table(struct hcapi_cfa_em_page_tbl *tp,
- struct hcapi_cfa_em_page_tbl *tp_next)
-{
- uint64_t *pg_va;
- uint32_t i;
- uint32_t j;
- uint32_t k = 0;
-
- printf("pg_count:%d pg_size:0x%x\n",
- tp->pg_count,
- tp->pg_size);
- for (i = 0; i < tp->pg_count; i++) {
- pg_va = tp->pg_va_tbl[i];
- printf("\t%p\n", (void *)pg_va);
- for (j = 0; j < MAX_PAGE_PTRS(tp->pg_size); j++) {
- printf("\t\t%p\n", (void *)(uintptr_t)pg_va[j]);
- if (((pg_va[j] & 0x7) ==
- tfp_cpu_to_le_64(PTU_PTE_LAST |
- PTU_PTE_VALID)))
- return;
-
- if (!(pg_va[j] & tfp_cpu_to_le_64(PTU_PTE_VALID))) {
- printf("** Invalid entry **\n");
- return;
- }
-
- if (++k >= tp_next->pg_count) {
- printf("** Shouldn't get here **\n");
- return;
- }
- }
- }
-}
-
-void tf_dump_dma(struct tf *tfp, uint32_t tbl_scope_id);
-
-void tf_dump_dma(struct tf *tfp, uint32_t tbl_scope_id)
-{
- struct tf_session *session;
- struct tf_tbl_scope_cb *tbl_scope_cb;
- struct hcapi_cfa_em_page_tbl *tp;
- struct hcapi_cfa_em_page_tbl *tp_next;
- struct hcapi_cfa_em_table *tbl;
- int i;
- int j;
- int dir;
-
- printf("called %s\n", __func__);
-
- /* find session struct */
- session = (struct tf_session *)tfp->session->core_data;
-
- /* find control block for table scope */
- tbl_scope_cb = tbl_scope_cb_find(session,
- tbl_scope_id);
- if (tbl_scope_cb == NULL)
- PMD_DRV_LOG(ERR, "No table scope\n");
-
- for (dir = 0; dir < TF_DIR_MAX; dir++) {
- printf("Direction %s:\n", (dir == TF_DIR_RX ? "Rx" : "Tx"));
-
- for (j = TF_KEY0_TABLE; j < TF_MAX_TABLE; j++) {
- tbl = &tbl_scope_cb->em_ctx_info[dir].em_tables[j];
- printf
- ("Table: j:%d type:%d num_entries:%d entry_size:0x%x num_lvl:%d ",
- j,
- tbl->type,
- tbl->num_entries,
- tbl->entry_size,
- tbl->num_lvl);
- if (tbl->pg_tbl[0].pg_va_tbl &&
- tbl->pg_tbl[0].pg_pa_tbl)
- printf("%p %p\n",
- tbl->pg_tbl[0].pg_va_tbl[0],
- (void *)(uintptr_t)tbl->pg_tbl[0].pg_pa_tbl[0]);
- for (i = 0; i < tbl->num_lvl - 1; i++) {
- printf("Level:%d\n", i);
- tp = &tbl->pg_tbl[i];
- tp_next = &tbl->pg_tbl[i + 1];
- tf_dump_link_page_table(tp, tp_next);
- }
- printf("\n");
- }
- }
-}
struct tf_tbl_set_parms *parms)
{
int rc;
- struct tf_rm_is_allocated_parms aparms;
int allocated = 0;
+ uint16_t hcapi_type;
+ struct tf_rm_is_allocated_parms aparms = { 0 };
+ struct tf_rm_get_hcapi_parms hparms = { 0 };
TF_CHECK_PARMS3(tfp, parms, parms->data);
}
/* Set the entry */
+ hparms.rm_db = tbl_db[parms->dir];
+ hparms.db_index = parms->type;
+ hparms.hcapi_type = &hcapi_type;
+ rc = tf_rm_get_hcapi_type(&hparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s, Failed type lookup, type:%d, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ strerror(-rc));
+ return rc;
+ }
+
rc = tf_msg_set_tbl_entry(tfp,
parms->dir,
- parms->type,
+ hcapi_type,
parms->data_sz_in_bytes,
parms->data,
parms->idx);
struct tf_tbl_get_parms *parms)
{
int rc;
- struct tf_rm_is_allocated_parms aparms;
+ uint16_t hcapi_type;
int allocated = 0;
+ struct tf_rm_is_allocated_parms aparms = { 0 };
+ struct tf_rm_get_hcapi_parms hparms = { 0 };
TF_CHECK_PARMS3(tfp, parms, parms->data);
return -EINVAL;
}
+ /* Set the entry */
+ hparms.rm_db = tbl_db[parms->dir];
+ hparms.db_index = parms->type;
+ hparms.hcapi_type = &hcapi_type;
+ rc = tf_rm_get_hcapi_type(&hparms);
+ if (rc) {
+ TFP_DRV_LOG(ERR,
+ "%s, Failed type lookup, type:%d, rc:%s\n",
+ tf_dir_2_str(parms->dir),
+ parms->type,
+ strerror(-rc));
+ return rc;
+ }
+
/* Get the entry */
rc = tf_msg_get_tbl_entry(tfp,
parms->dir,
- parms->type,
+ hcapi_type,
parms->data_sz_in_bytes,
parms->data,
parms->idx);
return -EINVAL;
}
- db_cfg.num_elements = parms->num_elements;
db_cfg.type = TF_DEVICE_MODULE_TYPE_TCAM;
db_cfg.num_elements = parms->num_elements;
db_cfg.cfg = parms->cfg;
}
int
-tf_tcam_free(struct tf *tfp __rte_unused,
- struct tf_tcam_free_parms *parms __rte_unused)
+tf_tcam_free(struct tf *tfp,
+ struct tf_tcam_free_parms *parms)
{
int rc;
struct tf_session *tfs;
struct tf_dev_info *dev;
struct tf_rm_is_allocated_parms aparms = { 0 };
struct tf_rm_free_parms fparms = { 0 };
+ struct tf_rm_get_hcapi_parms hparms = { 0 };
uint16_t num_slice_per_row = 1;
int allocated = 0;
return rc;
}
+ /* Convert TF type to HCAPI RM type */
+ hparms.rm_db = tcam_db[parms->dir];
+ hparms.db_index = parms->type;
+ hparms.hcapi_type = &parms->hcapi_type;
+
+ rc = tf_rm_get_hcapi_type(&hparms);
+ if (rc)
+ return rc;
+
rc = tf_msg_tcam_entry_free(tfp, parms);
if (rc) {
/* Log error */
struct tf_session *tfs;
struct tf_dev_info *dev;
struct tf_rm_is_allocated_parms aparms = { 0 };
+ struct tf_rm_get_hcapi_parms hparms = { 0 };
uint16_t num_slice_per_row = 1;
int allocated = 0;
return rc;
}
+ /* Convert TF type to HCAPI RM type */
+ hparms.rm_db = tcam_db[parms->dir];
+ hparms.db_index = parms->type;
+ hparms.hcapi_type = &parms->hcapi_type;
+
+ rc = tf_rm_get_hcapi_type(&hparms);
+ if (rc)
+ return rc;
+
rc = tf_msg_tcam_entry_set(tfp, parms);
if (rc) {
/* Log error */
* [in] Type of the allocation type
*/
enum tf_tcam_tbl_type type;
+ /**
+ * [in] Type of HCAPI
+ */
+ uint16_t hcapi_type;
/**
* [in] Index to free
*/
case TF_DEVICE_MODULE_TYPE_IDENTIFIER:
return tf_ident_2_str(mod_type);
case TF_DEVICE_MODULE_TYPE_TABLE:
- return tf_tcam_tbl_2_str(mod_type);
- case TF_DEVICE_MODULE_TYPE_TCAM:
return tf_tbl_type_2_str(mod_type);
+ case TF_DEVICE_MODULE_TYPE_TCAM:
+ return tf_tcam_tbl_2_str(mod_type);
case TF_DEVICE_MODULE_TYPE_EM:
return tf_em_tbl_type_2_str(mod_type);
default: