1c39526b7SPramod Gunjikar /*
2c39526b7SPramod Gunjikar  * CDDL HEADER START
3c39526b7SPramod Gunjikar  *
4c39526b7SPramod Gunjikar  * The contents of this file are subject to the terms of the
5c39526b7SPramod Gunjikar  * Common Development and Distribution License (the "License").
6c39526b7SPramod Gunjikar  * You may not use this file except in compliance with the License.
7c39526b7SPramod Gunjikar  *
8c39526b7SPramod Gunjikar  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c39526b7SPramod Gunjikar  * or http://www.opensolaris.org/os/licensing.
10c39526b7SPramod Gunjikar  * See the License for the specific language governing permissions
11c39526b7SPramod Gunjikar  * and limitations under the License.
12c39526b7SPramod Gunjikar  *
13c39526b7SPramod Gunjikar  * When distributing Covered Code, include this CDDL HEADER in each
14c39526b7SPramod Gunjikar  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c39526b7SPramod Gunjikar  * If applicable, add the following below this CDDL HEADER, with the
16c39526b7SPramod Gunjikar  * fields enclosed by brackets "[]" replaced with your own identifying
17c39526b7SPramod Gunjikar  * information: Portions Copyright [yyyy] [name of copyright owner]
18c39526b7SPramod Gunjikar  *
19c39526b7SPramod Gunjikar  * CDDL HEADER END
20c39526b7SPramod Gunjikar  */
21c39526b7SPramod Gunjikar 
22c39526b7SPramod Gunjikar /*
23c39526b7SPramod Gunjikar  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24c39526b7SPramod Gunjikar  */
25c39526b7SPramod Gunjikar 
26c39526b7SPramod Gunjikar #ifndef _SYS_IB_CLIENTS_OF_SOL_OFS_SOL_CMA_H
27c39526b7SPramod Gunjikar #define	_SYS_IB_CLIENTS_OF_SOL_OFS_SOL_CMA_H
28c39526b7SPramod Gunjikar 
29c39526b7SPramod Gunjikar #ifdef __cplusplus
30c39526b7SPramod Gunjikar extern "C" {
31c39526b7SPramod Gunjikar #endif
32c39526b7SPramod Gunjikar 
33*5c5f1371SRichard Lowe #include <sys/sysmacros.h>
34c39526b7SPramod Gunjikar 
35c39526b7SPramod Gunjikar #include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
36c39526b7SPramod Gunjikar #include <sys/ib/clients/of/rdma/rdma_cm.h>
37c39526b7SPramod Gunjikar #include <sys/ib/clients/of/sol_ofs/sol_ib_cma.h> /* Transport Specific */
38c39526b7SPramod Gunjikar 
39c39526b7SPramod Gunjikar 
40c39526b7SPramod Gunjikar #define	IS_UDP_CMID(idp)	((idp)->ps == RDMA_PS_UDP || \
41c39526b7SPramod Gunjikar 	(idp)->ps == RDMA_PS_IPOIB)
42c39526b7SPramod Gunjikar #define	IS_VALID_SOCKADDR(sockaddrp) \
43c39526b7SPramod Gunjikar 	((sockaddrp)->sa_family == AF_INET || \
44c39526b7SPramod Gunjikar 	(sockaddrp)->sa_family == AF_INET6)
45c39526b7SPramod Gunjikar 
46c39526b7SPramod Gunjikar /*
47c39526b7SPramod Gunjikar  * Global structure which contains information about all
48c39526b7SPramod Gunjikar  * CMIDs, which have called rdma_listen().
49c39526b7SPramod Gunjikar  */
50c39526b7SPramod Gunjikar typedef struct sol_cma_glbl_listen_s {
51c39526b7SPramod Gunjikar 	avl_node_t	cma_listen_node;
52c39526b7SPramod Gunjikar 
53c39526b7SPramod Gunjikar 	uint64_t	cma_listen_chan_sid;
54c39526b7SPramod Gunjikar 	void		*cma_listen_clnt_hdl;
55c39526b7SPramod Gunjikar 	void		*cma_listen_svc_hdl;
56c39526b7SPramod Gunjikar 	genlist_t	cma_listen_chan_list;
57c39526b7SPramod Gunjikar } sol_cma_glbl_listen_t;
58c39526b7SPramod Gunjikar 
59c39526b7SPramod Gunjikar /* State of the RDMA-CM ID */
60c39526b7SPramod Gunjikar typedef enum {
61c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_IDLE,
62c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_BOUND,
63c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ADDR_QUERY,
64c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ADDR_BOUND,
65c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ADDR_RESLVD,
66c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ROUTE_QUERY,
67c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ROUTE_RESLVD,
68c39526b7SPramod Gunjikar 
69c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_EVENT_NOTIFIED,
70c39526b7SPramod Gunjikar 
71c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_CONNECT,
72c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_LISTEN,
73c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_DISCONNECT,
74c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_ACCEPT,
75c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_REJECT,
76c39526b7SPramod Gunjikar 
77c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_DESTROYING,
78c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_DESTROY_PENDING,
79c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_DESTROY_WAIT,
80c39526b7SPramod Gunjikar 
81c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_HCA_DOWN,
82c39526b7SPramod Gunjikar 	SOL_CMA_CHAN_PORT_DOWN
83c39526b7SPramod Gunjikar } cma_chan_state_t;
84c39526b7SPramod Gunjikar 
85c39526b7SPramod Gunjikar typedef struct listen_info_s {
86c39526b7SPramod Gunjikar 	uint8_t			listen_is_root;
87c39526b7SPramod Gunjikar 
88c39526b7SPramod Gunjikar 	/* For Root CMIDs, pointer to global listen info */
89c39526b7SPramod Gunjikar 	genlist_entry_t		*listen_entry;
90c39526b7SPramod Gunjikar 	sol_cma_glbl_listen_t	*chan_glbl_listen_info;
91c39526b7SPramod Gunjikar 
92c39526b7SPramod Gunjikar 	/*
93c39526b7SPramod Gunjikar 	 * For EP CMIDs, pointer to ib_device and root CMID
94c39526b7SPramod Gunjikar 	 * for HCA DR
95c39526b7SPramod Gunjikar 	 */
96c39526b7SPramod Gunjikar 	genlist_entry_t		*listen_ep_dev_entry;
97c39526b7SPramod Gunjikar 	genlist_entry_t		*listen_ep_root_entry;
98c39526b7SPramod Gunjikar 	struct ib_device	*listen_ep_device;
99c39526b7SPramod Gunjikar 
100c39526b7SPramod Gunjikar 	/*
101c39526b7SPramod Gunjikar 	 * Count & list of EPs for this listen_info.
102c39526b7SPramod Gunjikar 	 * This is 0, if listen_is_root is 0.
103c39526b7SPramod Gunjikar 	 */
104c39526b7SPramod Gunjikar 	uint32_t		listen_eps;
105c39526b7SPramod Gunjikar 	genlist_t		listen_list;
106c39526b7SPramod Gunjikar 
107c39526b7SPramod Gunjikar 	/* Transport Specific */
108c39526b7SPramod Gunjikar 	union {
109c39526b7SPramod Gunjikar 		/* For Root CMID */
110c39526b7SPramod Gunjikar 		ibt_srv_hdl_t	_listen_srv_hdl;
111c39526b7SPramod Gunjikar 
112c39526b7SPramod Gunjikar 		/* For Endpoint CMID */
113c39526b7SPramod Gunjikar 		ibt_sbind_hdl_t	_listen_sbind_hdl;
114c39526b7SPramod Gunjikar 	} un_listen;
115c39526b7SPramod Gunjikar #define	listen_ib_srv_hdl	un_listen._listen_srv_hdl
116c39526b7SPramod Gunjikar #define	listen_ib_sbind_hdl	un_listen._listen_sbind_hdl
117c39526b7SPramod Gunjikar } sol_cma_listen_info_t;
118c39526b7SPramod Gunjikar 
119c39526b7SPramod Gunjikar typedef enum {
120c39526b7SPramod Gunjikar 	SOL_CMA_XPORT_NONE = 0,
121c39526b7SPramod Gunjikar 	SOL_CMA_XPORT_IB,
122c39526b7SPramod Gunjikar 	SOL_CMA_XPORT_IWARP
123c39526b7SPramod Gunjikar } sol_cma_xport_type_t;
124c39526b7SPramod Gunjikar 
125fffafeb2SJohnny Cheung /*
126fffafeb2SJohnny Cheung  * This is used to track the state of a client side CMID.
127fffafeb2SJohnny Cheung  * 	CONNECT_NONE	Server side CMID, or CMID for which
128fffafeb2SJohnny Cheung  * 			rdma_connect() has not been called.
129fffafeb2SJohnny Cheung  *
130fffafeb2SJohnny Cheung  * 	CLIENT_NONE	Client side CMID for which connection
131fffafeb2SJohnny Cheung  * 			has been torn down.
132fffafeb2SJohnny Cheung  *
133fffafeb2SJohnny Cheung  * 			For UDP it also represents connection
134fffafeb2SJohnny Cheung  * 			established (no more IBTF CM events
135fffafeb2SJohnny Cheung  * 			expected).
136fffafeb2SJohnny Cheung  *
137fffafeb2SJohnny Cheung  * 	INITIATED	rdma_connect() has been called not yet
138fffafeb2SJohnny Cheung  * 			established.
139fffafeb2SJohnny Cheung  *
140fffafeb2SJohnny Cheung  * 	ESTABLISHED	Client CMID has connection established.
141fffafeb2SJohnny Cheung  */
142c39526b7SPramod Gunjikar typedef enum {
143c39526b7SPramod Gunjikar 	SOL_CMA_CONNECT_NONE = 0,
144fffafeb2SJohnny Cheung 	SOL_CMA_CONNECT_CLIENT_NONE,
145c39526b7SPramod Gunjikar 	SOL_CMA_CONNECT_INITIATED,
146fffafeb2SJohnny Cheung 	SOL_CMA_CONNECT_ESTABLISHED,
147c39526b7SPramod Gunjikar } sol_cma_connect_flag_t;
148c39526b7SPramod Gunjikar 
149fffafeb2SJohnny Cheung /*
150fffafeb2SJohnny Cheung  * This is used to track the state of CMIDs created for Connection
151fffafeb2SJohnny Cheung  * Requests and listening CMID.
152fffafeb2SJohnny Cheung  *
153fffafeb2SJohnny Cheung  * 	NONE		Client CMID, listen CMID with no REQs yet.
154fffafeb2SJohnny Cheung  *
155fffafeb2SJohnny Cheung  * 	SERVER_DONE	REQ CMID connection done, no more events.
156fffafeb2SJohnny Cheung  *
157fffafeb2SJohnny Cheung  * 			For listening CMID all REQ CMIDs have events
158fffafeb2SJohnny Cheung  * 			completed.
159fffafeb2SJohnny Cheung  *
160fffafeb2SJohnny Cheung  * 	CREATED		listening CMID with > 1 REQ CMID with events
161fffafeb2SJohnny Cheung  * 			pending.
162fffafeb2SJohnny Cheung  *
163fffafeb2SJohnny Cheung  * 	QUEUED		REQ CMID in REQ AVL tree of listening CMID
164fffafeb2SJohnny Cheung  *
165fffafeb2SJohnny Cheung  * 	ACCEPTED	REQ CMID accepted and in ACPT AVL tree of the
166fffafeb2SJohnny Cheung  * 			listening CMID.
167fffafeb2SJohnny Cheung  */
168fffafeb2SJohnny Cheung typedef enum {
169fffafeb2SJohnny Cheung 	REQ_CMID_NONE = 0,
170fffafeb2SJohnny Cheung 	REQ_CMID_SERVER_NONE,
171fffafeb2SJohnny Cheung 	REQ_CMID_CREATED,
172fffafeb2SJohnny Cheung 	REQ_CMID_QUEUED,
173fffafeb2SJohnny Cheung 	REQ_CMID_NOTIFIED,
174fffafeb2SJohnny Cheung 	REQ_CMID_ACCEPTED,
175fffafeb2SJohnny Cheung } cma_req_cmid_state_t;
176fffafeb2SJohnny Cheung 
177fffafeb2SJohnny Cheung #define	SOL_IS_SERVER_CMID(chanp)	\
178fffafeb2SJohnny Cheung 	((chanp)->chan_req_state != REQ_CMID_NONE)
179fffafeb2SJohnny Cheung #define	SOL_IS_CLIENT_CMID(chanp)	\
180fffafeb2SJohnny Cheung 	((chanp)->chan_connect_flag != SOL_CMA_CONNECT_NONE)
181fffafeb2SJohnny Cheung 
182fffafeb2SJohnny Cheung #define	REQ_CMID_IN_REQ_AVL_TREE(chanp)	\
183fffafeb2SJohnny Cheung 	((chanp)->chan_req_state == REQ_CMID_QUEUED ||	\
184fffafeb2SJohnny Cheung 	(chanp)->chan_req_state == REQ_CMID_NOTIFIED)
185fffafeb2SJohnny Cheung #define	SOL_CMID_CLOSE_REQUIRED(chanp)		\
186fffafeb2SJohnny Cheung 	((chanp)->chan_connect_flag == SOL_CMA_CONNECT_INITIATED ||	\
187fffafeb2SJohnny Cheung 	(chanp)->chan_connect_flag == SOL_CMA_CONNECT_ESTABLISHED || \
188fffafeb2SJohnny Cheung 	(chanp)->chan_req_state == REQ_CMID_ACCEPTED)
189fffafeb2SJohnny Cheung #define	SOL_CMAID_CONNECTED(chanp)	\
190fffafeb2SJohnny Cheung 	(SOL_CMID_CLOSE_REQUIRED(chanp) ||	\
191fffafeb2SJohnny Cheung 	(chanp)->chan_req_state  ==  REQ_CMID_NOTIFIED)
192c39526b7SPramod Gunjikar 
193c0dd49bdSEiji Ota /*
194c0dd49bdSEiji Ota  * CMID_DESTROYED	- Flag to indicate rdma_destroy_id has been
195c0dd49bdSEiji Ota  * 			called for this CMID
196c0dd49bdSEiji Ota  *
197c0dd49bdSEiji Ota  * EVENT_PROGRESS	- RDMACM Event for this CMID been passed to
198c0dd49bdSEiji Ota  * 			the sol_ofs client.
199c0dd49bdSEiji Ota  *
200c0dd49bdSEiji Ota  * API_PROGRESS		- rdma_resolve_addr() / rdma_resolve_route() /
201c0dd49bdSEiji Ota  *			rdma_listen() is in progress.
202c0dd49bdSEiji Ota  */
203c39526b7SPramod Gunjikar #define	SOL_CMA_CALLER_CMID_DESTROYED		0x01
204c39526b7SPramod Gunjikar #define	SOL_CMA_CALLER_EVENT_PROGRESS		0x02
205c0dd49bdSEiji Ota #define	SOL_CMA_CALLER_API_PROGRESS		0x04
206c39526b7SPramod Gunjikar 
207c39526b7SPramod Gunjikar typedef struct {
208c39526b7SPramod Gunjikar 	struct rdma_cm_id	chan_rdma_cm;
209c39526b7SPramod Gunjikar 
210c39526b7SPramod Gunjikar 	/*
211c39526b7SPramod Gunjikar 	 * Below are all CMA Channel specific fields required in Solaris,
212c39526b7SPramod Gunjikar 	 * apart from rdma_cm_id.
213c39526b7SPramod Gunjikar 	 */
214c39526b7SPramod Gunjikar 
215c39526b7SPramod Gunjikar 	/* AVL Tree for REQs and EST CMIDs */
216c39526b7SPramod Gunjikar 	avl_node_t		chan_req_avl_node;
217c39526b7SPramod Gunjikar 	avl_node_t		chan_acpt_avl_node;
218c39526b7SPramod Gunjikar 	avl_tree_t		chan_req_avl_tree;
219c39526b7SPramod Gunjikar 	avl_tree_t		chan_acpt_avl_tree;
220c39526b7SPramod Gunjikar 
221c39526b7SPramod Gunjikar 	/*
222c39526b7SPramod Gunjikar 	 * chan_req_cnt -
223c39526b7SPramod Gunjikar 	 *	REQ CMIDs created not yet notified to client
224c39526b7SPramod Gunjikar 	 * chan_total_req_cnt -
225c39526b7SPramod Gunjikar 	 *	REQ CMIDs created not destroy_id(0 not called.
226c39526b7SPramod Gunjikar 	 */
227c39526b7SPramod Gunjikar 	uint64_t		chan_req_cnt;
228c39526b7SPramod Gunjikar 	uint64_t		chan_req_total_cnt;
229c39526b7SPramod Gunjikar 
230c39526b7SPramod Gunjikar 
231fffafeb2SJohnny Cheung 	/* State for Server side and client side CMIDs */
232c39526b7SPramod Gunjikar 	cma_req_cmid_state_t	chan_req_state;
233fffafeb2SJohnny Cheung 	sol_cma_connect_flag_t	chan_connect_flag;
234c39526b7SPramod Gunjikar 
235c39526b7SPramod Gunjikar 	kmutex_t		chan_mutex;
236c39526b7SPramod Gunjikar 	kcondvar_t		chan_destroy_cv;
237c39526b7SPramod Gunjikar 	cma_chan_state_t	chan_state;
238c39526b7SPramod Gunjikar 	uint8_t			chan_cmid_destroy_state;
239c39526b7SPramod Gunjikar 
240c39526b7SPramod Gunjikar 	/*
241c39526b7SPramod Gunjikar 	 * Transport type for the rdma_id, IB or IWARP. This is set to
242c39526b7SPramod Gunjikar 	 * NONE, when the transport type is not yet determined.
243c39526b7SPramod Gunjikar 	 */
244c39526b7SPramod Gunjikar 	sol_cma_xport_type_t	chan_xport_type;
245c39526b7SPramod Gunjikar 
246c39526b7SPramod Gunjikar 	/*
247c39526b7SPramod Gunjikar 	 * Passed from sol_ofs consumer, using the rdma_map_id2clnthdl
248c39526b7SPramod Gunjikar 	 * and rdma_map_id2qphdl
249c39526b7SPramod Gunjikar 	 */
250c39526b7SPramod Gunjikar 	void			*chan_ib_client_hdl;
251c39526b7SPramod Gunjikar 	void			*chan_iw_client_hdl;
252c39526b7SPramod Gunjikar 	void			*chan_qp_hdl;
253c39526b7SPramod Gunjikar 
254c39526b7SPramod Gunjikar 	/* Data for root / endpoint CM ID. */
255c39526b7SPramod Gunjikar 	sol_cma_listen_info_t	*chan_listenp;
256c39526b7SPramod Gunjikar 
257c39526b7SPramod Gunjikar 	/* Ptr to the root CMID for Endpoint & Req CMID */
258c39526b7SPramod Gunjikar 	struct rdma_cm_id	*listen_root;
259c39526b7SPramod Gunjikar #define	CHAN_LISTEN_LIST(chanp)	(((chanp)->chan_listenp)->listen_list)
260c39526b7SPramod Gunjikar #define	CHAN_LISTEN_ROOT(chanp)	((chanp)->listen_root)
261c39526b7SPramod Gunjikar 
262c39526b7SPramod Gunjikar 	struct rdma_conn_param	chan_param;
263c39526b7SPramod Gunjikar 
264c39526b7SPramod Gunjikar 	/* Session ID for completion */
265c39526b7SPramod Gunjikar 	void			*chan_session_id;
266c39526b7SPramod Gunjikar 
267c0dd49bdSEiji Ota 	uint32_t		chan_qp_num;
268c0dd49bdSEiji Ota 	uint8_t			chan_is_srq;
269c0dd49bdSEiji Ota 
270c39526b7SPramod Gunjikar 	union {
271c39526b7SPramod Gunjikar 		ibcma_chan_t	chan_ib_xport;
272c39526b7SPramod Gunjikar 	} un_xport;	/* Transport specific fields */
273c39526b7SPramod Gunjikar #define	chan_ib			un_xport.chan_ib_xport
274c39526b7SPramod Gunjikar } sol_cma_chan_t;
275c39526b7SPramod Gunjikar 
276c39526b7SPramod Gunjikar void ibcma_append_listen_list(struct rdma_cm_id *);
277c39526b7SPramod Gunjikar #ifdef	IWARP_SUPPORT
278c39526b7SPramod Gunjikar void iwcma_append_listen_list(struct rdma_cm_id *);
279c39526b7SPramod Gunjikar #endif
280c39526b7SPramod Gunjikar 
281c39526b7SPramod Gunjikar 
282c39526b7SPramod Gunjikar extern void cma_generate_event(struct rdma_cm_id *, enum rdma_cm_event_type,
283c39526b7SPramod Gunjikar     int, struct rdma_conn_param *, struct rdma_ud_param *);
284c39526b7SPramod Gunjikar extern struct ib_device *sol_cma_acquire_device(ib_guid_t);
285c39526b7SPramod Gunjikar 
286c39526b7SPramod Gunjikar static inline int
sol_cma_any_addr(struct sockaddr * addr)287c39526b7SPramod Gunjikar sol_cma_any_addr(struct sockaddr *addr)
288c39526b7SPramod Gunjikar {
289c39526b7SPramod Gunjikar 	ASSERT(addr);
290c39526b7SPramod Gunjikar 	if (addr->sa_family == AF_INET) {
291c39526b7SPramod Gunjikar 		struct sockaddr_in	*in_addr;
292c39526b7SPramod Gunjikar 		in_addr = (struct sockaddr_in *)addr;
293c39526b7SPramod Gunjikar 
294c39526b7SPramod Gunjikar 		return (in_addr->sin_addr.s_addr == INADDR_ANY);
295c39526b7SPramod Gunjikar 	} else if (addr->sa_family == AF_INET6) {
296c39526b7SPramod Gunjikar 		struct sockaddr_in6	*in6_addr;
297c39526b7SPramod Gunjikar 		in6_addr = (struct sockaddr_in6 *)addr;
298c39526b7SPramod Gunjikar 
299c39526b7SPramod Gunjikar 		return (IN6_IS_ADDR_UNSPECIFIED(&(in6_addr->sin6_addr)));
300c39526b7SPramod Gunjikar 	}
301c39526b7SPramod Gunjikar 	return (0);
302c39526b7SPramod Gunjikar }
303c39526b7SPramod Gunjikar 
304c39526b7SPramod Gunjikar static inline struct rdma_cm_id *
cma_create_new_id(struct rdma_cm_id * srcid)305c39526b7SPramod Gunjikar cma_create_new_id(struct rdma_cm_id *srcid)
306c39526b7SPramod Gunjikar {
307c39526b7SPramod Gunjikar 	struct	rdma_cm_id	*newid;
308c39526b7SPramod Gunjikar 	sol_cma_chan_t		*new_chanp, *src_chanp;
309c39526b7SPramod Gunjikar 
310c39526b7SPramod Gunjikar 	newid = rdma_create_id(srcid->event_handler, srcid->context,
311c39526b7SPramod Gunjikar 	    srcid->ps);
312c39526b7SPramod Gunjikar 	if (newid == NULL)
313c39526b7SPramod Gunjikar 		return (newid);
314c39526b7SPramod Gunjikar 
315c39526b7SPramod Gunjikar 	if (srcid->device) {
316c39526b7SPramod Gunjikar 		newid->device =
317c39526b7SPramod Gunjikar 		    sol_cma_acquire_device(srcid->device->node_guid);
318c39526b7SPramod Gunjikar 	}
319c39526b7SPramod Gunjikar 	bcopy(&((srcid->route).addr), &((newid->route).addr),
320c39526b7SPramod Gunjikar 	    sizeof (struct rdma_addr));
321c39526b7SPramod Gunjikar 	if ((srcid->route).num_paths) {
322c39526b7SPramod Gunjikar 		int	num_paths;
323c39526b7SPramod Gunjikar 
324c39526b7SPramod Gunjikar 		num_paths = (newid->route).num_paths =
325c39526b7SPramod Gunjikar 		    (srcid->route).num_paths;
326c39526b7SPramod Gunjikar 		(newid->route).path_rec = kmem_zalloc(num_paths *
327c39526b7SPramod Gunjikar 		    sizeof (struct ib_sa_path_rec), KM_SLEEP);
328c39526b7SPramod Gunjikar 		bcopy(&((srcid->route).path_rec),
329c39526b7SPramod Gunjikar 		    &((newid->route).path_rec),
330c39526b7SPramod Gunjikar 		    num_paths * sizeof (struct ib_sa_path_rec));
331c39526b7SPramod Gunjikar 	}
332c39526b7SPramod Gunjikar 	newid->port_num = srcid->port_num;
333c39526b7SPramod Gunjikar 
334c39526b7SPramod Gunjikar 	new_chanp = (sol_cma_chan_t *)newid;
335c39526b7SPramod Gunjikar 	src_chanp = (sol_cma_chan_t *)srcid;
336c39526b7SPramod Gunjikar 	new_chanp->chan_state = src_chanp->chan_state;
337c39526b7SPramod Gunjikar 	new_chanp->chan_xport_type = src_chanp->chan_xport_type;
338c39526b7SPramod Gunjikar 	if (CHAN_LISTEN_ROOT(src_chanp))
339c39526b7SPramod Gunjikar 		CHAN_LISTEN_ROOT(new_chanp) =  CHAN_LISTEN_ROOT(src_chanp);
340c39526b7SPramod Gunjikar 	else
341c39526b7SPramod Gunjikar 		CHAN_LISTEN_ROOT(new_chanp) = srcid;
342c39526b7SPramod Gunjikar 	return (newid);
343c39526b7SPramod Gunjikar }
344c39526b7SPramod Gunjikar 
345c39526b7SPramod Gunjikar 
346c39526b7SPramod Gunjikar static inline struct rdma_cm_id *
cma_get_req_idp(struct rdma_cm_id * root_idp,void * qp_hdl)347c39526b7SPramod Gunjikar cma_get_req_idp(struct rdma_cm_id *root_idp, void *qp_hdl)
348c39526b7SPramod Gunjikar {
349c39526b7SPramod Gunjikar 	struct rdma_cm_id	*req_idp;
350c39526b7SPramod Gunjikar 	sol_cma_chan_t		*root_chanp;
351c39526b7SPramod Gunjikar 
352c39526b7SPramod Gunjikar 	root_chanp = (sol_cma_chan_t *)root_idp;
353fffafeb2SJohnny Cheung 	ASSERT(MUTEX_HELD(&root_chanp->chan_mutex));
354c39526b7SPramod Gunjikar 	req_idp = (struct rdma_cm_id *)avl_find(
355c39526b7SPramod Gunjikar 	    &root_chanp->chan_req_avl_tree, (void *)qp_hdl, NULL);
356c39526b7SPramod Gunjikar 	return (req_idp);
357c39526b7SPramod Gunjikar }
358c39526b7SPramod Gunjikar 
359c39526b7SPramod Gunjikar static inline struct rdma_cm_id *
cma_get_acpt_idp(struct rdma_cm_id * root_idp,void * qp_hdl)360c39526b7SPramod Gunjikar cma_get_acpt_idp(struct rdma_cm_id *root_idp, void *qp_hdl)
361c39526b7SPramod Gunjikar {
362c39526b7SPramod Gunjikar 	struct rdma_cm_id	*acpt_idp;
363c39526b7SPramod Gunjikar 	sol_cma_chan_t		*root_chanp;
364c39526b7SPramod Gunjikar 
365c39526b7SPramod Gunjikar 	root_chanp = (sol_cma_chan_t *)root_idp;
366fffafeb2SJohnny Cheung 	ASSERT(MUTEX_HELD(&root_chanp->chan_mutex));
367c39526b7SPramod Gunjikar 	acpt_idp = (struct rdma_cm_id *)avl_find(
368c39526b7SPramod Gunjikar 	    &root_chanp->chan_acpt_avl_tree, (void *)qp_hdl, NULL);
369c39526b7SPramod Gunjikar 	return (acpt_idp);
370c39526b7SPramod Gunjikar }
371c39526b7SPramod Gunjikar #ifdef __cplusplus
372c39526b7SPramod Gunjikar }
373c39526b7SPramod Gunjikar #endif
374c39526b7SPramod Gunjikar 
375c39526b7SPramod Gunjikar #endif	/* _SYS_IB_CLIENTS_OF_SOL_OFS_SOL_CMA_H */
376