162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Shared Memory Communications over RDMA (SMC-R) and RoCE 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Definitions for the SMC module (socket related) 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright IBM Corp. 2016 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#ifndef __SMC_H 1262306a36Sopenharmony_ci#define __SMC_H 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/socket.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <linux/compiler.h> /* __aligned */ 1762306a36Sopenharmony_ci#include <net/genetlink.h> 1862306a36Sopenharmony_ci#include <net/sock.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include "smc_ib.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define SMC_V1 1 /* SMC version V1 */ 2362306a36Sopenharmony_ci#define SMC_V2 2 /* SMC version V2 */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define SMC_RELEASE_0 0 2662306a36Sopenharmony_ci#define SMC_RELEASE_1 1 2762306a36Sopenharmony_ci#define SMC_RELEASE SMC_RELEASE_1 /* the latest release version */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */ 3062306a36Sopenharmony_ci#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define SMC_MAX_ISM_DEVS 8 /* max # of proposed non-native ISM 3362306a36Sopenharmony_ci * devices 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci#define SMC_AUTOCORKING_DEFAULT_SIZE 0x10000 /* 64K by default */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciextern struct proto smc_proto; 3862306a36Sopenharmony_ciextern struct proto smc_proto6; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#ifdef ATOMIC64_INIT 4162306a36Sopenharmony_ci#define KERNEL_HAS_ATOMIC64 4262306a36Sopenharmony_ci#endif 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cienum smc_state { /* possible states of an SMC socket */ 4562306a36Sopenharmony_ci SMC_ACTIVE = 1, 4662306a36Sopenharmony_ci SMC_INIT = 2, 4762306a36Sopenharmony_ci SMC_CLOSED = 7, 4862306a36Sopenharmony_ci SMC_LISTEN = 10, 4962306a36Sopenharmony_ci /* normal close */ 5062306a36Sopenharmony_ci SMC_PEERCLOSEWAIT1 = 20, 5162306a36Sopenharmony_ci SMC_PEERCLOSEWAIT2 = 21, 5262306a36Sopenharmony_ci SMC_APPFINCLOSEWAIT = 24, 5362306a36Sopenharmony_ci SMC_APPCLOSEWAIT1 = 22, 5462306a36Sopenharmony_ci SMC_APPCLOSEWAIT2 = 23, 5562306a36Sopenharmony_ci SMC_PEERFINCLOSEWAIT = 25, 5662306a36Sopenharmony_ci /* abnormal close */ 5762306a36Sopenharmony_ci SMC_PEERABORTWAIT = 26, 5862306a36Sopenharmony_ci SMC_PROCESSABORT = 27, 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistruct smc_link_group; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct smc_wr_rx_hdr { /* common prefix part of LLC and CDC to demultiplex */ 6462306a36Sopenharmony_ci union { 6562306a36Sopenharmony_ci u8 type; 6662306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) 6762306a36Sopenharmony_ci struct { 6862306a36Sopenharmony_ci u8 llc_version:4, 6962306a36Sopenharmony_ci llc_type:4; 7062306a36Sopenharmony_ci }; 7162306a36Sopenharmony_ci#elif defined(__LITTLE_ENDIAN_BITFIELD) 7262306a36Sopenharmony_ci struct { 7362306a36Sopenharmony_ci u8 llc_type:4, 7462306a36Sopenharmony_ci llc_version:4; 7562306a36Sopenharmony_ci }; 7662306a36Sopenharmony_ci#endif 7762306a36Sopenharmony_ci }; 7862306a36Sopenharmony_ci} __aligned(1); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct smc_cdc_conn_state_flags { 8162306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) 8262306a36Sopenharmony_ci u8 peer_done_writing : 1; /* Sending done indicator */ 8362306a36Sopenharmony_ci u8 peer_conn_closed : 1; /* Peer connection closed indicator */ 8462306a36Sopenharmony_ci u8 peer_conn_abort : 1; /* Abnormal close indicator */ 8562306a36Sopenharmony_ci u8 reserved : 5; 8662306a36Sopenharmony_ci#elif defined(__LITTLE_ENDIAN_BITFIELD) 8762306a36Sopenharmony_ci u8 reserved : 5; 8862306a36Sopenharmony_ci u8 peer_conn_abort : 1; 8962306a36Sopenharmony_ci u8 peer_conn_closed : 1; 9062306a36Sopenharmony_ci u8 peer_done_writing : 1; 9162306a36Sopenharmony_ci#endif 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistruct smc_cdc_producer_flags { 9562306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) 9662306a36Sopenharmony_ci u8 write_blocked : 1; /* Writing Blocked, no rx buf space */ 9762306a36Sopenharmony_ci u8 urg_data_pending : 1; /* Urgent Data Pending */ 9862306a36Sopenharmony_ci u8 urg_data_present : 1; /* Urgent Data Present */ 9962306a36Sopenharmony_ci u8 cons_curs_upd_req : 1; /* cursor update requested */ 10062306a36Sopenharmony_ci u8 failover_validation : 1;/* message replay due to failover */ 10162306a36Sopenharmony_ci u8 reserved : 3; 10262306a36Sopenharmony_ci#elif defined(__LITTLE_ENDIAN_BITFIELD) 10362306a36Sopenharmony_ci u8 reserved : 3; 10462306a36Sopenharmony_ci u8 failover_validation : 1; 10562306a36Sopenharmony_ci u8 cons_curs_upd_req : 1; 10662306a36Sopenharmony_ci u8 urg_data_present : 1; 10762306a36Sopenharmony_ci u8 urg_data_pending : 1; 10862306a36Sopenharmony_ci u8 write_blocked : 1; 10962306a36Sopenharmony_ci#endif 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* in host byte order */ 11362306a36Sopenharmony_ciunion smc_host_cursor { /* SMC cursor - an offset in an RMBE */ 11462306a36Sopenharmony_ci struct { 11562306a36Sopenharmony_ci u16 reserved; 11662306a36Sopenharmony_ci u16 wrap; /* window wrap sequence number */ 11762306a36Sopenharmony_ci u32 count; /* cursor (= offset) part */ 11862306a36Sopenharmony_ci }; 11962306a36Sopenharmony_ci#ifdef KERNEL_HAS_ATOMIC64 12062306a36Sopenharmony_ci atomic64_t acurs; /* for atomic processing */ 12162306a36Sopenharmony_ci#else 12262306a36Sopenharmony_ci u64 acurs; /* for atomic processing */ 12362306a36Sopenharmony_ci#endif 12462306a36Sopenharmony_ci} __aligned(8); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* in host byte order, except for flag bitfields in network byte order */ 12762306a36Sopenharmony_cistruct smc_host_cdc_msg { /* Connection Data Control message */ 12862306a36Sopenharmony_ci struct smc_wr_rx_hdr common; /* .type = 0xFE */ 12962306a36Sopenharmony_ci u8 len; /* length = 44 */ 13062306a36Sopenharmony_ci u16 seqno; /* connection seq # */ 13162306a36Sopenharmony_ci u32 token; /* alert_token */ 13262306a36Sopenharmony_ci union smc_host_cursor prod; /* producer cursor */ 13362306a36Sopenharmony_ci union smc_host_cursor cons; /* consumer cursor, 13462306a36Sopenharmony_ci * piggy backed "ack" 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ci struct smc_cdc_producer_flags prod_flags; /* conn. tx/rx status */ 13762306a36Sopenharmony_ci struct smc_cdc_conn_state_flags conn_state_flags; /* peer conn. status*/ 13862306a36Sopenharmony_ci u8 reserved[18]; 13962306a36Sopenharmony_ci} __aligned(8); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cienum smc_urg_state { 14262306a36Sopenharmony_ci SMC_URG_VALID = 1, /* data present */ 14362306a36Sopenharmony_ci SMC_URG_NOTYET = 2, /* data pending */ 14462306a36Sopenharmony_ci SMC_URG_READ = 3, /* data was already read */ 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistruct smc_mark_woken { 14862306a36Sopenharmony_ci bool woken; 14962306a36Sopenharmony_ci void *key; 15062306a36Sopenharmony_ci wait_queue_entry_t wait_entry; 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistruct smc_connection { 15462306a36Sopenharmony_ci struct rb_node alert_node; 15562306a36Sopenharmony_ci struct smc_link_group *lgr; /* link group of connection */ 15662306a36Sopenharmony_ci struct smc_link *lnk; /* assigned SMC-R link */ 15762306a36Sopenharmony_ci u32 alert_token_local; /* unique conn. id */ 15862306a36Sopenharmony_ci u8 peer_rmbe_idx; /* from tcp handshake */ 15962306a36Sopenharmony_ci int peer_rmbe_size; /* size of peer rx buffer */ 16062306a36Sopenharmony_ci atomic_t peer_rmbe_space;/* remaining free bytes in peer 16162306a36Sopenharmony_ci * rmbe 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_ci int rtoken_idx; /* idx to peer RMB rkey/addr */ 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci struct smc_buf_desc *sndbuf_desc; /* send buffer descriptor */ 16662306a36Sopenharmony_ci struct smc_buf_desc *rmb_desc; /* RMBE descriptor */ 16762306a36Sopenharmony_ci int rmbe_size_comp; /* compressed notation */ 16862306a36Sopenharmony_ci int rmbe_update_limit; 16962306a36Sopenharmony_ci /* lower limit for consumer 17062306a36Sopenharmony_ci * cursor update 17162306a36Sopenharmony_ci */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci struct smc_host_cdc_msg local_tx_ctrl; /* host byte order staging 17462306a36Sopenharmony_ci * buffer for CDC msg send 17562306a36Sopenharmony_ci * .prod cf. TCP snd_nxt 17662306a36Sopenharmony_ci * .cons cf. TCP sends ack 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_ci union smc_host_cursor local_tx_ctrl_fin; 17962306a36Sopenharmony_ci /* prod crsr - confirmed by peer 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ci union smc_host_cursor tx_curs_prep; /* tx - prepared data 18262306a36Sopenharmony_ci * snd_max..wmem_alloc 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci union smc_host_cursor tx_curs_sent; /* tx - sent data 18562306a36Sopenharmony_ci * snd_nxt ? 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_ci union smc_host_cursor tx_curs_fin; /* tx - confirmed by peer 18862306a36Sopenharmony_ci * snd-wnd-begin ? 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_ci atomic_t sndbuf_space; /* remaining space in sndbuf */ 19162306a36Sopenharmony_ci u16 tx_cdc_seq; /* sequence # for CDC send */ 19262306a36Sopenharmony_ci u16 tx_cdc_seq_fin; /* sequence # - tx completed */ 19362306a36Sopenharmony_ci spinlock_t send_lock; /* protect wr_sends */ 19462306a36Sopenharmony_ci atomic_t cdc_pend_tx_wr; /* number of pending tx CDC wqe 19562306a36Sopenharmony_ci * - inc when post wqe, 19662306a36Sopenharmony_ci * - dec on polled tx cqe 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci wait_queue_head_t cdc_pend_tx_wq; /* wakeup on no cdc_pend_tx_wr*/ 19962306a36Sopenharmony_ci atomic_t tx_pushing; /* nr_threads trying tx push */ 20062306a36Sopenharmony_ci struct delayed_work tx_work; /* retry of smc_cdc_msg_send */ 20162306a36Sopenharmony_ci u32 tx_off; /* base offset in peer rmb */ 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci struct smc_host_cdc_msg local_rx_ctrl; /* filled during event_handl. 20462306a36Sopenharmony_ci * .prod cf. TCP rcv_nxt 20562306a36Sopenharmony_ci * .cons cf. TCP snd_una 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_ci union smc_host_cursor rx_curs_confirmed; /* confirmed to peer 20862306a36Sopenharmony_ci * source of snd_una ? 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_ci union smc_host_cursor urg_curs; /* points at urgent byte */ 21162306a36Sopenharmony_ci enum smc_urg_state urg_state; 21262306a36Sopenharmony_ci bool urg_tx_pend; /* urgent data staged */ 21362306a36Sopenharmony_ci bool urg_rx_skip_pend; 21462306a36Sopenharmony_ci /* indicate urgent oob data 21562306a36Sopenharmony_ci * read, but previous regular 21662306a36Sopenharmony_ci * data still pending 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ci char urg_rx_byte; /* urgent byte */ 21962306a36Sopenharmony_ci bool tx_in_release_sock; 22062306a36Sopenharmony_ci /* flush pending tx data in 22162306a36Sopenharmony_ci * sock release_cb() 22262306a36Sopenharmony_ci */ 22362306a36Sopenharmony_ci atomic_t bytes_to_rcv; /* arrived data, 22462306a36Sopenharmony_ci * not yet received 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_ci atomic_t splice_pending; /* number of spliced bytes 22762306a36Sopenharmony_ci * pending processing 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_ci#ifndef KERNEL_HAS_ATOMIC64 23062306a36Sopenharmony_ci spinlock_t acurs_lock; /* protect cursors */ 23162306a36Sopenharmony_ci#endif 23262306a36Sopenharmony_ci struct work_struct close_work; /* peer sent some closing */ 23362306a36Sopenharmony_ci struct work_struct abort_work; /* abort the connection */ 23462306a36Sopenharmony_ci struct tasklet_struct rx_tsklet; /* Receiver tasklet for SMC-D */ 23562306a36Sopenharmony_ci u8 rx_off; /* receive offset: 23662306a36Sopenharmony_ci * 0 for SMC-R, 32 for SMC-D 23762306a36Sopenharmony_ci */ 23862306a36Sopenharmony_ci u64 peer_token; /* SMC-D token of peer */ 23962306a36Sopenharmony_ci u8 killed : 1; /* abnormal termination */ 24062306a36Sopenharmony_ci u8 freed : 1; /* normal termiation */ 24162306a36Sopenharmony_ci u8 out_of_sync : 1; /* out of sync with peer */ 24262306a36Sopenharmony_ci}; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistruct smc_sock { /* smc sock container */ 24562306a36Sopenharmony_ci struct sock sk; 24662306a36Sopenharmony_ci struct socket *clcsock; /* internal tcp socket */ 24762306a36Sopenharmony_ci void (*clcsk_state_change)(struct sock *sk); 24862306a36Sopenharmony_ci /* original stat_change fct. */ 24962306a36Sopenharmony_ci void (*clcsk_data_ready)(struct sock *sk); 25062306a36Sopenharmony_ci /* original data_ready fct. */ 25162306a36Sopenharmony_ci void (*clcsk_write_space)(struct sock *sk); 25262306a36Sopenharmony_ci /* original write_space fct. */ 25362306a36Sopenharmony_ci void (*clcsk_error_report)(struct sock *sk); 25462306a36Sopenharmony_ci /* original error_report fct. */ 25562306a36Sopenharmony_ci struct smc_connection conn; /* smc connection */ 25662306a36Sopenharmony_ci struct smc_sock *listen_smc; /* listen parent */ 25762306a36Sopenharmony_ci struct work_struct connect_work; /* handle non-blocking connect*/ 25862306a36Sopenharmony_ci struct work_struct tcp_listen_work;/* handle tcp socket accepts */ 25962306a36Sopenharmony_ci struct work_struct smc_listen_work;/* prepare new accept socket */ 26062306a36Sopenharmony_ci struct list_head accept_q; /* sockets to be accepted */ 26162306a36Sopenharmony_ci spinlock_t accept_q_lock; /* protects accept_q */ 26262306a36Sopenharmony_ci bool limit_smc_hs; /* put constraint on handshake */ 26362306a36Sopenharmony_ci bool use_fallback; /* fallback to tcp */ 26462306a36Sopenharmony_ci int fallback_rsn; /* reason for fallback */ 26562306a36Sopenharmony_ci u32 peer_diagnosis; /* decline reason from peer */ 26662306a36Sopenharmony_ci atomic_t queued_smc_hs; /* queued smc handshakes */ 26762306a36Sopenharmony_ci struct inet_connection_sock_af_ops af_ops; 26862306a36Sopenharmony_ci const struct inet_connection_sock_af_ops *ori_af_ops; 26962306a36Sopenharmony_ci /* original af ops */ 27062306a36Sopenharmony_ci int sockopt_defer_accept; 27162306a36Sopenharmony_ci /* sockopt TCP_DEFER_ACCEPT 27262306a36Sopenharmony_ci * value 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci u8 wait_close_tx_prepared : 1; 27562306a36Sopenharmony_ci /* shutdown wr or close 27662306a36Sopenharmony_ci * started, waiting for unsent 27762306a36Sopenharmony_ci * data to be sent 27862306a36Sopenharmony_ci */ 27962306a36Sopenharmony_ci u8 connect_nonblock : 1; 28062306a36Sopenharmony_ci /* non-blocking connect in 28162306a36Sopenharmony_ci * flight 28262306a36Sopenharmony_ci */ 28362306a36Sopenharmony_ci struct mutex clcsock_release_lock; 28462306a36Sopenharmony_ci /* protects clcsock of a listen 28562306a36Sopenharmony_ci * socket 28662306a36Sopenharmony_ci * */ 28762306a36Sopenharmony_ci}; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci#define smc_sk(ptr) container_of_const(ptr, struct smc_sock, sk) 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_cistatic inline void smc_init_saved_callbacks(struct smc_sock *smc) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci smc->clcsk_state_change = NULL; 29462306a36Sopenharmony_ci smc->clcsk_data_ready = NULL; 29562306a36Sopenharmony_ci smc->clcsk_write_space = NULL; 29662306a36Sopenharmony_ci smc->clcsk_error_report = NULL; 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic inline struct smc_sock *smc_clcsock_user_data(const struct sock *clcsk) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci return (struct smc_sock *) 30262306a36Sopenharmony_ci ((uintptr_t)clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY); 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/* save target_cb in saved_cb, and replace target_cb with new_cb */ 30662306a36Sopenharmony_cistatic inline void smc_clcsock_replace_cb(void (**target_cb)(struct sock *), 30762306a36Sopenharmony_ci void (*new_cb)(struct sock *), 30862306a36Sopenharmony_ci void (**saved_cb)(struct sock *)) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci /* only save once */ 31162306a36Sopenharmony_ci if (!*saved_cb) 31262306a36Sopenharmony_ci *saved_cb = *target_cb; 31362306a36Sopenharmony_ci *target_cb = new_cb; 31462306a36Sopenharmony_ci} 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci/* restore target_cb to saved_cb, and reset saved_cb to NULL */ 31762306a36Sopenharmony_cistatic inline void smc_clcsock_restore_cb(void (**target_cb)(struct sock *), 31862306a36Sopenharmony_ci void (**saved_cb)(struct sock *)) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci if (!*saved_cb) 32162306a36Sopenharmony_ci return; 32262306a36Sopenharmony_ci *target_cb = *saved_cb; 32362306a36Sopenharmony_ci *saved_cb = NULL; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ciextern struct workqueue_struct *smc_hs_wq; /* wq for handshake work */ 32762306a36Sopenharmony_ciextern struct workqueue_struct *smc_close_wq; /* wq for close work */ 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci#define SMC_SYSTEMID_LEN 8 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ciextern u8 local_systemid[SMC_SYSTEMID_LEN]; /* unique system identifier */ 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci#define ntohll(x) be64_to_cpu(x) 33462306a36Sopenharmony_ci#define htonll(x) cpu_to_be64(x) 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci/* convert an u32 value into network byte order, store it into a 3 byte field */ 33762306a36Sopenharmony_cistatic inline void hton24(u8 *net, u32 host) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci __be32 t; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci t = cpu_to_be32(host); 34262306a36Sopenharmony_ci memcpy(net, ((u8 *)&t) + 1, 3); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci/* convert a received 3 byte field into host byte order*/ 34662306a36Sopenharmony_cistatic inline u32 ntoh24(u8 *net) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci __be32 t = 0; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci memcpy(((u8 *)&t) + 1, net, 3); 35162306a36Sopenharmony_ci return be32_to_cpu(t); 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci#ifdef CONFIG_XFRM 35562306a36Sopenharmony_cistatic inline bool using_ipsec(struct smc_sock *smc) 35662306a36Sopenharmony_ci{ 35762306a36Sopenharmony_ci return (smc->clcsock->sk->sk_policy[0] || 35862306a36Sopenharmony_ci smc->clcsock->sk->sk_policy[1]) ? true : false; 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci#else 36162306a36Sopenharmony_cistatic inline bool using_ipsec(struct smc_sock *smc) 36262306a36Sopenharmony_ci{ 36362306a36Sopenharmony_ci return false; 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci#endif 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistruct smc_gidlist; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistruct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock); 37062306a36Sopenharmony_civoid smc_close_non_accepted(struct sock *sk); 37162306a36Sopenharmony_civoid smc_fill_gid_list(struct smc_link_group *lgr, 37262306a36Sopenharmony_ci struct smc_gidlist *gidlist, 37362306a36Sopenharmony_ci struct smc_ib_device *known_dev, u8 *known_gid); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci/* smc handshake limitation interface for netlink */ 37662306a36Sopenharmony_ciint smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb); 37762306a36Sopenharmony_ciint smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info); 37862306a36Sopenharmony_ciint smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic inline void smc_sock_set_flag(struct sock *sk, enum sock_flags flag) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci set_bit(flag, &sk->sk_flags); 38362306a36Sopenharmony_ci} 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci#endif /* __SMC_H */ 386