hermon.h revision 13cc0a0b8d667c14344b4ff49cc47350cd9ef182
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#ifndef _SYS_IB_ADAPTERS_HERMON_H
#define _SYS_IB_ADAPTERS_HERMON_H
/*
* hermon.h
* Contains the #defines and typedefs necessary for the Hermon softstate
* structure and for proper attach() and detach() processing. Also
* includes all the other Hermon header files (and so is the only header
* file that is directly included by the Hermon source files).
* Lastly, this file includes everything necessary for implementing the
* devmap interface and for maintaining the "mapped resource database".
*/
#include <sys/tnf_probe.h>
#ifdef FMA_TEST
#endif
/*
* First include all the Hermon typedefs, then include all the other Hermon
* specific headers (many of which depend on the typedefs having already
* been defined).
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Number of initial states to setup. Used in call to ddi_soft_state_init()
*/
#define HERMON_INITIAL_STATES 3
/*
* Macro and defines used to calculate device instance number from minor
* number (and vice versa).
*/
#define HERMON_MINORNUM_SHIFT 3
/*
* Locations for the various Hermon hardware CMD,UAR & MSIx PCIe BARs
*/
#define HERMON_ONCLOSE_FLASH_INPROGRESS (1 << 0)
/*
* VPD header size - or more rightfully, the area of interest for fwflash
* There's more, but we don't need it for our use so we don't read it
*/
/*
*/
#define HERMON_PCI_CAP_DEV_OFFS 0x08
#define HERMON_PCI_CAP_LNK_OFFS 0x10
/*
* Some defines for the software reset. These define the value that should
* be written to begin the reset (HERMON_SW_RESET_START), the delay before
* beginning to poll for completion (HERMON_SW_RESET_DELAY), the in-between
* polling delay (HERMON_SW_RESET_POLL_DELAY), and the value that indicates
* that the reset has not completed (HERMON_SW_RESET_NOTDONE).
*/
#define HERMON_SW_RESET_START 0x00000001
#define HERMON_SW_RESET_NOTDONE 0xFFFFFFFF
/*
* These defines are used in the Hermon software reset operation. They define
* also specify two config registers which should not be read or restored.
*/
#define HERMON_SW_RESET_NUMREGS 0x40
/*
* Macro used to output HCA warning messages. Note: HCA warning messages
* are only generated when an unexpected condition has been detected. This
* can be the result of a software bug or some other problem, but it is more
* something unexpected. This warning message means that the driver state
*/
/*
* Macro used to set attach failure messages. Also, the attach message buf
* size is set here.
*/
#define HERMON_ATTACH_MSGSIZE 80
#define HERMON_ATTACH_MSG_INIT(attach_buf) \
(attach_buf)[0] = '\0';
/*
* Macros used for controlling whether or not event callbacks will be forwarded
* to the IBTF. This is necessary because there are certain race conditions
* that can occur (e.g. calling IBTF with an asynch event before the IBTF
* registration has successfully completed or handling an event after we've
* detached from the IBTF.)
*
* HERMON_ENABLE_IBTF_CALLB() initializes the "hs_ibtfpriv" field in the Hermon
* softstate. When "hs_ibtfpriv" is non-NULL, it is OK to forward asynch
* and CQ events to the IBTF.
*
* HERMON_DO_IBTF_ASYNC_CALLB() and HERMON_DO_IBTF_CQ_CALLB() both set and clear
* the "hs_in_evcallb" flag, as necessary, to indicate that an IBTF
* callback is currently in progress. This is necessary so that we can
* block on this condition in hermon_detach().
*
* HERMON_QUIESCE_IBTF_CALLB() is used in hermon_detach() to set the
* "hs_ibtfpriv" to NULL (thereby disabling any further IBTF callbacks)
* and to poll on the "hs_in_evcallb" flag. When this flag is zero, all
* IBTF callbacks have quiesced and it is safe to continue with detach
* (i.e. continue detaching from IBTF).
*/
(state)->hs_in_evcallb = 0;
(state)->hs_in_evcallb = 0;
#define HERMON_QUIESCE_IBTF_CALLB(state) \
{ \
\
while (((state)->hs_in_evcallb != 0) && \
(count++ < HERMON_QUIESCE_IBTF_CALLB_POLL_MAX)) { \
} \
}
/*
* Defines used by the HERMON_QUIESCE_IBTF_CALLB() macro to determine the
* duration and number of times (at maximum) to poll while waiting for IBTF
* callbacks to quiesce.
*/
#define HERMON_QUIESCE_IBTF_CALLB_POLL_DELAY 1
#define HERMON_QUIESCE_IBTF_CALLB_POLL_MAX 1000000
/*
* Macros to retrieve PCI id's of the device
*/
property, -1))
/*
* Defines used to record the device mode to which Hermon driver has been
* attached. HERMON_MAINTENANCE_MODE is used when the device has
* come up in the "maintenance mode". In this mode, no InfiniBand interfaces
* HERMON_HCA_MODE isused when the device has come up in the
* normal HCA mode. In this mode, all necessary InfiniBand interfaces are
*/
#define HERMON_MAINTENANCE_MODE 1
#define HERMON_HCA_MODE 2
/*
* Used to determine if the device is operational, or not in maintenance mode.
* This means either the driver has attached successfully against an hermon
* device in hermon compatibility mode, or against a hermon device in full HCA
* mode.
*/
#define HERMON_IS_OPERATIONAL(mode) \
(mode == HERMON_HCA_MODE)
/*
* The following define is used (in hermon_umap_db_set_onclose_cb()) to
* indicate that a cleanup callback is needed to undo initialization done
* by the firmware flash burn code.
*/
#define HERMON_ONCLOSE_FLASH_INPROGRESS (1 << 0)
/*
* The following enumerated type and structures are used during driver
* initialization. Note: The HERMON_DRV_CLEANUP_ALL type is used as a marker
* for end of the cleanup steps. No cleanup steps should be added after
* HERMON_DRV_CLEANUP_ALL. Any addition steps should be added before it.
*/
typedef enum {
/* No more driver cleanup steps below this point! */
/*
* The hermon_dma_info_t structure is used to store information related to
* the various ICM resources' DMA allocations. The related ICM table and
* virtual address are stored here. The DMA and Access handles are stored
* here. Also, the allocation length and virtual (host) address.
*/
struct hermon_dma_info_s {
};
/*
* The hermon_cmd_reg_t structure is used to hold the address of the each of
* the most frequently accessed hardware registers. Specifically, it holds
* the HCA Command Registers (HCR, used to pass command and mailbox
* information back and forth to Hermon firmware) and the lock used to guarantee
* mutually exclusive access to the registers.
* Related to this, is the "clr_int" register which is used to clear the
* interrupt once all EQs have been serviced.
* Finally, there is the software reset register which is used to reinitialize
* the Hermon device and to put it into a known state at driver startup time.
* Below we also have the offsets (into the CMD register space) for each of
* the various registers.
*/
typedef struct hermon_cmd_reg_s {
/* SOME TEMPORARY PRINTING THINGS */
#define HERMON_PRINT_CI (0x01 << 0)
/* END PRINTING THINGS */
/*
* The hermon_state_t structure is the HCA software state structure. It
* contains all the pointers and placeholder for everything that the HCA
* driver needs to properly operate. One of these structures exists for
* every instance of the HCA driver.
*/
struct hermon_state_s {
int hs_instance;
int hs_debug; /* for debug, a way of tracing */
/* see hermon.c for setting it */
/* PCI device, vendor, and revision IDs */
struct hermon_hw_qpc_s hs_debug_qpc;
struct hermon_hw_cqc_s hs_debug_cqc;
struct hermon_hw_eqc_s hs_debug_eqc;
/*
* DMA information for the InfiniHost Context Memory (ICM),
* ICM Auxiliary allocation and the firmware. Also, record
* of ICM and ICMA sizes, in bytes.
*/
/* JBDB -- store here hs_icm_table, with hs_icm_dma in */
int hs_intr_types_avail;
int hs_intrmsi_count;
int hs_intrmsi_avail;
int hs_intrmsi_allocd;
int hs_intrmsi_cap;
/* assign EQs to CQs in a round robin fashion */
/* hermon HCA name and HCA part number */
char hs_hca_name[64];
char hs_hca_pn[64];
int hs_hca_pn_len;
/* Hermon device operational mode */
int hs_operational_mode;
/* Attach buffer saved per state to store detailed attach errors */
/* Hermon NodeGUID, SystemImageGUID, and NodeDescription */
char hs_nodedesc[64];
/* Info passed to IBTF during registration */
/*
* Hermon register mapping. Holds the device access attributes,
* kernel mapped addresses, and DDI access handles for both
* Hermon's CMD and UAR BARs.
*/
/*
* Some additional things for UAR Pages
*/
/* Bar to Blueflame */
/*
* Hermon PCI config space registers. This array is used to
* save and restore the PCI config registers before and after a
* software reset.
*/
/* for reset per Linux driver */
/*
* Hermon UAR page resources. Holds the resource pointers for
* UAR page #0 (reserved) and for UAR page #1 (used for kernel
* driver doorbells). In addition, we save a pointer to the
* UAR page #1 doorbells which will be used throughout the driver
* whenever it is necessary to ring one of them. And, in case we
* are unable to do 64-bit writes to the page (because of system
* architecture), we include a lock (to ensure atomic 64-bit access).
*/
/*
* Used during a call to open() if we are in maintenance mode, this
* field serves as a semi-unique rolling count index value, used only
* in the setup of umap_db entries. This is primarily needed to
* firmware device access ioctl operations can still be guaranteed to
* close in the event of an unplanned process exit, even in maintenance
* mode.
*/
/*
* Hermon command registers. This structure contains the addresses
* for each of the most frequently accessed CMD registers. Since
* almost all accesses to the Hermon hardware are through the Hermon
* command interface (i.e. the HCR), we save away the pointer to
* the HCR, as well as pointers to the ECR and INT registers (as
* well as their corresponding "clear" registers) for interrupt
* processing. And we also save away a pointer to the software
* reset register (see above).
*/
/*
* Hermon resource pointers. The following are pointers to the
* kmem cache (from which the Hermon resource handles are allocated),
* and the array of "resource pools" (which store all the pertinent
* information necessary to manage each of the various types of
* resources that are used by the driver. See hermon_rsrc.h for
* more detail.
*/
/*
* Hermon mailbox lists. These hold the information necessary to
* manage the pools of pre-allocated Hermon mailboxes (both "In" and
* "Out" type). See hermon_cmd.h for more detail.
*/
/*
* Hermon interrupt mailbox lists. We allocate both an "In" mailbox
* and an "Out" type mailbox for the interrupt context. This is in
* order to guarantee that a mailbox entry will always be available in
* the interrupt context, and we can NOSLEEP without having to worry
* about possible failure allocating the mbox. We create this as an
* mboxlist so that we have the potential for having multiple mboxes
* available based on the number of interrupts we can receive at once.
*/
/*
* Hermon outstanding command list. Used to hold all the information
* necessary to manage the Hermon "outstanding command list". See
* hermon_cmd.h for more detail.
*/
/*
* This structure contains the Hermon driver's "configuration profile".
* This is the collected set of configuration information, such as
* number of QPs, CQs, mailboxes and other resources, sizes of
* individual resources, other system level configuration information,
* etc. See hermon_cfg.h for more detail.
*/
/*
* This flag contains the profile setting, selecting which profile the
* driver would use. This is needed in the case where we have to
* fallback to a smaller profile based on some DDR conditions. If we
* don't fallback, then it is set to the size of DDR in the system.
*/
/*
* The following are a collection of resource handles used by the
* Hermon driver (internally). First is the protection domain (PD)
* handle that is used when mapping all kernel memory (work queues,
* completion queues, etc). Next is an array of EQ handles. This
* array is indexed by EQ number and allows the Hermon driver to quickly
* convert an EQ number into the software structure associated with the
* given EQ. Likewise, we have three arrays for CQ, QP and SRQ
* handles. These arrays are also indexed by CQ, QP or SRQ number and
* allow the driver to quickly find the corresponding CQ, QP or SRQ
* software structure. Note: while the EQ table is of fixed size
* (because there are a maximum of 64 EQs), each of the CQ, QP and SRQ
* handle lists must be allocated at driver startup.
*/
/* linked list of kernel dbr resources */
/* linked list of non-kernel dbr resources */
/*
* The AVL tree is used to store information regarding QP number
* allocations. The lock protects access to the AVL tree.
*/
/*
* This field is used to indicate whether or not the Hermon driver is
* currently in an IBTF event callback elsewhere in the system. Note:
* It is "volatile" because we intend to poll on this value - in
* hermon_detach() - until we are assured that no further IBTF callbacks
* are currently being processed.
*/
volatile uint32_t hs_in_evcallb;
/*
* The following structures are used to store the results of several
* device query commands passed to the Hermon hardware at startup.
* Specifically, we have hung onto the results of QUERY_DDR (which
* gives information about how much DDR memory is present and where
* it is located), QUERY_FW (which gives information about firmware
* version numbers and the location and extent of firmware's footprint
* in DDR, QUERY_DEVLIM (which gives the device limitations/resource
* maximums) and QUERY_PORT (where some of the specs from DEVLIM moved),
* QUERY_ADAPTER (which gives additional miscellaneous
* recording what configuration information was passed to the firmware
* when the HCA was initialized).
*/
struct hermon_hw_queryfw_s hs_fw;
struct hermon_hw_querydevlim_s hs_devlim;
struct hermon_hw_query_port_s hs_queryport;
struct hermon_hw_set_port_s *hs_initport;
struct hermon_hw_queryadapter_s hs_adapter;
struct hermon_hw_initqueryhca_s hs_hcaparams;
/*
* The following are used for managing special QP resources.
* Specifically, we have a lock, a set of flags (in "hs_spec_qpflags")
* used to track the special QP resources, and two Hermon resource
* handle pointers. Each resource handle actually corresponds to two
* consecutive QP contexts (one per port) for each special QP type.
*/
/*
* For Hermon, you have to alloc 8 qp's total, but the last 4 are
* last 4 qp's
*/
/*
* Related in some ways to the special QP handling above are these
* resources which are used specifically for implementing the Hermon
* agents (SMA, PMA, and BMA). Although, each of these agents does
* little more that intercept the appropriate incoming MAD and forward
* it along to the firmware (see hermon_agents.c for more details), we
* do still use a task queue to queue them up. We can also configure
* the driver to force firmware handling for certain classes of MAD,
* and, therefore, we require the agent list and number of agents
* in order to know what needs to be torn down at detach() time.
*/
/*
* Multicast group lists. These are used to track the "shadow" MCG
* lists that speed up the processing of attach and detach multicast
* group operations. See hermon_misc.h for more details. Note: we
* need the pointer to the "temporary" MCG entry here primarily
* because the size of a given MCG entry is configurable. Therefore,
* it is impossible to put this variable on the stack. And rather
* than allocate and deallocate the entry multiple times, we choose
* instead to preallocate it once and reuse it over and over again.
*/
/*
* Cache of the pkey table, sgid (guid-only) tables, and
* sgid (subnet) prefix. These arrays are set
* during port_query, and mainly used for generating MLX GSI wqes.
*/
/*
* Used for tracking Hermon kstat information
*/
/*
* Used for Hermon info ioctl used by VTS
*/
/*
* Used for Hermon FW flash burning. They are used exclusively
* within the ioctl calls for use when accessing the hermon
* flash device.
*/
int hs_fw_flashstarted;
int hs_fw_cmdset;
/*
* Used for Hermon FM. They are basically used to manage
* Please see the comment in hermon_fm.c.
*/
int hs_fm_capabilities; /* FM capabilities */
int hs_fm_disable; /* Hermon FM disable flag */
int hs_fm_state; /* Hermon FM state */
#ifdef FMA_TEST
#endif
/*
* Hermon fastreboot support. To sw-reset Hermon HCA, the driver
* used for the purpose.
*/
/* Access handle for PCI config space */
/* members to handle MSI-X tables */
char *hs_msix_tbl_addr; /* MSI-X table addr */
char *hs_msix_tbl_entries; /* MSI-X table entry */
/* members to handle MSI-X PBA */
char *hs_msix_pba_addr; /* MSI-X PBA addr */
char *hs_msix_pba_entries; /* MSI-X PBA entry */
};
/*
* HERMON_IN_FASTREBOOT() shows if Hermon driver is at fastreboot.
* This macro should be used to check if the mutex lock can be used
* since the lock cannot be used if the driver is in the quiesce mode.
*/
/*
* Bit positions in the "hs_spec_qpflags" field above. The flags are (from
* least significant to most): (QP0,Port1), (QP0,Port2), (QP1,Port1), and
* (QP1,Port2). The masks are there to help with some specific allocation
* and freeing operations
*/
#define HERMON_SPECIAL_QP0_RSRC 0
#define HERMON_SPECIAL_QP0_RSRC_MASK 0x3
#define HERMON_SPECIAL_QP1_RSRC 2
#define HERMON_SPECIAL_QP1_RSRC_MASK 0xC
/*
* These flags specifies additional behaviors on database access.
* HERMON_UMAP_DB_REMOVE, for example, specifies that (if found) the database
* entry should be removed from the database. HERMON_UMAP_DB_IGNORE_INSTANCE
* specifies that a particular database query should ignore value in the
* "tdb_instance" field as a criterion for the search.
*/
#define HERMON_UMAP_DB_REMOVE (1 << 0)
/*
* The hermon_umap_db_t structure contains what is referred to throughout the
* driver code as the "userland resources database". This structure contains
* all the necessary information to track resources that have been prepared
* for direct-from-userland access. There is an AVL tree ("hdl_umapdb_avl")
* which consists of the "hermon_umap_db_entry_t" (below) and a lock to ensure
* atomic access when adding or removing entries from the database.
*/
typedef struct hermon_umap_db_s {
/*
* The hermon_umap_db_priv_t structure currently contains information necessary
* to provide the "on close" callback to the firmware flash interfaces. It
* is intended that this structure could be extended to enable other "on
* close" callbacks as well.
*/
typedef struct hermon_umap_db_priv_s {
int (*hdp_cb)(void *);
void *hdp_arg;
/*
* The hermon_umap_db_common_t structure contains fields which are common
* between the database entries ("hermon_umap_db_entry_t") and the structure
* used to contain the search criteria ("hermon_umap_db_query_t"). This
* structure contains a key, a resource type (described above), an instance
* (corresponding to the driver instance which inserted the database entry),
* and a "value" field. Typically, "hdb_value" is a pointer to a Hermon
* resource object. Although for memory regions, the value field corresponds
* to the ddi_umem_cookie_t for the pinned userland memory.
* The structure also includes a placeholder for private data ("hdb_priv").
* Currently this data is being used for holding "on close" callback
* information to allow certain kinds of cleanup even if a userland process
* prematurely exits.
*/
typedef struct hermon_umap_db_common_s {
void *hdb_priv;
/*
* The hermon_umap_db_entry_t structure is the entry in "userland resources
* database". As required by the AVL framework, each entry contains an
* "avl_node_t". Then, as required to implement the database, each entry
* contains a "hermon_umap_db_common_t" structure used to contain all of the
* relevant entries.
*/
typedef struct hermon_umap_db_entry_s {
/*
* The hermon_umap_db_query_t structure is used in queries to the "userland
* resources database". In addition to the "hermon_umap_db_common_t" structure
* used to contain the various search criteria, this structure also contains
* a flags field "hqdb_flags" which can be used to specify additional behaviors
* (as described above). Specifically, the flags field can be used to specify
* that an entry should be removed from the database, if found, and to
* specify whether the database lookup should consider "tdb_instance" in the
* search.
*/
typedef struct hermon_umap_db_query_s {
/*
* The hermon_devmap_track_t structure contains all the necessary information
* to track resources that have been mapped through devmap. There is a
* back-pointer to the Hermon softstate, the logical offset corresponding with
* the mapped resource, the size of the mapped resource (zero indicates an
* "invalid mapping"), and a reference count and lock used to determine when
* to free the structure (specifically, this is necessary to handle partial
* unmappings).
*/
typedef struct hermon_devmap_track_s {
int hdt_refcnt;
#define HERMON_ICM_SPLIT 64
#define HERMON_ICM_SPAN 4096
bitmap = \
KM_SLEEP); \
} \
/*
* The hermon_icm_table_t encodes data pertaining to a given ICM table, and
* holds an array of hermon_dma_info_t's related to its backing memory. Each
* ICM table is sized during initialization, but real memory is allocated
* and mapped into and out of ICM in the device throughout the life of the
* instance. We use a bitmap to determine whether or not a given ICM object
* has memory backing it or not, and an array of hermon_dma_info_t's to house
* the actual allocations. Memory is allocated in chunks of span_size, stored
* in the icm_dma array, and can later be looked up by using the bitmap index.
* The total number of ICM spans is equal to table_size / span_size. We also
* keep track of the ICM characteristics, such as ICM object size and the
* number of entries in the ICM area.
*/
struct hermon_icm_table_s {
/* two arrays of pointers, each pointer points to arrays */
};
/*
* Split the rsrc index into three pieces:
*
* index1 - icm_bitmap[HERMON_ICM_SPLIT], icm_dma[HERMON_ICM_SPLIT]
* index2 - bitmap[], dma[]
* offset - rsrc within the icm mapping
*/
/* Defined in hermon.c */
/* Defined in hermon_umap.c */
void hermon_umap_db_init(void);
void hermon_umap_db_fini(void);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_IB_ADAPTERS_HERMON_H */