162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2016 - 2020 Intel Corporation. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef DEF_RDMAVT_INCQP_H 762306a36Sopenharmony_ci#define DEF_RDMAVT_INCQP_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <rdma/rdma_vt.h> 1062306a36Sopenharmony_ci#include <rdma/ib_pack.h> 1162306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 1262306a36Sopenharmony_ci#include <rdma/rdmavt_cq.h> 1362306a36Sopenharmony_ci#include <rdma/rvt-abi.h> 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * Atomic bit definitions for r_aflags. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci#define RVT_R_WRID_VALID 0 1862306a36Sopenharmony_ci#define RVT_R_REWIND_SGE 1 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * Bit definitions for r_flags. 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define RVT_R_REUSE_SGE 0x01 2462306a36Sopenharmony_ci#define RVT_R_RDMAR_SEQ 0x02 2562306a36Sopenharmony_ci#define RVT_R_RSP_NAK 0x04 2662306a36Sopenharmony_ci#define RVT_R_RSP_SEND 0x08 2762306a36Sopenharmony_ci#define RVT_R_COMM_EST 0x10 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * If a packet's QP[23:16] bits match this value, then it is 3162306a36Sopenharmony_ci * a PSM packet and the hardware will expect a KDETH header 3262306a36Sopenharmony_ci * following the BTH. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci#define RVT_KDETH_QP_PREFIX 0x80 3562306a36Sopenharmony_ci#define RVT_KDETH_QP_SUFFIX 0xffff 3662306a36Sopenharmony_ci#define RVT_KDETH_QP_PREFIX_MASK 0x00ff0000 3762306a36Sopenharmony_ci#define RVT_KDETH_QP_PREFIX_SHIFT 16 3862306a36Sopenharmony_ci#define RVT_KDETH_QP_BASE (u32)(RVT_KDETH_QP_PREFIX << \ 3962306a36Sopenharmony_ci RVT_KDETH_QP_PREFIX_SHIFT) 4062306a36Sopenharmony_ci#define RVT_KDETH_QP_MAX (u32)(RVT_KDETH_QP_BASE + RVT_KDETH_QP_SUFFIX) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* 4362306a36Sopenharmony_ci * If a packet's LNH == BTH and DEST QPN[23:16] in the BTH match this 4462306a36Sopenharmony_ci * prefix value, then it is an AIP packet with a DETH containing the entropy 4562306a36Sopenharmony_ci * value in byte 4 following the BTH. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci#define RVT_AIP_QP_PREFIX 0x81 4862306a36Sopenharmony_ci#define RVT_AIP_QP_SUFFIX 0xffff 4962306a36Sopenharmony_ci#define RVT_AIP_QP_PREFIX_MASK 0x00ff0000 5062306a36Sopenharmony_ci#define RVT_AIP_QP_PREFIX_SHIFT 16 5162306a36Sopenharmony_ci#define RVT_AIP_QP_BASE (u32)(RVT_AIP_QP_PREFIX << \ 5262306a36Sopenharmony_ci RVT_AIP_QP_PREFIX_SHIFT) 5362306a36Sopenharmony_ci#define RVT_AIP_QPN_MAX BIT(RVT_AIP_QP_PREFIX_SHIFT) 5462306a36Sopenharmony_ci#define RVT_AIP_QP_MAX (u32)(RVT_AIP_QP_BASE + RVT_AIP_QPN_MAX - 1) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* 5762306a36Sopenharmony_ci * Bit definitions for s_flags. 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * RVT_S_SIGNAL_REQ_WR - set if QP send WRs contain completion signaled 6062306a36Sopenharmony_ci * RVT_S_BUSY - send tasklet is processing the QP 6162306a36Sopenharmony_ci * RVT_S_TIMER - the RC retry timer is active 6262306a36Sopenharmony_ci * RVT_S_ACK_PENDING - an ACK is waiting to be sent after RDMA read/atomics 6362306a36Sopenharmony_ci * RVT_S_WAIT_FENCE - waiting for all prior RDMA read or atomic SWQEs 6462306a36Sopenharmony_ci * before processing the next SWQE 6562306a36Sopenharmony_ci * RVT_S_WAIT_RDMAR - waiting for a RDMA read or atomic SWQE to complete 6662306a36Sopenharmony_ci * before processing the next SWQE 6762306a36Sopenharmony_ci * RVT_S_WAIT_RNR - waiting for RNR timeout 6862306a36Sopenharmony_ci * RVT_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE 6962306a36Sopenharmony_ci * RVT_S_WAIT_DMA - waiting for send DMA queue to drain before generating 7062306a36Sopenharmony_ci * next send completion entry not via send DMA 7162306a36Sopenharmony_ci * RVT_S_WAIT_PIO - waiting for a send buffer to be available 7262306a36Sopenharmony_ci * RVT_S_WAIT_TX - waiting for a struct verbs_txreq to be available 7362306a36Sopenharmony_ci * RVT_S_WAIT_DMA_DESC - waiting for DMA descriptors to be available 7462306a36Sopenharmony_ci * RVT_S_WAIT_KMEM - waiting for kernel memory to be available 7562306a36Sopenharmony_ci * RVT_S_WAIT_PSN - waiting for a packet to exit the send DMA queue 7662306a36Sopenharmony_ci * RVT_S_WAIT_ACK - waiting for an ACK packet before sending more requests 7762306a36Sopenharmony_ci * RVT_S_SEND_ONE - send one packet, request ACK, then wait for ACK 7862306a36Sopenharmony_ci * RVT_S_ECN - a BECN was queued to the send engine 7962306a36Sopenharmony_ci * RVT_S_MAX_BIT_MASK - The max bit that can be used by rdmavt 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci#define RVT_S_SIGNAL_REQ_WR 0x0001 8262306a36Sopenharmony_ci#define RVT_S_BUSY 0x0002 8362306a36Sopenharmony_ci#define RVT_S_TIMER 0x0004 8462306a36Sopenharmony_ci#define RVT_S_RESP_PENDING 0x0008 8562306a36Sopenharmony_ci#define RVT_S_ACK_PENDING 0x0010 8662306a36Sopenharmony_ci#define RVT_S_WAIT_FENCE 0x0020 8762306a36Sopenharmony_ci#define RVT_S_WAIT_RDMAR 0x0040 8862306a36Sopenharmony_ci#define RVT_S_WAIT_RNR 0x0080 8962306a36Sopenharmony_ci#define RVT_S_WAIT_SSN_CREDIT 0x0100 9062306a36Sopenharmony_ci#define RVT_S_WAIT_DMA 0x0200 9162306a36Sopenharmony_ci#define RVT_S_WAIT_PIO 0x0400 9262306a36Sopenharmony_ci#define RVT_S_WAIT_TX 0x0800 9362306a36Sopenharmony_ci#define RVT_S_WAIT_DMA_DESC 0x1000 9462306a36Sopenharmony_ci#define RVT_S_WAIT_KMEM 0x2000 9562306a36Sopenharmony_ci#define RVT_S_WAIT_PSN 0x4000 9662306a36Sopenharmony_ci#define RVT_S_WAIT_ACK 0x8000 9762306a36Sopenharmony_ci#define RVT_S_SEND_ONE 0x10000 9862306a36Sopenharmony_ci#define RVT_S_UNLIMITED_CREDIT 0x20000 9962306a36Sopenharmony_ci#define RVT_S_ECN 0x40000 10062306a36Sopenharmony_ci#define RVT_S_MAX_BIT_MASK 0x800000 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* 10362306a36Sopenharmony_ci * Drivers should use s_flags starting with bit 31 down to the bit next to 10462306a36Sopenharmony_ci * RVT_S_MAX_BIT_MASK 10562306a36Sopenharmony_ci */ 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* 10862306a36Sopenharmony_ci * Wait flags that would prevent any packet type from being sent. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci#define RVT_S_ANY_WAIT_IO \ 11162306a36Sopenharmony_ci (RVT_S_WAIT_PIO | RVT_S_WAIT_TX | \ 11262306a36Sopenharmony_ci RVT_S_WAIT_DMA_DESC | RVT_S_WAIT_KMEM) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/* 11562306a36Sopenharmony_ci * Wait flags that would prevent send work requests from making progress. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci#define RVT_S_ANY_WAIT_SEND (RVT_S_WAIT_FENCE | RVT_S_WAIT_RDMAR | \ 11862306a36Sopenharmony_ci RVT_S_WAIT_RNR | RVT_S_WAIT_SSN_CREDIT | RVT_S_WAIT_DMA | \ 11962306a36Sopenharmony_ci RVT_S_WAIT_PSN | RVT_S_WAIT_ACK) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define RVT_S_ANY_WAIT (RVT_S_ANY_WAIT_IO | RVT_S_ANY_WAIT_SEND) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* Number of bits to pay attention to in the opcode for checking qp type */ 12462306a36Sopenharmony_ci#define RVT_OPCODE_QP_MASK 0xE0 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* Flags for checking QP state (see ib_rvt_state_ops[]) */ 12762306a36Sopenharmony_ci#define RVT_POST_SEND_OK 0x01 12862306a36Sopenharmony_ci#define RVT_POST_RECV_OK 0x02 12962306a36Sopenharmony_ci#define RVT_PROCESS_RECV_OK 0x04 13062306a36Sopenharmony_ci#define RVT_PROCESS_SEND_OK 0x08 13162306a36Sopenharmony_ci#define RVT_PROCESS_NEXT_SEND_OK 0x10 13262306a36Sopenharmony_ci#define RVT_FLUSH_SEND 0x20 13362306a36Sopenharmony_ci#define RVT_FLUSH_RECV 0x40 13462306a36Sopenharmony_ci#define RVT_PROCESS_OR_FLUSH_SEND \ 13562306a36Sopenharmony_ci (RVT_PROCESS_SEND_OK | RVT_FLUSH_SEND) 13662306a36Sopenharmony_ci#define RVT_SEND_OR_FLUSH_OR_RECV_OK \ 13762306a36Sopenharmony_ci (RVT_PROCESS_SEND_OK | RVT_FLUSH_SEND | RVT_PROCESS_RECV_OK) 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/* 14062306a36Sopenharmony_ci * Internal send flags 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ci#define RVT_SEND_RESERVE_USED IB_SEND_RESERVED_START 14362306a36Sopenharmony_ci#define RVT_SEND_COMPLETION_ONLY (IB_SEND_RESERVED_START << 1) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/** 14662306a36Sopenharmony_ci * rvt_ud_wr - IB UD work plus AH cache 14762306a36Sopenharmony_ci * @wr: valid IB work request 14862306a36Sopenharmony_ci * @attr: pointer to an allocated AH attribute 14962306a36Sopenharmony_ci * 15062306a36Sopenharmony_ci * Special case the UD WR so we can keep track of the AH attributes. 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci * NOTE: This data structure is stricly ordered wr then attr. I.e the attr 15362306a36Sopenharmony_ci * MUST come after wr. The ib_ud_wr is sized and copied in rvt_post_one_wr. 15462306a36Sopenharmony_ci * The copy assumes that wr is first. 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_cistruct rvt_ud_wr { 15762306a36Sopenharmony_ci struct ib_ud_wr wr; 15862306a36Sopenharmony_ci struct rdma_ah_attr *attr; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* 16262306a36Sopenharmony_ci * Send work request queue entry. 16362306a36Sopenharmony_ci * The size of the sg_list is determined when the QP is created and stored 16462306a36Sopenharmony_ci * in qp->s_max_sge. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_cistruct rvt_swqe { 16762306a36Sopenharmony_ci union { 16862306a36Sopenharmony_ci struct ib_send_wr wr; /* don't use wr.sg_list */ 16962306a36Sopenharmony_ci struct rvt_ud_wr ud_wr; 17062306a36Sopenharmony_ci struct ib_reg_wr reg_wr; 17162306a36Sopenharmony_ci struct ib_rdma_wr rdma_wr; 17262306a36Sopenharmony_ci struct ib_atomic_wr atomic_wr; 17362306a36Sopenharmony_ci }; 17462306a36Sopenharmony_ci u32 psn; /* first packet sequence number */ 17562306a36Sopenharmony_ci u32 lpsn; /* last packet sequence number */ 17662306a36Sopenharmony_ci u32 ssn; /* send sequence number */ 17762306a36Sopenharmony_ci u32 length; /* total length of data in sg_list */ 17862306a36Sopenharmony_ci void *priv; /* driver dependent field */ 17962306a36Sopenharmony_ci struct rvt_sge sg_list[]; 18062306a36Sopenharmony_ci}; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/** 18362306a36Sopenharmony_ci * struct rvt_krwq - kernel struct receive work request 18462306a36Sopenharmony_ci * @p_lock: lock to protect producer of the kernel buffer 18562306a36Sopenharmony_ci * @head: index of next entry to fill 18662306a36Sopenharmony_ci * @c_lock:lock to protect consumer of the kernel buffer 18762306a36Sopenharmony_ci * @tail: index of next entry to pull 18862306a36Sopenharmony_ci * @count: count is aproximate of total receive enteries posted 18962306a36Sopenharmony_ci * @rvt_rwqe: struct of receive work request queue entry 19062306a36Sopenharmony_ci * 19162306a36Sopenharmony_ci * This structure is used to contain the head pointer, 19262306a36Sopenharmony_ci * tail pointer and receive work queue entries for kernel 19362306a36Sopenharmony_ci * mode user. 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_cistruct rvt_krwq { 19662306a36Sopenharmony_ci spinlock_t p_lock; /* protect producer */ 19762306a36Sopenharmony_ci u32 head; /* new work requests posted to the head */ 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci /* protect consumer */ 20062306a36Sopenharmony_ci spinlock_t c_lock ____cacheline_aligned_in_smp; 20162306a36Sopenharmony_ci u32 tail; /* receives pull requests from here. */ 20262306a36Sopenharmony_ci u32 count; /* approx count of receive entries posted */ 20362306a36Sopenharmony_ci struct rvt_rwqe *curr_wq; 20462306a36Sopenharmony_ci struct rvt_rwqe wq[]; 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci/* 20862306a36Sopenharmony_ci * rvt_get_swqe_ah - Return the pointer to the struct rvt_ah 20962306a36Sopenharmony_ci * @swqe: valid Send WQE 21062306a36Sopenharmony_ci * 21162306a36Sopenharmony_ci */ 21262306a36Sopenharmony_cistatic inline struct rvt_ah *rvt_get_swqe_ah(struct rvt_swqe *swqe) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci return ibah_to_rvtah(swqe->ud_wr.wr.ah); 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/** 21862306a36Sopenharmony_ci * rvt_get_swqe_ah_attr - Return the cached ah attribute information 21962306a36Sopenharmony_ci * @swqe: valid Send WQE 22062306a36Sopenharmony_ci * 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_cistatic inline struct rdma_ah_attr *rvt_get_swqe_ah_attr(struct rvt_swqe *swqe) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci return swqe->ud_wr.attr; 22562306a36Sopenharmony_ci} 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci/** 22862306a36Sopenharmony_ci * rvt_get_swqe_remote_qpn - Access the remote QPN value 22962306a36Sopenharmony_ci * @swqe: valid Send WQE 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci */ 23262306a36Sopenharmony_cistatic inline u32 rvt_get_swqe_remote_qpn(struct rvt_swqe *swqe) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci return swqe->ud_wr.wr.remote_qpn; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci/** 23862306a36Sopenharmony_ci * rvt_get_swqe_remote_qkey - Acces the remote qkey value 23962306a36Sopenharmony_ci * @swqe: valid Send WQE 24062306a36Sopenharmony_ci * 24162306a36Sopenharmony_ci */ 24262306a36Sopenharmony_cistatic inline u32 rvt_get_swqe_remote_qkey(struct rvt_swqe *swqe) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci return swqe->ud_wr.wr.remote_qkey; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/** 24862306a36Sopenharmony_ci * rvt_get_swqe_pkey_index - Access the pkey index 24962306a36Sopenharmony_ci * @swqe: valid Send WQE 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_cistatic inline u16 rvt_get_swqe_pkey_index(struct rvt_swqe *swqe) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci return swqe->ud_wr.wr.pkey_index; 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistruct rvt_rq { 25862306a36Sopenharmony_ci struct rvt_rwq *wq; 25962306a36Sopenharmony_ci struct rvt_krwq *kwq; 26062306a36Sopenharmony_ci u32 size; /* size of RWQE array */ 26162306a36Sopenharmony_ci u8 max_sge; 26262306a36Sopenharmony_ci /* protect changes in this struct */ 26362306a36Sopenharmony_ci spinlock_t lock ____cacheline_aligned_in_smp; 26462306a36Sopenharmony_ci}; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci/** 26762306a36Sopenharmony_ci * rvt_get_rq_count - count numbers of request work queue entries 26862306a36Sopenharmony_ci * in circular buffer 26962306a36Sopenharmony_ci * @rq: data structure for request queue entry 27062306a36Sopenharmony_ci * @head: head indices of the circular buffer 27162306a36Sopenharmony_ci * @tail: tail indices of the circular buffer 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * Return - total number of entries in the Receive Queue 27462306a36Sopenharmony_ci */ 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic inline u32 rvt_get_rq_count(struct rvt_rq *rq, u32 head, u32 tail) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci u32 count = head - tail; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci if ((s32)count < 0) 28162306a36Sopenharmony_ci count += rq->size; 28262306a36Sopenharmony_ci return count; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci/* 28662306a36Sopenharmony_ci * This structure holds the information that the send tasklet needs 28762306a36Sopenharmony_ci * to send a RDMA read response or atomic operation. 28862306a36Sopenharmony_ci */ 28962306a36Sopenharmony_cistruct rvt_ack_entry { 29062306a36Sopenharmony_ci struct rvt_sge rdma_sge; 29162306a36Sopenharmony_ci u64 atomic_data; 29262306a36Sopenharmony_ci u32 psn; 29362306a36Sopenharmony_ci u32 lpsn; 29462306a36Sopenharmony_ci u8 opcode; 29562306a36Sopenharmony_ci u8 sent; 29662306a36Sopenharmony_ci void *priv; 29762306a36Sopenharmony_ci}; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci#define RC_QP_SCALING_INTERVAL 5 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#define RVT_OPERATION_PRIV 0x00000001 30262306a36Sopenharmony_ci#define RVT_OPERATION_ATOMIC 0x00000002 30362306a36Sopenharmony_ci#define RVT_OPERATION_ATOMIC_SGE 0x00000004 30462306a36Sopenharmony_ci#define RVT_OPERATION_LOCAL 0x00000008 30562306a36Sopenharmony_ci#define RVT_OPERATION_USE_RESERVE 0x00000010 30662306a36Sopenharmony_ci#define RVT_OPERATION_IGN_RNR_CNT 0x00000020 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci#define RVT_OPERATION_MAX (IB_WR_RESERVED10 + 1) 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci/** 31162306a36Sopenharmony_ci * rvt_operation_params - op table entry 31262306a36Sopenharmony_ci * @length - the length to copy into the swqe entry 31362306a36Sopenharmony_ci * @qpt_support - a bit mask indicating QP type support 31462306a36Sopenharmony_ci * @flags - RVT_OPERATION flags (see above) 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci * This supports table driven post send so that 31762306a36Sopenharmony_ci * the driver can have differing an potentially 31862306a36Sopenharmony_ci * different sets of operations. 31962306a36Sopenharmony_ci * 32062306a36Sopenharmony_ci **/ 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cistruct rvt_operation_params { 32362306a36Sopenharmony_ci size_t length; 32462306a36Sopenharmony_ci u32 qpt_support; 32562306a36Sopenharmony_ci u32 flags; 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/* 32962306a36Sopenharmony_ci * Common variables are protected by both r_rq.lock and s_lock in that order 33062306a36Sopenharmony_ci * which only happens in modify_qp() or changing the QP 'state'. 33162306a36Sopenharmony_ci */ 33262306a36Sopenharmony_cistruct rvt_qp { 33362306a36Sopenharmony_ci struct ib_qp ibqp; 33462306a36Sopenharmony_ci void *priv; /* Driver private data */ 33562306a36Sopenharmony_ci /* read mostly fields above and below */ 33662306a36Sopenharmony_ci struct rdma_ah_attr remote_ah_attr; 33762306a36Sopenharmony_ci struct rdma_ah_attr alt_ah_attr; 33862306a36Sopenharmony_ci struct rvt_qp __rcu *next; /* link list for QPN hash table */ 33962306a36Sopenharmony_ci struct rvt_swqe *s_wq; /* send work queue */ 34062306a36Sopenharmony_ci struct rvt_mmap_info *ip; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci unsigned long timeout_jiffies; /* computed from timeout */ 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci int srate_mbps; /* s_srate (below) converted to Mbit/s */ 34562306a36Sopenharmony_ci pid_t pid; /* pid for user mode QPs */ 34662306a36Sopenharmony_ci u32 remote_qpn; 34762306a36Sopenharmony_ci u32 qkey; /* QKEY for this QP (for UD or RD) */ 34862306a36Sopenharmony_ci u32 s_size; /* send work queue size */ 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci u16 pmtu; /* decoded from path_mtu */ 35162306a36Sopenharmony_ci u8 log_pmtu; /* shift for pmtu */ 35262306a36Sopenharmony_ci u8 state; /* QP state */ 35362306a36Sopenharmony_ci u8 allowed_ops; /* high order bits of allowed opcodes */ 35462306a36Sopenharmony_ci u8 qp_access_flags; 35562306a36Sopenharmony_ci u8 alt_timeout; /* Alternate path timeout for this QP */ 35662306a36Sopenharmony_ci u8 timeout; /* Timeout for this QP */ 35762306a36Sopenharmony_ci u8 s_srate; 35862306a36Sopenharmony_ci u8 s_mig_state; 35962306a36Sopenharmony_ci u8 port_num; 36062306a36Sopenharmony_ci u8 s_pkey_index; /* PKEY index to use */ 36162306a36Sopenharmony_ci u8 s_alt_pkey_index; /* Alternate path PKEY index to use */ 36262306a36Sopenharmony_ci u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ 36362306a36Sopenharmony_ci u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ 36462306a36Sopenharmony_ci u8 s_retry_cnt; /* number of times to retry */ 36562306a36Sopenharmony_ci u8 s_rnr_retry_cnt; 36662306a36Sopenharmony_ci u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ 36762306a36Sopenharmony_ci u8 s_max_sge; /* size of s_wq->sg_list */ 36862306a36Sopenharmony_ci u8 s_draining; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci /* start of read/write fields */ 37162306a36Sopenharmony_ci atomic_t refcount ____cacheline_aligned_in_smp; 37262306a36Sopenharmony_ci wait_queue_head_t wait; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci struct rvt_ack_entry *s_ack_queue; 37562306a36Sopenharmony_ci struct rvt_sge_state s_rdma_read_sge; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci spinlock_t r_lock ____cacheline_aligned_in_smp; /* used for APM */ 37862306a36Sopenharmony_ci u32 r_psn; /* expected rcv packet sequence number */ 37962306a36Sopenharmony_ci unsigned long r_aflags; 38062306a36Sopenharmony_ci u64 r_wr_id; /* ID for current receive WQE */ 38162306a36Sopenharmony_ci u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ 38262306a36Sopenharmony_ci u32 r_len; /* total length of r_sge */ 38362306a36Sopenharmony_ci u32 r_rcv_len; /* receive data len processed */ 38462306a36Sopenharmony_ci u32 r_msn; /* message sequence number */ 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci u8 r_state; /* opcode of last packet received */ 38762306a36Sopenharmony_ci u8 r_flags; 38862306a36Sopenharmony_ci u8 r_head_ack_queue; /* index into s_ack_queue[] */ 38962306a36Sopenharmony_ci u8 r_adefered; /* defered ack count */ 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci struct list_head rspwait; /* link for waiting to respond */ 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci struct rvt_sge_state r_sge; /* current receive data */ 39462306a36Sopenharmony_ci struct rvt_rq r_rq; /* receive work queue */ 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* post send line */ 39762306a36Sopenharmony_ci spinlock_t s_hlock ____cacheline_aligned_in_smp; 39862306a36Sopenharmony_ci u32 s_head; /* new entries added here */ 39962306a36Sopenharmony_ci u32 s_next_psn; /* PSN for next request */ 40062306a36Sopenharmony_ci u32 s_avail; /* number of entries avail */ 40162306a36Sopenharmony_ci u32 s_ssn; /* SSN of tail entry */ 40262306a36Sopenharmony_ci atomic_t s_reserved_used; /* reserved entries in use */ 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci spinlock_t s_lock ____cacheline_aligned_in_smp; 40562306a36Sopenharmony_ci u32 s_flags; 40662306a36Sopenharmony_ci struct rvt_sge_state *s_cur_sge; 40762306a36Sopenharmony_ci struct rvt_swqe *s_wqe; 40862306a36Sopenharmony_ci struct rvt_sge_state s_sge; /* current send request data */ 40962306a36Sopenharmony_ci struct rvt_mregion *s_rdma_mr; 41062306a36Sopenharmony_ci u32 s_len; /* total length of s_sge */ 41162306a36Sopenharmony_ci u32 s_rdma_read_len; /* total length of s_rdma_read_sge */ 41262306a36Sopenharmony_ci u32 s_last_psn; /* last response PSN processed */ 41362306a36Sopenharmony_ci u32 s_sending_psn; /* lowest PSN that is being sent */ 41462306a36Sopenharmony_ci u32 s_sending_hpsn; /* highest PSN that is being sent */ 41562306a36Sopenharmony_ci u32 s_psn; /* current packet sequence number */ 41662306a36Sopenharmony_ci u32 s_ack_rdma_psn; /* PSN for sending RDMA read responses */ 41762306a36Sopenharmony_ci u32 s_ack_psn; /* PSN for acking sends and RDMA writes */ 41862306a36Sopenharmony_ci u32 s_tail; /* next entry to process */ 41962306a36Sopenharmony_ci u32 s_cur; /* current work queue entry */ 42062306a36Sopenharmony_ci u32 s_acked; /* last un-ACK'ed entry */ 42162306a36Sopenharmony_ci u32 s_last; /* last completed entry */ 42262306a36Sopenharmony_ci u32 s_lsn; /* limit sequence number (credit) */ 42362306a36Sopenharmony_ci u32 s_ahgpsn; /* set to the psn in the copy of the header */ 42462306a36Sopenharmony_ci u16 s_cur_size; /* size of send packet in bytes */ 42562306a36Sopenharmony_ci u16 s_rdma_ack_cnt; 42662306a36Sopenharmony_ci u8 s_hdrwords; /* size of s_hdr in 32 bit words */ 42762306a36Sopenharmony_ci s8 s_ahgidx; 42862306a36Sopenharmony_ci u8 s_state; /* opcode of last packet sent */ 42962306a36Sopenharmony_ci u8 s_ack_state; /* opcode of packet to ACK */ 43062306a36Sopenharmony_ci u8 s_nak_state; /* non-zero if NAK is pending */ 43162306a36Sopenharmony_ci u8 r_nak_state; /* non-zero if NAK is pending */ 43262306a36Sopenharmony_ci u8 s_retry; /* requester retry counter */ 43362306a36Sopenharmony_ci u8 s_rnr_retry; /* requester RNR retry counter */ 43462306a36Sopenharmony_ci u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ 43562306a36Sopenharmony_ci u8 s_tail_ack_queue; /* index into s_ack_queue[] */ 43662306a36Sopenharmony_ci u8 s_acked_ack_queue; /* index into s_ack_queue[] */ 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci struct rvt_sge_state s_ack_rdma_sge; 43962306a36Sopenharmony_ci struct timer_list s_timer; 44062306a36Sopenharmony_ci struct hrtimer s_rnr_timer; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci atomic_t local_ops_pending; /* number of fast_reg/local_inv reqs */ 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci /* 44562306a36Sopenharmony_ci * This sge list MUST be last. Do not add anything below here. 44662306a36Sopenharmony_ci */ 44762306a36Sopenharmony_ci struct rvt_sge *r_sg_list /* verified SGEs */ 44862306a36Sopenharmony_ci ____cacheline_aligned_in_smp; 44962306a36Sopenharmony_ci}; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistruct rvt_srq { 45262306a36Sopenharmony_ci struct ib_srq ibsrq; 45362306a36Sopenharmony_ci struct rvt_rq rq; 45462306a36Sopenharmony_ci struct rvt_mmap_info *ip; 45562306a36Sopenharmony_ci /* send signal when number of RWQEs < limit */ 45662306a36Sopenharmony_ci u32 limit; 45762306a36Sopenharmony_ci}; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_cistatic inline struct rvt_srq *ibsrq_to_rvtsrq(struct ib_srq *ibsrq) 46062306a36Sopenharmony_ci{ 46162306a36Sopenharmony_ci return container_of(ibsrq, struct rvt_srq, ibsrq); 46262306a36Sopenharmony_ci} 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_cistatic inline struct rvt_qp *ibqp_to_rvtqp(struct ib_qp *ibqp) 46562306a36Sopenharmony_ci{ 46662306a36Sopenharmony_ci return container_of(ibqp, struct rvt_qp, ibqp); 46762306a36Sopenharmony_ci} 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci#define RVT_QPN_MAX BIT(24) 47062306a36Sopenharmony_ci#define RVT_QPNMAP_ENTRIES (RVT_QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) 47162306a36Sopenharmony_ci#define RVT_BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE) 47262306a36Sopenharmony_ci#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE - 1) 47362306a36Sopenharmony_ci#define RVT_QPN_MASK IB_QPN_MASK 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci/* 47662306a36Sopenharmony_ci * QPN-map pages start out as NULL, they get allocated upon 47762306a36Sopenharmony_ci * first use and are never deallocated. This way, 47862306a36Sopenharmony_ci * large bitmaps are not allocated unless large numbers of QPs are used. 47962306a36Sopenharmony_ci */ 48062306a36Sopenharmony_cistruct rvt_qpn_map { 48162306a36Sopenharmony_ci void *page; 48262306a36Sopenharmony_ci}; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistruct rvt_qpn_table { 48562306a36Sopenharmony_ci spinlock_t lock; /* protect changes to the qp table */ 48662306a36Sopenharmony_ci unsigned flags; /* flags for QP0/1 allocated for each port */ 48762306a36Sopenharmony_ci u32 last; /* last QP number allocated */ 48862306a36Sopenharmony_ci u32 nmaps; /* size of the map table */ 48962306a36Sopenharmony_ci u16 limit; 49062306a36Sopenharmony_ci u8 incr; 49162306a36Sopenharmony_ci /* bit map of free QP numbers other than 0/1 */ 49262306a36Sopenharmony_ci struct rvt_qpn_map map[RVT_QPNMAP_ENTRIES]; 49362306a36Sopenharmony_ci}; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_cistruct rvt_qp_ibdev { 49662306a36Sopenharmony_ci u32 qp_table_size; 49762306a36Sopenharmony_ci u32 qp_table_bits; 49862306a36Sopenharmony_ci struct rvt_qp __rcu **qp_table; 49962306a36Sopenharmony_ci spinlock_t qpt_lock; /* qptable lock */ 50062306a36Sopenharmony_ci struct rvt_qpn_table qpn_table; 50162306a36Sopenharmony_ci}; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci/* 50462306a36Sopenharmony_ci * There is one struct rvt_mcast for each multicast GID. 50562306a36Sopenharmony_ci * All attached QPs are then stored as a list of 50662306a36Sopenharmony_ci * struct rvt_mcast_qp. 50762306a36Sopenharmony_ci */ 50862306a36Sopenharmony_cistruct rvt_mcast_qp { 50962306a36Sopenharmony_ci struct list_head list; 51062306a36Sopenharmony_ci struct rvt_qp *qp; 51162306a36Sopenharmony_ci}; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistruct rvt_mcast_addr { 51462306a36Sopenharmony_ci union ib_gid mgid; 51562306a36Sopenharmony_ci u16 lid; 51662306a36Sopenharmony_ci}; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_cistruct rvt_mcast { 51962306a36Sopenharmony_ci struct rb_node rb_node; 52062306a36Sopenharmony_ci struct rvt_mcast_addr mcast_addr; 52162306a36Sopenharmony_ci struct list_head qp_list; 52262306a36Sopenharmony_ci wait_queue_head_t wait; 52362306a36Sopenharmony_ci atomic_t refcount; 52462306a36Sopenharmony_ci int n_attached; 52562306a36Sopenharmony_ci}; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci/* 52862306a36Sopenharmony_ci * Since struct rvt_swqe is not a fixed size, we can't simply index into 52962306a36Sopenharmony_ci * struct rvt_qp.s_wq. This function does the array index computation. 53062306a36Sopenharmony_ci */ 53162306a36Sopenharmony_cistatic inline struct rvt_swqe *rvt_get_swqe_ptr(struct rvt_qp *qp, 53262306a36Sopenharmony_ci unsigned n) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci return (struct rvt_swqe *)((char *)qp->s_wq + 53562306a36Sopenharmony_ci (sizeof(struct rvt_swqe) + 53662306a36Sopenharmony_ci qp->s_max_sge * 53762306a36Sopenharmony_ci sizeof(struct rvt_sge)) * n); 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/* 54162306a36Sopenharmony_ci * Since struct rvt_rwqe is not a fixed size, we can't simply index into 54262306a36Sopenharmony_ci * struct rvt_rwq.wq. This function does the array index computation. 54362306a36Sopenharmony_ci */ 54462306a36Sopenharmony_cistatic inline struct rvt_rwqe *rvt_get_rwqe_ptr(struct rvt_rq *rq, unsigned n) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci return (struct rvt_rwqe *) 54762306a36Sopenharmony_ci ((char *)rq->kwq->curr_wq + 54862306a36Sopenharmony_ci (sizeof(struct rvt_rwqe) + 54962306a36Sopenharmony_ci rq->max_sge * sizeof(struct ib_sge)) * n); 55062306a36Sopenharmony_ci} 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci/** 55362306a36Sopenharmony_ci * rvt_is_user_qp - return if this is user mode QP 55462306a36Sopenharmony_ci * @qp - the target QP 55562306a36Sopenharmony_ci */ 55662306a36Sopenharmony_cistatic inline bool rvt_is_user_qp(struct rvt_qp *qp) 55762306a36Sopenharmony_ci{ 55862306a36Sopenharmony_ci return !!qp->pid; 55962306a36Sopenharmony_ci} 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci/** 56262306a36Sopenharmony_ci * rvt_get_qp - get a QP reference 56362306a36Sopenharmony_ci * @qp - the QP to hold 56462306a36Sopenharmony_ci */ 56562306a36Sopenharmony_cistatic inline void rvt_get_qp(struct rvt_qp *qp) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci atomic_inc(&qp->refcount); 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci/** 57162306a36Sopenharmony_ci * rvt_put_qp - release a QP reference 57262306a36Sopenharmony_ci * @qp - the QP to release 57362306a36Sopenharmony_ci */ 57462306a36Sopenharmony_cistatic inline void rvt_put_qp(struct rvt_qp *qp) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci if (qp && atomic_dec_and_test(&qp->refcount)) 57762306a36Sopenharmony_ci wake_up(&qp->wait); 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci/** 58162306a36Sopenharmony_ci * rvt_put_swqe - drop mr refs held by swqe 58262306a36Sopenharmony_ci * @wqe - the send wqe 58362306a36Sopenharmony_ci * 58462306a36Sopenharmony_ci * This drops any mr references held by the swqe 58562306a36Sopenharmony_ci */ 58662306a36Sopenharmony_cistatic inline void rvt_put_swqe(struct rvt_swqe *wqe) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci int i; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci for (i = 0; i < wqe->wr.num_sge; i++) { 59162306a36Sopenharmony_ci struct rvt_sge *sge = &wqe->sg_list[i]; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci rvt_put_mr(sge->mr); 59462306a36Sopenharmony_ci } 59562306a36Sopenharmony_ci} 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci/** 59862306a36Sopenharmony_ci * rvt_qp_wqe_reserve - reserve operation 59962306a36Sopenharmony_ci * @qp - the rvt qp 60062306a36Sopenharmony_ci * @wqe - the send wqe 60162306a36Sopenharmony_ci * 60262306a36Sopenharmony_ci * This routine used in post send to record 60362306a36Sopenharmony_ci * a wqe relative reserved operation use. 60462306a36Sopenharmony_ci */ 60562306a36Sopenharmony_cistatic inline void rvt_qp_wqe_reserve( 60662306a36Sopenharmony_ci struct rvt_qp *qp, 60762306a36Sopenharmony_ci struct rvt_swqe *wqe) 60862306a36Sopenharmony_ci{ 60962306a36Sopenharmony_ci atomic_inc(&qp->s_reserved_used); 61062306a36Sopenharmony_ci} 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci/** 61362306a36Sopenharmony_ci * rvt_qp_wqe_unreserve - clean reserved operation 61462306a36Sopenharmony_ci * @qp - the rvt qp 61562306a36Sopenharmony_ci * @flags - send wqe flags 61662306a36Sopenharmony_ci * 61762306a36Sopenharmony_ci * This decrements the reserve use count. 61862306a36Sopenharmony_ci * 61962306a36Sopenharmony_ci * This call MUST precede the change to 62062306a36Sopenharmony_ci * s_last to insure that post send sees a stable 62162306a36Sopenharmony_ci * s_avail. 62262306a36Sopenharmony_ci * 62362306a36Sopenharmony_ci * An smp_mp__after_atomic() is used to insure 62462306a36Sopenharmony_ci * the compiler does not juggle the order of the s_last 62562306a36Sopenharmony_ci * ring index and the decrementing of s_reserved_used. 62662306a36Sopenharmony_ci */ 62762306a36Sopenharmony_cistatic inline void rvt_qp_wqe_unreserve(struct rvt_qp *qp, int flags) 62862306a36Sopenharmony_ci{ 62962306a36Sopenharmony_ci if (unlikely(flags & RVT_SEND_RESERVE_USED)) { 63062306a36Sopenharmony_ci atomic_dec(&qp->s_reserved_used); 63162306a36Sopenharmony_ci /* insure no compiler re-order up to s_last change */ 63262306a36Sopenharmony_ci smp_mb__after_atomic(); 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ciextern const enum ib_wc_opcode ib_rvt_wc_opcode[]; 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci/* 63962306a36Sopenharmony_ci * Compare the lower 24 bits of the msn values. 64062306a36Sopenharmony_ci * Returns an integer <, ==, or > than zero. 64162306a36Sopenharmony_ci */ 64262306a36Sopenharmony_cistatic inline int rvt_cmp_msn(u32 a, u32 b) 64362306a36Sopenharmony_ci{ 64462306a36Sopenharmony_ci return (((int)a) - ((int)b)) << 8; 64562306a36Sopenharmony_ci} 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci__be32 rvt_compute_aeth(struct rvt_qp *qp); 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_civoid rvt_get_credit(struct rvt_qp *qp, u32 aeth); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ciu32 rvt_restart_sge(struct rvt_sge_state *ss, struct rvt_swqe *wqe, u32 len); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci/** 65462306a36Sopenharmony_ci * rvt_div_round_up_mtu - round up divide 65562306a36Sopenharmony_ci * @qp - the qp pair 65662306a36Sopenharmony_ci * @len - the length 65762306a36Sopenharmony_ci * 65862306a36Sopenharmony_ci * Perform a shift based mtu round up divide 65962306a36Sopenharmony_ci */ 66062306a36Sopenharmony_cistatic inline u32 rvt_div_round_up_mtu(struct rvt_qp *qp, u32 len) 66162306a36Sopenharmony_ci{ 66262306a36Sopenharmony_ci return (len + qp->pmtu - 1) >> qp->log_pmtu; 66362306a36Sopenharmony_ci} 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci/** 66662306a36Sopenharmony_ci * @qp - the qp pair 66762306a36Sopenharmony_ci * @len - the length 66862306a36Sopenharmony_ci * 66962306a36Sopenharmony_ci * Perform a shift based mtu divide 67062306a36Sopenharmony_ci */ 67162306a36Sopenharmony_cistatic inline u32 rvt_div_mtu(struct rvt_qp *qp, u32 len) 67262306a36Sopenharmony_ci{ 67362306a36Sopenharmony_ci return len >> qp->log_pmtu; 67462306a36Sopenharmony_ci} 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci/** 67762306a36Sopenharmony_ci * rvt_timeout_to_jiffies - Convert a ULP timeout input into jiffies 67862306a36Sopenharmony_ci * @timeout - timeout input(0 - 31). 67962306a36Sopenharmony_ci * 68062306a36Sopenharmony_ci * Return a timeout value in jiffies. 68162306a36Sopenharmony_ci */ 68262306a36Sopenharmony_cistatic inline unsigned long rvt_timeout_to_jiffies(u8 timeout) 68362306a36Sopenharmony_ci{ 68462306a36Sopenharmony_ci if (timeout > 31) 68562306a36Sopenharmony_ci timeout = 31; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci return usecs_to_jiffies(1U << timeout) * 4096UL / 1000UL; 68862306a36Sopenharmony_ci} 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci/** 69162306a36Sopenharmony_ci * rvt_lookup_qpn - return the QP with the given QPN 69262306a36Sopenharmony_ci * @ibp: the ibport 69362306a36Sopenharmony_ci * @qpn: the QP number to look up 69462306a36Sopenharmony_ci * 69562306a36Sopenharmony_ci * The caller must hold the rcu_read_lock(), and keep the lock until 69662306a36Sopenharmony_ci * the returned qp is no longer in use. 69762306a36Sopenharmony_ci */ 69862306a36Sopenharmony_cistatic inline struct rvt_qp *rvt_lookup_qpn(struct rvt_dev_info *rdi, 69962306a36Sopenharmony_ci struct rvt_ibport *rvp, 70062306a36Sopenharmony_ci u32 qpn) __must_hold(RCU) 70162306a36Sopenharmony_ci{ 70262306a36Sopenharmony_ci struct rvt_qp *qp = NULL; 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci if (unlikely(qpn <= 1)) { 70562306a36Sopenharmony_ci qp = rcu_dereference(rvp->qp[qpn]); 70662306a36Sopenharmony_ci } else { 70762306a36Sopenharmony_ci u32 n = hash_32(qpn, rdi->qp_dev->qp_table_bits); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci for (qp = rcu_dereference(rdi->qp_dev->qp_table[n]); qp; 71062306a36Sopenharmony_ci qp = rcu_dereference(qp->next)) 71162306a36Sopenharmony_ci if (qp->ibqp.qp_num == qpn) 71262306a36Sopenharmony_ci break; 71362306a36Sopenharmony_ci } 71462306a36Sopenharmony_ci return qp; 71562306a36Sopenharmony_ci} 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci/** 71862306a36Sopenharmony_ci * rvt_mod_retry_timer - mod a retry timer 71962306a36Sopenharmony_ci * @qp - the QP 72062306a36Sopenharmony_ci * @shift - timeout shift to wait for multiple packets 72162306a36Sopenharmony_ci * Modify a potentially already running retry timer 72262306a36Sopenharmony_ci */ 72362306a36Sopenharmony_cistatic inline void rvt_mod_retry_timer_ext(struct rvt_qp *qp, u8 shift) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci struct ib_qp *ibqp = &qp->ibqp; 72662306a36Sopenharmony_ci struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 72962306a36Sopenharmony_ci qp->s_flags |= RVT_S_TIMER; 73062306a36Sopenharmony_ci /* 4.096 usec. * (1 << qp->timeout) */ 73162306a36Sopenharmony_ci mod_timer(&qp->s_timer, jiffies + rdi->busy_jiffies + 73262306a36Sopenharmony_ci (qp->timeout_jiffies << shift)); 73362306a36Sopenharmony_ci} 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_cistatic inline void rvt_mod_retry_timer(struct rvt_qp *qp) 73662306a36Sopenharmony_ci{ 73762306a36Sopenharmony_ci return rvt_mod_retry_timer_ext(qp, 0); 73862306a36Sopenharmony_ci} 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci/** 74162306a36Sopenharmony_ci * rvt_put_qp_swqe - drop refs held by swqe 74262306a36Sopenharmony_ci * @qp: the send qp 74362306a36Sopenharmony_ci * @wqe: the send wqe 74462306a36Sopenharmony_ci * 74562306a36Sopenharmony_ci * This drops any references held by the swqe 74662306a36Sopenharmony_ci */ 74762306a36Sopenharmony_cistatic inline void rvt_put_qp_swqe(struct rvt_qp *qp, struct rvt_swqe *wqe) 74862306a36Sopenharmony_ci{ 74962306a36Sopenharmony_ci rvt_put_swqe(wqe); 75062306a36Sopenharmony_ci if (qp->allowed_ops == IB_OPCODE_UD) 75162306a36Sopenharmony_ci rdma_destroy_ah_attr(wqe->ud_wr.attr); 75262306a36Sopenharmony_ci} 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci/** 75562306a36Sopenharmony_ci * rvt_qp_sqwe_incr - increment ring index 75662306a36Sopenharmony_ci * @qp: the qp 75762306a36Sopenharmony_ci * @val: the starting value 75862306a36Sopenharmony_ci * 75962306a36Sopenharmony_ci * Return: the new value wrapping as appropriate 76062306a36Sopenharmony_ci */ 76162306a36Sopenharmony_cistatic inline u32 76262306a36Sopenharmony_cirvt_qp_swqe_incr(struct rvt_qp *qp, u32 val) 76362306a36Sopenharmony_ci{ 76462306a36Sopenharmony_ci if (++val >= qp->s_size) 76562306a36Sopenharmony_ci val = 0; 76662306a36Sopenharmony_ci return val; 76762306a36Sopenharmony_ci} 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ciint rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err); 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_ci/** 77262306a36Sopenharmony_ci * rvt_recv_cq - add a new entry to completion queue 77362306a36Sopenharmony_ci * by receive queue 77462306a36Sopenharmony_ci * @qp: receive queue 77562306a36Sopenharmony_ci * @wc: work completion entry to add 77662306a36Sopenharmony_ci * @solicited: true if @entry is solicited 77762306a36Sopenharmony_ci * 77862306a36Sopenharmony_ci * This is wrapper function for rvt_enter_cq function call by 77962306a36Sopenharmony_ci * receive queue. If rvt_cq_enter return false, it means cq is 78062306a36Sopenharmony_ci * full and the qp is put into error state. 78162306a36Sopenharmony_ci */ 78262306a36Sopenharmony_cistatic inline void rvt_recv_cq(struct rvt_qp *qp, struct ib_wc *wc, 78362306a36Sopenharmony_ci bool solicited) 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci struct rvt_cq *cq = ibcq_to_rvtcq(qp->ibqp.recv_cq); 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci if (unlikely(!rvt_cq_enter(cq, wc, solicited))) 78862306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_LOC_QP_OP_ERR); 78962306a36Sopenharmony_ci} 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci/** 79262306a36Sopenharmony_ci * rvt_send_cq - add a new entry to completion queue 79362306a36Sopenharmony_ci * by send queue 79462306a36Sopenharmony_ci * @qp: send queue 79562306a36Sopenharmony_ci * @wc: work completion entry to add 79662306a36Sopenharmony_ci * @solicited: true if @entry is solicited 79762306a36Sopenharmony_ci * 79862306a36Sopenharmony_ci * This is wrapper function for rvt_enter_cq function call by 79962306a36Sopenharmony_ci * send queue. If rvt_cq_enter return false, it means cq is 80062306a36Sopenharmony_ci * full and the qp is put into error state. 80162306a36Sopenharmony_ci */ 80262306a36Sopenharmony_cistatic inline void rvt_send_cq(struct rvt_qp *qp, struct ib_wc *wc, 80362306a36Sopenharmony_ci bool solicited) 80462306a36Sopenharmony_ci{ 80562306a36Sopenharmony_ci struct rvt_cq *cq = ibcq_to_rvtcq(qp->ibqp.send_cq); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci if (unlikely(!rvt_cq_enter(cq, wc, solicited))) 80862306a36Sopenharmony_ci rvt_error_qp(qp, IB_WC_LOC_QP_OP_ERR); 80962306a36Sopenharmony_ci} 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci/** 81262306a36Sopenharmony_ci * rvt_qp_complete_swqe - insert send completion 81362306a36Sopenharmony_ci * @qp - the qp 81462306a36Sopenharmony_ci * @wqe - the send wqe 81562306a36Sopenharmony_ci * @opcode - wc operation (driver dependent) 81662306a36Sopenharmony_ci * @status - completion status 81762306a36Sopenharmony_ci * 81862306a36Sopenharmony_ci * Update the s_last information, and then insert a send 81962306a36Sopenharmony_ci * completion into the completion 82062306a36Sopenharmony_ci * queue if the qp indicates it should be done. 82162306a36Sopenharmony_ci * 82262306a36Sopenharmony_ci * See IBTA 10.7.3.1 for info on completion 82362306a36Sopenharmony_ci * control. 82462306a36Sopenharmony_ci * 82562306a36Sopenharmony_ci * Return: new last 82662306a36Sopenharmony_ci */ 82762306a36Sopenharmony_cistatic inline u32 82862306a36Sopenharmony_cirvt_qp_complete_swqe(struct rvt_qp *qp, 82962306a36Sopenharmony_ci struct rvt_swqe *wqe, 83062306a36Sopenharmony_ci enum ib_wc_opcode opcode, 83162306a36Sopenharmony_ci enum ib_wc_status status) 83262306a36Sopenharmony_ci{ 83362306a36Sopenharmony_ci bool need_completion; 83462306a36Sopenharmony_ci u64 wr_id; 83562306a36Sopenharmony_ci u32 byte_len, last; 83662306a36Sopenharmony_ci int flags = wqe->wr.send_flags; 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci rvt_qp_wqe_unreserve(qp, flags); 83962306a36Sopenharmony_ci rvt_put_qp_swqe(qp, wqe); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci need_completion = 84262306a36Sopenharmony_ci !(flags & RVT_SEND_RESERVE_USED) && 84362306a36Sopenharmony_ci (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) || 84462306a36Sopenharmony_ci (flags & IB_SEND_SIGNALED) || 84562306a36Sopenharmony_ci status != IB_WC_SUCCESS); 84662306a36Sopenharmony_ci if (need_completion) { 84762306a36Sopenharmony_ci wr_id = wqe->wr.wr_id; 84862306a36Sopenharmony_ci byte_len = wqe->length; 84962306a36Sopenharmony_ci /* above fields required before writing s_last */ 85062306a36Sopenharmony_ci } 85162306a36Sopenharmony_ci last = rvt_qp_swqe_incr(qp, qp->s_last); 85262306a36Sopenharmony_ci /* see rvt_qp_is_avail() */ 85362306a36Sopenharmony_ci smp_store_release(&qp->s_last, last); 85462306a36Sopenharmony_ci if (need_completion) { 85562306a36Sopenharmony_ci struct ib_wc w = { 85662306a36Sopenharmony_ci .wr_id = wr_id, 85762306a36Sopenharmony_ci .status = status, 85862306a36Sopenharmony_ci .opcode = opcode, 85962306a36Sopenharmony_ci .qp = &qp->ibqp, 86062306a36Sopenharmony_ci .byte_len = byte_len, 86162306a36Sopenharmony_ci }; 86262306a36Sopenharmony_ci rvt_send_cq(qp, &w, status != IB_WC_SUCCESS); 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci return last; 86562306a36Sopenharmony_ci} 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ciextern const int ib_rvt_state_ops[]; 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_cistruct rvt_dev_info; 87062306a36Sopenharmony_ciint rvt_get_rwqe(struct rvt_qp *qp, bool wr_id_only); 87162306a36Sopenharmony_civoid rvt_comm_est(struct rvt_qp *qp); 87262306a36Sopenharmony_civoid rvt_rc_error(struct rvt_qp *qp, enum ib_wc_status err); 87362306a36Sopenharmony_ciunsigned long rvt_rnr_tbl_to_usec(u32 index); 87462306a36Sopenharmony_cienum hrtimer_restart rvt_rc_rnr_retry(struct hrtimer *t); 87562306a36Sopenharmony_civoid rvt_add_rnr_timer(struct rvt_qp *qp, u32 aeth); 87662306a36Sopenharmony_civoid rvt_del_timers_sync(struct rvt_qp *qp); 87762306a36Sopenharmony_civoid rvt_stop_rc_timers(struct rvt_qp *qp); 87862306a36Sopenharmony_civoid rvt_add_retry_timer_ext(struct rvt_qp *qp, u8 shift); 87962306a36Sopenharmony_cistatic inline void rvt_add_retry_timer(struct rvt_qp *qp) 88062306a36Sopenharmony_ci{ 88162306a36Sopenharmony_ci rvt_add_retry_timer_ext(qp, 0); 88262306a36Sopenharmony_ci} 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_civoid rvt_copy_sge(struct rvt_qp *qp, struct rvt_sge_state *ss, 88562306a36Sopenharmony_ci void *data, u32 length, 88662306a36Sopenharmony_ci bool release, bool copy_last); 88762306a36Sopenharmony_civoid rvt_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe, 88862306a36Sopenharmony_ci enum ib_wc_status status); 88962306a36Sopenharmony_civoid rvt_ruc_loopback(struct rvt_qp *qp); 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci/** 89262306a36Sopenharmony_ci * struct rvt_qp_iter - the iterator for QPs 89362306a36Sopenharmony_ci * @qp - the current QP 89462306a36Sopenharmony_ci * 89562306a36Sopenharmony_ci * This structure defines the current iterator 89662306a36Sopenharmony_ci * state for sequenced access to all QPs relative 89762306a36Sopenharmony_ci * to an rvt_dev_info. 89862306a36Sopenharmony_ci */ 89962306a36Sopenharmony_cistruct rvt_qp_iter { 90062306a36Sopenharmony_ci struct rvt_qp *qp; 90162306a36Sopenharmony_ci /* private: backpointer */ 90262306a36Sopenharmony_ci struct rvt_dev_info *rdi; 90362306a36Sopenharmony_ci /* private: callback routine */ 90462306a36Sopenharmony_ci void (*cb)(struct rvt_qp *qp, u64 v); 90562306a36Sopenharmony_ci /* private: for arg to callback routine */ 90662306a36Sopenharmony_ci u64 v; 90762306a36Sopenharmony_ci /* private: number of SMI,GSI QPs for device */ 90862306a36Sopenharmony_ci int specials; 90962306a36Sopenharmony_ci /* private: current iterator index */ 91062306a36Sopenharmony_ci int n; 91162306a36Sopenharmony_ci}; 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci/** 91462306a36Sopenharmony_ci * ib_cq_tail - Return tail index of cq buffer 91562306a36Sopenharmony_ci * @send_cq - The cq for send 91662306a36Sopenharmony_ci * 91762306a36Sopenharmony_ci * This is called in qp_iter_print to get tail 91862306a36Sopenharmony_ci * of cq buffer. 91962306a36Sopenharmony_ci */ 92062306a36Sopenharmony_cistatic inline u32 ib_cq_tail(struct ib_cq *send_cq) 92162306a36Sopenharmony_ci{ 92262306a36Sopenharmony_ci struct rvt_cq *cq = ibcq_to_rvtcq(send_cq); 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci return ibcq_to_rvtcq(send_cq)->ip ? 92562306a36Sopenharmony_ci RDMA_READ_UAPI_ATOMIC(cq->queue->tail) : 92662306a36Sopenharmony_ci ibcq_to_rvtcq(send_cq)->kqueue->tail; 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci/** 93062306a36Sopenharmony_ci * ib_cq_head - Return head index of cq buffer 93162306a36Sopenharmony_ci * @send_cq - The cq for send 93262306a36Sopenharmony_ci * 93362306a36Sopenharmony_ci * This is called in qp_iter_print to get head 93462306a36Sopenharmony_ci * of cq buffer. 93562306a36Sopenharmony_ci */ 93662306a36Sopenharmony_cistatic inline u32 ib_cq_head(struct ib_cq *send_cq) 93762306a36Sopenharmony_ci{ 93862306a36Sopenharmony_ci struct rvt_cq *cq = ibcq_to_rvtcq(send_cq); 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci return ibcq_to_rvtcq(send_cq)->ip ? 94162306a36Sopenharmony_ci RDMA_READ_UAPI_ATOMIC(cq->queue->head) : 94262306a36Sopenharmony_ci ibcq_to_rvtcq(send_cq)->kqueue->head; 94362306a36Sopenharmony_ci} 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci/** 94662306a36Sopenharmony_ci * rvt_free_rq - free memory allocated for rvt_rq struct 94762306a36Sopenharmony_ci * @rvt_rq: request queue data structure 94862306a36Sopenharmony_ci * 94962306a36Sopenharmony_ci * This function should only be called if the rvt_mmap_info() 95062306a36Sopenharmony_ci * has not succeeded. 95162306a36Sopenharmony_ci */ 95262306a36Sopenharmony_cistatic inline void rvt_free_rq(struct rvt_rq *rq) 95362306a36Sopenharmony_ci{ 95462306a36Sopenharmony_ci kvfree(rq->kwq); 95562306a36Sopenharmony_ci rq->kwq = NULL; 95662306a36Sopenharmony_ci vfree(rq->wq); 95762306a36Sopenharmony_ci rq->wq = NULL; 95862306a36Sopenharmony_ci} 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci/** 96162306a36Sopenharmony_ci * rvt_to_iport - Get the ibport pointer 96262306a36Sopenharmony_ci * @qp: the qp pointer 96362306a36Sopenharmony_ci * 96462306a36Sopenharmony_ci * This function returns the ibport pointer from the qp pointer. 96562306a36Sopenharmony_ci */ 96662306a36Sopenharmony_cistatic inline struct rvt_ibport *rvt_to_iport(struct rvt_qp *qp) 96762306a36Sopenharmony_ci{ 96862306a36Sopenharmony_ci struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci return rdi->ports[qp->port_num - 1]; 97162306a36Sopenharmony_ci} 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci/** 97462306a36Sopenharmony_ci * rvt_rc_credit_avail - Check if there are enough RC credits for the request 97562306a36Sopenharmony_ci * @qp: the qp 97662306a36Sopenharmony_ci * @wqe: the request 97762306a36Sopenharmony_ci * 97862306a36Sopenharmony_ci * This function returns false when there are not enough credits for the given 97962306a36Sopenharmony_ci * request and true otherwise. 98062306a36Sopenharmony_ci */ 98162306a36Sopenharmony_cistatic inline bool rvt_rc_credit_avail(struct rvt_qp *qp, struct rvt_swqe *wqe) 98262306a36Sopenharmony_ci{ 98362306a36Sopenharmony_ci lockdep_assert_held(&qp->s_lock); 98462306a36Sopenharmony_ci if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) && 98562306a36Sopenharmony_ci rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) { 98662306a36Sopenharmony_ci struct rvt_ibport *rvp = rvt_to_iport(qp); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci qp->s_flags |= RVT_S_WAIT_SSN_CREDIT; 98962306a36Sopenharmony_ci rvp->n_rc_crwaits++; 99062306a36Sopenharmony_ci return false; 99162306a36Sopenharmony_ci } 99262306a36Sopenharmony_ci return true; 99362306a36Sopenharmony_ci} 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_cistruct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi, 99662306a36Sopenharmony_ci u64 v, 99762306a36Sopenharmony_ci void (*cb)(struct rvt_qp *qp, u64 v)); 99862306a36Sopenharmony_ciint rvt_qp_iter_next(struct rvt_qp_iter *iter); 99962306a36Sopenharmony_civoid rvt_qp_iter(struct rvt_dev_info *rdi, 100062306a36Sopenharmony_ci u64 v, 100162306a36Sopenharmony_ci void (*cb)(struct rvt_qp *qp, u64 v)); 100262306a36Sopenharmony_civoid rvt_qp_mr_clean(struct rvt_qp *qp, u32 lkey); 100362306a36Sopenharmony_ci#endif /* DEF_RDMAVT_INCQP_H */ 1004