#ifndef UD_DEF_H_
#define UD_DEF_H_
#include <uct/ib/base/ib_iface.h>
#include <ucs/arch/cpu.h>
#include <ucs/datastruct/queue.h>
#include <ucs/datastruct/frag_list.h>
#include <ucs/sys/math.h>
#define UCT_UD_QP_HASH_SIZE 256
#define UCT_UD_TX_MODERATION 64
#define UCT_UD_RX_BATCH_MIN 8
#define UCT_UD_INITIAL_PSN 1
#define UCT_UD_CA_AI_VALUE 1
#define UCT_UD_CA_MD_FACTOR 2
#define UCT_UD_CA_DUP_ACK_CNT 2
#define UCT_UD_RESENDS_PER_ACK 4
#define UCT_UD_SKB_ALIGN UCS_SYS_CACHE_LINE_SIZE
#define UCT_UD_SKIP_SWEEP 8
#define UCT_UD_CA_MIN_WINDOW 2
#define UCT_UD_CA_MAX_WINDOW 1025
typedef uint16_t uct_ud_psn_t;
#define UCT_UD_PSN_COMPARE UCS_CIRCULAR_COMPARE16
typedef struct uct_ud_iface uct_ud_iface_t;
typedef struct uct_ud_ep uct_ud_ep_t;
typedef struct uct_ud_ctl_hdr uct_ud_ctl_hdr_t;
typedef struct uct_ud_iface_addr uct_ud_iface_addr_t;
typedef struct uct_ud_ep_addr uct_ud_ep_addr_t;
typedef struct uct_ud_iface_peer uct_ud_iface_peer_t;
enum {
UCT_UD_PACKET_ACK_REQ_SHIFT = 25,
UCT_UD_PACKET_AM_ID_SHIFT = 27,
UCT_UD_PACKET_DEST_ID_SHIFT = 24,
UCT_UD_PACKET_PUT_SHIFT = 28,
};
enum {
UCT_UD_PACKET_FLAG_AM = UCS_BIT(24),
UCT_UD_PACKET_FLAG_ACK_REQ = UCS_BIT(25),
UCT_UD_PACKET_FLAG_ECN = UCS_BIT(26),
UCT_UD_PACKET_FLAG_NACK = UCS_BIT(27),
UCT_UD_PACKET_FLAG_PUT = UCS_BIT(28),
UCT_UD_PACKET_FLAG_CTL = UCS_BIT(29),
UCT_UD_PACKET_AM_ID_MASK = UCS_MASK(UCT_UD_PACKET_AM_ID_SHIFT),
UCT_UD_PACKET_DEST_ID_MASK = UCS_MASK(UCT_UD_PACKET_DEST_ID_SHIFT),
};
enum {
UCT_UD_PACKET_CREQ = 1,
UCT_UD_PACKET_CREP = 2,
};
typedef struct uct_ud_neth {
uint32_t packet_type;
uct_ud_psn_t psn;
uct_ud_psn_t ack_psn;
} UCS_S_PACKED uct_ud_neth_t;
enum {
UCT_UD_SEND_SKB_FLAG_ACK_REQ = UCS_BIT(0),
UCT_UD_SEND_SKB_FLAG_COMP = UCS_BIT(1),
UCT_UD_SEND_SKB_FLAG_ZCOPY = UCS_BIT(2),
UCT_UD_SEND_SKB_FLAG_RESENDING = UCS_BIT(3),
#if UCS_ENABLE_ASSERT
UCT_UD_SEND_SKB_FLAG_CTL_ACK = UCS_BIT(5),
UCT_UD_SEND_SKB_FLAG_CTL_RESEND = UCS_BIT(6),
UCT_UD_SEND_SKB_FLAG_INVALID = UCS_BIT(7)
#else
UCT_UD_SEND_SKB_FLAG_CTL_ACK = 0,
UCT_UD_SEND_SKB_FLAG_CTL_RESEND = 0,
UCT_UD_SEND_SKB_FLAG_INVALID = 0
#endif
};
typedef struct uct_ud_send_skb {
ucs_queue_elem_t queue;
uint32_t lkey;
uint16_t len;
uint16_t flags;
uct_ud_neth_t neth[0];
} UCS_S_PACKED UCS_V_ALIGNED(UCT_UD_SKB_ALIGN) uct_ud_send_skb_t;
typedef struct uct_ud_comp_desc {
uct_completion_t *comp;
uct_ud_ep_t *ep;
} uct_ud_comp_desc_t;
typedef struct uct_ud_iov {
void *buffer;
uint32_t lkey;
uint16_t length;
} UCS_S_PACKED uct_ud_iov_t;
typedef struct uct_ud_ctl_desc {
ucs_queue_elem_t queue;
uint16_t sn;
uct_ud_send_skb_t *self_skb;
uct_ud_send_skb_t *resent_skb;
uct_ud_ep_t *ep;
} uct_ud_ctl_desc_t;
typedef struct uct_ud_zcopy_desc {
uct_ud_comp_desc_t super;
uct_ud_iov_t iov[UCT_IB_MAX_IOV];
uint16_t iovcnt;
} uct_ud_zcopy_desc_t;
typedef struct uct_ud_recv_skb {
uct_ib_iface_recv_desc_t super;
union {
struct {
ucs_frag_list_elem_t elem;
} ooo;
struct {
ucs_queue_elem_t queue;
uint32_t len;
} am;
} u;
} uct_ud_recv_skb_t;
typedef struct uct_ud_am_short_hdr {
uint64_t hdr;
} UCS_S_PACKED uct_ud_am_short_hdr_t;
typedef struct uct_ud_put_hdr {
uint64_t rva;
} UCS_S_PACKED uct_ud_put_hdr_t;
struct uct_ud_iface_addr {
uct_ib_uint24_t qp_num;
};
struct uct_ud_ep_addr {
uct_ud_iface_addr_t iface_addr;
uct_ib_uint24_t ep_id;
};
static inline uint32_t uct_ud_neth_get_dest_id(uct_ud_neth_t *neth)
{
return neth->packet_type & UCT_UD_PACKET_DEST_ID_MASK;
}
static inline void uct_ud_neth_set_dest_id(uct_ud_neth_t *neth, uint32_t id)
{
neth->packet_type |= id;
}
static inline uint8_t uct_ud_neth_get_am_id(uct_ud_neth_t *neth)
{
return neth->packet_type >> UCT_UD_PACKET_AM_ID_SHIFT;
}
static inline void uct_ud_neth_set_am_id(uct_ud_neth_t *neth, uint8_t id)
{
neth->packet_type |= (id << UCT_UD_PACKET_AM_ID_SHIFT);
}
static inline uct_ud_ctl_desc_t *uct_ud_ctl_desc(uct_ud_send_skb_t *skb)
{
ucs_assert(skb->flags & (UCT_UD_SEND_SKB_FLAG_CTL_ACK |
UCT_UD_SEND_SKB_FLAG_CTL_RESEND));
ucs_assert(!(skb->flags & UCT_UD_SEND_SKB_FLAG_INVALID));
return (uct_ud_ctl_desc_t*)((char*)skb->neth + skb->len);
}
static inline uct_ud_comp_desc_t *uct_ud_comp_desc(uct_ud_send_skb_t *skb)
{
ucs_assert(skb->flags & UCT_UD_SEND_SKB_FLAG_COMP);
ucs_assert(!(skb->flags & UCT_UD_SEND_SKB_FLAG_INVALID));
return (uct_ud_comp_desc_t*)((char*)skb->neth + skb->len);
}
static inline uct_ud_zcopy_desc_t *uct_ud_zcopy_desc(uct_ud_send_skb_t *skb)
{
ucs_assert(skb->flags & UCT_UD_SEND_SKB_FLAG_ZCOPY);
ucs_assert(!(skb->flags & UCT_UD_SEND_SKB_FLAG_INVALID));
return (uct_ud_zcopy_desc_t*)((char*)skb->neth + skb->len);
}
#endif