18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _RDS_IB_H 38c2ecf20Sopenharmony_ci#define _RDS_IB_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h> 68c2ecf20Sopenharmony_ci#include <rdma/rdma_cm.h> 78c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 88c2ecf20Sopenharmony_ci#include <linux/pci.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include "rds.h" 118c2ecf20Sopenharmony_ci#include "rdma_transport.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define RDS_IB_MAX_SGE 8 148c2ecf20Sopenharmony_ci#define RDS_IB_RECV_SGE 2 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define RDS_IB_DEFAULT_RECV_WR 1024 178c2ecf20Sopenharmony_ci#define RDS_IB_DEFAULT_SEND_WR 256 188c2ecf20Sopenharmony_ci#define RDS_IB_DEFAULT_FR_WR 512 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define RDS_IB_DEFAULT_RETRY_COUNT 1 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define RDS_IB_SUPPORTED_PROTOCOLS 0x00000003 /* minor versions supported */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define RDS_IB_RECYCLE_BATCH_COUNT 32 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define RDS_IB_WC_MAX 32 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciextern struct rw_semaphore rds_ib_devices_lock; 298c2ecf20Sopenharmony_ciextern struct list_head rds_ib_devices; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * IB posts RDS_FRAG_SIZE fragments of pages to the receive queues to 338c2ecf20Sopenharmony_ci * try and minimize the amount of memory tied up both the device and 348c2ecf20Sopenharmony_ci * socket receive queues. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_cistruct rds_page_frag { 378c2ecf20Sopenharmony_ci struct list_head f_item; 388c2ecf20Sopenharmony_ci struct list_head f_cache_entry; 398c2ecf20Sopenharmony_ci struct scatterlist f_sg; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct rds_ib_incoming { 438c2ecf20Sopenharmony_ci struct list_head ii_frags; 448c2ecf20Sopenharmony_ci struct list_head ii_cache_entry; 458c2ecf20Sopenharmony_ci struct rds_incoming ii_inc; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistruct rds_ib_cache_head { 498c2ecf20Sopenharmony_ci struct list_head *first; 508c2ecf20Sopenharmony_ci unsigned long count; 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistruct rds_ib_refill_cache { 548c2ecf20Sopenharmony_ci struct rds_ib_cache_head __percpu *percpu; 558c2ecf20Sopenharmony_ci struct list_head *xfer; 568c2ecf20Sopenharmony_ci struct list_head *ready; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* This is the common structure for the IB private data exchange in setting up 608c2ecf20Sopenharmony_ci * an RDS connection. The exchange is different for IPv4 and IPv6 connections. 618c2ecf20Sopenharmony_ci * The reason is that the address size is different and the addresses 628c2ecf20Sopenharmony_ci * exchanged are in the beginning of the structure. Hence it is not possible 638c2ecf20Sopenharmony_ci * for interoperability if same structure is used. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_cistruct rds_ib_conn_priv_cmn { 668c2ecf20Sopenharmony_ci u8 ricpc_protocol_major; 678c2ecf20Sopenharmony_ci u8 ricpc_protocol_minor; 688c2ecf20Sopenharmony_ci __be16 ricpc_protocol_minor_mask; /* bitmask */ 698c2ecf20Sopenharmony_ci u8 ricpc_dp_toss; 708c2ecf20Sopenharmony_ci u8 ripc_reserved1; 718c2ecf20Sopenharmony_ci __be16 ripc_reserved2; 728c2ecf20Sopenharmony_ci __be64 ricpc_ack_seq; 738c2ecf20Sopenharmony_ci __be32 ricpc_credit; /* non-zero enables flow ctl */ 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistruct rds_ib_connect_private { 778c2ecf20Sopenharmony_ci /* Add new fields at the end, and don't permute existing fields. */ 788c2ecf20Sopenharmony_ci __be32 dp_saddr; 798c2ecf20Sopenharmony_ci __be32 dp_daddr; 808c2ecf20Sopenharmony_ci struct rds_ib_conn_priv_cmn dp_cmn; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistruct rds6_ib_connect_private { 848c2ecf20Sopenharmony_ci /* Add new fields at the end, and don't permute existing fields. */ 858c2ecf20Sopenharmony_ci struct in6_addr dp_saddr; 868c2ecf20Sopenharmony_ci struct in6_addr dp_daddr; 878c2ecf20Sopenharmony_ci struct rds_ib_conn_priv_cmn dp_cmn; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#define dp_protocol_major dp_cmn.ricpc_protocol_major 918c2ecf20Sopenharmony_ci#define dp_protocol_minor dp_cmn.ricpc_protocol_minor 928c2ecf20Sopenharmony_ci#define dp_protocol_minor_mask dp_cmn.ricpc_protocol_minor_mask 938c2ecf20Sopenharmony_ci#define dp_ack_seq dp_cmn.ricpc_ack_seq 948c2ecf20Sopenharmony_ci#define dp_credit dp_cmn.ricpc_credit 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ciunion rds_ib_conn_priv { 978c2ecf20Sopenharmony_ci struct rds_ib_connect_private ricp_v4; 988c2ecf20Sopenharmony_ci struct rds6_ib_connect_private ricp_v6; 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistruct rds_ib_send_work { 1028c2ecf20Sopenharmony_ci void *s_op; 1038c2ecf20Sopenharmony_ci union { 1048c2ecf20Sopenharmony_ci struct ib_send_wr s_wr; 1058c2ecf20Sopenharmony_ci struct ib_rdma_wr s_rdma_wr; 1068c2ecf20Sopenharmony_ci struct ib_atomic_wr s_atomic_wr; 1078c2ecf20Sopenharmony_ci }; 1088c2ecf20Sopenharmony_ci struct ib_sge s_sge[RDS_IB_MAX_SGE]; 1098c2ecf20Sopenharmony_ci unsigned long s_queued; 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistruct rds_ib_recv_work { 1138c2ecf20Sopenharmony_ci struct rds_ib_incoming *r_ibinc; 1148c2ecf20Sopenharmony_ci struct rds_page_frag *r_frag; 1158c2ecf20Sopenharmony_ci struct ib_recv_wr r_wr; 1168c2ecf20Sopenharmony_ci struct ib_sge r_sge[2]; 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistruct rds_ib_work_ring { 1208c2ecf20Sopenharmony_ci u32 w_nr; 1218c2ecf20Sopenharmony_ci u32 w_alloc_ptr; 1228c2ecf20Sopenharmony_ci u32 w_alloc_ctr; 1238c2ecf20Sopenharmony_ci u32 w_free_ptr; 1248c2ecf20Sopenharmony_ci atomic_t w_free_ctr; 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci/* Rings are posted with all the allocations they'll need to queue the 1288c2ecf20Sopenharmony_ci * incoming message to the receiving socket so this can't fail. 1298c2ecf20Sopenharmony_ci * All fragments start with a header, so we can make sure we're not receiving 1308c2ecf20Sopenharmony_ci * garbage, and we can tell a small 8 byte fragment from an ACK frame. 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_cistruct rds_ib_ack_state { 1338c2ecf20Sopenharmony_ci u64 ack_next; 1348c2ecf20Sopenharmony_ci u64 ack_recv; 1358c2ecf20Sopenharmony_ci unsigned int ack_required:1; 1368c2ecf20Sopenharmony_ci unsigned int ack_next_valid:1; 1378c2ecf20Sopenharmony_ci unsigned int ack_recv_valid:1; 1388c2ecf20Sopenharmony_ci}; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistruct rds_ib_device; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistruct rds_ib_connection { 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci struct list_head ib_node; 1468c2ecf20Sopenharmony_ci struct rds_ib_device *rds_ibdev; 1478c2ecf20Sopenharmony_ci struct rds_connection *conn; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci /* alphabet soup, IBTA style */ 1508c2ecf20Sopenharmony_ci struct rdma_cm_id *i_cm_id; 1518c2ecf20Sopenharmony_ci struct ib_pd *i_pd; 1528c2ecf20Sopenharmony_ci struct ib_cq *i_send_cq; 1538c2ecf20Sopenharmony_ci struct ib_cq *i_recv_cq; 1548c2ecf20Sopenharmony_ci struct ib_wc i_send_wc[RDS_IB_WC_MAX]; 1558c2ecf20Sopenharmony_ci struct ib_wc i_recv_wc[RDS_IB_WC_MAX]; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci /* To control the number of wrs from fastreg */ 1588c2ecf20Sopenharmony_ci atomic_t i_fastreg_wrs; 1598c2ecf20Sopenharmony_ci atomic_t i_fastreg_inuse_count; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci /* interrupt handling */ 1628c2ecf20Sopenharmony_ci struct tasklet_struct i_send_tasklet; 1638c2ecf20Sopenharmony_ci struct tasklet_struct i_recv_tasklet; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci /* tx */ 1668c2ecf20Sopenharmony_ci struct rds_ib_work_ring i_send_ring; 1678c2ecf20Sopenharmony_ci struct rm_data_op *i_data_op; 1688c2ecf20Sopenharmony_ci struct rds_header **i_send_hdrs; 1698c2ecf20Sopenharmony_ci dma_addr_t *i_send_hdrs_dma; 1708c2ecf20Sopenharmony_ci struct rds_ib_send_work *i_sends; 1718c2ecf20Sopenharmony_ci atomic_t i_signaled_sends; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci /* rx */ 1748c2ecf20Sopenharmony_ci struct mutex i_recv_mutex; 1758c2ecf20Sopenharmony_ci struct rds_ib_work_ring i_recv_ring; 1768c2ecf20Sopenharmony_ci struct rds_ib_incoming *i_ibinc; 1778c2ecf20Sopenharmony_ci u32 i_recv_data_rem; 1788c2ecf20Sopenharmony_ci struct rds_header **i_recv_hdrs; 1798c2ecf20Sopenharmony_ci dma_addr_t *i_recv_hdrs_dma; 1808c2ecf20Sopenharmony_ci struct rds_ib_recv_work *i_recvs; 1818c2ecf20Sopenharmony_ci u64 i_ack_recv; /* last ACK received */ 1828c2ecf20Sopenharmony_ci struct rds_ib_refill_cache i_cache_incs; 1838c2ecf20Sopenharmony_ci struct rds_ib_refill_cache i_cache_frags; 1848c2ecf20Sopenharmony_ci atomic_t i_cache_allocs; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci /* sending acks */ 1878c2ecf20Sopenharmony_ci unsigned long i_ack_flags; 1888c2ecf20Sopenharmony_ci#ifdef KERNEL_HAS_ATOMIC64 1898c2ecf20Sopenharmony_ci atomic64_t i_ack_next; /* next ACK to send */ 1908c2ecf20Sopenharmony_ci#else 1918c2ecf20Sopenharmony_ci spinlock_t i_ack_lock; /* protect i_ack_next */ 1928c2ecf20Sopenharmony_ci u64 i_ack_next; /* next ACK to send */ 1938c2ecf20Sopenharmony_ci#endif 1948c2ecf20Sopenharmony_ci struct rds_header *i_ack; 1958c2ecf20Sopenharmony_ci struct ib_send_wr i_ack_wr; 1968c2ecf20Sopenharmony_ci struct ib_sge i_ack_sge; 1978c2ecf20Sopenharmony_ci dma_addr_t i_ack_dma; 1988c2ecf20Sopenharmony_ci unsigned long i_ack_queued; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* Flow control related information 2018c2ecf20Sopenharmony_ci * 2028c2ecf20Sopenharmony_ci * Our algorithm uses a pair variables that we need to access 2038c2ecf20Sopenharmony_ci * atomically - one for the send credits, and one posted 2048c2ecf20Sopenharmony_ci * recv credits we need to transfer to remote. 2058c2ecf20Sopenharmony_ci * Rather than protect them using a slow spinlock, we put both into 2068c2ecf20Sopenharmony_ci * a single atomic_t and update it using cmpxchg 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci atomic_t i_credits; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci /* Protocol version specific information */ 2118c2ecf20Sopenharmony_ci unsigned int i_flowctl:1; /* enable/disable flow ctl */ 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci /* Batched completions */ 2148c2ecf20Sopenharmony_ci unsigned int i_unsignaled_wrs; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* Endpoint role in connection */ 2178c2ecf20Sopenharmony_ci bool i_active_side; 2188c2ecf20Sopenharmony_ci atomic_t i_cq_quiesce; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* Send/Recv vectors */ 2218c2ecf20Sopenharmony_ci int i_scq_vector; 2228c2ecf20Sopenharmony_ci int i_rcq_vector; 2238c2ecf20Sopenharmony_ci u8 i_sl; 2248c2ecf20Sopenharmony_ci}; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci/* This assumes that atomic_t is at least 32 bits */ 2278c2ecf20Sopenharmony_ci#define IB_GET_SEND_CREDITS(v) ((v) & 0xffff) 2288c2ecf20Sopenharmony_ci#define IB_GET_POST_CREDITS(v) ((v) >> 16) 2298c2ecf20Sopenharmony_ci#define IB_SET_SEND_CREDITS(v) ((v) & 0xffff) 2308c2ecf20Sopenharmony_ci#define IB_SET_POST_CREDITS(v) ((v) << 16) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistruct rds_ib_ipaddr { 2338c2ecf20Sopenharmony_ci struct list_head list; 2348c2ecf20Sopenharmony_ci __be32 ipaddr; 2358c2ecf20Sopenharmony_ci struct rcu_head rcu; 2368c2ecf20Sopenharmony_ci}; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cienum { 2398c2ecf20Sopenharmony_ci RDS_IB_MR_8K_POOL, 2408c2ecf20Sopenharmony_ci RDS_IB_MR_1M_POOL, 2418c2ecf20Sopenharmony_ci}; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistruct rds_ib_device { 2448c2ecf20Sopenharmony_ci struct list_head list; 2458c2ecf20Sopenharmony_ci struct list_head ipaddr_list; 2468c2ecf20Sopenharmony_ci struct list_head conn_list; 2478c2ecf20Sopenharmony_ci struct ib_device *dev; 2488c2ecf20Sopenharmony_ci struct ib_pd *pd; 2498c2ecf20Sopenharmony_ci u8 odp_capable:1; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci unsigned int max_mrs; 2528c2ecf20Sopenharmony_ci struct rds_ib_mr_pool *mr_1m_pool; 2538c2ecf20Sopenharmony_ci struct rds_ib_mr_pool *mr_8k_pool; 2548c2ecf20Sopenharmony_ci unsigned int max_8k_mrs; 2558c2ecf20Sopenharmony_ci unsigned int max_1m_mrs; 2568c2ecf20Sopenharmony_ci int max_sge; 2578c2ecf20Sopenharmony_ci unsigned int max_wrs; 2588c2ecf20Sopenharmony_ci unsigned int max_initiator_depth; 2598c2ecf20Sopenharmony_ci unsigned int max_responder_resources; 2608c2ecf20Sopenharmony_ci spinlock_t spinlock; /* protect the above */ 2618c2ecf20Sopenharmony_ci refcount_t refcount; 2628c2ecf20Sopenharmony_ci struct work_struct free_work; 2638c2ecf20Sopenharmony_ci int *vector_load; 2648c2ecf20Sopenharmony_ci}; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci#define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/* bits for i_ack_flags */ 2698c2ecf20Sopenharmony_ci#define IB_ACK_IN_FLIGHT 0 2708c2ecf20Sopenharmony_ci#define IB_ACK_REQUESTED 1 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci/* Magic WR_ID for ACKs */ 2738c2ecf20Sopenharmony_ci#define RDS_IB_ACK_WR_ID (~(u64) 0) 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistruct rds_ib_statistics { 2768c2ecf20Sopenharmony_ci uint64_t s_ib_connect_raced; 2778c2ecf20Sopenharmony_ci uint64_t s_ib_listen_closed_stale; 2788c2ecf20Sopenharmony_ci uint64_t s_ib_evt_handler_call; 2798c2ecf20Sopenharmony_ci uint64_t s_ib_tasklet_call; 2808c2ecf20Sopenharmony_ci uint64_t s_ib_tx_cq_event; 2818c2ecf20Sopenharmony_ci uint64_t s_ib_tx_ring_full; 2828c2ecf20Sopenharmony_ci uint64_t s_ib_tx_throttle; 2838c2ecf20Sopenharmony_ci uint64_t s_ib_tx_sg_mapping_failure; 2848c2ecf20Sopenharmony_ci uint64_t s_ib_tx_stalled; 2858c2ecf20Sopenharmony_ci uint64_t s_ib_tx_credit_updates; 2868c2ecf20Sopenharmony_ci uint64_t s_ib_rx_cq_event; 2878c2ecf20Sopenharmony_ci uint64_t s_ib_rx_ring_empty; 2888c2ecf20Sopenharmony_ci uint64_t s_ib_rx_refill_from_cq; 2898c2ecf20Sopenharmony_ci uint64_t s_ib_rx_refill_from_thread; 2908c2ecf20Sopenharmony_ci uint64_t s_ib_rx_alloc_limit; 2918c2ecf20Sopenharmony_ci uint64_t s_ib_rx_total_frags; 2928c2ecf20Sopenharmony_ci uint64_t s_ib_rx_total_incs; 2938c2ecf20Sopenharmony_ci uint64_t s_ib_rx_credit_updates; 2948c2ecf20Sopenharmony_ci uint64_t s_ib_ack_sent; 2958c2ecf20Sopenharmony_ci uint64_t s_ib_ack_send_failure; 2968c2ecf20Sopenharmony_ci uint64_t s_ib_ack_send_delayed; 2978c2ecf20Sopenharmony_ci uint64_t s_ib_ack_send_piggybacked; 2988c2ecf20Sopenharmony_ci uint64_t s_ib_ack_received; 2998c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_alloc; 3008c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_free; 3018c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_used; 3028c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_pool_flush; 3038c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_pool_wait; 3048c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_pool_depleted; 3058c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_alloc; 3068c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_free; 3078c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_used; 3088c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_pool_flush; 3098c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_pool_wait; 3108c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_pool_depleted; 3118c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_8k_reused; 3128c2ecf20Sopenharmony_ci uint64_t s_ib_rdma_mr_1m_reused; 3138c2ecf20Sopenharmony_ci uint64_t s_ib_atomic_cswp; 3148c2ecf20Sopenharmony_ci uint64_t s_ib_atomic_fadd; 3158c2ecf20Sopenharmony_ci uint64_t s_ib_recv_added_to_cache; 3168c2ecf20Sopenharmony_ci uint64_t s_ib_recv_removed_from_cache; 3178c2ecf20Sopenharmony_ci}; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ciextern struct workqueue_struct *rds_ib_wq; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* 3228c2ecf20Sopenharmony_ci * Fake ib_dma_sync_sg_for_{cpu,device} as long as ib_verbs.h 3238c2ecf20Sopenharmony_ci * doesn't define it. 3248c2ecf20Sopenharmony_ci */ 3258c2ecf20Sopenharmony_cistatic inline void rds_ib_dma_sync_sg_for_cpu(struct ib_device *dev, 3268c2ecf20Sopenharmony_ci struct scatterlist *sglist, 3278c2ecf20Sopenharmony_ci unsigned int sg_dma_len, 3288c2ecf20Sopenharmony_ci int direction) 3298c2ecf20Sopenharmony_ci{ 3308c2ecf20Sopenharmony_ci struct scatterlist *sg; 3318c2ecf20Sopenharmony_ci unsigned int i; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci for_each_sg(sglist, sg, sg_dma_len, i) { 3348c2ecf20Sopenharmony_ci ib_dma_sync_single_for_cpu(dev, sg_dma_address(sg), 3358c2ecf20Sopenharmony_ci sg_dma_len(sg), direction); 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci#define ib_dma_sync_sg_for_cpu rds_ib_dma_sync_sg_for_cpu 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic inline void rds_ib_dma_sync_sg_for_device(struct ib_device *dev, 3418c2ecf20Sopenharmony_ci struct scatterlist *sglist, 3428c2ecf20Sopenharmony_ci unsigned int sg_dma_len, 3438c2ecf20Sopenharmony_ci int direction) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci struct scatterlist *sg; 3468c2ecf20Sopenharmony_ci unsigned int i; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci for_each_sg(sglist, sg, sg_dma_len, i) { 3498c2ecf20Sopenharmony_ci ib_dma_sync_single_for_device(dev, sg_dma_address(sg), 3508c2ecf20Sopenharmony_ci sg_dma_len(sg), direction); 3518c2ecf20Sopenharmony_ci } 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci#define ib_dma_sync_sg_for_device rds_ib_dma_sync_sg_for_device 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci/* ib.c */ 3578c2ecf20Sopenharmony_ciextern struct rds_transport rds_ib_transport; 3588c2ecf20Sopenharmony_cistruct rds_ib_device *rds_ib_get_client_data(struct ib_device *device); 3598c2ecf20Sopenharmony_civoid rds_ib_dev_put(struct rds_ib_device *rds_ibdev); 3608c2ecf20Sopenharmony_ciextern struct ib_client rds_ib_client; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ciextern unsigned int rds_ib_retry_count; 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ciextern spinlock_t ib_nodev_conns_lock; 3658c2ecf20Sopenharmony_ciextern struct list_head ib_nodev_conns; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci/* ib_cm.c */ 3688c2ecf20Sopenharmony_ciint rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp); 3698c2ecf20Sopenharmony_civoid rds_ib_conn_free(void *arg); 3708c2ecf20Sopenharmony_ciint rds_ib_conn_path_connect(struct rds_conn_path *cp); 3718c2ecf20Sopenharmony_civoid rds_ib_conn_path_shutdown(struct rds_conn_path *cp); 3728c2ecf20Sopenharmony_civoid rds_ib_state_change(struct sock *sk); 3738c2ecf20Sopenharmony_ciint rds_ib_listen_init(void); 3748c2ecf20Sopenharmony_civoid rds_ib_listen_stop(void); 3758c2ecf20Sopenharmony_ci__printf(2, 3) 3768c2ecf20Sopenharmony_civoid __rds_ib_conn_error(struct rds_connection *conn, const char *, ...); 3778c2ecf20Sopenharmony_ciint rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, 3788c2ecf20Sopenharmony_ci struct rdma_cm_event *event, bool isv6); 3798c2ecf20Sopenharmony_ciint rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id, bool isv6); 3808c2ecf20Sopenharmony_civoid rds_ib_cm_connect_complete(struct rds_connection *conn, 3818c2ecf20Sopenharmony_ci struct rdma_cm_event *event); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci#define rds_ib_conn_error(conn, fmt...) \ 3848c2ecf20Sopenharmony_ci __rds_ib_conn_error(conn, KERN_WARNING "RDS/IB: " fmt) 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci/* ib_rdma.c */ 3878c2ecf20Sopenharmony_ciint rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, 3888c2ecf20Sopenharmony_ci struct in6_addr *ipaddr); 3898c2ecf20Sopenharmony_civoid rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); 3908c2ecf20Sopenharmony_civoid rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); 3918c2ecf20Sopenharmony_civoid rds_ib_destroy_nodev_conns(void); 3928c2ecf20Sopenharmony_civoid rds_ib_mr_cqe_handler(struct rds_ib_connection *ic, struct ib_wc *wc); 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci/* ib_recv.c */ 3958c2ecf20Sopenharmony_ciint rds_ib_recv_init(void); 3968c2ecf20Sopenharmony_civoid rds_ib_recv_exit(void); 3978c2ecf20Sopenharmony_ciint rds_ib_recv_path(struct rds_conn_path *conn); 3988c2ecf20Sopenharmony_ciint rds_ib_recv_alloc_caches(struct rds_ib_connection *ic, gfp_t gfp); 3998c2ecf20Sopenharmony_civoid rds_ib_recv_free_caches(struct rds_ib_connection *ic); 4008c2ecf20Sopenharmony_civoid rds_ib_recv_refill(struct rds_connection *conn, int prefill, gfp_t gfp); 4018c2ecf20Sopenharmony_civoid rds_ib_inc_free(struct rds_incoming *inc); 4028c2ecf20Sopenharmony_ciint rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); 4038c2ecf20Sopenharmony_civoid rds_ib_recv_cqe_handler(struct rds_ib_connection *ic, struct ib_wc *wc, 4048c2ecf20Sopenharmony_ci struct rds_ib_ack_state *state); 4058c2ecf20Sopenharmony_civoid rds_ib_recv_tasklet_fn(unsigned long data); 4068c2ecf20Sopenharmony_civoid rds_ib_recv_init_ring(struct rds_ib_connection *ic); 4078c2ecf20Sopenharmony_civoid rds_ib_recv_clear_ring(struct rds_ib_connection *ic); 4088c2ecf20Sopenharmony_civoid rds_ib_recv_init_ack(struct rds_ib_connection *ic); 4098c2ecf20Sopenharmony_civoid rds_ib_attempt_ack(struct rds_ib_connection *ic); 4108c2ecf20Sopenharmony_civoid rds_ib_ack_send_complete(struct rds_ib_connection *ic); 4118c2ecf20Sopenharmony_ciu64 rds_ib_piggyb_ack(struct rds_ib_connection *ic); 4128c2ecf20Sopenharmony_civoid rds_ib_set_ack(struct rds_ib_connection *ic, u64 seq, int ack_required); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci/* ib_ring.c */ 4158c2ecf20Sopenharmony_civoid rds_ib_ring_init(struct rds_ib_work_ring *ring, u32 nr); 4168c2ecf20Sopenharmony_civoid rds_ib_ring_resize(struct rds_ib_work_ring *ring, u32 nr); 4178c2ecf20Sopenharmony_ciu32 rds_ib_ring_alloc(struct rds_ib_work_ring *ring, u32 val, u32 *pos); 4188c2ecf20Sopenharmony_civoid rds_ib_ring_free(struct rds_ib_work_ring *ring, u32 val); 4198c2ecf20Sopenharmony_civoid rds_ib_ring_unalloc(struct rds_ib_work_ring *ring, u32 val); 4208c2ecf20Sopenharmony_ciint rds_ib_ring_empty(struct rds_ib_work_ring *ring); 4218c2ecf20Sopenharmony_ciint rds_ib_ring_low(struct rds_ib_work_ring *ring); 4228c2ecf20Sopenharmony_ciu32 rds_ib_ring_oldest(struct rds_ib_work_ring *ring); 4238c2ecf20Sopenharmony_ciu32 rds_ib_ring_completed(struct rds_ib_work_ring *ring, u32 wr_id, u32 oldest); 4248c2ecf20Sopenharmony_ciextern wait_queue_head_t rds_ib_ring_empty_wait; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci/* ib_send.c */ 4278c2ecf20Sopenharmony_civoid rds_ib_xmit_path_complete(struct rds_conn_path *cp); 4288c2ecf20Sopenharmony_ciint rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, 4298c2ecf20Sopenharmony_ci unsigned int hdr_off, unsigned int sg, unsigned int off); 4308c2ecf20Sopenharmony_civoid rds_ib_send_cqe_handler(struct rds_ib_connection *ic, struct ib_wc *wc); 4318c2ecf20Sopenharmony_civoid rds_ib_send_init_ring(struct rds_ib_connection *ic); 4328c2ecf20Sopenharmony_civoid rds_ib_send_clear_ring(struct rds_ib_connection *ic); 4338c2ecf20Sopenharmony_ciint rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op); 4348c2ecf20Sopenharmony_civoid rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); 4358c2ecf20Sopenharmony_civoid rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); 4368c2ecf20Sopenharmony_ciint rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, 4378c2ecf20Sopenharmony_ci u32 *adv_credits, int need_posted, int max_posted); 4388c2ecf20Sopenharmony_ciint rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci/* ib_stats.c */ 4418c2ecf20Sopenharmony_ciDECLARE_PER_CPU_SHARED_ALIGNED(struct rds_ib_statistics, rds_ib_stats); 4428c2ecf20Sopenharmony_ci#define rds_ib_stats_inc(member) rds_stats_inc_which(rds_ib_stats, member) 4438c2ecf20Sopenharmony_ci#define rds_ib_stats_add(member, count) \ 4448c2ecf20Sopenharmony_ci rds_stats_add_which(rds_ib_stats, member, count) 4458c2ecf20Sopenharmony_ciunsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter, 4468c2ecf20Sopenharmony_ci unsigned int avail); 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci/* ib_sysctl.c */ 4498c2ecf20Sopenharmony_ciint rds_ib_sysctl_init(void); 4508c2ecf20Sopenharmony_civoid rds_ib_sysctl_exit(void); 4518c2ecf20Sopenharmony_ciextern unsigned long rds_ib_sysctl_max_send_wr; 4528c2ecf20Sopenharmony_ciextern unsigned long rds_ib_sysctl_max_recv_wr; 4538c2ecf20Sopenharmony_ciextern unsigned long rds_ib_sysctl_max_unsig_wrs; 4548c2ecf20Sopenharmony_ciextern unsigned long rds_ib_sysctl_max_unsig_bytes; 4558c2ecf20Sopenharmony_ciextern unsigned long rds_ib_sysctl_max_recv_allocation; 4568c2ecf20Sopenharmony_ciextern unsigned int rds_ib_sysctl_flow_control; 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci#endif 459