From 873661aa641a18c3c6eaee56ab4ff2a3fdee0350 Mon Sep 17 00:00:00 2001 From: Jay Ding Date: Sun, 30 May 2021 14:28:45 +0530 Subject: [PATCH] net/bnxt: support shared session There are 2 types of sessions - shared and non-shared. For non-shared all the allocated resources are owned and managed by a single session instance. No other applications have access to the resources owned by the non-shared session. For a shared session, resources are shared between 2 applications. The FW shared session can only be created by one application and shared by other apps. The host session that creates the FW shared session is the creator. Applications can retrieve the reserved resources through a new API tf_get_session_resc_info. Each module supports two sessions, one is shared session, the other is non-shared session. Signed-off-by: Jay Ding Signed-off-by: Randy Schacher Signed-off-by: Venkat Duvvuru Reviewed-by: Farah Smith Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/hsi_struct_def_dpdk.h | 250 ++++++++++++++++--- drivers/net/bnxt/tf_core/bitalloc.c | 10 +- drivers/net/bnxt/tf_core/bitalloc.h | 3 +- drivers/net/bnxt/tf_core/tf_core.c | 105 ++++++++ drivers/net/bnxt/tf_core/tf_core.h | 177 +++++++++++++- drivers/net/bnxt/tf_core/tf_device.c | 76 +++--- drivers/net/bnxt/tf_core/tf_device.h | 73 ++++++ drivers/net/bnxt/tf_core/tf_device_p4.c | 8 + drivers/net/bnxt/tf_core/tf_device_p58.c | 8 + drivers/net/bnxt/tf_core/tf_em.h | 17 ++ drivers/net/bnxt/tf_core/tf_em_common.c | 25 -- drivers/net/bnxt/tf_core/tf_em_internal.c | 118 +++++---- drivers/net/bnxt/tf_core/tf_identifier.c | 89 +++---- drivers/net/bnxt/tf_core/tf_identifier.h | 16 ++ drivers/net/bnxt/tf_core/tf_msg.c | 223 ++++++++++++++--- drivers/net/bnxt/tf_core/tf_msg.h | 47 +++- drivers/net/bnxt/tf_core/tf_rm.c | 277 +++++++++++++++++++++- drivers/net/bnxt/tf_core/tf_rm.h | 34 +++ drivers/net/bnxt/tf_core/tf_session.c | 37 ++- drivers/net/bnxt/tf_core/tf_session.h | 66 ++++++ drivers/net/bnxt/tf_core/tf_tbl.c | 104 ++++---- drivers/net/bnxt/tf_core/tf_tbl.h | 17 ++ drivers/net/bnxt/tf_core/tf_tcam.c | 103 ++++---- drivers/net/bnxt/tf_core/tf_tcam.h | 16 ++ drivers/net/bnxt/tf_core/tfp.c | 6 +- drivers/net/bnxt/tf_core/tfp.h | 3 +- 26 files changed, 1557 insertions(+), 351 deletions(-) diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index aea9305486..1f0b37addf 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -699,6 +699,8 @@ struct cmd_nums { /* Experimental */ #define HWRM_TF_SESSION_RESC_FLUSH UINT32_C(0x2cf) /* Experimental */ + #define HWRM_TF_SESSION_RESC_INFO UINT32_C(0x2d0) + /* Experimental */ #define HWRM_TF_TBL_TYPE_GET UINT32_C(0x2da) /* Experimental */ #define HWRM_TF_TBL_TYPE_SET UINT32_C(0x2db) @@ -727,6 +729,8 @@ struct cmd_nums { /* Experimental */ #define HWRM_TF_EM_HASH_INSERT UINT32_C(0x2ec) /* Experimental */ + #define HWRM_TF_EM_MOVE UINT32_C(0x2ed) + /* Experimental */ #define HWRM_TF_TCAM_SET UINT32_C(0x2f8) /* Experimental */ #define HWRM_TF_TCAM_GET UINT32_C(0x2f9) @@ -986,8 +990,8 @@ struct hwrm_err_output { #define HWRM_VERSION_MINOR 10 #define HWRM_VERSION_UPDATE 2 /* non-zero means beta version */ -#define HWRM_VERSION_RSVD 15 -#define HWRM_VERSION_STR "1.10.2.15" +#define HWRM_VERSION_RSVD 22 +#define HWRM_VERSION_STR "1.10.2.22" /**************** * hwrm_ver_get * @@ -30177,7 +30181,7 @@ struct hwrm_vnic_qcaps_output { UINT32_C(0x20) /* * When this bit is '1', the capability to - * mirror the the RoCE traffic is supported. + * mirror the RoCE traffic is supported. * If set to '0', then the capability to mirror the * RoCE traffic is not supported. */ @@ -30930,7 +30934,7 @@ struct hwrm_vnic_plcmodes_cfg_input { uint16_t hds_threshold; /* * When virtio placement algorithm is enabled, this - * value is used to determine the the maximum number of BDs + * value is used to determine the maximum number of BDs * that can be used to place an Rx Packet. * If an incoming packet does not fit in the buffers described * by the max BDs, the packet will be dropped and an error @@ -31094,7 +31098,7 @@ struct hwrm_vnic_plcmodes_qcfg_output { uint16_t hds_threshold; /* * When virtio placement algorithm is enabled, this - * value is used to determine the the maximum number of BDs + * value is used to determine the maximum number of BDs * that can be used to place an Rx Packet. * If an incoming packet does not fit in the buffers described * by the max BDs, the packet will be dropped and an error @@ -42143,8 +42147,24 @@ struct hwrm_tf_session_open_output { * the newly created session. */ uint32_t fw_session_client_id; - /* unused. */ - uint32_t unused0; + uint32_t flags; + /* Indicates if the shared session has been created. */ + #define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION \ + UINT32_C(0x1) + /* + * If this bit set to 0, then it indicates the shared session + * has been created by another session. + */ + #define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_NOT_CREATOR \ + UINT32_C(0x0) + /* + * If this bit is set to 1, then it indicates the shared session + * is created by this session. + */ + #define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR \ + UINT32_C(0x1) + #define HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_LAST \ + HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR /* unused. */ uint8_t unused1[3]; /* @@ -42948,6 +42968,105 @@ struct hwrm_tf_session_resc_flush_output { uint8_t valid; } __rte_packed; +/***************************** + * hwrm_tf_session_resc_info * + *****************************/ + + +/* hwrm_tf_session_resc_info_input (size:320b/40B) */ +struct hwrm_tf_session_resc_info_input { + /* The HWRM command request type. */ + uint16_t req_type; + /* + * The completion ring to send the completion event on. This should + * be the NQ ID returned from the `nq_alloc` HWRM command. + */ + uint16_t cmpl_ring; + /* + * The sequence ID is used by the driver for tracking multiple + * commands. This ID is treated as opaque data by the firmware and + * the value is returned in the `hwrm_resp_hdr` upon completion. + */ + uint16_t seq_id; + /* + * The target ID of the command: + * * 0x0-0xFFF8 - The function ID + * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors + * * 0xFFFD - Reserved for user-space HWRM interface + * * 0xFFFF - HWRM + */ + uint16_t target_id; + /* + * A physical address pointer pointing to a host buffer that the + * command's response data will be written. This can be either a host + * physical address (HPA) or a guest physical address (GPA) and must + * point to a physically contiguous block of memory. + */ + uint64_t resp_addr; + /* Firmware session id returned when HWRM_TF_SESSION_OPEN is sent. */ + uint32_t fw_session_id; + /* Control flags. */ + uint16_t flags; + /* Indicates the flow direction. */ + #define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR UINT32_C(0x1) + /* If this bit set to 0, then it indicates rx flow. */ + #define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_RX UINT32_C(0x0) + /* If this bit is set to 1, then it indicates tx flow. */ + #define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX UINT32_C(0x1) + #define HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_LAST \ + HWRM_TF_SESSION_RESC_INFO_INPUT_FLAGS_DIR_TX + /* + * Defines the array size of the provided req_addr and + * resv_addr array buffers. Should be set to the number of + * request entries. + */ + uint16_t req_size; + /* + * This is the DMA address for the request input data array + * buffer. Array is of tf_rm_resc_req_entry type. Size of the + * array buffer is provided by the 'req_size' field in this + * message. + */ + uint64_t req_addr; + /* + * This is the DMA address for the resc output data array + * buffer. Array is of tf_rm_resc_entry type. Size of the array + * buffer is provided by the 'req_size' field in this + * message. + */ + uint64_t resc_addr; +} __rte_packed; + +/* hwrm_tf_session_resc_info_output (size:128b/16B) */ +struct hwrm_tf_session_resc_info_output { + /* The specific error status for the command. */ + uint16_t error_code; + /* The HWRM command request type. */ + uint16_t req_type; + /* The sequence ID from the original command. */ + uint16_t seq_id; + /* The length of the response data in number of bytes. */ + uint16_t resp_len; + /* + * Size of the returned tf_rm_resc_entry data array. The value + * cannot exceed the req_size defined by the input msg. The data + * array is returned using the resv_addr specified DMA + * address also provided by the input msg. + */ + uint16_t size; + /* unused. */ + uint8_t unused0[5]; + /* + * This field is used in Output records to indicate that the output + * is completely written to RAM. This field should be read as '1' + * to indicate that the output has been completely written. + * When writing a command completion or response to an internal + * processor, the order of writes has to be such that this field is + * written last. + */ + uint8_t valid; +} __rte_packed; + /* TruFlow RM capability of a resource. */ /* tf_rm_resc_req_entry (size:64b/8B) */ struct tf_rm_resc_req_entry { @@ -44434,6 +44553,79 @@ struct hwrm_tf_em_delete_output { uint16_t unused0[3]; } __rte_packed; +/******************* + * hwrm_tf_em_move * + *******************/ + + +/* hwrm_tf_em_move_input (size:320b/40B) */ +struct hwrm_tf_em_move_input { + /* The HWRM command request type. */ + uint16_t req_type; + /* + * The completion ring to send the completion event on. This should + * be the NQ ID returned from the `nq_alloc` HWRM command. + */ + uint16_t cmpl_ring; + /* + * The sequence ID is used by the driver for tracking multiple + * commands. This ID is treated as opaque data by the firmware and + * the value is returned in the `hwrm_resp_hdr` upon completion. + */ + uint16_t seq_id; + /* + * The target ID of the command: + * * 0x0-0xFFF8 - The function ID + * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors + * * 0xFFFD - Reserved for user-space HWRM interface + * * 0xFFFF - HWRM + */ + uint16_t target_id; + /* + * A physical address pointer pointing to a host buffer that the + * command's response data will be written. This can be either a host + * physical address (HPA) or a guest physical address (GPA) and must + * point to a physically contiguous block of memory. + */ + uint64_t resp_addr; + /* Session Id. */ + uint32_t fw_session_id; + /* Control flags. */ + uint16_t flags; + /* Indicates the flow direction. */ + #define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR UINT32_C(0x1) + /* If this bit set to 0, then it indicates rx flow. */ + #define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_RX UINT32_C(0x0) + /* If this bit is set to 1, then it indicates tx flow. */ + #define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX UINT32_C(0x1) + #define HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_LAST \ + HWRM_TF_EM_MOVE_INPUT_FLAGS_DIR_TX + /* Number of EM entry blocks */ + uint16_t num_blocks; + /* New index for entry */ + uint32_t new_index; + /* Unused */ + uint32_t unused0; + /* EM internal flow handle. */ + uint64_t flow_handle; +} __rte_packed; + +/* hwrm_tf_em_move_output (size:128b/16B) */ +struct hwrm_tf_em_move_output { + /* The specific error status for the command. */ + uint16_t error_code; + /* The HWRM command request type. */ + uint16_t req_type; + /* The sequence ID from the original command. */ + uint16_t seq_id; + /* The length of the response data in number of bytes. */ + uint16_t resp_len; + /* Index of old entry. */ + uint16_t em_index; + /* unused. */ + uint16_t unused0[3]; +} __rte_packed; + /******************** * hwrm_tf_tcam_set * ********************/ @@ -46989,8 +47181,8 @@ struct hwrm_nvm_write_input { */ uint64_t host_src_addr; /* - * The Directory Entry Type (valid values are defined in the bnxnvm - * directory_type enum defined in the file bnxnvm_defs.h). + * The Directory Entry Type (valid values are defined in the + * bnxnvm_directory_type enum defined in the file bnxnvm_defs.h). */ uint16_t dir_type; /* @@ -47003,10 +47195,10 @@ struct hwrm_nvm_write_input { /* Directory Entry Attribute flags (see BNX_DIR_ATTR_* in the file bnxnvm_defs.h). */ uint16_t dir_attr; /* - * Length of data to write, in bytes. May be less than or equal to the allocated - * size for the directory entry. - * The data length stored in the directory entry will be updated to reflect - * this value once the write is complete. + * Length of data to write, in bytes.May be + * less than or equal to the allocated size for the directory entry. + * The data length stored in the directory entry will be updated to + * reflect this value once the write is complete. */ uint32_t dir_data_length; /* Option. */ @@ -47019,15 +47211,15 @@ struct hwrm_nvm_write_input { #define HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG \ UINT32_C(0x1) /* - * The requested length of the allocated NVM for the item, in bytes. This - * value may be greater than or equal to the specified data length (dir_data_length). + * The requested length of the allocated NVM for the item, in bytes. + * This value may be greater than or equal to the specified data length (dir_data_length). * If this value is less than the specified data length, it will be ignored. - * The response will contain the actual allocated item length, which may be - * greater than the requested item length. + * The response will contain the actual allocated item length, which may + * be greater than the requested item length. * The purpose for allocating more than the required number of bytes for * an item's data is to pre-allocate extra storage (padding) to accommodate - * the potential future growth of an item (e.g. upgraded firmware with a - * size increase, log growth, expanded configuration data). + * the potential future growth of an item (e.g. upgraded firmware with + * a size increase, log growth, expanded configuration data). */ uint32_t dir_item_length; uint32_t unused_0; @@ -47045,10 +47237,9 @@ struct hwrm_nvm_write_output { uint16_t resp_len; /* * Length of the allocated NVM for the item, in bytes. The value may be - * greater than or equal to the specified data length or the requested - * item length. - * The actual item length used when creating a new directory entry will be - * a multiple of an NVM block size. + * greater than or equal to the specified data length or the requested item length. + * The actual item length used when creating a new directory entry will + * be a multiple of an NVM block size. */ uint32_t dir_item_length; /* The directory index of the created or modified item. */ @@ -47538,14 +47729,11 @@ struct hwrm_nvm_mod_dir_entry_input { */ uint16_t dir_ordinal; /* - * The Directory Entry Extension flags (see BNX_DIR_EXT_* for extension - * flag definitions). + * The Directory Entry Extension flags (see BNX_DIR_EXT_* for + * extension flag definitions). */ uint16_t dir_ext; - /* - * Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag - * definitions). - */ + /* Directory Entry Attribute flags (see BNX_DIR_ATTR_* for attribute flag definitions). */ uint16_t dir_attr; /* * If valid, then this field updates the checksum @@ -48406,8 +48594,8 @@ struct hwrm_fw_reset_input { #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST \ UINT32_C(0x4) /* - * AP processor complex (in multi-host environment). Use host_idx to - * control which core is reset + * AP processor complex (in multi-host environment). + * Use host_idx to control which core is reset */ #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_AP \ UINT32_C(0x5) diff --git a/drivers/net/bnxt/tf_core/bitalloc.c b/drivers/net/bnxt/tf_core/bitalloc.c index af1397071b..e253cfc3a6 100644 --- a/drivers/net/bnxt/tf_core/bitalloc.c +++ b/drivers/net/bnxt/tf_core/bitalloc.c @@ -65,7 +65,7 @@ ba_ffs(bitalloc_word_t v) } int -ba_init(struct bitalloc *pool, int size) +ba_init(struct bitalloc *pool, int size, bool free) { bitalloc_word_t *mem = (bitalloc_word_t *)pool; int i; @@ -101,9 +101,11 @@ ba_init(struct bitalloc *pool, int size) pool->storage[offset++] = words[--lev]; } - /* Free the entire pool */ - for (i = 0; i < size; i++) - ba_free(pool, i); + /* Free the entire pool if it is required*/ + if (free) { + for (i = 0; i < size; i++) + ba_free(pool, i); + } return 0; } diff --git a/drivers/net/bnxt/tf_core/bitalloc.h b/drivers/net/bnxt/tf_core/bitalloc.h index 7244b86e95..e3b389e68d 100644 --- a/drivers/net/bnxt/tf_core/bitalloc.h +++ b/drivers/net/bnxt/tf_core/bitalloc.h @@ -7,6 +7,7 @@ #define _BITALLOC_H_ #include +#include /* Bitalloc works on uint32_t as its word size */ typedef uint32_t bitalloc_word_t; @@ -64,7 +65,7 @@ struct bitalloc { * Returns 0 on success, -1 on failure. Size is arbitrary up to * BITALLOC_MAX_SIZE */ -int ba_init(struct bitalloc *pool, int size); +int ba_init(struct bitalloc *pool, int size, bool free); /** * Returns -1 on failure, or index of allocated entry diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index 9b8677caac..69f5c10293 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -27,6 +27,8 @@ tf_open_session(struct tf *tfp, int rc; unsigned int domain, bus, slot, device; struct tf_session_open_session_parms oparms; + int name_len; + char *name; TF_CHECK_PARMS2(tfp, parms); @@ -69,6 +71,13 @@ tf_open_session(struct tf *tfp, } } + name_len = strlen(parms->ctrl_chan_name); + name = &parms->ctrl_chan_name[name_len - strlen("tf_shared")]; + if (!strncmp(name, "tf_shared", strlen("tf_shared"))) { + memset(parms->ctrl_chan_name, 0, strlen(parms->ctrl_chan_name)); + strcpy(parms->ctrl_chan_name, "tf_share"); + } + parms->session_id.internal.domain = domain; parms->session_id.internal.bus = bus; parms->session_id.internal.device = device; @@ -1593,3 +1602,99 @@ tf_get_if_tbl_entry(struct tf *tfp, return 0; } + +int tf_get_session_info(struct tf *tfp, + struct tf_get_session_info_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + + TF_CHECK_PARMS2(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; + } + + TF_CHECK_PARMS2(tfp, parms); + + if (dev->ops->tf_dev_get_ident_resc_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "Operation not supported, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_get_ident_resc_info(tfp, parms->session_info.ident); + if (rc) { + TFP_DRV_LOG(ERR, + "Ident get resc info failed, rc:%s\n", + strerror(-rc)); + return rc; + } + + if (dev->ops->tf_dev_get_tbl_resc_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "Operation not supported, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_get_tbl_resc_info(tfp, parms->session_info.tbl); + if (rc) { + TFP_DRV_LOG(ERR, + "Tbl get resc info failed, rc:%s\n", + strerror(-rc)); + return rc; + } + + if (dev->ops->tf_dev_get_tcam_resc_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "Operation not supported, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_get_tcam_resc_info(tfp, parms->session_info.tcam); + if (rc) { + TFP_DRV_LOG(ERR, + "TCAM get resc info failed, rc:%s\n", + strerror(-rc)); + return rc; + } + + if (dev->ops->tf_dev_get_em_resc_info == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "Operation not supported, rc:%s\n", + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_get_em_resc_info(tfp, parms->session_info.em); + if (rc) { + TFP_DRV_LOG(ERR, + "EM get resc info failed, rc:%s\n", + strerror(-rc)); + return rc; + } + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index 7b26b58000..4440d60fe5 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -557,7 +557,8 @@ struct tf_open_session_parms { * rte_eth_dev_get_name_by_port() within the ULP. * * ctrl_chan_name will be used as part of a name for any - * shared memory allocation. + * shared memory allocation. The ctrl_chan_name is usually in format + * 0000:02:00.0. The name for shared session is 0000:02:00.0-tf_shared. */ char ctrl_chan_name[TF_SESSION_NAME_MAX]; /** @@ -616,29 +617,63 @@ struct tf_open_session_parms { * Resource allocation for the session. */ struct tf_session_resources resources; + + /** + * [in] bp + * The pointer to the parent bp struct. This is only used for HWRM + * message passing within the portability layer. The type is struct + * bnxt. + */ + void *bp; + + /** + * [out] shared_session_creator + * + * Indicates whether the application created the session if set. + * Otherwise the shared session already existed. Just for information + * purposes. + */ + int shared_session_creator; }; /** * Opens a new TruFlow Session or session client. * - * What gets created depends on the passed in tfp content. If the tfp - * does not have prior session data a new session with associated - * session client. If tfp has a session already a session client will - * be created. In both cases the session client is created using the - * provided ctrl_chan_name. + * What gets created depends on the passed in tfp content. If the tfp does not + * have prior session data a new session with associated session client. If tfp + * has a session already a session client will be created. In both cases the + * session client is created using the provided ctrl_chan_name. * - * In case of session creation TruFlow will allocate session specific - * memory, shared memory, to hold its session data. This data is - * private to TruFlow. + * In case of session creation TruFlow will allocate session specific memory to + * hold its session data. This data is private to TruFlow. * * No other TruFlow APIs will succeed unless this API is first called * and succeeds. * - * tf_open_session() returns a session id and session client id that - * is used on all other TF APIs. + * tf_open_session() returns a session id and session client id. These are + * also stored within the tfp structure passed in to all other APIs. * * A Session or session client can be closed using tf_close_session(). * + * There are 2 types of sessions - shared and not. For non-shared all + * the allocated resources are owned and managed by a single session instance. + * No other applications have access to the resources owned by the non-shared + * session. For a shared session, resources are shared between 2 applications. + * + * When the caller of tf_open_session() sets the ctrl_chan_name[] to a name + * like "0000:02:00.0-tf_shared", it is a request to create a new "shared" + * session in the firmware or access the existing shared session. There is + * only 1 shared session that can be created. If the shared session has + * already been created in the firmware, this API will return this indication + * by clearing the shared_session_creator flag. Only the first shared session + * create will have the shared_session_creator flag set. + * + * The shared session should always be the first session to be created by + * application and the last session closed due to RM management preference. + * + * Sessions remain open in the firmware until the last client of the session + * closes the session (tf_close_session()). + * * [in] tfp * Pointer to TF handle * @@ -652,6 +687,126 @@ struct tf_open_session_parms { int tf_open_session(struct tf *tfp, struct tf_open_session_parms *parms); +/** + * General internal resource info + * + * TODO: remove tf_rm_new_entry structure and use this structure + * internally. + */ +struct tf_resource_info { + uint16_t start; + uint16_t stride; +}; + +/** + * Identifier resource definition + */ +struct tf_identifier_resource_info { + /** + * Array of TF Identifiers. The index used is tf_identifier_type. + */ + struct tf_resource_info info[TF_IDENT_TYPE_MAX]; +}; + +/** + * Table type resource info definition + */ +struct tf_tbl_resource_info { + /** + * Array of TF Table types. The index used is tf_tbl_type. + */ + struct tf_resource_info info[TF_TBL_TYPE_MAX]; +}; + +/** + * TCAM type resource definition + */ +struct tf_tcam_resource_info { + /** + * Array of TF TCAM types. The index used is tf_tcam_tbl_type. + */ + struct tf_resource_info info[TF_TCAM_TBL_TYPE_MAX]; +}; + +/** + * EM type resource definition + */ +struct tf_em_resource_info { + /** + * Array of TF EM table types. The index used is tf_em_tbl_type. + */ + struct tf_resource_info info[TF_EM_TBL_TYPE_MAX]; +}; + +/** + * tf_session_resources parameter definition. + */ +struct tf_session_resource_info { + /** + * [in] Requested Identifier Resources + * + * Number of identifier resources requested for the + * session. + */ + struct tf_identifier_resource_info ident[TF_DIR_MAX]; + /** + * [in] Requested Index Table resource counts + * + * The number of index table resources requested for the + * session. + */ + struct tf_tbl_resource_info tbl[TF_DIR_MAX]; + /** + * [in] Requested TCAM Table resource counts + * + * The number of TCAM table resources requested for the + * session. + */ + + struct tf_tcam_resource_info tcam[TF_DIR_MAX]; + /** + * [in] Requested EM resource counts + * + * The number of internal EM table resources requested for the + * session. + */ + struct tf_em_resource_info em[TF_DIR_MAX]; +}; + +/** + * tf_get_session_resources parameter definition. + */ +struct tf_get_session_info_parms { + /** + * [out] the structure is used to return the information of + * allocated resources. + * + */ + struct tf_session_resource_info session_info; +}; + +/** (experimental) + * Gets info about a TruFlow Session + * + * Get info about the session which has been created. Whether it exists and + * what resource start and stride offsets are in use. This API is primarily + * intended to be used by an application which has created a shared session + * This application needs to obtain the resources which have already been + * allocated for the shared session. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to get parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_get_session_info(struct tf *tfp, + struct tf_get_session_info_parms *parms); + /** * Experimental * diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c index 9e71c04bf2..fed4156200 100644 --- a/drivers/net/bnxt/tf_core/tf_device.c +++ b/drivers/net/bnxt/tf_core/tf_device.c @@ -351,10 +351,16 @@ tf_dev_bind_p58(struct tf *tfp, struct tf_em_cfg_parms em_cfg; struct tf_if_tbl_cfg_parms if_tbl_cfg; struct tf_global_cfg_cfg_parms global_cfg; + struct tf_session *tfs; /* Initial function initialization */ dev_handle->ops = &tf_dev_ops_p58_init; + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX, tf_ident_p58, (uint16_t *)resources->ident_cnt); @@ -440,26 +446,28 @@ tf_dev_bind_p58(struct tf *tfp, /* * IF_TBL */ - if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; - if_tbl_cfg.cfg = tf_if_tbl_p58; - if_tbl_cfg.shadow_copy = shadow_copy; - rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); - if (rc) { - TFP_DRV_LOG(ERR, - "IF Table initialization failure\n"); - goto fail; - } + if (!tf_session_is_shared_session(tfs)) { + if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; + if_tbl_cfg.cfg = tf_if_tbl_p58; + if_tbl_cfg.shadow_copy = shadow_copy; + rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "IF Table initialization failure\n"); + goto fail; + } - /* - * GLOBAL_CFG - */ - global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; - global_cfg.cfg = tf_global_cfg_p58; - rc = tf_global_cfg_bind(tfp, &global_cfg); - if (rc) { - TFP_DRV_LOG(ERR, - "Global Cfg initialization failure\n"); - goto fail; + /* + * GLOBAL_CFG + */ + global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; + global_cfg.cfg = tf_global_cfg_p58; + rc = tf_global_cfg_bind(tfp, &global_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Global Cfg initialization failure\n"); + goto fail; + } } /* Final function initialization */ @@ -491,6 +499,12 @@ tf_dev_unbind_p58(struct tf *tfp) { int rc = 0; bool fail = false; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; /* Unbind all the support modules. As this is only done on * close we only report errors as everything has to be cleaned @@ -527,18 +541,20 @@ tf_dev_unbind_p58(struct tf *tfp) fail = true; } - rc = tf_if_tbl_unbind(tfp); - if (rc) { - TFP_DRV_LOG(ERR, - "Device unbind failed, IF Table Type\n"); - fail = true; - } + if (!tf_session_is_shared_session(tfs)) { + rc = tf_if_tbl_unbind(tfp); + if (rc) { + TFP_DRV_LOG(ERR, + "Device unbind failed, IF Table Type\n"); + fail = true; + } - rc = tf_global_cfg_unbind(tfp); - if (rc) { - TFP_DRV_LOG(ERR, - "Device unbind failed, Global Cfg Type\n"); - fail = true; + rc = tf_global_cfg_unbind(tfp); + if (rc) { + TFP_DRV_LOG(ERR, + "Device unbind failed, Global Cfg Type\n"); + fail = true; + } } if (fail) diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h index 3f2c24a0c6..16c2fe0f64 100644 --- a/drivers/net/bnxt/tf_core/tf_device.h +++ b/drivers/net/bnxt/tf_core/tf_device.h @@ -220,6 +220,25 @@ struct tf_dev_ops { */ int (*tf_dev_search_ident)(struct tf *tfp, struct tf_ident_search_parms *parms); + + /** + * Retrieves the identifier resource info. + * + * This API retrieves the identifier resource info from the rm db. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to identifier info + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_ident_resc_info)(struct tf *tfp, + struct tf_identifier_resource_info *parms); + /** * Get SRAM table information. * @@ -425,6 +444,24 @@ struct tf_dev_ops { int (*tf_dev_get_bulk_tbl)(struct tf *tfp, struct tf_tbl_get_bulk_parms *parms); + /** + * Retrieves the table resource info. + * + * This API retrieves the table resource info from the rm db. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to tbl info + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_tbl_resc_info)(struct tf *tfp, + struct tf_tbl_resource_info *parms); + /** * Allocation of a tcam element. * @@ -524,6 +561,24 @@ struct tf_dev_ops { int (*tf_dev_get_tcam)(struct tf *tfp, struct tf_tcam_get_parms *parms); + /** + * Retrieves the tcam resource info. + * + * This API retrieves the tcam resource info from the rm db. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to tcam info + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_tcam_resc_info)(struct tf *tfp, + struct tf_tcam_resource_info *parms); + /** * Insert EM hash entry API * @@ -588,6 +643,24 @@ struct tf_dev_ops { int (*tf_dev_delete_ext_em_entry)(struct tf *tfp, struct tf_delete_em_entry_parms *parms); + /** + * Retrieves the em resource info. + * + * This API retrieves the em resource info from the rm db. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to em info + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_em_resc_info)(struct tf *tfp, + struct tf_em_resource_info *parms); + /** * Allocate EEM table scope * diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index 8797afa100..e74ba6cd8f 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -206,6 +206,7 @@ const struct tf_dev_ops tf_dev_ops_p4_init = { .tf_dev_alloc_ident = NULL, .tf_dev_free_ident = NULL, .tf_dev_search_ident = NULL, + .tf_dev_get_ident_resc_info = NULL, .tf_dev_get_tbl_info = NULL, .tf_dev_alloc_ext_tbl = NULL, .tf_dev_alloc_tbl = NULL, @@ -216,15 +217,18 @@ const struct tf_dev_ops tf_dev_ops_p4_init = { .tf_dev_set_ext_tbl = NULL, .tf_dev_get_tbl = NULL, .tf_dev_get_bulk_tbl = NULL, + .tf_dev_get_tbl_resc_info = NULL, .tf_dev_alloc_tcam = NULL, .tf_dev_free_tcam = NULL, .tf_dev_alloc_search_tcam = NULL, .tf_dev_set_tcam = NULL, .tf_dev_get_tcam = NULL, + .tf_dev_get_tcam_resc_info = 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_get_em_resc_info = NULL, .tf_dev_alloc_tbl_scope = NULL, .tf_dev_map_tbl_scope = NULL, .tf_dev_map_parif = NULL, @@ -247,6 +251,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, .tf_dev_search_ident = tf_ident_search, + .tf_dev_get_ident_resc_info = tf_ident_get_resc_info, .tf_dev_get_tbl_info = NULL, .tf_dev_alloc_tbl = tf_tbl_alloc, .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc, @@ -257,15 +262,18 @@ const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_set_ext_tbl = tf_tbl_ext_common_set, .tf_dev_get_tbl = tf_tbl_get, .tf_dev_get_bulk_tbl = tf_tbl_bulk_get, + .tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info, .tf_dev_alloc_tcam = tf_tcam_alloc, .tf_dev_free_tcam = tf_tcam_free, .tf_dev_alloc_search_tcam = tf_tcam_alloc_search, .tf_dev_set_tcam = tf_tcam_set, .tf_dev_get_tcam = NULL, + .tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info, .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_get_em_resc_info = tf_em_get_resc_info, .tf_dev_alloc_tbl_scope = tf_em_ext_common_alloc, .tf_dev_map_tbl_scope = tf_em_ext_map_tbl_scope, .tf_dev_map_parif = tf_dev_p4_map_parif, diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c index b44648d216..32d621e7da 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.c +++ b/drivers/net/bnxt/tf_core/tf_device_p58.c @@ -227,6 +227,7 @@ const struct tf_dev_ops tf_dev_ops_p58_init = { .tf_dev_alloc_ident = NULL, .tf_dev_free_ident = NULL, .tf_dev_search_ident = NULL, + .tf_dev_get_ident_resc_info = NULL, .tf_dev_get_tbl_info = NULL, .tf_dev_alloc_ext_tbl = NULL, .tf_dev_alloc_tbl = NULL, @@ -237,15 +238,18 @@ const struct tf_dev_ops tf_dev_ops_p58_init = { .tf_dev_set_ext_tbl = NULL, .tf_dev_get_tbl = NULL, .tf_dev_get_bulk_tbl = NULL, + .tf_dev_get_tbl_resc_info = NULL, .tf_dev_alloc_tcam = NULL, .tf_dev_free_tcam = NULL, .tf_dev_alloc_search_tcam = NULL, .tf_dev_set_tcam = NULL, .tf_dev_get_tcam = NULL, + .tf_dev_get_tcam_resc_info = 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_get_em_resc_info = NULL, .tf_dev_alloc_tbl_scope = NULL, .tf_dev_map_tbl_scope = NULL, .tf_dev_map_parif = NULL, @@ -268,6 +272,7 @@ const struct tf_dev_ops tf_dev_ops_p58 = { .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, .tf_dev_search_ident = tf_ident_search, + .tf_dev_get_ident_resc_info = tf_ident_get_resc_info, .tf_dev_get_tbl_info = tf_dev_p58_get_sram_tbl_info, .tf_dev_alloc_tbl = tf_tbl_alloc, .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc, @@ -278,15 +283,18 @@ const struct tf_dev_ops tf_dev_ops_p58 = { .tf_dev_set_ext_tbl = tf_tbl_ext_common_set, .tf_dev_get_tbl = tf_tbl_get, .tf_dev_get_bulk_tbl = tf_tbl_bulk_get, + .tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info, .tf_dev_alloc_tcam = tf_tcam_alloc, .tf_dev_free_tcam = tf_tcam_free, .tf_dev_alloc_search_tcam = tf_tcam_alloc_search, .tf_dev_set_tcam = tf_tcam_set, .tf_dev_get_tcam = tf_tcam_get, + .tf_dev_get_tcam_resc_info = tf_tcam_get_resc_info, .tf_dev_insert_int_em_entry = tf_em_hash_insert_int_entry, .tf_dev_delete_int_em_entry = tf_em_hash_delete_int_entry, .tf_dev_insert_ext_em_entry = NULL, .tf_dev_delete_ext_em_entry = NULL, + .tf_dev_get_em_resc_info = tf_em_get_resc_info, .tf_dev_alloc_tbl_scope = NULL, .tf_dev_map_tbl_scope = NULL, .tf_dev_map_parif = NULL, diff --git a/drivers/net/bnxt/tf_core/tf_em.h b/drivers/net/bnxt/tf_core/tf_em.h index 19ad7f12be..60d90e28de 100644 --- a/drivers/net/bnxt/tf_core/tf_em.h +++ b/drivers/net/bnxt/tf_core/tf_em.h @@ -530,4 +530,21 @@ tf_em_ext_system_bind(struct tf *tfp, struct tf_em_cfg_parms *parms); int offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb); + +/** + * Retrieves the allocated resource info + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int +tf_em_get_resc_info(struct tf *tfp, + struct tf_em_resource_info *em); #endif /* _TF_EM_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_em_common.c b/drivers/net/bnxt/tf_core/tf_em_common.c index 4dc3c86b57..ed8f6db58c 100644 --- a/drivers/net/bnxt/tf_core/tf_em_common.c +++ b/drivers/net/bnxt/tf_core/tf_em_common.c @@ -26,11 +26,6 @@ /* Number of pointers per page_size */ #define MAX_PAGE_PTRS(page_size) ((page_size) / sizeof(void *)) -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - /** * Host or system */ @@ -924,18 +919,11 @@ tf_em_ext_common_bind(struct tf *tfp, int rc; int i; struct tf_rm_create_db_parms db_cfg = { 0 }; - uint8_t db_exists = 0; struct em_ext_db *ext_db; struct tfp_calloc_parms cparms; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "EM Ext DB already initialized\n"); - return -EINVAL; - } - cparms.nitems = 1; cparms.size = sizeof(struct em_ext_db); cparms.alignment = 0; @@ -974,12 +962,8 @@ tf_em_ext_common_bind(struct tf *tfp, return rc; } - db_exists = 1; } - if (db_exists) - init = 1; - mem_type = parms->mem_type; return 0; @@ -1001,13 +985,6 @@ tf_em_ext_common_unbind(struct tf *tfp) TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No EM Ext DBs created\n"); - return 0; - } - rc = tf_session_get_session_internal(tfp, &tfs); if (rc) { TFP_DRV_LOG(ERR, "Failed to get tf_session, rc:%s\n", @@ -1064,8 +1041,6 @@ tf_em_ext_common_unbind(struct tf *tfp) tfp_free(ext_db); tf_session_set_em_ext_db(tfp, NULL); - init = 0; - return 0; } diff --git a/drivers/net/bnxt/tf_core/tf_em_internal.c b/drivers/net/bnxt/tf_core/tf_em_internal.c index 5a100ef1de..e373a9b029 100644 --- a/drivers/net/bnxt/tf_core/tf_em_internal.c +++ b/drivers/net/bnxt/tf_core/tf_em_internal.c @@ -20,11 +20,6 @@ #define TF_EM_DB_EM_REC 0 -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - /** * EM Pool */ @@ -234,19 +229,18 @@ tf_em_int_bind(struct tf *tfp, int rc; int i; struct tf_rm_create_db_parms db_cfg = { 0 }; - uint8_t db_exists = 0; struct tf_rm_get_alloc_info_parms iparms; struct tf_rm_alloc_info info; struct em_rm_db *em_db; struct tfp_calloc_parms cparms; + struct tf_session *tfs; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "EM Int DB already initialized\n"); - return -EINVAL; - } + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; memset(&db_cfg, 0, sizeof(db_cfg)); cparms.nitems = 1; @@ -290,8 +284,11 @@ tf_em_int_bind(struct tf *tfp, } db_cfg.rm_db = (void *)&em_db->em_db[i]; - - rc = tf_rm_create_db(tfp, &db_cfg); + if (tf_session_is_shared_session(tfs) && + (!tf_session_is_shared_session_creator(tfs))) + rc = tf_rm_create_db_no_reservation(tfp, &db_cfg); + else + rc = tf_rm_create_db(tfp, &db_cfg); if (rc) { TFP_DRV_LOG(ERR, "%s: EM Int DB creation failed\n", @@ -299,34 +296,31 @@ tf_em_int_bind(struct tf *tfp, return rc; } - db_exists = 1; } - if (db_exists) - init = 1; - - for (i = 0; i < TF_DIR_MAX; i++) { - iparms.rm_db = em_db->em_db[i]; - iparms.subtype = TF_EM_DB_EM_REC; - iparms.info = &info; + if (!tf_session_is_shared_session(tfs)) { + for (i = 0; i < TF_DIR_MAX; i++) { + iparms.rm_db = em_db->em_db[i]; + iparms.subtype = TF_EM_DB_EM_REC; + iparms.info = &info; + + rc = tf_rm_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: EM DB get info failed\n", + tf_dir_2_str(i)); + return rc; + } - rc = tf_rm_get_info(&iparms); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: EM DB get info failed\n", - tf_dir_2_str(i)); - return rc; + rc = tf_create_em_pool(i, + iparms.info->entry.stride, + iparms.info->entry.start); + /* Logging handled in tf_create_em_pool */ + if (rc) + return rc; } - - rc = tf_create_em_pool(i, - iparms.info->entry.stride, - iparms.info->entry.start); - /* Logging handled in tf_create_em_pool */ - if (rc) - return rc; } - return 0; } @@ -338,18 +332,19 @@ tf_em_int_unbind(struct tf *tfp) struct tf_rm_free_db_parms fparms = { 0 }; struct em_rm_db *em_db; void *em_db_ptr = NULL; + struct tf_session *tfs; TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No EM Int DBs created\n"); - return 0; - } + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; - for (i = 0; i < TF_DIR_MAX; i++) - tf_free_em_pool(i); + if (!tf_session_is_shared_session(tfs)) { + for (i = 0; i < TF_DIR_MAX; i++) + tf_free_em_pool(i); + } rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr); if (rc) { @@ -372,7 +367,42 @@ tf_em_int_unbind(struct tf *tfp) em_db->em_db[i] = NULL; } - init = 0; + return 0; +} + +int +tf_em_get_resc_info(struct tf *tfp, + struct tf_em_resource_info *em) +{ + int rc; + int d; + struct tf_resource_info *dinfo; + struct tf_rm_get_alloc_info_parms ainfo; + void *em_db_ptr = NULL; + struct em_rm_db *em_db; + + TF_CHECK_PARMS2(tfp, em); + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_EM, &em_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + em_db = (struct em_rm_db *)em_db_ptr; + + /* check if reserved resource for WC is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + ainfo.rm_db = em_db->em_db[d]; + dinfo = em[d].info; + + ainfo.info = (struct tf_rm_alloc_info *)dinfo; + ainfo.subtype = 0; + rc = tf_rm_get_all_info(&ainfo, TF_EM_TBL_TYPE_MAX); + if (rc && rc != -ENOTSUP) + return rc; + } return 0; } diff --git a/drivers/net/bnxt/tf_core/tf_identifier.c b/drivers/net/bnxt/tf_core/tf_identifier.c index ee68b6ca58..4063f3ba17 100644 --- a/drivers/net/bnxt/tf_core/tf_identifier.c +++ b/drivers/net/bnxt/tf_core/tf_identifier.c @@ -15,11 +15,6 @@ struct tf; -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - /** * Identifier shadow DBs. */ @@ -41,14 +36,14 @@ tf_ident_bind(struct tf *tfp, struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 }; struct ident_rm_db *ident_db; struct tfp_calloc_parms cparms; + struct tf_session *tfs; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "Identifier DB already initialized\n"); - return -EINVAL; - } + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; memset(&db_cfg, 0, sizeof(db_cfg)); cparms.nitems = 1; @@ -73,7 +68,11 @@ tf_ident_bind(struct tf *tfp, db_cfg.rm_db = (void *)&ident_db->ident_db[i]; db_cfg.dir = i; db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt; - rc = tf_rm_create_db(tfp, &db_cfg); + if (tf_session_is_shared_session(tfs) && + (!tf_session_is_shared_session_creator(tfs))) + rc = tf_rm_create_db_no_reservation(tfp, &db_cfg); + else + rc = tf_rm_create_db(tfp, &db_cfg); if (rc) { TFP_DRV_LOG(ERR, "%s: Identifier DB creation failed\n", @@ -100,8 +99,6 @@ tf_ident_bind(struct tf *tfp, } } - init = 1; - TFP_DRV_LOG(INFO, "Identifier - initialized\n"); @@ -120,13 +117,6 @@ tf_ident_unbind(struct tf *tfp) TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No Identifier DBs created\n"); - return 0; - } - rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); if (rc) { TFP_DRV_LOG(ERR, @@ -158,7 +148,6 @@ tf_ident_unbind(struct tf *tfp) ident_db->ident_db[i] = NULL; } - init = 0; shadow_init = 0; return 0; @@ -178,13 +167,6 @@ tf_ident_alloc(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Identifier DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); if (rc) { TFP_DRV_LOG(ERR, @@ -242,13 +224,6 @@ tf_ident_free(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Identifier DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); if (rc) { TFP_DRV_LOG(ERR, @@ -329,13 +304,6 @@ tf_ident_search(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Identifier DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - if (!shadow_init) { TFP_DRV_LOG(ERR, "%s: Identifier Shadow copy is not enabled\n", @@ -388,3 +356,40 @@ tf_ident_search(struct tf *tfp __rte_unused, return 0; } + +int +tf_ident_get_resc_info(struct tf *tfp, + struct tf_identifier_resource_info *ident) +{ + int rc; + int d; + struct tf_resource_info *dinfo; + struct tf_rm_get_alloc_info_parms ainfo; + void *ident_db_ptr = NULL; + struct ident_rm_db *ident_db; + + TF_CHECK_PARMS2(tfp, ident); + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get ident_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + ident_db = (struct ident_rm_db *)ident_db_ptr; + + /* check if reserved resource for WC is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + ainfo.rm_db = ident_db->ident_db[d]; + dinfo = ident[d].info; + + ainfo.info = (struct tf_rm_alloc_info *)dinfo; + ainfo.subtype = 0; + rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX); + if (rc) + return rc; + } + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_identifier.h b/drivers/net/bnxt/tf_core/tf_identifier.h index 54cecbfd4c..55c093802e 100644 --- a/drivers/net/bnxt/tf_core/tf_identifier.h +++ b/drivers/net/bnxt/tf_core/tf_identifier.h @@ -201,4 +201,20 @@ int tf_ident_free(struct tf *tfp, int tf_ident_search(struct tf *tfp, struct tf_ident_search_parms *parms); +/** + * Retrieves the allocated resource info + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_ident_get_resc_info(struct tf *tfp, + struct tf_identifier_resource_info *parms); + #endif /* _TF_IDENTIFIER_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index c6eb94bee0..4a840f3473 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -114,11 +114,12 @@ tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf) /* HWRM Direct messages */ int -tf_msg_session_open(struct tf *tfp, +tf_msg_session_open(struct bnxt *bp, char *ctrl_chan_name, uint8_t *fw_session_id, uint8_t *fw_session_client_id, - struct tf_dev_info *dev) + struct tf_dev_info *dev, + bool *shared_session_creator) { int rc; struct hwrm_tf_session_open_input req = { 0 }; @@ -135,7 +136,7 @@ tf_msg_session_open(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(bp, &parms); if (rc) return rc; @@ -143,6 +144,8 @@ tf_msg_session_open(struct tf *tfp, *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id); *fw_session_client_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); + *shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags + & HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR); return rc; } @@ -198,7 +201,7 @@ tf_msg_session_client_register(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -249,7 +252,7 @@ tf_msg_session_client_unregister(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; @@ -293,7 +296,7 @@ tf_msg_session_close(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -345,7 +348,7 @@ tf_msg_session_qcfg(struct tf *tfp) parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -367,6 +370,16 @@ tf_msg_session_resc_qcaps(struct tf *tfp, struct tf_msg_dma_buf qcaps_buf = { 0 }; struct tf_rm_resc_req_entry *data; int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } TF_CHECK_PARMS3(tfp, query, resv_strategy); @@ -398,7 +411,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) goto cleanup; @@ -416,6 +429,7 @@ tf_msg_session_resc_qcaps(struct tf *tfp, /* Post process the response */ data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr; + for (i = 0; i < size; i++) { query[i].type = tfp_le_to_cpu_32(data[i].type); query[i].min = tfp_le_to_cpu_16(data[i].min); @@ -450,6 +464,16 @@ tf_msg_session_resc_alloc(struct tf *tfp, struct tf_rm_resc_req_entry *req_data; struct tf_rm_resc_entry *resv_data; int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } TF_CHECK_PARMS3(tfp, request, resv); @@ -497,7 +521,114 @@ tf_msg_session_resc_alloc(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); + if (rc) + goto cleanup; + + /* Process the response + * Should always get expected number of entries + */ + 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), + strerror(EINVAL)); + rc = -EINVAL; + goto cleanup; + } + + /* 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_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); + } + +cleanup: + tf_msg_free_dma_buf(&req_buf); + tf_msg_free_dma_buf(&resv_buf); + + return rc; +} + +int +tf_msg_session_resc_info(struct tf *tfp, + struct tf_dev_info *dev, + enum tf_dir dir, + uint16_t size, + struct tf_rm_resc_req_entry *request, + struct tf_rm_resc_entry *resv) +{ + int rc; + int i; + struct tfp_send_msg_parms parms = { 0 }; + struct hwrm_tf_session_resc_info_input req = { 0 }; + struct hwrm_tf_session_resc_info_output resp = { 0 }; + uint8_t fw_session_id; + struct tf_msg_dma_buf req_buf = { 0 }; + struct tf_msg_dma_buf resv_buf = { 0 }; + struct tf_rm_resc_req_entry *req_data; + struct tf_rm_resc_entry *resv_data; + int dma_size; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } + + TF_CHECK_PARMS3(tfp, request, resv); + + rc = tf_session_get_fw_session_id(tfp, &fw_session_id); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Unable to lookup FW id, rc:%s\n", + tf_dir_2_str(dir), + strerror(-rc)); + return rc; + } + + /* Prepare DMA buffers */ + dma_size = size * sizeof(struct tf_rm_resc_req_entry); + rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); + if (rc) + return rc; + + dma_size = size * sizeof(struct tf_rm_resc_entry); + rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); + if (rc) { + tf_msg_free_dma_buf(&req_buf); + return rc; + } + + /* Populate the request */ + req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); + req.flags = tfp_cpu_to_le_16(dir); + req.req_size = size; + + req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; + for (i = 0; i < size; i++) { + req_data[i].type = tfp_cpu_to_le_32(request[i].type); + req_data[i].min = tfp_cpu_to_le_16(request[i].min); + req_data[i].max = tfp_cpu_to_le_16(request[i].max); + } + + req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); + req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); + + parms.tf_type = HWRM_TF_SESSION_RESC_INFO; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = dev->ops->tf_dev_get_mailbox(); + + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) goto cleanup; @@ -604,7 +735,7 @@ tf_msg_session_resc_flush(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); tf_msg_free_dma_buf(&resv_buf); @@ -698,7 +829,7 @@ tf_msg_insert_em_internal_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -793,7 +924,7 @@ tf_msg_hash_insert_em_internal_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -863,7 +994,7 @@ tf_msg_delete_em_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -919,7 +1050,7 @@ int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp, parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) { TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n", strerror(-rc)); @@ -979,7 +1110,7 @@ int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp, parms.resp_data = (uint32_t *)&resp; parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1030,7 +1161,7 @@ tf_msg_em_mem_rgtr(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -1082,7 +1213,7 @@ tf_msg_em_mem_unrgtr(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1134,7 +1265,7 @@ tf_msg_em_qcaps(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -1209,7 +1340,7 @@ tf_msg_em_cfg(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1283,7 +1414,7 @@ tf_msg_ext_em_cfg(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1333,7 +1464,7 @@ tf_msg_em_op(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1351,6 +1482,16 @@ tf_msg_tcam_entry_set(struct tf *tfp, uint8_t *data = NULL; int data_size = 0; uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } rc = tf_session_get_fw_session_id(tfp, &fw_session_id); if (rc) { @@ -1401,7 +1542,7 @@ tf_msg_tcam_entry_set(struct tf *tfp, mparms.resp_size = sizeof(resp); mparms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &mparms); cleanup: @@ -1420,6 +1561,16 @@ tf_msg_tcam_entry_get(struct tf *tfp, struct hwrm_tf_tcam_get_input req = { 0 }; struct hwrm_tf_tcam_get_output resp = { 0 }; uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } rc = tf_session_get_fw_session_id(tfp, &fw_session_id); if (rc) { @@ -1444,7 +1595,7 @@ tf_msg_tcam_entry_get(struct tf *tfp, mparms.resp_size = sizeof(resp); mparms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &mparms); if (rc != 0) @@ -1480,6 +1631,16 @@ tf_msg_tcam_entry_free(struct tf *tfp, struct hwrm_tf_tcam_free_output resp = { 0 }; struct tfp_send_msg_parms parms = { 0 }; uint8_t fw_session_id; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to lookup session, rc:%s\n", + strerror(-rc)); + return rc; + } rc = tf_session_get_fw_session_id(tfp, &fw_session_id); if (rc) { @@ -1505,7 +1666,7 @@ tf_msg_tcam_entry_free(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); return rc; } @@ -1586,7 +1747,7 @@ tf_msg_set_tbl_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -1652,7 +1813,7 @@ tf_msg_get_tbl_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -1738,7 +1899,7 @@ tf_msg_get_global_cfg(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc != 0) return rc; @@ -1839,7 +2000,7 @@ tf_msg_set_global_cfg(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc != 0) return rc; @@ -1912,7 +2073,7 @@ tf_msg_bulk_get_tbl_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc) return rc; @@ -1975,7 +2136,7 @@ tf_msg_get_if_tbl_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc != 0) return rc; @@ -2032,7 +2193,7 @@ tf_msg_set_if_tbl_entry(struct tf *tfp, parms.resp_size = sizeof(resp); parms.mailbox = dev->ops->tf_dev_get_mailbox(); - rc = tfp_send_msg_direct(tfp, &parms); + rc = tfp_send_msg_direct(tf_session_get_bp(tfs), &parms); if (rc != 0) return rc; diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h index 7b4a6a3d92..5ecaf9e7e7 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.h +++ b/drivers/net/bnxt/tf_core/tf_msg.h @@ -14,6 +14,7 @@ #include "tf_rm.h" #include "tf_tcam.h" #include "tf_global_cfg.h" +#include "bnxt.h" struct tf; @@ -22,8 +23,8 @@ struct tf; /** * Sends session open request to Firmware * - * [in] session - * Pointer to session handle + * [in] bp + * Pointer to bnxt handle * * [in] ctrl_chan_name * PCI name of the control channel @@ -31,14 +32,24 @@ struct tf; * [in/out] fw_session_id * Pointer to the fw_session_id that is allocated on firmware side * + * [in/out] fw_session_client_id + * Pointer to the fw_session_client_id that is allocated on firmware side + * + * [in/out] dev + * Pointer to the associated device + * + * [out] shared_session_creator + * Pointer to the shared_session_creator + * * Returns: * 0 on Success else internal Truflow error */ -int tf_msg_session_open(struct tf *tfp, +int tf_msg_session_open(struct bnxt *bp, char *ctrl_chan_name, uint8_t *fw_session_id, uint8_t *fw_session_client_id, - struct tf_dev_info *dev); + struct tf_dev_info *dev, + bool *shared_session_creator); /** * Sends session close request to Firmware @@ -178,6 +189,34 @@ int tf_msg_session_resc_alloc(struct tf *tfp, struct tf_rm_resc_req_entry *request, struct tf_rm_resc_entry *resv); +/** + * Sends session HW resource allocation 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] req + * Pointer to an array of request elements + * + * [in] resv + * Pointer to an array of reserved elements + * + * Returns: + * 0 on Success else internal Truflow error + */ +int tf_msg_session_resc_info(struct tf *tfp, + struct tf_dev_info *dev, + enum tf_dir dir, + uint16_t size, + struct tf_rm_resc_req_entry *request, + struct tf_rm_resc_entry *resv); + /** * Sends session resource flush request to TF Firmware * diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c index 50f6b1eeab..f44b5b1ab6 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.c +++ b/drivers/net/bnxt/tf_core/tf_rm.c @@ -702,7 +702,9 @@ tf_rm_create_db(struct tf *tfp, } db[i].pool = (struct bitalloc *)cparms.mem_va; - rc = ba_init(db[i].pool, resv[j].stride); + rc = ba_init(db[i].pool, + resv[j].stride, + !tf_session_is_shared_session(tfs)); if (rc) { TFP_DRV_LOG(ERR, "%s: Pool init failed, type:%d:%s\n", @@ -746,6 +748,249 @@ tf_rm_create_db(struct tf *tfp, return -EINVAL; } +int +tf_rm_create_db_no_reservation(struct tf *tfp, + struct tf_rm_create_db_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + int i, j; + uint16_t hcapi_items, *req_cnt; + struct tfp_calloc_parms cparms; + struct tf_rm_resc_req_entry *req; + struct tf_rm_resc_entry *resv; + struct tf_rm_new_db *rm_db; + struct tf_rm_element *db; + uint32_t pool_size; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + /* Retrieve device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) + return rc; + + /* Copy requested counts (alloc_cnt) from tf_open_session() to local + * copy (req_cnt) so that it can be updated if required. + */ + + cparms.nitems = parms->num_elements; + cparms.size = sizeof(uint16_t); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) + return rc; + + req_cnt = (uint16_t *)cparms.mem_va; + + tfp_memcpy(req_cnt, parms->alloc_cnt, + parms->num_elements * sizeof(uint16_t)); + + /* Process capabilities against DB requirements. However, as a + * DB can hold elements that are not HCAPI we can reduce the + * req msg content by removing those out of the request yet + * 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->dir, + parms->module, + parms->cfg, + req_cnt, + parms->num_elements, + &hcapi_items); + + if (hcapi_items == 0) { + TFP_DRV_LOG(ERR, + "%s: module:%s Empty RM DB create request\n", + tf_dir_2_str(parms->dir), + tf_module_2_str(parms->module)); + + parms->rm_db = NULL; + return -ENOMEM; + } + + /* Alloc request, alignment already set */ + cparms.nitems = (size_t)hcapi_items; + cparms.size = sizeof(struct tf_rm_resc_req_entry); + rc = tfp_calloc(&cparms); + if (rc) + return rc; + req = (struct tf_rm_resc_req_entry *)cparms.mem_va; + + /* Alloc reservation, alignment and nitems already set */ + cparms.size = sizeof(struct tf_rm_resc_entry); + rc = tfp_calloc(&cparms); + if (rc) + return rc; + resv = (struct tf_rm_resc_entry *)cparms.mem_va; + + /* Build the request */ + for (i = 0, j = 0; i < parms->num_elements; i++) { + struct tf_rm_element_cfg *cfg = &parms->cfg[i]; + uint16_t hcapi_type = cfg->hcapi_type; + + /* Only perform reservation for requested entries + */ + if (req_cnt[i] == 0) + continue; + + /* Skip any children in the request */ + if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI || + cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA || + cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) { + req[j].type = hcapi_type; + req[j].min = req_cnt[i]; + req[j].max = req_cnt[i]; + j++; + } + } + + /* Get all resources info for the module type + */ + rc = tf_msg_session_resc_info(tfp, + dev, + parms->dir, + hcapi_items, + req, + resv); + if (rc) + return rc; + + /* Build the RM DB per the request */ + cparms.nitems = 1; + cparms.size = sizeof(struct tf_rm_new_db); + rc = tfp_calloc(&cparms); + if (rc) + return rc; + rm_db = (void *)cparms.mem_va; + + /* Build the DB within RM DB */ + cparms.nitems = parms->num_elements; + cparms.size = sizeof(struct tf_rm_element); + rc = tfp_calloc(&cparms); + if (rc) + return rc; + rm_db->db = (struct tf_rm_element *)cparms.mem_va; + + db = rm_db->db; + for (i = 0, j = 0; i < parms->num_elements; i++) { + struct tf_rm_element_cfg *cfg = &parms->cfg[i]; + const char *type_str; + + dev->ops->tf_dev_get_resource_str(tfp, + cfg->hcapi_type, + &type_str); + + db[i].cfg_type = cfg->cfg_type; + db[i].hcapi_type = cfg->hcapi_type; + + /* Save the parent subtype for later use to find the pool + */ + if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD) + db[i].parent_subtype = cfg->parent_subtype; + + /* If the element didn't request an allocation no need + * to create a pool nor verify if we got a reservation. + */ + if (req_cnt[i] == 0) + continue; + + /* Skip any children or invalid + */ + if (cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI && + cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA && + cfg->cfg_type != TF_RM_ELEM_CFG_HCAPI_BA_PARENT) + continue; + + /* If the element had requested an allocation and that + * allocation was a success (full amount) then + * allocate the pool. + */ + if (req_cnt[i] == resv[j].stride) { + db[i].alloc.entry.start = resv[j].start; + db[i].alloc.entry.stride = resv[j].stride; + + /* Only allocate BA pool if a BA type not a child */ + if (cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA || + cfg->cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_PARENT) { + if (cfg->divider) { + resv[j].stride = + resv[j].stride / cfg->divider; + if (resv[j].stride <= 0) { + TFP_DRV_LOG(ERR, + "%s:Divide fails:%d:%s\n", + tf_dir_2_str(parms->dir), + cfg->hcapi_type, type_str); + goto fail; + } + } + /* Create pool */ + pool_size = (BITALLOC_SIZEOF(resv[j].stride) / + sizeof(struct bitalloc)); + /* Alloc request, alignment already set */ + cparms.nitems = pool_size; + cparms.size = sizeof(struct bitalloc); + rc = tfp_calloc(&cparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Pool alloc failed, type:%d:%s\n", + tf_dir_2_str(parms->dir), + cfg->hcapi_type, type_str); + goto fail; + } + db[i].pool = (struct bitalloc *)cparms.mem_va; + + rc = ba_init(db[i].pool, + resv[j].stride, + !tf_session_is_shared_session(tfs)); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Pool init failed, type:%d:%s\n", + tf_dir_2_str(parms->dir), + cfg->hcapi_type, type_str); + goto fail; + } + } + j++; + } else { + /* Bail out as we want what we requested for + * all elements, not any less. + */ + TFP_DRV_LOG(ERR, + "%s: Alloc failed %d:%s req:%d, alloc:%d\n", + tf_dir_2_str(parms->dir), cfg->hcapi_type, + type_str, req_cnt[i], resv[j].stride); + goto fail; + } + } + + rm_db->num_entries = parms->num_elements; + rm_db->dir = parms->dir; + rm_db->module = parms->module; + *parms->rm_db = (void *)rm_db; + + tfp_free((void *)req); + tfp_free((void *)resv); + tfp_free((void *)req_cnt); + return 0; + + fail: + tfp_free((void *)req); + tfp_free((void *)resv); + tfp_free((void *)db->pool); + tfp_free((void *)db); + tfp_free((void *)rm_db); + tfp_free((void *)req_cnt); + parms->rm_db = NULL; + + return -EINVAL; +} int tf_rm_free_db(struct tf *tfp, struct tf_rm_free_db_parms *parms) @@ -1043,6 +1288,36 @@ tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms) return 0; } +int +tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size) +{ + struct tf_rm_new_db *rm_db; + enum tf_rm_elem_cfg_type cfg_type; + struct tf_rm_alloc_info *info = parms->info; + int i; + + TF_CHECK_PARMS2(parms, parms->rm_db); + rm_db = (struct tf_rm_new_db *)parms->rm_db; + TF_CHECK_PARMS1(rm_db->db); + + for (i = 0; i < size; i++) { + cfg_type = rm_db->db[i].cfg_type; + + /* Bail out if not controlled by HCAPI */ + if (cfg_type == TF_RM_ELEM_CFG_NULL) { + info++; + continue; + } + + memcpy(info, + &rm_db->db[i].alloc, + sizeof(struct tf_rm_alloc_info)); + info++; + } + + return 0; +} + int tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms) { diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h index 6eb6865dac..8b984112e8 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.h +++ b/drivers/net/bnxt/tf_core/tf_rm.h @@ -425,6 +425,24 @@ struct tf_rm_check_indexes_in_range_parms { int tf_rm_create_db(struct tf *tfp, struct tf_rm_create_db_parms *parms); +/** + * Creates and fills a Resource Manager (RM) DB with requested + * elements. The DB is indexed per the parms structure. It only retrieve + * allocated resource information for a exist session. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to create parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_rm_create_db_no_reservation(struct tf *tfp, + struct tf_rm_create_db_parms *parms); + /** * Closes the Resource Manager (RM) DB and frees all allocated * resources per the associated database. @@ -498,6 +516,22 @@ int tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms); */ int tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms); +/** + * Retrieves all elements allocation information from the Resource + * Manager (RM) DB. + * + * [in] parms + * Pointer to get info parameters + * + * [in] size + * number of the elements for the specific module + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_rm_get_all_info(struct tf_rm_get_alloc_info_parms *parms, int size); + /** * Performs a lookup in the Resource Manager DB and retrieves the * requested HCAPI RM type. diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c index f591fbe3f5..391d8786ab 100644 --- a/drivers/net/bnxt/tf_core/tf_session.c +++ b/drivers/net/bnxt/tf_core/tf_session.c @@ -11,6 +11,7 @@ #include "tf_common.h" #include "tf_msg.h" #include "tfp.h" +#include "bnxt.h" struct tf_session_client_create_parms { /** @@ -57,6 +58,7 @@ tf_session_create(struct tf *tfp, uint8_t fw_session_client_id; union tf_session_id *session_id; struct tf_dev_info dev; + bool shared_session_creator; TF_CHECK_PARMS2(tfp, parms); @@ -64,11 +66,12 @@ tf_session_create(struct tf *tfp, &dev); /* Open FW session and get a new session_id */ - rc = tf_msg_session_open(tfp, + rc = tf_msg_session_open(parms->open_cfg->bp, parms->open_cfg->ctrl_chan_name, &fw_session_id, &fw_session_client_id, - &dev); + &dev, + &shared_session_creator); if (rc) { /* Log error */ if (rc == -EEXIST) @@ -137,6 +140,7 @@ tf_session_create(struct tf *tfp, session_id->id = session->session_id.id; session->shadow_copy = parms->open_cfg->shadow_copy; + session->bp = parms->open_cfg->bp; /* Init session client list */ ll_init(&session->client_ll); @@ -175,12 +179,20 @@ tf_session_create(struct tf *tfp, /* Init session em_ext_db */ session->em_ext_db_handle = NULL; + if (!strcmp(parms->open_cfg->ctrl_chan_name, "tf_share")) + session->shared_session = true; + + if (session->shared_session && shared_session_creator) { + session->shared_session_creator = true; + parms->open_cfg->shared_session_creator = true; + } rc = tf_dev_bind(tfp, parms->open_cfg->device_type, session->shadow_copy, &parms->open_cfg->resources, &session->dev); + /* Logging handled by dev_bind */ if (rc) goto cleanup; @@ -857,16 +869,29 @@ tf_session_get_db(struct tf *tfp, switch (type) { case TF_MODULE_TYPE_IDENTIFIER: - *db_handle = tfs->id_db_handle; + if (tfs->id_db_handle) + *db_handle = tfs->id_db_handle; + else + rc = -EINVAL; break; case TF_MODULE_TYPE_TABLE: - *db_handle = tfs->tbl_db_handle; + if (tfs->tbl_db_handle) + *db_handle = tfs->tbl_db_handle; + else + rc = -EINVAL; + break; case TF_MODULE_TYPE_TCAM: - *db_handle = tfs->tcam_db_handle; + if (tfs->tcam_db_handle) + *db_handle = tfs->tcam_db_handle; + else + rc = -EINVAL; break; case TF_MODULE_TYPE_EM: - *db_handle = tfs->em_db_handle; + if (tfs->em_db_handle) + *db_handle = tfs->em_db_handle; + else + rc = -EINVAL; break; default: rc = -EINVAL; diff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h index e5c7a07daf..0b8f63c374 100644 --- a/drivers/net/bnxt/tf_core/tf_session.h +++ b/drivers/net/bnxt/tf_core/tf_session.h @@ -70,6 +70,23 @@ struct tf_session { */ union tf_session_id session_id; + /** + * Boolean controlling the use and availability of shared session. + * Shared session will allow the application to share resources + * on the firmware side without having to allocate them on firmware. + * Additional private session core_data will be allocated if this + * boolean is set to 'true', default 'false'. + * + */ + bool shared_session; + + /** + * This flag indicates the shared session on firmware side is created + * by this session. Some privileges may be assigned to this session. + * + */ + bool shared_session_creator; + /** * Boolean controlling the use and availability of shadow * copy. Shadow copy will allow the TruFlow Core to keep track @@ -137,6 +154,11 @@ struct tf_session { * em db reference for the session */ void *em_db_handle; + + /** + * the pointer to the parent bp struct + */ + void *bp; }; /** @@ -500,4 +522,48 @@ int tf_session_set_db(struct tf *tfp, enum tf_module_type type, void *db_handle); + +/** + * Check if the session is shared session. + * + * [in] session, pointer to the session + * + * Returns: + * - true if it is shared session + * - false if it is not shared session + */ +static inline bool +tf_session_is_shared_session(struct tf_session *tfs) +{ + return tfs->shared_session; +} + +/** + * Check if the session is the shared session creator + * + * [in] session, pointer to the session + * + * Returns: + * - true if it is the shared session creator + * - false if it is not the shared session creator + */ +static inline bool +tf_session_is_shared_session_creator(struct tf_session *tfs) +{ + return tfs->shared_session_creator; +} + +/** + * Get the pointer to the parent bnxt struct + * + * [in] session, pointer to the session + * + * Returns: + * - the pointer to the parent bnxt struct + */ +static inline struct bnxt* +tf_session_get_bp(struct tf_session *tfs) +{ + return tfs->bp; +} #endif /* _TF_SESSION_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c index 2d0dda18c9..17fb550917 100644 --- a/drivers/net/bnxt/tf_core/tf_tbl.c +++ b/drivers/net/bnxt/tf_core/tf_tbl.c @@ -31,11 +31,6 @@ struct tf; */ static void *shadow_tbl_db[TF_DIR_MAX]; -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - /** * Shadow init flag, set on bind and cleared on unbind */ @@ -49,14 +44,14 @@ tf_tbl_bind(struct tf *tfp, struct tf_rm_create_db_parms db_cfg = { 0 }; struct tbl_rm_db *tbl_db; struct tfp_calloc_parms cparms; + struct tf_session *tfs; TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "Table DB already initialized\n"); - return -EINVAL; - } + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; memset(&db_cfg, 0, sizeof(db_cfg)); cparms.nitems = 1; @@ -82,8 +77,11 @@ tf_tbl_bind(struct tf *tfp, db_cfg.dir = d; db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt; db_cfg.rm_db = (void *)&tbl_db->tbl_db[d]; - - rc = tf_rm_create_db(tfp, &db_cfg); + if (tf_session_is_shared_session(tfs) && + (!tf_session_is_shared_session_creator(tfs))) + rc = tf_rm_create_db_no_reservation(tfp, &db_cfg); + else + rc = tf_rm_create_db(tfp, &db_cfg); if (rc) { TFP_DRV_LOG(ERR, "%s: Table DB creation failed\n", @@ -92,7 +90,6 @@ tf_tbl_bind(struct tf *tfp, return rc; } } - init = 1; TFP_DRV_LOG(INFO, "Table Type - initialized\n"); @@ -110,13 +107,6 @@ tf_tbl_unbind(struct tf *tfp) void *tbl_db_ptr = NULL; TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No Table DBs created\n"); - return 0; - } - rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); if (rc) { TFP_DRV_LOG(ERR, @@ -136,7 +126,6 @@ tf_tbl_unbind(struct tf *tfp) tbl_db->tbl_db[i] = NULL; } - init = 0; shadow_init = 0; return 0; @@ -157,13 +146,6 @@ tf_tbl_alloc(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Table DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -234,12 +216,6 @@ tf_tbl_free(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Table DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -346,13 +322,6 @@ tf_tbl_set(struct tf *tfp, TF_CHECK_PARMS3(tfp, parms, parms->data); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Table DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -456,14 +425,6 @@ tf_tbl_get(struct tf *tfp, TF_CHECK_PARMS3(tfp, parms, parms->data); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Table DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -567,14 +528,6 @@ tf_tbl_bulk_get(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No Table DBs created\n", - tf_dir_2_str(parms->dir)); - - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -662,3 +615,40 @@ tf_tbl_bulk_get(struct tf *tfp, return rc; } + +int +tf_tbl_get_resc_info(struct tf *tfp, + struct tf_tbl_resource_info *tbl) +{ + int rc; + int d; + struct tf_resource_info *dinfo; + struct tf_rm_get_alloc_info_parms ainfo; + void *tbl_db_ptr = NULL; + struct tbl_rm_db *tbl_db; + + TF_CHECK_PARMS2(tfp, tbl); + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + /* check if reserved resource for WC is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + ainfo.rm_db = tbl_db->tbl_db[d]; + dinfo = tbl[d].info; + + ainfo.info = (struct tf_rm_alloc_info *)dinfo; + ainfo.subtype = 0; + rc = tf_rm_get_all_info(&ainfo, TF_TBL_TYPE_MAX); + if (rc) + return rc; + } + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_tbl.h b/drivers/net/bnxt/tf_core/tf_tbl.h index 83b72d1b3f..aba46fd161 100644 --- a/drivers/net/bnxt/tf_core/tf_tbl.h +++ b/drivers/net/bnxt/tf_core/tf_tbl.h @@ -396,4 +396,21 @@ int tf_tbl_get(struct tf *tfp, int tf_tbl_bulk_get(struct tf *tfp, struct tf_tbl_get_bulk_parms *parms); +/** + * Retrieves the allocated resource info + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table resource info parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int +tf_tbl_get_resc_info(struct tf *tfp, + struct tf_tbl_resource_info *tbl); + #endif /* TF_TBL_TYPE_H */ diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c index c2eef26dbb..70dc539f15 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.c +++ b/drivers/net/bnxt/tf_core/tf_tcam.c @@ -23,11 +23,6 @@ struct tf; */ static void *shadow_tcam_db[TF_DIR_MAX]; -/** - * Init flag, set on bind and cleared on unbind - */ -static uint8_t init; - /** * Shadow init flag, set on bind and cleared on unbind */ @@ -55,12 +50,6 @@ tf_tcam_bind(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - if (init) { - TFP_DRV_LOG(ERR, - "TCAM DB already initialized\n"); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -118,7 +107,11 @@ tf_tcam_bind(struct tf *tfp, db_cfg.dir = d; db_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt; db_cfg.rm_db = (void *)&tcam_db->tcam_db[d]; - rc = tf_rm_create_db(tfp, &db_cfg); + if (tf_session_is_shared_session(tfs) && + (!tf_session_is_shared_session_creator(tfs))) + rc = tf_rm_create_db_no_reservation(tfp, &db_cfg); + else + rc = tf_rm_create_db(tfp, &db_cfg); if (rc) { TFP_DRV_LOG(ERR, "%s: TCAM DB creation failed\n", @@ -143,7 +136,8 @@ tf_tcam_bind(struct tf *tfp, "%s: TCAM reserved resource is not multiple of %d\n", tf_dir_2_str(d), num_slices); - return -EINVAL; + rc = -EINVAL; + goto error; } } @@ -186,8 +180,6 @@ tf_tcam_bind(struct tf *tfp, shadow_init = 1; } - init = 1; - TFP_DRV_LOG(INFO, "TCAM - initialized\n"); @@ -211,7 +203,6 @@ error: } shadow_init = 0; - init = 0; return rc; } @@ -227,13 +218,6 @@ tf_tcam_unbind(struct tf *tfp) struct tf_shadow_tcam_free_db_parms fshadow; TF_CHECK_PARMS1(tfp); - /* Bail if nothing has been initialized */ - if (!init) { - TFP_DRV_LOG(INFO, - "No TCAM DBs created\n"); - return 0; - } - rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr); if (rc) { TFP_DRV_LOG(ERR, @@ -263,7 +247,6 @@ tf_tcam_unbind(struct tf *tfp) } shadow_init = 0; - init = 0; return 0; } @@ -283,13 +266,6 @@ tf_tcam_alloc(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No TCAM DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -372,13 +348,6 @@ tf_tcam_free(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No TCAM DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -529,13 +498,6 @@ tf_tcam_alloc_search(struct tf *tfp, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No TCAM DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - if (!shadow_init || !shadow_tcam_db[parms->dir]) { TFP_DRV_LOG(ERR, "%s: TCAM Shadow not initialized for %s\n", tf_dir_2_str(parms->dir), @@ -660,13 +622,6 @@ tf_tcam_set(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No TCAM DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -781,13 +736,6 @@ tf_tcam_get(struct tf *tfp __rte_unused, TF_CHECK_PARMS2(tfp, parms); - if (!init) { - TFP_DRV_LOG(ERR, - "%s: No TCAM DBs created\n", - tf_dir_2_str(parms->dir)); - return -EINVAL; - } - /* Retrieve the session information */ rc = tf_session_get_session_internal(tfp, &tfs); if (rc) @@ -852,3 +800,40 @@ tf_tcam_get(struct tf *tfp __rte_unused, return 0; } + +int +tf_tcam_get_resc_info(struct tf *tfp, + struct tf_tcam_resource_info *tcam) +{ + int rc; + int d; + struct tf_resource_info *dinfo; + struct tf_rm_get_alloc_info_parms ainfo; + void *tcam_db_ptr = NULL; + struct tcam_rm_db *tcam_db; + + TF_CHECK_PARMS2(tfp, tcam); + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_db = (struct tcam_rm_db *)tcam_db_ptr; + + /* check if reserved resource for WC is multiple of num_slices */ + for (d = 0; d < TF_DIR_MAX; d++) { + ainfo.rm_db = tcam_db->tcam_db[d]; + dinfo = tcam[d].info; + + ainfo.info = (struct tf_rm_alloc_info *)dinfo; + ainfo.subtype = 0; + rc = tf_rm_get_all_info(&ainfo, TF_TCAM_TBL_TYPE_MAX); + if (rc && rc != -ENOTSUP) + return rc; + } + + return 0; +} diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h index acab223532..bed17af6ae 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.h +++ b/drivers/net/bnxt/tf_core/tf_tcam.h @@ -386,4 +386,20 @@ int tf_tcam_set(struct tf *tfp, int tf_tcam_get(struct tf *tfp, struct tf_tcam_get_parms *parms); +/** + * Retrieves the allocated resource info + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tcam_get_resc_info(struct tf *tfp, + struct tf_tcam_resource_info *parms); + #endif /* _TF_TCAM_H */ diff --git a/drivers/net/bnxt/tf_core/tfp.c b/drivers/net/bnxt/tf_core/tfp.c index 37c49b587d..4d9b37f749 100644 --- a/drivers/net/bnxt/tf_core/tfp.c +++ b/drivers/net/bnxt/tf_core/tfp.c @@ -28,7 +28,7 @@ * Returns success or failure code. */ int -tfp_send_msg_direct(struct tf *tfp, +tfp_send_msg_direct(struct bnxt *bp, struct tfp_send_msg_parms *parms) { int rc = 0; @@ -40,9 +40,7 @@ tfp_send_msg_direct(struct tf *tfp, if (parms->mailbox == TF_CHIMP_MB) use_kong_mb = 0; - rc = bnxt_hwrm_tf_message_direct(container_of(tfp, - struct bnxt, - tfp), + rc = bnxt_hwrm_tf_message_direct(bp, use_kong_mb, parms->tf_type, parms->req_data, diff --git a/drivers/net/bnxt/tf_core/tfp.h b/drivers/net/bnxt/tf_core/tfp.h index bcc56b0a54..58f34bbcab 100644 --- a/drivers/net/bnxt/tf_core/tfp.h +++ b/drivers/net/bnxt/tf_core/tfp.h @@ -15,6 +15,7 @@ #include #include #include +#include /** * DPDK/Driver specific log level for the BNXT Eth driver. @@ -130,7 +131,7 @@ struct tfp_calloc_parms { * -1 - Global error like not supported * -EINVAL - Parameter Error */ -int tfp_send_msg_direct(struct tf *tfp, +int tfp_send_msg_direct(struct bnxt *bp, struct tfp_send_msg_parms *parms); /** -- 2.20.1