18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Shared Memory Communications over RDMA (SMC-R) and RoCE 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Definitions for SMC Connections, Link Groups and Links 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2016 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com> 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifndef _SMC_CORE_H 138c2ecf20Sopenharmony_ci#define _SMC_CORE_H 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/atomic.h> 168c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "smc.h" 198c2ecf20Sopenharmony_ci#include "smc_ib.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define SMC_RMBS_PER_LGR_MAX 255 /* max. # of RMBs per link group */ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct smc_lgr_list { /* list of link group definition */ 248c2ecf20Sopenharmony_ci struct list_head list; 258c2ecf20Sopenharmony_ci spinlock_t lock; /* protects list of link groups */ 268c2ecf20Sopenharmony_ci u32 num; /* unique link group number */ 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cienum smc_lgr_role { /* possible roles of a link group */ 308c2ecf20Sopenharmony_ci SMC_CLNT, /* client */ 318c2ecf20Sopenharmony_ci SMC_SERV /* server */ 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cienum smc_link_state { /* possible states of a link */ 358c2ecf20Sopenharmony_ci SMC_LNK_UNUSED, /* link is unused */ 368c2ecf20Sopenharmony_ci SMC_LNK_INACTIVE, /* link is inactive */ 378c2ecf20Sopenharmony_ci SMC_LNK_ACTIVATING, /* link is being activated */ 388c2ecf20Sopenharmony_ci SMC_LNK_ACTIVE, /* link is active */ 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define SMC_WR_BUF_SIZE 48 /* size of work request buffer */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct smc_wr_buf { 448c2ecf20Sopenharmony_ci u8 raw[SMC_WR_BUF_SIZE]; 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define SMC_WR_REG_MR_WAIT_TIME (5 * HZ)/* wait time for ib_wr_reg_mr result */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cienum smc_wr_reg_state { 508c2ecf20Sopenharmony_ci POSTED, /* ib_wr_reg_mr request posted */ 518c2ecf20Sopenharmony_ci CONFIRMED, /* ib_wr_reg_mr response: successful */ 528c2ecf20Sopenharmony_ci FAILED /* ib_wr_reg_mr response: failure */ 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct smc_rdma_sge { /* sges for RDMA writes */ 568c2ecf20Sopenharmony_ci struct ib_sge wr_tx_rdma_sge[SMC_IB_MAX_SEND_SGE]; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define SMC_MAX_RDMA_WRITES 2 /* max. # of RDMA writes per 608c2ecf20Sopenharmony_ci * message send 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct smc_rdma_sges { /* sges per message send */ 648c2ecf20Sopenharmony_ci struct smc_rdma_sge tx_rdma_sge[SMC_MAX_RDMA_WRITES]; 658c2ecf20Sopenharmony_ci}; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistruct smc_rdma_wr { /* work requests per message 688c2ecf20Sopenharmony_ci * send 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci struct ib_rdma_wr wr_tx_rdma[SMC_MAX_RDMA_WRITES]; 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#define SMC_LGR_ID_SIZE 4 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct smc_link { 768c2ecf20Sopenharmony_ci struct smc_ib_device *smcibdev; /* ib-device */ 778c2ecf20Sopenharmony_ci u8 ibport; /* port - values 1 | 2 */ 788c2ecf20Sopenharmony_ci struct ib_pd *roce_pd; /* IB protection domain, 798c2ecf20Sopenharmony_ci * unique for every RoCE QP 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci struct ib_qp *roce_qp; /* IB queue pair */ 828c2ecf20Sopenharmony_ci struct ib_qp_attr qp_attr; /* IB queue pair attributes */ 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci struct smc_wr_buf *wr_tx_bufs; /* WR send payload buffers */ 858c2ecf20Sopenharmony_ci struct ib_send_wr *wr_tx_ibs; /* WR send meta data */ 868c2ecf20Sopenharmony_ci struct ib_sge *wr_tx_sges; /* WR send gather meta data */ 878c2ecf20Sopenharmony_ci struct smc_rdma_sges *wr_tx_rdma_sges;/*RDMA WRITE gather meta data*/ 888c2ecf20Sopenharmony_ci struct smc_rdma_wr *wr_tx_rdmas; /* WR RDMA WRITE */ 898c2ecf20Sopenharmony_ci struct smc_wr_tx_pend *wr_tx_pends; /* WR send waiting for CQE */ 908c2ecf20Sopenharmony_ci struct completion *wr_tx_compl; /* WR send CQE completion */ 918c2ecf20Sopenharmony_ci /* above four vectors have wr_tx_cnt elements and use the same index */ 928c2ecf20Sopenharmony_ci dma_addr_t wr_tx_dma_addr; /* DMA address of wr_tx_bufs */ 938c2ecf20Sopenharmony_ci atomic_long_t wr_tx_id; /* seq # of last sent WR */ 948c2ecf20Sopenharmony_ci unsigned long *wr_tx_mask; /* bit mask of used indexes */ 958c2ecf20Sopenharmony_ci u32 wr_tx_cnt; /* number of WR send buffers */ 968c2ecf20Sopenharmony_ci wait_queue_head_t wr_tx_wait; /* wait for free WR send buf */ 978c2ecf20Sopenharmony_ci atomic_t wr_tx_refcnt; /* tx refs to link */ 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci struct smc_wr_buf *wr_rx_bufs; /* WR recv payload buffers */ 1008c2ecf20Sopenharmony_ci struct ib_recv_wr *wr_rx_ibs; /* WR recv meta data */ 1018c2ecf20Sopenharmony_ci struct ib_sge *wr_rx_sges; /* WR recv scatter meta data */ 1028c2ecf20Sopenharmony_ci /* above three vectors have wr_rx_cnt elements and use the same index */ 1038c2ecf20Sopenharmony_ci dma_addr_t wr_rx_dma_addr; /* DMA address of wr_rx_bufs */ 1048c2ecf20Sopenharmony_ci u64 wr_rx_id; /* seq # of last recv WR */ 1058c2ecf20Sopenharmony_ci u32 wr_rx_cnt; /* number of WR recv buffers */ 1068c2ecf20Sopenharmony_ci unsigned long wr_rx_tstamp; /* jiffies when last buf rx */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci struct ib_reg_wr wr_reg; /* WR register memory region */ 1098c2ecf20Sopenharmony_ci wait_queue_head_t wr_reg_wait; /* wait for wr_reg result */ 1108c2ecf20Sopenharmony_ci atomic_t wr_reg_refcnt; /* reg refs to link */ 1118c2ecf20Sopenharmony_ci enum smc_wr_reg_state wr_reg_state; /* state of wr_reg request */ 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci u8 gid[SMC_GID_SIZE];/* gid matching used vlan id*/ 1148c2ecf20Sopenharmony_ci u8 sgid_index; /* gid index for vlan id */ 1158c2ecf20Sopenharmony_ci u32 peer_qpn; /* QP number of peer */ 1168c2ecf20Sopenharmony_ci enum ib_mtu path_mtu; /* used mtu */ 1178c2ecf20Sopenharmony_ci enum ib_mtu peer_mtu; /* mtu size of peer */ 1188c2ecf20Sopenharmony_ci u32 psn_initial; /* QP tx initial packet seqno */ 1198c2ecf20Sopenharmony_ci u32 peer_psn; /* QP rx initial packet seqno */ 1208c2ecf20Sopenharmony_ci u8 peer_mac[ETH_ALEN]; /* = gid[8:10||13:15] */ 1218c2ecf20Sopenharmony_ci u8 peer_gid[SMC_GID_SIZE]; /* gid of peer*/ 1228c2ecf20Sopenharmony_ci u8 link_id; /* unique # within link group */ 1238c2ecf20Sopenharmony_ci u8 link_uid[SMC_LGR_ID_SIZE]; /* unique lnk id */ 1248c2ecf20Sopenharmony_ci u8 peer_link_uid[SMC_LGR_ID_SIZE]; /* peer uid */ 1258c2ecf20Sopenharmony_ci u8 link_idx; /* index in lgr link array */ 1268c2ecf20Sopenharmony_ci u8 link_is_asym; /* is link asymmetric? */ 1278c2ecf20Sopenharmony_ci struct smc_link_group *lgr; /* parent link group */ 1288c2ecf20Sopenharmony_ci struct work_struct link_down_wrk; /* wrk to bring link down */ 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci enum smc_link_state state; /* state of link */ 1318c2ecf20Sopenharmony_ci struct delayed_work llc_testlink_wrk; /* testlink worker */ 1328c2ecf20Sopenharmony_ci struct completion llc_testlink_resp; /* wait for rx of testlink */ 1338c2ecf20Sopenharmony_ci int llc_testlink_time; /* testlink interval */ 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/* For now we just allow one parallel link per link group. The SMC protocol 1378c2ecf20Sopenharmony_ci * allows more (up to 8). 1388c2ecf20Sopenharmony_ci */ 1398c2ecf20Sopenharmony_ci#define SMC_LINKS_PER_LGR_MAX 3 1408c2ecf20Sopenharmony_ci#define SMC_SINGLE_LINK 0 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci/* tx/rx buffer list element for sndbufs list and rmbs list of a lgr */ 1438c2ecf20Sopenharmony_cistruct smc_buf_desc { 1448c2ecf20Sopenharmony_ci struct list_head list; 1458c2ecf20Sopenharmony_ci void *cpu_addr; /* virtual address of buffer */ 1468c2ecf20Sopenharmony_ci struct page *pages; 1478c2ecf20Sopenharmony_ci int len; /* length of buffer */ 1488c2ecf20Sopenharmony_ci u32 used; /* currently used / unused */ 1498c2ecf20Sopenharmony_ci union { 1508c2ecf20Sopenharmony_ci struct { /* SMC-R */ 1518c2ecf20Sopenharmony_ci struct sg_table sgt[SMC_LINKS_PER_LGR_MAX]; 1528c2ecf20Sopenharmony_ci /* virtual buffer */ 1538c2ecf20Sopenharmony_ci struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX]; 1548c2ecf20Sopenharmony_ci /* for rmb only: memory region 1558c2ecf20Sopenharmony_ci * incl. rkey provided to peer 1568c2ecf20Sopenharmony_ci */ 1578c2ecf20Sopenharmony_ci u32 order; /* allocation order */ 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci u8 is_conf_rkey; 1608c2ecf20Sopenharmony_ci /* confirm_rkey done */ 1618c2ecf20Sopenharmony_ci u8 is_reg_mr[SMC_LINKS_PER_LGR_MAX]; 1628c2ecf20Sopenharmony_ci /* mem region registered */ 1638c2ecf20Sopenharmony_ci u8 is_map_ib[SMC_LINKS_PER_LGR_MAX]; 1648c2ecf20Sopenharmony_ci /* mem region mapped to lnk */ 1658c2ecf20Sopenharmony_ci u8 is_reg_err; 1668c2ecf20Sopenharmony_ci /* buffer registration err */ 1678c2ecf20Sopenharmony_ci }; 1688c2ecf20Sopenharmony_ci struct { /* SMC-D */ 1698c2ecf20Sopenharmony_ci unsigned short sba_idx; 1708c2ecf20Sopenharmony_ci /* SBA index number */ 1718c2ecf20Sopenharmony_ci u64 token; 1728c2ecf20Sopenharmony_ci /* DMB token number */ 1738c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 1748c2ecf20Sopenharmony_ci /* DMA address */ 1758c2ecf20Sopenharmony_ci }; 1768c2ecf20Sopenharmony_ci }; 1778c2ecf20Sopenharmony_ci}; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_cistruct smc_rtoken { /* address/key of remote RMB */ 1808c2ecf20Sopenharmony_ci u64 dma_addr; 1818c2ecf20Sopenharmony_ci u32 rkey; 1828c2ecf20Sopenharmony_ci}; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#define SMC_BUF_MIN_SIZE 16384 /* minimum size of an RMB */ 1858c2ecf20Sopenharmony_ci#define SMC_RMBE_SIZES 16 /* number of distinct RMBE sizes */ 1868c2ecf20Sopenharmony_ci/* theoretically, the RFC states that largest size would be 512K, 1878c2ecf20Sopenharmony_ci * i.e. compressed 5 and thus 6 sizes (0..5), despite 1888c2ecf20Sopenharmony_ci * struct smc_clc_msg_accept_confirm.rmbe_size being a 4 bit value (0..15) 1898c2ecf20Sopenharmony_ci */ 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistruct smcd_dev; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cienum smc_lgr_type { /* redundancy state of lgr */ 1948c2ecf20Sopenharmony_ci SMC_LGR_NONE, /* no active links, lgr to be deleted */ 1958c2ecf20Sopenharmony_ci SMC_LGR_SINGLE, /* 1 active RNIC on each peer */ 1968c2ecf20Sopenharmony_ci SMC_LGR_SYMMETRIC, /* 2 active RNICs on each peer */ 1978c2ecf20Sopenharmony_ci SMC_LGR_ASYMMETRIC_PEER, /* local has 2, peer 1 active RNICs */ 1988c2ecf20Sopenharmony_ci SMC_LGR_ASYMMETRIC_LOCAL, /* local has 1, peer 2 active RNICs */ 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cienum smc_llc_flowtype { 2028c2ecf20Sopenharmony_ci SMC_LLC_FLOW_NONE = 0, 2038c2ecf20Sopenharmony_ci SMC_LLC_FLOW_ADD_LINK = 2, 2048c2ecf20Sopenharmony_ci SMC_LLC_FLOW_DEL_LINK = 4, 2058c2ecf20Sopenharmony_ci SMC_LLC_FLOW_RKEY = 6, 2068c2ecf20Sopenharmony_ci}; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistruct smc_llc_qentry; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistruct smc_llc_flow { 2118c2ecf20Sopenharmony_ci enum smc_llc_flowtype type; 2128c2ecf20Sopenharmony_ci struct smc_llc_qentry *qentry; 2138c2ecf20Sopenharmony_ci}; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistruct smc_link_group { 2168c2ecf20Sopenharmony_ci struct list_head list; 2178c2ecf20Sopenharmony_ci struct rb_root conns_all; /* connection tree */ 2188c2ecf20Sopenharmony_ci rwlock_t conns_lock; /* protects conns_all */ 2198c2ecf20Sopenharmony_ci unsigned int conns_num; /* current # of connections */ 2208c2ecf20Sopenharmony_ci unsigned short vlan_id; /* vlan id of link group */ 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci struct list_head sndbufs[SMC_RMBE_SIZES];/* tx buffers */ 2238c2ecf20Sopenharmony_ci struct mutex sndbufs_lock; /* protects tx buffers */ 2248c2ecf20Sopenharmony_ci struct list_head rmbs[SMC_RMBE_SIZES]; /* rx buffers */ 2258c2ecf20Sopenharmony_ci struct mutex rmbs_lock; /* protects rx buffers */ 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci u8 id[SMC_LGR_ID_SIZE]; /* unique lgr id */ 2288c2ecf20Sopenharmony_ci struct delayed_work free_work; /* delayed freeing of an lgr */ 2298c2ecf20Sopenharmony_ci struct work_struct terminate_work; /* abnormal lgr termination */ 2308c2ecf20Sopenharmony_ci struct workqueue_struct *tx_wq; /* wq for conn. tx workers */ 2318c2ecf20Sopenharmony_ci u8 sync_err : 1; /* lgr no longer fits to peer */ 2328c2ecf20Sopenharmony_ci u8 terminating : 1;/* lgr is terminating */ 2338c2ecf20Sopenharmony_ci u8 freeing : 1; /* lgr is being freed */ 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci bool is_smcd; /* SMC-R or SMC-D */ 2368c2ecf20Sopenharmony_ci u8 smc_version; 2378c2ecf20Sopenharmony_ci u8 negotiated_eid[SMC_MAX_EID_LEN]; 2388c2ecf20Sopenharmony_ci u8 peer_os; /* peer operating system */ 2398c2ecf20Sopenharmony_ci u8 peer_smc_release; 2408c2ecf20Sopenharmony_ci u8 peer_hostname[SMC_MAX_HOSTNAME_LEN]; 2418c2ecf20Sopenharmony_ci union { 2428c2ecf20Sopenharmony_ci struct { /* SMC-R */ 2438c2ecf20Sopenharmony_ci enum smc_lgr_role role; 2448c2ecf20Sopenharmony_ci /* client or server */ 2458c2ecf20Sopenharmony_ci struct smc_link lnk[SMC_LINKS_PER_LGR_MAX]; 2468c2ecf20Sopenharmony_ci /* smc link */ 2478c2ecf20Sopenharmony_ci char peer_systemid[SMC_SYSTEMID_LEN]; 2488c2ecf20Sopenharmony_ci /* unique system_id of peer */ 2498c2ecf20Sopenharmony_ci struct smc_rtoken rtokens[SMC_RMBS_PER_LGR_MAX] 2508c2ecf20Sopenharmony_ci [SMC_LINKS_PER_LGR_MAX]; 2518c2ecf20Sopenharmony_ci /* remote addr/key pairs */ 2528c2ecf20Sopenharmony_ci DECLARE_BITMAP(rtokens_used_mask, SMC_RMBS_PER_LGR_MAX); 2538c2ecf20Sopenharmony_ci /* used rtoken elements */ 2548c2ecf20Sopenharmony_ci u8 next_link_id; 2558c2ecf20Sopenharmony_ci enum smc_lgr_type type; 2568c2ecf20Sopenharmony_ci /* redundancy state */ 2578c2ecf20Sopenharmony_ci u8 pnet_id[SMC_MAX_PNETID_LEN + 1]; 2588c2ecf20Sopenharmony_ci /* pnet id of this lgr */ 2598c2ecf20Sopenharmony_ci struct list_head llc_event_q; 2608c2ecf20Sopenharmony_ci /* queue for llc events */ 2618c2ecf20Sopenharmony_ci spinlock_t llc_event_q_lock; 2628c2ecf20Sopenharmony_ci /* protects llc_event_q */ 2638c2ecf20Sopenharmony_ci struct mutex llc_conf_mutex; 2648c2ecf20Sopenharmony_ci /* protects lgr reconfig. */ 2658c2ecf20Sopenharmony_ci struct work_struct llc_add_link_work; 2668c2ecf20Sopenharmony_ci struct work_struct llc_del_link_work; 2678c2ecf20Sopenharmony_ci struct work_struct llc_event_work; 2688c2ecf20Sopenharmony_ci /* llc event worker */ 2698c2ecf20Sopenharmony_ci wait_queue_head_t llc_flow_waiter; 2708c2ecf20Sopenharmony_ci /* w4 next llc event */ 2718c2ecf20Sopenharmony_ci wait_queue_head_t llc_msg_waiter; 2728c2ecf20Sopenharmony_ci /* w4 next llc msg */ 2738c2ecf20Sopenharmony_ci struct smc_llc_flow llc_flow_lcl; 2748c2ecf20Sopenharmony_ci /* llc local control field */ 2758c2ecf20Sopenharmony_ci struct smc_llc_flow llc_flow_rmt; 2768c2ecf20Sopenharmony_ci /* llc remote control field */ 2778c2ecf20Sopenharmony_ci struct smc_llc_qentry *delayed_event; 2788c2ecf20Sopenharmony_ci /* arrived when flow active */ 2798c2ecf20Sopenharmony_ci spinlock_t llc_flow_lock; 2808c2ecf20Sopenharmony_ci /* protects llc flow */ 2818c2ecf20Sopenharmony_ci int llc_testlink_time; 2828c2ecf20Sopenharmony_ci /* link keep alive time */ 2838c2ecf20Sopenharmony_ci u32 llc_termination_rsn; 2848c2ecf20Sopenharmony_ci /* rsn code for termination */ 2858c2ecf20Sopenharmony_ci }; 2868c2ecf20Sopenharmony_ci struct { /* SMC-D */ 2878c2ecf20Sopenharmony_ci u64 peer_gid; 2888c2ecf20Sopenharmony_ci /* Peer GID (remote) */ 2898c2ecf20Sopenharmony_ci struct smcd_dev *smcd; 2908c2ecf20Sopenharmony_ci /* ISM device for VLAN reg. */ 2918c2ecf20Sopenharmony_ci u8 peer_shutdown : 1; 2928c2ecf20Sopenharmony_ci /* peer triggered shutdownn */ 2938c2ecf20Sopenharmony_ci }; 2948c2ecf20Sopenharmony_ci }; 2958c2ecf20Sopenharmony_ci}; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistruct smc_clc_msg_local; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistruct smc_init_info { 3008c2ecf20Sopenharmony_ci u8 is_smcd; 3018c2ecf20Sopenharmony_ci u8 smc_type_v1; 3028c2ecf20Sopenharmony_ci u8 smc_type_v2; 3038c2ecf20Sopenharmony_ci u8 first_contact_peer; 3048c2ecf20Sopenharmony_ci u8 first_contact_local; 3058c2ecf20Sopenharmony_ci unsigned short vlan_id; 3068c2ecf20Sopenharmony_ci /* SMC-R */ 3078c2ecf20Sopenharmony_ci struct smc_clc_msg_local *ib_lcl; 3088c2ecf20Sopenharmony_ci struct smc_ib_device *ib_dev; 3098c2ecf20Sopenharmony_ci u8 ib_gid[SMC_GID_SIZE]; 3108c2ecf20Sopenharmony_ci u8 ib_port; 3118c2ecf20Sopenharmony_ci u32 ib_clcqpn; 3128c2ecf20Sopenharmony_ci /* SMC-D */ 3138c2ecf20Sopenharmony_ci u64 ism_peer_gid[SMC_MAX_ISM_DEVS + 1]; 3148c2ecf20Sopenharmony_ci struct smcd_dev *ism_dev[SMC_MAX_ISM_DEVS + 1]; 3158c2ecf20Sopenharmony_ci u16 ism_chid[SMC_MAX_ISM_DEVS + 1]; 3168c2ecf20Sopenharmony_ci u8 ism_offered_cnt; /* # of ISM devices offered */ 3178c2ecf20Sopenharmony_ci u8 ism_selected; /* index of selected ISM dev*/ 3188c2ecf20Sopenharmony_ci u8 smcd_version; 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* Find the connection associated with the given alert token in the link group. 3228c2ecf20Sopenharmony_ci * To use rbtrees we have to implement our own search core. 3238c2ecf20Sopenharmony_ci * Requires @conns_lock 3248c2ecf20Sopenharmony_ci * @token alert token to search for 3258c2ecf20Sopenharmony_ci * @lgr link group to search in 3268c2ecf20Sopenharmony_ci * Returns connection associated with token if found, NULL otherwise. 3278c2ecf20Sopenharmony_ci */ 3288c2ecf20Sopenharmony_cistatic inline struct smc_connection *smc_lgr_find_conn( 3298c2ecf20Sopenharmony_ci u32 token, struct smc_link_group *lgr) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci struct smc_connection *res = NULL; 3328c2ecf20Sopenharmony_ci struct rb_node *node; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci node = lgr->conns_all.rb_node; 3358c2ecf20Sopenharmony_ci while (node) { 3368c2ecf20Sopenharmony_ci struct smc_connection *cur = rb_entry(node, 3378c2ecf20Sopenharmony_ci struct smc_connection, alert_node); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if (cur->alert_token_local > token) { 3408c2ecf20Sopenharmony_ci node = node->rb_left; 3418c2ecf20Sopenharmony_ci } else { 3428c2ecf20Sopenharmony_ci if (cur->alert_token_local < token) { 3438c2ecf20Sopenharmony_ci node = node->rb_right; 3448c2ecf20Sopenharmony_ci } else { 3458c2ecf20Sopenharmony_ci res = cur; 3468c2ecf20Sopenharmony_ci break; 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci } 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci return res; 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci/* returns true if the specified link is usable */ 3558c2ecf20Sopenharmony_cistatic inline bool smc_link_usable(struct smc_link *lnk) 3568c2ecf20Sopenharmony_ci{ 3578c2ecf20Sopenharmony_ci if (lnk->state == SMC_LNK_UNUSED || lnk->state == SMC_LNK_INACTIVE) 3588c2ecf20Sopenharmony_ci return false; 3598c2ecf20Sopenharmony_ci return true; 3608c2ecf20Sopenharmony_ci} 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_cistatic inline bool smc_link_sendable(struct smc_link *lnk) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci return smc_link_usable(lnk) && 3658c2ecf20Sopenharmony_ci lnk->qp_attr.cur_qp_state == IB_QPS_RTS; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic inline bool smc_link_active(struct smc_link *lnk) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci return lnk->state == SMC_LNK_ACTIVE; 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistruct smc_sock; 3748c2ecf20Sopenharmony_cistruct smc_clc_msg_accept_confirm; 3758c2ecf20Sopenharmony_cistruct smc_clc_msg_local; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_civoid smc_lgr_cleanup_early(struct smc_connection *conn); 3788c2ecf20Sopenharmony_civoid smc_lgr_terminate_sched(struct smc_link_group *lgr); 3798c2ecf20Sopenharmony_civoid smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport); 3808c2ecf20Sopenharmony_civoid smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport); 3818c2ecf20Sopenharmony_civoid smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, 3828c2ecf20Sopenharmony_ci unsigned short vlan); 3838c2ecf20Sopenharmony_civoid smc_smcd_terminate_all(struct smcd_dev *dev); 3848c2ecf20Sopenharmony_civoid smc_smcr_terminate_all(struct smc_ib_device *smcibdev); 3858c2ecf20Sopenharmony_ciint smc_buf_create(struct smc_sock *smc, bool is_smcd); 3868c2ecf20Sopenharmony_ciint smc_uncompress_bufsize(u8 compressed); 3878c2ecf20Sopenharmony_ciint smc_rmb_rtoken_handling(struct smc_connection *conn, struct smc_link *link, 3888c2ecf20Sopenharmony_ci struct smc_clc_msg_accept_confirm *clc); 3898c2ecf20Sopenharmony_ciint smc_rtoken_add(struct smc_link *lnk, __be64 nw_vaddr, __be32 nw_rkey); 3908c2ecf20Sopenharmony_ciint smc_rtoken_delete(struct smc_link *lnk, __be32 nw_rkey); 3918c2ecf20Sopenharmony_civoid smc_rtoken_set(struct smc_link_group *lgr, int link_idx, int link_idx_new, 3928c2ecf20Sopenharmony_ci __be32 nw_rkey_known, __be64 nw_vaddr, __be32 nw_rkey); 3938c2ecf20Sopenharmony_civoid smc_rtoken_set2(struct smc_link_group *lgr, int rtok_idx, int link_id, 3948c2ecf20Sopenharmony_ci __be64 nw_vaddr, __be32 nw_rkey); 3958c2ecf20Sopenharmony_civoid smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn); 3968c2ecf20Sopenharmony_civoid smc_sndbuf_sync_sg_for_device(struct smc_connection *conn); 3978c2ecf20Sopenharmony_civoid smc_rmb_sync_sg_for_cpu(struct smc_connection *conn); 3988c2ecf20Sopenharmony_civoid smc_rmb_sync_sg_for_device(struct smc_connection *conn); 3998c2ecf20Sopenharmony_ciint smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_civoid smc_conn_free(struct smc_connection *conn); 4028c2ecf20Sopenharmony_ciint smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini); 4038c2ecf20Sopenharmony_civoid smc_lgr_schedule_free_work_fast(struct smc_link_group *lgr); 4048c2ecf20Sopenharmony_ciint smc_core_init(void); 4058c2ecf20Sopenharmony_civoid smc_core_exit(void); 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ciint smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk, 4088c2ecf20Sopenharmony_ci u8 link_idx, struct smc_init_info *ini); 4098c2ecf20Sopenharmony_civoid smcr_link_clear(struct smc_link *lnk, bool log); 4108c2ecf20Sopenharmony_ciint smcr_buf_map_lgr(struct smc_link *lnk); 4118c2ecf20Sopenharmony_ciint smcr_buf_reg_lgr(struct smc_link *lnk); 4128c2ecf20Sopenharmony_civoid smcr_lgr_set_type(struct smc_link_group *lgr, enum smc_lgr_type new_type); 4138c2ecf20Sopenharmony_civoid smcr_lgr_set_type_asym(struct smc_link_group *lgr, 4148c2ecf20Sopenharmony_ci enum smc_lgr_type new_type, int asym_lnk_idx); 4158c2ecf20Sopenharmony_ciint smcr_link_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc); 4168c2ecf20Sopenharmony_cistruct smc_link *smc_switch_conns(struct smc_link_group *lgr, 4178c2ecf20Sopenharmony_ci struct smc_link *from_lnk, bool is_dev_err); 4188c2ecf20Sopenharmony_civoid smcr_link_down_cond(struct smc_link *lnk); 4198c2ecf20Sopenharmony_civoid smcr_link_down_cond_sched(struct smc_link *lnk); 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_cistatic inline struct smc_link_group *smc_get_lgr(struct smc_link *link) 4228c2ecf20Sopenharmony_ci{ 4238c2ecf20Sopenharmony_ci return link->lgr; 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci#endif 426