2016-01-06 21:04:31 +03:00
# ifndef DEF_RDMAVT_INCQP_H
# define DEF_RDMAVT_INCQP_H
/*
* Copyright ( c ) 2015 Intel Corporation .
*
* This file is provided under a dual BSD / GPLv2 license . When using or
* redistributing this file , you may do so under either license .
*
* GPL LICENSE SUMMARY
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* BSD LICENSE
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* - Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* - Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in
* the documentation and / or other materials provided with the
* distribution .
* - Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
*/
2016-01-22 23:50:11 +03:00
# include <rdma/ib_pack.h>
/*
* Atomic bit definitions for r_aflags .
*/
# define RVT_R_WRID_VALID 0
# define RVT_R_REWIND_SGE 1
/*
* Bit definitions for r_flags .
*/
# define RVT_R_REUSE_SGE 0x01
# define RVT_R_RDMAR_SEQ 0x02
# define RVT_R_RSP_NAK 0x04
# define RVT_R_RSP_SEND 0x08
# define RVT_R_COMM_EST 0x10
/*
* Bit definitions for s_flags .
*
* RVT_S_SIGNAL_REQ_WR - set if QP send WRs contain completion signaled
* RVT_S_BUSY - send tasklet is processing the QP
* RVT_S_TIMER - the RC retry timer is active
* RVT_S_ACK_PENDING - an ACK is waiting to be sent after RDMA read / atomics
* RVT_S_WAIT_FENCE - waiting for all prior RDMA read or atomic SWQEs
* before processing the next SWQE
* RVT_S_WAIT_RDMAR - waiting for a RDMA read or atomic SWQE to complete
* before processing the next SWQE
* RVT_S_WAIT_RNR - waiting for RNR timeout
* RVT_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE
* RVT_S_WAIT_DMA - waiting for send DMA queue to drain before generating
* next send completion entry not via send DMA
* RVT_S_WAIT_PIO - waiting for a send buffer to be available
* RVT_S_WAIT_TX - waiting for a struct verbs_txreq to be available
* RVT_S_WAIT_DMA_DESC - waiting for DMA descriptors to be available
* RVT_S_WAIT_KMEM - waiting for kernel memory to be available
* RVT_S_WAIT_PSN - waiting for a packet to exit the send DMA queue
* RVT_S_WAIT_ACK - waiting for an ACK packet before sending more requests
* RVT_S_SEND_ONE - send one packet , request ACK , then wait for ACK
* RVT_S_ECN - a BECN was queued to the send engine
*/
# define RVT_S_SIGNAL_REQ_WR 0x0001
# define RVT_S_BUSY 0x0002
# define RVT_S_TIMER 0x0004
# define RVT_S_RESP_PENDING 0x0008
# define RVT_S_ACK_PENDING 0x0010
# define RVT_S_WAIT_FENCE 0x0020
# define RVT_S_WAIT_RDMAR 0x0040
# define RVT_S_WAIT_RNR 0x0080
# define RVT_S_WAIT_SSN_CREDIT 0x0100
# define RVT_S_WAIT_DMA 0x0200
# define RVT_S_WAIT_PIO 0x0400
# define RVT_S_WAIT_TX 0x0800
# define RVT_S_WAIT_DMA_DESC 0x1000
# define RVT_S_WAIT_KMEM 0x2000
# define RVT_S_WAIT_PSN 0x4000
# define RVT_S_WAIT_ACK 0x8000
# define RVT_S_SEND_ONE 0x10000
# define RVT_S_UNLIMITED_CREDIT 0x20000
# define RVT_S_AHG_VALID 0x40000
# define RVT_S_AHG_CLEAR 0x80000
# define RVT_S_ECN 0x100000
/*
* Wait flags that would prevent any packet type from being sent .
*/
# define RVT_S_ANY_WAIT_IO (RVT_S_WAIT_PIO | RVT_S_WAIT_TX | \
RVT_S_WAIT_DMA_DESC | RVT_S_WAIT_KMEM )
/*
* Wait flags that would prevent send work requests from making progress .
*/
# define RVT_S_ANY_WAIT_SEND (RVT_S_WAIT_FENCE | RVT_S_WAIT_RDMAR | \
RVT_S_WAIT_RNR | RVT_S_WAIT_SSN_CREDIT | RVT_S_WAIT_DMA | \
RVT_S_WAIT_PSN | RVT_S_WAIT_ACK )
# define RVT_S_ANY_WAIT (RVT_S_ANY_WAIT_IO | RVT_S_ANY_WAIT_SEND)
/* Number of bits to pay attention to in the opcode for checking qp type */
# define RVT_OPCODE_QP_MASK 0xE0
2016-01-06 21:04:31 +03:00
/*
* Send work request queue entry .
* The size of the sg_list is determined when the QP is created and stored
* in qp - > s_max_sge .
*/
struct rvt_swqe {
union {
struct ib_send_wr wr ; /* don't use wr.sg_list */
struct ib_ud_wr ud_wr ;
struct ib_reg_wr reg_wr ;
struct ib_rdma_wr rdma_wr ;
struct ib_atomic_wr atomic_wr ;
} ;
u32 psn ; /* first packet sequence number */
u32 lpsn ; /* last packet sequence number */
u32 ssn ; /* send sequence number */
u32 length ; /* total length of data in sg_list */
struct rvt_sge sg_list [ 0 ] ;
} ;
/*
* Receive work request queue entry .
* The size of the sg_list is determined when the QP ( or SRQ ) is created
* and stored in qp - > r_rq . max_sge ( or srq - > rq . max_sge ) .
*/
struct rvt_rwqe {
u64 wr_id ;
u8 num_sge ;
struct ib_sge sg_list [ 0 ] ;
} ;
/*
* This structure is used to contain the head pointer , tail pointer ,
* and receive work queue entries as a single memory allocation so
* it can be mmap ' ed into user space .
* Note that the wq array elements are variable size so you can ' t
* just index into the array to get the N ' th element ;
* use get_rwqe_ptr ( ) instead .
*/
struct rvt_rwq {
u32 head ; /* new work requests posted to the head */
u32 tail ; /* receives pull requests from here. */
struct rvt_rwqe wq [ 0 ] ;
} ;
struct rvt_rq {
struct rvt_rwq * wq ;
u32 size ; /* size of RWQE array */
u8 max_sge ;
/* protect changes in this struct */
spinlock_t lock ____cacheline_aligned_in_smp ;
} ;
/*
* This structure is used by rvt_mmap ( ) to validate an offset
* when an mmap ( ) request is made . The vm_area_struct then uses
* this as its vm_private_data .
*/
struct rvt_mmap_info {
struct list_head pending_mmaps ;
struct ib_ucontext * context ;
void * obj ;
__u64 offset ;
struct kref ref ;
unsigned size ;
} ;
# define RVT_MAX_RDMA_ATOMIC 16
/*
* This structure holds the information that the send tasklet needs
* to send a RDMA read response or atomic operation .
*/
struct rvt_ack_entry {
u8 opcode ;
u8 sent ;
u32 psn ;
u32 lpsn ;
union {
struct rvt_sge rdma_sge ;
u64 atomic_data ;
} ;
} ;
/*
* Variables prefixed with s_ are for the requester ( sender ) .
* Variables prefixed with r_ are for the responder ( receiver ) .
* Variables prefixed with ack_ are for responder replies .
*
* Common variables are protected by both r_rq . lock and s_lock in that order
* which only happens in modify_qp ( ) or changing the QP ' state ' .
*/
struct rvt_qp {
struct ib_qp ibqp ;
void * priv ; /* Driver private data */
/* read mostly fields above and below */
struct ib_ah_attr remote_ah_attr ;
struct ib_ah_attr alt_ah_attr ;
struct rvt_qp __rcu * next ; /* link list for QPN hash table */
struct rvt_swqe * s_wq ; /* send work queue */
struct rvt_mmap_info * ip ;
unsigned long timeout_jiffies ; /* computed from timeout */
enum ib_mtu path_mtu ;
int srate_mbps ; /* s_srate (below) converted to Mbit/s */
u32 remote_qpn ;
u32 pmtu ; /* decoded from path_mtu */
u32 qkey ; /* QKEY for this QP (for UD or RD) */
u32 s_size ; /* send work queue size */
u32 s_rnr_timeout ; /* number of milliseconds for RNR timeout */
u32 s_ahgpsn ; /* set to the psn in the copy of the header */
u8 state ; /* QP state */
u8 allowed_ops ; /* high order bits of allowed opcodes */
u8 qp_access_flags ;
u8 alt_timeout ; /* Alternate path timeout for this QP */
u8 timeout ; /* Timeout for this QP */
u8 s_srate ;
u8 s_mig_state ;
u8 port_num ;
u8 s_pkey_index ; /* PKEY index to use */
u8 s_alt_pkey_index ; /* Alternate path PKEY index to use */
u8 r_max_rd_atomic ; /* max number of RDMA read/atomic to receive */
u8 s_max_rd_atomic ; /* max number of RDMA read/atomic to send */
u8 s_retry_cnt ; /* number of times to retry */
u8 s_rnr_retry_cnt ;
u8 r_min_rnr_timer ; /* retry timeout value for RNR NAKs */
u8 s_max_sge ; /* size of s_wq->sg_list */
u8 s_draining ;
/* start of read/write fields */
atomic_t refcount ____cacheline_aligned_in_smp ;
wait_queue_head_t wait ;
struct rvt_ack_entry s_ack_queue [ RVT_MAX_RDMA_ATOMIC + 1 ]
____cacheline_aligned_in_smp ;
struct rvt_sge_state s_rdma_read_sge ;
spinlock_t r_lock ____cacheline_aligned_in_smp ; /* used for APM */
unsigned long r_aflags ;
u64 r_wr_id ; /* ID for current receive WQE */
u32 r_ack_psn ; /* PSN for next ACK or atomic ACK */
u32 r_len ; /* total length of r_sge */
u32 r_rcv_len ; /* receive data len processed */
u32 r_psn ; /* expected rcv packet sequence number */
u32 r_msn ; /* message sequence number */
u8 r_state ; /* opcode of last packet received */
u8 r_flags ;
u8 r_head_ack_queue ; /* index into s_ack_queue[] */
struct list_head rspwait ; /* link for waiting to respond */
struct rvt_sge_state r_sge ; /* current receive data */
struct rvt_rq r_rq ; /* receive work queue */
spinlock_t s_lock ____cacheline_aligned_in_smp ;
struct rvt_sge_state * s_cur_sge ;
u32 s_flags ;
struct rvt_swqe * s_wqe ;
struct rvt_sge_state s_sge ; /* current send request data */
struct rvt_mregion * s_rdma_mr ;
struct sdma_engine * s_sde ; /* current sde */
u32 s_cur_size ; /* size of send packet in bytes */
u32 s_len ; /* total length of s_sge */
u32 s_rdma_read_len ; /* total length of s_rdma_read_sge */
u32 s_next_psn ; /* PSN for next request */
u32 s_last_psn ; /* last response PSN processed */
u32 s_sending_psn ; /* lowest PSN that is being sent */
u32 s_sending_hpsn ; /* highest PSN that is being sent */
u32 s_psn ; /* current packet sequence number */
u32 s_ack_rdma_psn ; /* PSN for sending RDMA read responses */
u32 s_ack_psn ; /* PSN for acking sends and RDMA writes */
u32 s_head ; /* new entries added here */
u32 s_tail ; /* next entry to process */
u32 s_cur ; /* current work queue entry */
u32 s_acked ; /* last un-ACK'ed entry */
u32 s_last ; /* last completed entry */
u32 s_ssn ; /* SSN of tail entry */
u32 s_lsn ; /* limit sequence number (credit) */
u16 s_hdrwords ; /* size of s_hdr in 32 bit words */
u16 s_rdma_ack_cnt ;
s8 s_ahgidx ;
u8 s_state ; /* opcode of last packet sent */
u8 s_ack_state ; /* opcode of packet to ACK */
u8 s_nak_state ; /* non-zero if NAK is pending */
u8 r_nak_state ; /* non-zero if NAK is pending */
u8 s_retry ; /* requester retry counter */
u8 s_rnr_retry ; /* requester RNR retry counter */
u8 s_num_rd_atomic ; /* number of RDMA read/atomic pending */
u8 s_tail_ack_queue ; /* index into s_ack_queue[] */
struct rvt_sge_state s_ack_rdma_sge ;
struct timer_list s_timer ;
/*
* This sge list MUST be last . Do not add anything below here .
*/
struct rvt_sge r_sg_list [ 0 ] /* verified SGEs */
____cacheline_aligned_in_smp ;
} ;
struct rvt_srq {
struct ib_srq ibsrq ;
struct rvt_rq rq ;
struct rvt_mmap_info * ip ;
/* send signal when number of RWQEs < limit */
u32 limit ;
} ;
2016-01-06 21:04:46 +03:00
# define RVT_QPN_MAX BIT(24)
# define RVT_QPNMAP_ENTRIES (RVT_QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
# define RVT_BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE)
# define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE - 1)
/*
* QPN - map pages start out as NULL , they get allocated upon
* first use and are never deallocated . This way ,
* large bitmaps are not allocated unless large numbers of QPs are used .
*/
struct rvt_qpn_map {
void * page ;
} ;
struct rvt_qpn_table {
spinlock_t lock ; /* protect changes to the qp table */
unsigned flags ; /* flags for QP0/1 allocated for each port */
u32 last ; /* last QP number allocated */
u32 nmaps ; /* size of the map table */
u16 limit ;
u8 incr ;
/* bit map of free QP numbers other than 0/1 */
struct rvt_qpn_map map [ RVT_QPNMAP_ENTRIES ] ;
} ;
struct rvt_qp_ibdev {
u32 qp_table_size ;
u32 qp_table_bits ;
struct rvt_qp __rcu * * qp_table ;
spinlock_t qpt_lock ; /* qptable lock */
struct rvt_qpn_table qpn_table ;
} ;
2016-01-06 21:04:31 +03:00
# endif /* DEF_RDMAVT_INCQP_H */