dapl_tavor_hw.h revision 9e39c5ba00a55fa05777cc94b148296af305e135
/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DAPL_TAVOR_HW_H
#define _DAPL_TAVOR_HW_H
/*
* Contains all the structure definitions and #defines for all Tavor
* hardware resources and registers.
* Most of these definitions have been replicated from the tavor_hw.h
* header file used by the tavor device driver.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "dapl.h"
#include "dapl_tavor_ibtf.h"
/*
* Ownership flags used to define hardware or software ownership for
* various Tavor resources
*/
#define TAVOR_HW_OWNER 0x1U
#define TAVOR_SW_OWNER 0x0
/*
* Tavor Completion Queue Entries (CQE)
* Each CQE contains enough information for the software to associate the
* completion with the Work Queue Element (WQE) to which it corresponds.
*
* Note: The following structure is not #define'd with both little-endian
* and big-endian definitions. This is because each CQE's individual
* fields are not directly accessed except through the macros defined below.
*/
/*
* The following defines are used for Tavor CQ error handling. Note: For
* CQEs which correspond to error events, the Tavor device requires some
* special handling by software. These defines are used to identify and
* extract the necessary information from each error CQE, including status
* code (above), doorbell count, and whether a error completion is for a
* send or receive work request.
*/
#define TAVOR_CQE_ERR_STATUS_SHIFT 24
#define TAVOR_CQE_ERR_STATUS_MASK 0xFF
#define TAVOR_CQE_ERR_DBDCNT_MASK 0xFFFF
#define TAVOR_CQE_SEND_ERR_OPCODE 0xFF
#define TAVOR_CQE_RECV_ERR_OPCODE 0xFE
#define TAVOR_CQ_SYNC_AND_DB 0
#define TAVOR_CQ_RECYCLE_ENTRY 1
/*
* These are the defines for the Tavor CQ entry types. They are also
* specified by the Tavor register specification. They indicate what type
* of work request is completing (for successful completions). Note: The
* "SND" or "RCV" in each define is used to indicate whether the completion
* work request was from the Send work queue or the Receive work queue on
* the associated QP.
*/
#define TAVOR_CQE_SND_RDMAWR 0x8
#define TAVOR_CQE_SND_RDMAWR_IMM 0x9
#define TAVOR_CQE_SND_SEND 0xA
#define TAVOR_CQE_SND_SEND_IMM 0xB
#define TAVOR_CQE_SND_RDMARD 0x10
#define TAVOR_CQE_SND_ATOMIC_CS 0x11
#define TAVOR_CQE_SND_ATOMIC_FA 0x12
#define TAVOR_CQE_SND_BIND_MW 0x18
#define TAVOR_CQE_RCV_RECV_IMM 0x3
#define TAVOR_CQE_RCV_RECV_IMM2 0x5
#define TAVOR_CQE_RCV_RECV 0x2
#define TAVOR_CQE_RCV_RECV2 0x4
#define TAVOR_CQE_RCV_RDMAWR_IMM 0x9
#define TAVOR_CQE_RCV_RDMAWR_IMM2 0xB
/*
* These are the defines for the Tavor CQ completion statuses. They are
* specified by the Tavor register specification.
*/
#define TAVOR_CQE_SUCCESS 0x0
#define TAVOR_CQE_LOC_LEN_ERR 0x1
#define TAVOR_CQE_LOC_OP_ERR 0x2
#define TAVOR_CQE_LOC_PROT_ERR 0x4
#define TAVOR_CQE_WR_FLUSHED_ERR 0x5
#define TAVOR_CQE_MW_BIND_ERR 0x6
#define TAVOR_CQE_BAD_RESPONSE_ERR 0x10
#define TAVOR_CQE_LOCAL_ACCESS_ERR 0x11
#define TAVOR_CQE_REM_INV_REQ_ERR 0x12
#define TAVOR_CQE_REM_ACC_ERR 0x13
#define TAVOR_CQE_REM_OP_ERR 0x14
#define TAVOR_CQE_TRANS_TO_ERR 0x15
#define TAVOR_CQE_RNRNAK_TO_ERR 0x16
typedef struct tavor_hw_cqe_s {
uint32_t :4;
uint32_t :8;
uint32_t :8;
uint32_t :4;
uint32_t :15;
#define TAVOR_COMPLETION_RECV 0x0
#define TAVOR_COMPLETION_SEND 0x1
#define TAVOR_CQE_DEFAULT_VERSION 0x0
/*
* The following macros are used for extracting (and in some cases filling in)
* information from CQEs
*/
#define TAVOR_CQE_QPNUM_MASK 0x00FFFFFF
#define TAVOR_CQE_QPNUM_SHIFT 0
#define TAVOR_CQE_DQPN_MASK 0x00FFFFFF
#define TAVOR_CQE_DQPN_SHIFT 0
#define TAVOR_CQE_SL_MASK 0xF0000000
#define TAVOR_CQE_SL_SHIFT 28
#define TAVOR_CQE_GRH_MASK 0x00800000
#define TAVOR_CQE_GRH_SHIFT 23
#define TAVOR_CQE_PATHBITS_MASK 0x007F0000
#define TAVOR_CQE_PATHBITS_SHIFT 16
#define TAVOR_CQE_DLID_MASK 0x0000FFFF
#define TAVOR_CQE_DLID_SHIFT 0
#define TAVOR_CQE_OPCODE_MASK 0xFF000000
#define TAVOR_CQE_OPCODE_SHIFT 24
#define TAVOR_CQE_SENDRECV_MASK 0x00800000
#define TAVOR_CQE_SENDRECV_SHIFT 23
#define TAVOR_CQE_OWNER_MASK 0x00000080
#define TAVOR_CQE_OWNER_SHIFT 7
#define TAVOR_CQE_QPNUM_GET(cqe) \
#define TAVOR_CQE_DQPN_GET(cqe) \
#define TAVOR_CQE_SL_GET(cqe) \
#define TAVOR_CQE_GRH_GET(cqe) \
#define TAVOR_CQE_PATHBITS_GET(cqe) \
#define TAVOR_CQE_DLID_GET(cqe) \
#define TAVOR_CQE_IMM_ETH_PKEY_CRED_GET(cqe) \
#define TAVOR_CQE_BYTECNT_GET(cqe) \
#define TAVOR_CQE_WQEADDRSZ_GET(cqe) \
#define TAVOR_CQE_OPCODE_GET(cqe) \
#define TAVOR_CQE_SENDRECV_GET(cqe) \
#define TAVOR_CQE_OWNER_IS_SW(cqe) \
#define TAVOR_CQE_OWNER_SET_HW(cqe) \
/*
* Tavor User Access Region (UAR)
* Tavor doorbells are each rung by writing to the doorbell registers that
* form a User Access Region (UAR). A doorbell is a write-only hardware
* register which enables passing information from software to hardware
* with minimum software latency. A write operation from the host software
* to these doorbell registers passes information about the HCA resources
* and initiates processing of the doorbell data. There are 6 types of
* doorbells in Tavor.
*
* "Send Doorbell" for synchronizing the attachment of a WQE (or a chain
* of WQEs) to the send queue.
* "RD Send Doorbell" (Same as above, except for RD QPs) is not supported.
* "Receive Doorbell" for synchronizing the attachment of a WQE (or a chain
* of WQEs) to the receive queue.
* "CQ Doorbell" for updating the CQ consumer index and requesting
* completion notifications.
* "EQ Doorbell" for updating the EQ consumer index, arming interrupt
* triggering, and disarming CQ notification requests.
* "InfiniBlast" (which would have enabled access to the "InfiniBlast
* buffer") is not supported.
*
* Note: The tavor_hw_uar_t below is the container for all of the various
* doorbell types. Below we first define several structures which make up
* the contents of those doorbell types.
*
* Note also: The following structures are not #define'd with both little-
* endian and big-endian definitions. This is because each doorbell type
* is not directly accessed except through a single ddi_put64() operation
* (see tavor_qp_send_doorbell, tavor_qp_recv_doorbell, tavor_cq_doorbell,
* or tavor_eq_doorbell)
*/
typedef struct tavor_hw_uar_send_s {
uint32_t :2;
#define TAVOR_QPSNDDB_NDA_MASK 0xFFFFFFC0
#define TAVOR_QPSNDDB_NDA_SHIFT 0x20
#define TAVOR_QPSNDDB_F_SHIFT 0x25
#define TAVOR_QPSNDDB_NOPCODE_SHIFT 0x20
#define TAVOR_QPSNDDB_QPN_SHIFT 0x8
typedef struct tavor_hw_uar_recv_s {
#define TAVOR_QPRCVDB_NDA_MASK 0xFFFFFFC0
#define TAVOR_QPRCVDB_NDA_SHIFT 0x20
#define TAVOR_QPRCVDB_NDS_SHIFT 0x20
#define TAVOR_QPRCVDB_QPN_SHIFT 0x8
/* Max descriptors per Tavor doorbell */
#define TAVOR_QP_MAXDESC_PER_DB 256
typedef struct tavor_hw_uar_cq_s {
#define TAVOR_CQDB_CMD_SHIFT 0x38
#define TAVOR_CQDB_CQN_SHIFT 0x20
#define TAVOR_CQDB_INCR_CONSINDX 0x01
#define TAVOR_CQDB_NOTIFY_CQ 0x02
#define TAVOR_CQDB_NOTIFY_CQ_SOLICIT 0x03
#define TAVOR_CQDB_SET_CONSINDX 0x04
#define TAVOR_CQDB_NOTIFY_NCQ 0x05
/* Default value for use in NOTIFY_CQ doorbell */
#define TAVOR_CQDB_DEFAULT_PARAM 0xFFFFFFFF
typedef struct tavor_hw_uar_eq_s {
uint32_t :18;
typedef struct tavor_hw_uar_s {
typedef struct tavor_hw_uar32_s {
/*
* Tavor Send Work Queue Element (WQE)
* A Tavor Send WQE is built of the following segments, each of which is a
* multiple of 16 bytes. Note: Each individual WQE may contain only a
* subset of these segments described below (according to the operation type
* and transport type of the QP).
*
* This segment contains the address of the next WQE to be executed and the
* information required in order to allocate the resources to execute the
* next WQE. The "Ctrl" part of this segment contains the control
* information required to execute the WQE, including the opcode and other
* control information.
* The "Datagram" segment contains address information required in order to
* form a UD message.
* The "Bind" segment contains the parameters required for a Bind Memory
* Window operation.
* The "Remote Address" segment is present only in RDMA or Atomic WQEs and
* specifies remote virtual addresses and RKey, respectively. Length of
* RDMA-write/RDMA-read) or set to eight (for Atomic).
* The "Atomic" segment is present only in Atomic WQEs and specifies
*
* Note: The following structures are not #define'd with both little-endian
* and big-endian definitions. This is because their individual fields are
* not directly accessed except through macros defined below.
*/
typedef struct tavor_hw_snd_wqe_nextctrl_s {
uint32_t :1;
uint32_t :28;
uint32_t c :1;
uint32_t e :1;
uint32_t s :1;
uint32_t i :1;
#define TAVOR_WQE_NDA_MASK 0x00000000FFFFFFC0
#define TAVOR_WQE_NDS_MASK 0x3F
#define TAVOR_WQE_DBD_MASK 0x80
#define TAVOR_WQE_SEND_FENCE_MASK 0x40
#define TAVOR_WQE_SEND_NOPCODE_RDMAW 0x8
#define TAVOR_WQE_SEND_NOPCODE_RDMAWI 0x9
#define TAVOR_WQE_SEND_NOPCODE_SEND 0xA
#define TAVOR_WQE_SEND_NOPCODE_SENDI 0xB
#define TAVOR_WQE_SEND_NOPCODE_RDMAR 0x10
#define TAVOR_WQE_SEND_NOPCODE_ATMCS 0x11
#define TAVOR_WQE_SEND_NOPCODE_ATMFA 0x12
#define TAVOR_WQE_SEND_NOPCODE_BIND 0x18
#define TAVOR_WQE_SEND_SIGNALED_MASK 0x800000000ULL
#define TAVOR_WQE_SEND_EVENT_MASK 0x400000000ULL
#define TAVOR_WQE_SEND_SOLICIT_MASK 0x200000000ULL
#define TAVOR_WQE_SEND_IMMEDIATE_MASK 0x100000000ULL
#define TAVOR_WQE_SENDHDR_UD_AV_MASK 0xFFFFFFFFFFFFFFE0
#define TAVOR_WQE_SENDHDR_UD_DQPN_MASK 0xFFFFFF
typedef struct tavor_hw_snd_wqe_bind_s {
uint32_t :29;
uint32_t :32;
#define TAVOR_WQE_SENDHDR_BIND_ATOM 0x8000000000000000ULL
#define TAVOR_WQE_SENDHDR_BIND_WR 0x4000000000000000ULL
#define TAVOR_WQE_SENDHDR_BIND_RD 0x2000000000000000ULL
typedef struct tavor_hw_snd_wqe_remaddr_s {
uint32_t :32;
/*
* Tavor Receive Work Queue Element (WQE)
* Like the Send WQE, the Receive WQE is built of 16-byte segments. The
* some number of scatter list entries for the incoming message.
*
* The format of the scatter-gather list entries is also shown below. For
* Receive WQEs the "inline_data" field must be cleared (i.e. data segments
* cannot contain inline data).
*/
typedef struct tavor_hw_rcv_wqe_nextctrl_s {
uint32_t :5;
uint32_t :24;
uint32_t :1;
uint32_t :28;
uint32_t c :1;
uint32_t e :1;
uint32_t :2;
uint32_t :32;
/*
* as a workaround to a Tavor hardware erratum related to having
* the first 32-bits in the WQE set to zero.
*/
#define TAVOR_RCV_WQE_NDA0_WA_MASK 0x0000000100000000ULL
#define TAVOR_WQE_RCV_SIGNALED_MASK 0x800000000ULL
#define TAVOR_WQE_RCV_EVENT_MASK 0x400000000ULL
typedef struct tavor_hw_wqe_sgl_s {
#define TAVOR_WQE_SGL_BYTE_CNT_MASK 0x7FFFFFFF
#define TAVOR_WQE_SGL_INLINE_MASK 0x80000000
/*
* The tavor_sw_wqe_dbinfo_t structure is used internally by the Tavor
* driver to return information (from the tavor_wqe_mlx_build_nextctl() and
* tavor_wqe_send_build_nextctl() routines) regarding the type of Tavor
* doorbell necessary.
*/
typedef struct tavor_sw_wqe_dbinfo_s {
/*
* The following macros are used for building each of the individual
* segments that can make up a Tavor WQE. Note: We try not to use the
* structures (with their associated bitfields) here, instead opting to
* build and put 64-bit or 32-bit chunks to the WQEs as appropriate,
* primarily because using the bitfields appears to force more read-modify-
* write operations.
*
* TAVOR_WQE_BUILD_REMADDR - Builds Remote Address Segment using
* RDMA info from the work request
* TAVOR_WQE_BUILD_BIND - Builds the Bind Memory Window
* Segment using bind info from the
* work request
* TAVOR_WQE_LINKNEXT - Links the current WQE to the
* previous one
* TAVOR_WQE_LINKFIRST - Links the first WQE on the current
* chain to the previous WQE
*/
{ \
\
}
{ \
\
TAVOR_WQE_SENDHDR_BIND_ATOM : 0; \
TAVOR_WQE_SENDHDR_BIND_WR : 0; \
TAVOR_WQE_SENDHDR_BIND_RD : 0; \
}
{ \
\
}
{ \
}
{ \
}
/*
* The following macro is used to convert WQE address and size into the
* "wqeaddrsz" value needed in the tavor_wrid_entry_t (see below).
*/
((size) & TAVOR_WQE_NDS_MASK))
/*
* The following macros are used to calculate pointers to the Send or Receive
* WQEs on a given QP, respectively
*/
/*
* Maximum header before the data bytes when inlining data.
* "Header" includes the link (nextctrl) struct, a remote address struct
* (only for RDMA Write, not for Send) and the 32-bit byte count field.
*/
#define TAVOR_INLINE_HEADER_SIZE_RDMAW \
(sizeof (tavor_hw_snd_wqe_nextctrl_t) + \
sizeof (tavor_hw_snd_wqe_remaddr_t) + \
sizeof (uint32_t))
#define TAVOR_INLINE_HEADER_SIZE_SEND \
(sizeof (tavor_hw_snd_wqe_nextctrl_t) + \
sizeof (uint32_t))
/*
* Function signatures
*/
extern int dapls_tavor_max_inline(void);
#ifdef __cplusplus
}
#endif
#endif /* _DAPL_TAVOR_HW_H */