/* 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)
/* 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)
#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 *
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.
*/
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
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
* 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];
/*
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 {
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 *
********************/
*/
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;
/*
/* 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. */
#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;
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. */
*/
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
#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)
}
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;
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;
}
#define _BITALLOC_H_
#include <stdint.h>
+#include <stdbool.h>
/* Bitalloc works on uint32_t as its word size */
typedef uint32_t bitalloc_word_t;
* 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
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);
}
}
+ 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;
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;
+}
* 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];
/**
* 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
*
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
*
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);
/*
* 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 */
{
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
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)
*/
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.
*
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.
*
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
*
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
*
.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,
.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,
.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,
.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,
.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,
.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,
.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,
.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,
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_ */
/* 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
*/
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;
return rc;
}
- db_exists = 1;
}
- if (db_exists)
- init = 1;
-
mem_type = parms->mem_type;
return 0;
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",
tfp_free(ext_db);
tf_session_set_em_ext_db(tfp, NULL);
- init = 0;
-
return 0;
}
#define TF_EM_DB_EM_REC 0
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
/**
* EM Pool
*/
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;
}
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",
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;
}
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) {
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;
}
struct tf;
-/**
- * Init flag, set on bind and cleared on unbind
- */
-static uint8_t init;
-
/**
* Identifier shadow DBs.
*/
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;
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",
}
}
- init = 1;
-
TFP_DRV_LOG(INFO,
"Identifier - initialized\n");
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,
ident_db->ident_db[i] = NULL;
}
- init = 0;
shadow_init = 0;
return 0;
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,
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,
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",
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;
+}
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_ */
/* 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 };
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;
*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;
}
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;
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;
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;
}
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;
}
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);
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;
/* 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);
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);
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;
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);
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;
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;
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;
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));
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;
}
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;
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;
}
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;
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;
}
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;
}
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;
}
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) {
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:
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) {
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)
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) {
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;
}
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;
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;
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;
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;
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;
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;
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;
#include "tf_rm.h"
#include "tf_tcam.h"
#include "tf_global_cfg.h"
+#include "bnxt.h"
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
* [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
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
*
}
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",
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)
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)
{
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.
*/
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.
#include "tf_common.h"
#include "tf_msg.h"
#include "tfp.h"
+#include "bnxt.h"
struct tf_session_client_create_parms {
/**
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);
&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)
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);
/* 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;
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;
*/
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
* em db reference for the session
*/
void *em_db_handle;
+
+ /**
+ * the pointer to the parent bp struct
+ */
+ void *bp;
};
/**
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_ */
*/
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
*/
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;
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",
return rc;
}
}
- init = 1;
TFP_DRV_LOG(INFO,
"Table Type - initialized\n");
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,
tbl_db->tbl_db[i] = NULL;
}
- init = 0;
shadow_init = 0;
return 0;
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)
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)
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)
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)
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)
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;
+}
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 */
*/
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
*/
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)
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",
"%s: TCAM reserved resource is not multiple of %d\n",
tf_dir_2_str(d),
num_slices);
- return -EINVAL;
+ rc = -EINVAL;
+ goto error;
}
}
shadow_init = 1;
}
- init = 1;
-
TFP_DRV_LOG(INFO,
"TCAM - initialized\n");
}
shadow_init = 0;
- init = 0;
return rc;
}
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,
}
shadow_init = 0;
- init = 0;
return 0;
}
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)
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)
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),
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)
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)
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;
+}
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 */
* 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;
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,
#include <rte_spinlock.h>
#include <rte_log.h>
#include <rte_byteorder.h>
+#include <bnxt.h>
/**
* DPDK/Driver specific log level for the BNXT Eth driver.
* -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);
/**