xref: /onnv-gate/usr/src/uts/common/sys/ib/clients/rdsv3/rdsv3_impl.h (revision 12922:c58988eacbb2)
112198SEiji.Ota@Sun.COM /*
212198SEiji.Ota@Sun.COM  * CDDL HEADER START
312198SEiji.Ota@Sun.COM  *
412198SEiji.Ota@Sun.COM  * The contents of this file are subject to the terms of the
512198SEiji.Ota@Sun.COM  * Common Development and Distribution License (the "License").
612198SEiji.Ota@Sun.COM  * You may not use this file except in compliance with the License.
712198SEiji.Ota@Sun.COM  *
812198SEiji.Ota@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
912198SEiji.Ota@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1012198SEiji.Ota@Sun.COM  * See the License for the specific language governing permissions
1112198SEiji.Ota@Sun.COM  * and limitations under the License.
1212198SEiji.Ota@Sun.COM  *
1312198SEiji.Ota@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1412198SEiji.Ota@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1512198SEiji.Ota@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1612198SEiji.Ota@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1712198SEiji.Ota@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1812198SEiji.Ota@Sun.COM  *
1912198SEiji.Ota@Sun.COM  * CDDL HEADER END
2012198SEiji.Ota@Sun.COM  */
2112198SEiji.Ota@Sun.COM /*
2212198SEiji.Ota@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2312198SEiji.Ota@Sun.COM  */
2412198SEiji.Ota@Sun.COM 
2512198SEiji.Ota@Sun.COM #ifndef _RDSV3_IMPL_H
2612198SEiji.Ota@Sun.COM #define	_RDSV3_IMPL_H
2712198SEiji.Ota@Sun.COM 
2812198SEiji.Ota@Sun.COM #include <sys/atomic.h>
2912198SEiji.Ota@Sun.COM 
3012198SEiji.Ota@Sun.COM /*
3112198SEiji.Ota@Sun.COM  * This file is only present in Solaris
3212198SEiji.Ota@Sun.COM  */
3312198SEiji.Ota@Sun.COM 
3412198SEiji.Ota@Sun.COM #ifdef __cplusplus
3512198SEiji.Ota@Sun.COM extern "C" {
3612198SEiji.Ota@Sun.COM #endif
3712198SEiji.Ota@Sun.COM 
3812198SEiji.Ota@Sun.COM extern dev_info_t	*rdsv3_dev_info;
3912198SEiji.Ota@Sun.COM 
4012198SEiji.Ota@Sun.COM #define	uint16_be_t	uint16_t
4112198SEiji.Ota@Sun.COM #define	uint32_be_t	uint32_t
4212198SEiji.Ota@Sun.COM #define	uint64_be_t	uint64_t
4312198SEiji.Ota@Sun.COM 
4412198SEiji.Ota@Sun.COM /*
4512198SEiji.Ota@Sun.COM  * RDS Well known service id
4612198SEiji.Ota@Sun.COM  * Format: 0x1h00144Fhhhhhhhh
4712198SEiji.Ota@Sun.COM  *         "00144F" is the Sun OUI
4812198SEiji.Ota@Sun.COM  * 'h' can be any hex-decimal digit.
4912198SEiji.Ota@Sun.COM  */
5012198SEiji.Ota@Sun.COM #define	RDS_SERVICE_ID		0x1000144F00000001ULL
5112198SEiji.Ota@Sun.COM 
5212198SEiji.Ota@Sun.COM /*
5312198SEiji.Ota@Sun.COM  * Atomic operations
5412198SEiji.Ota@Sun.COM  */
5512198SEiji.Ota@Sun.COM typedef unsigned int	atomic_t;
5612198SEiji.Ota@Sun.COM #define	ATOMIC_INIT(a)	a
5712198SEiji.Ota@Sun.COM 
5812198SEiji.Ota@Sun.COM #define	atomic_get(p)	(*(p))
5912198SEiji.Ota@Sun.COM 
6012198SEiji.Ota@Sun.COM #define	atomic_cmpset_long(p, c, n) \
6112198SEiji.Ota@Sun.COM 	((c == atomic_cas_uint(p, c, n)) ? c : -1)
6212198SEiji.Ota@Sun.COM 
6312198SEiji.Ota@Sun.COM #define	atomic_dec_and_test(a)			\
6412198SEiji.Ota@Sun.COM 	(atomic_dec_uint_nv((a)) == 0)
6512198SEiji.Ota@Sun.COM 
6612198SEiji.Ota@Sun.COM #define	atomic_cmpxchg(a, o, n)			\
6712198SEiji.Ota@Sun.COM 	atomic_cas_uint(a, o, n)
6812198SEiji.Ota@Sun.COM 
6912198SEiji.Ota@Sun.COM #ifdef _LP64
7012198SEiji.Ota@Sun.COM #define	set_bit(b, p) \
7112198SEiji.Ota@Sun.COM 	atomic_or_ulong(((volatile ulong_t *)(void *)(p)) + ((b) >> 6), \
7212198SEiji.Ota@Sun.COM 	1ul << ((b) & 0x3f))
7312198SEiji.Ota@Sun.COM 
7412198SEiji.Ota@Sun.COM #define	clear_bit(b, p) \
7512198SEiji.Ota@Sun.COM 	atomic_and_ulong(((volatile ulong_t *)(void *)(p)) + ((b) >> 6), \
7612198SEiji.Ota@Sun.COM 	~(1ul << ((b) & 0x3f)))
7712198SEiji.Ota@Sun.COM 
7812198SEiji.Ota@Sun.COM #define	test_bit(b, p) \
7912198SEiji.Ota@Sun.COM 	(((volatile ulong_t *)(void *)(p))[(b) >> 6] & (1ul << ((b) & 0x3f)))
8012198SEiji.Ota@Sun.COM 
8112198SEiji.Ota@Sun.COM #define	test_and_set_bit(b, p) \
8212198SEiji.Ota@Sun.COM 	atomic_set_long_excl(((ulong_t *)(void *)(p)) +		\
8312198SEiji.Ota@Sun.COM 	    ((b) >> 6), ((b) & 0x3f))
8412198SEiji.Ota@Sun.COM #define	test_and_clear_bit(b, p) \
8512198SEiji.Ota@Sun.COM 	!atomic_clear_long_excl(((ulong_t *)(void *)(p)) + ((b) >> 6), \
8612198SEiji.Ota@Sun.COM 	((b) & 0x3f))
8712198SEiji.Ota@Sun.COM #else
8812198SEiji.Ota@Sun.COM #define	set_bit(b, p) \
8912198SEiji.Ota@Sun.COM 	atomic_or_uint(((volatile uint_t *)(void *)p) + (b >> 5), \
9012198SEiji.Ota@Sun.COM 	1ul << (b & 0x1f))
9112198SEiji.Ota@Sun.COM 
9212198SEiji.Ota@Sun.COM #define	clear_bit(b, p) \
9312198SEiji.Ota@Sun.COM 	atomic_and_uint(((volatile uint_t *)(void *)p) + (b >> 5), \
9412198SEiji.Ota@Sun.COM 	~(1ul << (b & 0x1f)))
9512198SEiji.Ota@Sun.COM 
9612198SEiji.Ota@Sun.COM #define	test_bit(b, p) \
9712198SEiji.Ota@Sun.COM 	(((volatile uint_t *)(void *)p)[b >> 5] & (1ul << (b & 0x1f)))
9812198SEiji.Ota@Sun.COM 
9912198SEiji.Ota@Sun.COM #define	test_and_set_bit(b, p) \
10012198SEiji.Ota@Sun.COM 	atomic_set_long_excl(((ulong_t *)(void *)p) + (b >> 5), (b & 0x1f))
10112198SEiji.Ota@Sun.COM #define	test_and_clear_bit(b, p) \
10212198SEiji.Ota@Sun.COM 	!atomic_clear_long_excl(((ulong_t *)(void *)p) + (b >> 5), (b & 0x1f))
10312198SEiji.Ota@Sun.COM #endif
10412198SEiji.Ota@Sun.COM 
105*12414SEiji.Ota@Sun.COM /*
106*12414SEiji.Ota@Sun.COM  * These macros and/or constants are used instead of Linux
107*12414SEiji.Ota@Sun.COM  * generic_{test,__{clear,set}}_le_bit().
108*12414SEiji.Ota@Sun.COM  */
109*12414SEiji.Ota@Sun.COM #if defined(sparc)
110*12414SEiji.Ota@Sun.COM #define	LE_BIT_XOR	((BITS_PER_LONG-1) & ~0x7)
111*12414SEiji.Ota@Sun.COM #else
112*12414SEiji.Ota@Sun.COM #define	LE_BIT_XOR	0
113*12414SEiji.Ota@Sun.COM #endif
114*12414SEiji.Ota@Sun.COM 
115*12414SEiji.Ota@Sun.COM #define	set_le_bit(b, p)	set_bit(b ^ LE_BIT_XOR, p)
116*12414SEiji.Ota@Sun.COM #define	clear_le_bit(b, p)	clear_bit(b ^ LE_BIT_XOR, p)
117*12414SEiji.Ota@Sun.COM #define	test_le_bit(b, p)	test_bit(b ^ LE_BIT_XOR, p)
11812198SEiji.Ota@Sun.COM 
11912198SEiji.Ota@Sun.COM uint_t	rdsv3_one_sec_in_hz;
12012198SEiji.Ota@Sun.COM 
12112198SEiji.Ota@Sun.COM #define	jiffies	100
12212198SEiji.Ota@Sun.COM #define	HZ	(drv_hztousec(1))
12312198SEiji.Ota@Sun.COM #define	container_of(m, s, name)			\
12412198SEiji.Ota@Sun.COM 	(void *)((uintptr_t)(m) - (uintptr_t)offsetof(s, name))
12512198SEiji.Ota@Sun.COM #define	ARRAY_SIZE(x)	(sizeof (x) / sizeof (x[0]))
12612198SEiji.Ota@Sun.COM /* setting this to PAGESIZE throws build errors */
12712198SEiji.Ota@Sun.COM #define	PAGE_SIZE	4096 /* xxx - fix this */
12812198SEiji.Ota@Sun.COM #define	BITS_PER_LONG	(sizeof (unsigned long) * 8)
12912198SEiji.Ota@Sun.COM 
13012198SEiji.Ota@Sun.COM /* debug */
13112198SEiji.Ota@Sun.COM #define	RDSV3_PANIC()		cmn_err(CE_PANIC, "Panic forced by RDSV3");
13212198SEiji.Ota@Sun.COM 
13312198SEiji.Ota@Sun.COM /* ERR */
13412198SEiji.Ota@Sun.COM #define	MAX_ERRNO	4095
13512198SEiji.Ota@Sun.COM #define	ERR_PTR(x)	((void *)(uintptr_t)x)
13612198SEiji.Ota@Sun.COM #define	IS_ERR(ptr)	(((uintptr_t)ptr) >= (uintptr_t)-MAX_ERRNO)
13712198SEiji.Ota@Sun.COM #define	PTR_ERR(ptr)	(int)(uintptr_t)ptr
13812198SEiji.Ota@Sun.COM 
13912198SEiji.Ota@Sun.COM #define	MAX_SCHEDULE_TIMEOUT	(~0UL>>1)
14012198SEiji.Ota@Sun.COM 
14112198SEiji.Ota@Sun.COM #define	RDMA_CM_EVENT_ADDR_CHANGE	14
14212198SEiji.Ota@Sun.COM 
14312198SEiji.Ota@Sun.COM /* list */
14412198SEiji.Ota@Sun.COM /* copied and modified list_remove_node */
14512198SEiji.Ota@Sun.COM #define	list_remove_node(node)						\
14612198SEiji.Ota@Sun.COM 	if ((node)->list_next != NULL) {				\
14712198SEiji.Ota@Sun.COM 		(node)->list_prev->list_next = (node)->list_next;	\
14812198SEiji.Ota@Sun.COM 		(node)->list_next->list_prev = (node)->list_prev;	\
14912198SEiji.Ota@Sun.COM 		(node)->list_next = (node)->list_prev = NULL;		\
15012198SEiji.Ota@Sun.COM 	}
15112198SEiji.Ota@Sun.COM 
15212198SEiji.Ota@Sun.COM #define	list_splice(src, dst)	{				\
15312198SEiji.Ota@Sun.COM 	list_create(dst, (src)->list_size, (src)->list_offset);	\
15412198SEiji.Ota@Sun.COM 	list_move_tail(dst, src);				\
15512198SEiji.Ota@Sun.COM 	}
15612198SEiji.Ota@Sun.COM 
15712198SEiji.Ota@Sun.COM #define	RDSV3_FOR_EACH_LIST_NODE(objp, listp, member)	\
15812198SEiji.Ota@Sun.COM 	for (objp = list_head(listp); objp; objp = list_next(listp, objp))
15912198SEiji.Ota@Sun.COM #define	RDSV3_FOR_EACH_LIST_NODE_SAFE(objp, tmp, listp, member)	\
16012198SEiji.Ota@Sun.COM 	for (objp = list_head(listp), tmp = (objp != NULL) ?	\
16112198SEiji.Ota@Sun.COM 	    list_next(listp, objp) : NULL;			\
16212198SEiji.Ota@Sun.COM 	    objp;						\
16312198SEiji.Ota@Sun.COM 	    objp = tmp, tmp = (objp != NULL) ?			\
16412198SEiji.Ota@Sun.COM 	    list_next(listp, objp) : NULL)
16512198SEiji.Ota@Sun.COM 
16612198SEiji.Ota@Sun.COM /* simulate wait_queue_head_t */
16712198SEiji.Ota@Sun.COM typedef struct rdsv3_wait_queue_s {
16812198SEiji.Ota@Sun.COM 	kmutex_t	waitq_mutex;
16912198SEiji.Ota@Sun.COM 	kcondvar_t	waitq_cv;
17012320SGiri.Adari@Sun.COM 	uint_t		waitq_waiters;
17112198SEiji.Ota@Sun.COM } rdsv3_wait_queue_t;
17212198SEiji.Ota@Sun.COM 
17312198SEiji.Ota@Sun.COM #define	rdsv3_init_waitqueue(waitqp)					\
17412198SEiji.Ota@Sun.COM 	mutex_init(&(waitqp)->waitq_mutex, NULL, MUTEX_DRIVER, NULL);	\
17512320SGiri.Adari@Sun.COM 	cv_init(&(waitqp)->waitq_cv, NULL, CV_DRIVER, NULL);		\
17612320SGiri.Adari@Sun.COM 	(waitqp)->waitq_waiters = 0
17712198SEiji.Ota@Sun.COM 
17812198SEiji.Ota@Sun.COM #define	rdsv3_exit_waitqueue(waitqp)					\
17912320SGiri.Adari@Sun.COM 	ASSERT((waitqp)->waitq_waiters == 0);				\
18012198SEiji.Ota@Sun.COM 	mutex_destroy(&(waitqp)->waitq_mutex);				\
18112198SEiji.Ota@Sun.COM 	cv_destroy(&(waitqp)->waitq_cv)
18212198SEiji.Ota@Sun.COM 
18312198SEiji.Ota@Sun.COM #define	rdsv3_wake_up(waitqp)	{					\
18412198SEiji.Ota@Sun.COM 	mutex_enter(&(waitqp)->waitq_mutex);				\
18512320SGiri.Adari@Sun.COM 	if ((waitqp)->waitq_waiters)					\
18612320SGiri.Adari@Sun.COM 		cv_signal(&(waitqp)->waitq_cv);				\
18712198SEiji.Ota@Sun.COM 	mutex_exit(&(waitqp)->waitq_mutex);				\
18812198SEiji.Ota@Sun.COM 	}
18912198SEiji.Ota@Sun.COM 
19012198SEiji.Ota@Sun.COM #define	rdsv3_wake_up_all(waitqp)	{				\
19112198SEiji.Ota@Sun.COM 	mutex_enter(&(waitqp)->waitq_mutex);				\
19212320SGiri.Adari@Sun.COM 	if ((waitqp)->waitq_waiters)					\
19312320SGiri.Adari@Sun.COM 		cv_broadcast(&(waitqp)->waitq_cv);			\
19412198SEiji.Ota@Sun.COM 	mutex_exit(&(waitqp)->waitq_mutex);				\
19512198SEiji.Ota@Sun.COM 	}
19612198SEiji.Ota@Sun.COM 
19712320SGiri.Adari@Sun.COM /* analogous to cv_wait */
19812198SEiji.Ota@Sun.COM #define	rdsv3_wait_event(waitq, condition)				\
19912198SEiji.Ota@Sun.COM {									\
20012320SGiri.Adari@Sun.COM 	mutex_enter(&(waitq)->waitq_mutex);				\
20112320SGiri.Adari@Sun.COM 	(waitq)->waitq_waiters++;					\
20212198SEiji.Ota@Sun.COM 	while (!(condition)) {						\
20312320SGiri.Adari@Sun.COM 		cv_wait(&(waitq)->waitq_cv, &(waitq)->waitq_mutex);	\
20412198SEiji.Ota@Sun.COM 	}								\
20512320SGiri.Adari@Sun.COM 	(waitq)->waitq_waiters--;					\
20612320SGiri.Adari@Sun.COM 	mutex_exit(&(waitq)->waitq_mutex);				\
20712320SGiri.Adari@Sun.COM }
20812198SEiji.Ota@Sun.COM 
20912320SGiri.Adari@Sun.COM /* analogous to cv_wait_sig */
21012320SGiri.Adari@Sun.COM #define	rdsv3_wait_sig(waitqp, condition)				\
21112198SEiji.Ota@Sun.COM (									\
21212198SEiji.Ota@Sun.COM {									\
21312320SGiri.Adari@Sun.COM 	int cv_return = 1;						\
21412320SGiri.Adari@Sun.COM 	mutex_enter(&(waitqp)->waitq_mutex);				\
21512320SGiri.Adari@Sun.COM 	(waitqp)->waitq_waiters++;					\
21612320SGiri.Adari@Sun.COM 	while (!(condition)) {						\
21712320SGiri.Adari@Sun.COM 		cv_return = cv_wait_sig(&(waitqp)->waitq_cv,		\
21812320SGiri.Adari@Sun.COM 		    &(waitqp)->waitq_mutex);				\
21912198SEiji.Ota@Sun.COM 		if (cv_return == 0) {					\
22012198SEiji.Ota@Sun.COM 			break;						\
22112198SEiji.Ota@Sun.COM 		}							\
22212198SEiji.Ota@Sun.COM 	}								\
22312320SGiri.Adari@Sun.COM 	(waitqp)->waitq_waiters--;					\
22412320SGiri.Adari@Sun.COM 	mutex_exit(&(waitqp)->waitq_mutex);				\
22512198SEiji.Ota@Sun.COM 	cv_return;							\
22612198SEiji.Ota@Sun.COM }									\
22712198SEiji.Ota@Sun.COM )
22812198SEiji.Ota@Sun.COM 
22912198SEiji.Ota@Sun.COM #define	SOCK_DEAD	1ul
23012198SEiji.Ota@Sun.COM 
23112198SEiji.Ota@Sun.COM /* socket */
23212198SEiji.Ota@Sun.COM typedef struct rsock {
23312198SEiji.Ota@Sun.COM 	sock_upper_handle_t	sk_upper_handle;
23412198SEiji.Ota@Sun.COM 	sock_upcalls_t		*sk_upcalls;
23512198SEiji.Ota@Sun.COM 
23612198SEiji.Ota@Sun.COM 	kmutex_t		sk_lock;
23712198SEiji.Ota@Sun.COM 	ulong_t			sk_flag;
23812320SGiri.Adari@Sun.COM 	rdsv3_wait_queue_t	*sk_sleep; /* Also protected by rs_recv_lock */
23912198SEiji.Ota@Sun.COM 	int			sk_sndbuf;
24012198SEiji.Ota@Sun.COM 	int			sk_rcvbuf;
24112198SEiji.Ota@Sun.COM 	atomic_t		sk_refcount;
24212198SEiji.Ota@Sun.COM 
24312198SEiji.Ota@Sun.COM 	struct rdsv3_sock	*sk_protinfo;
24412198SEiji.Ota@Sun.COM } rsock_t;
24512198SEiji.Ota@Sun.COM 
24612198SEiji.Ota@Sun.COM typedef struct rdsv3_conn_info_s {
24712198SEiji.Ota@Sun.COM 	uint32_be_t  c_laddr;
24812198SEiji.Ota@Sun.COM 	uint32_be_t  c_faddr;
24912198SEiji.Ota@Sun.COM } rdsv3_conn_info_t;
25012198SEiji.Ota@Sun.COM 
25112198SEiji.Ota@Sun.COM /* WQ */
25212198SEiji.Ota@Sun.COM typedef struct rdsv3_workqueue_struct_s {
25312198SEiji.Ota@Sun.COM 	kmutex_t wq_lock;
25412198SEiji.Ota@Sun.COM 	uint_t	wq_state;
25512198SEiji.Ota@Sun.COM 	int	wq_pending;
25612198SEiji.Ota@Sun.COM 	list_t	wq_queue;
25712198SEiji.Ota@Sun.COM } rdsv3_workqueue_struct_t;
25812198SEiji.Ota@Sun.COM 
25912198SEiji.Ota@Sun.COM struct rdsv3_work_s;
26012198SEiji.Ota@Sun.COM typedef void (*rdsv3_work_func_t)(struct rdsv3_work_s *);
26112198SEiji.Ota@Sun.COM typedef struct rdsv3_work_s {
26212198SEiji.Ota@Sun.COM 	list_node_t	work_item;
26312198SEiji.Ota@Sun.COM 	rdsv3_work_func_t	func;
26412198SEiji.Ota@Sun.COM } rdsv3_work_t;
26512198SEiji.Ota@Sun.COM 
26612198SEiji.Ota@Sun.COM /* simulate delayed_work */
26712198SEiji.Ota@Sun.COM typedef struct rdsv3_delayed_work_s {
26812198SEiji.Ota@Sun.COM 	kmutex_t		lock;
26912198SEiji.Ota@Sun.COM 	rdsv3_work_t		work;
27012198SEiji.Ota@Sun.COM 	timeout_id_t		timeid;
27112198SEiji.Ota@Sun.COM 	rdsv3_workqueue_struct_t	*wq;
27212198SEiji.Ota@Sun.COM } rdsv3_delayed_work_t;
27312198SEiji.Ota@Sun.COM 
27412198SEiji.Ota@Sun.COM #define	RDSV3_INIT_WORK(wp, f)	(wp)->func = f
27512198SEiji.Ota@Sun.COM #define	RDSV3_INIT_DELAYED_WORK(dwp, f)				\
27612198SEiji.Ota@Sun.COM 	(dwp)->work.func = f;					\
27712198SEiji.Ota@Sun.COM 	mutex_init(&(dwp)->lock, NULL, MUTEX_DRIVER, NULL);	\
27812198SEiji.Ota@Sun.COM 	(dwp)->timeid = 0
27912198SEiji.Ota@Sun.COM 
28012198SEiji.Ota@Sun.COM /* simulate scatterlist */
28112198SEiji.Ota@Sun.COM struct rdsv3_scatterlist {
28212198SEiji.Ota@Sun.COM 	caddr_t		vaddr;
28312198SEiji.Ota@Sun.COM 	uint_t		length;
28412198SEiji.Ota@Sun.COM 	ibt_wr_ds_t	*sgl;
28512198SEiji.Ota@Sun.COM 	ibt_mi_hdl_t	mihdl;
28612198SEiji.Ota@Sun.COM };
28712198SEiji.Ota@Sun.COM #define	rdsv3_sg_page(scat)	(scat)->vaddr
28812198SEiji.Ota@Sun.COM #define	rdsv3_sg_len(scat)	(scat)->length
28912198SEiji.Ota@Sun.COM #define	rdsv3_sg_set_page(scat, pg, len, off)		\
29012198SEiji.Ota@Sun.COM 	(scat)->vaddr = (caddr_t)(pg + off);		\
29112198SEiji.Ota@Sun.COM 	(scat)->length = len
29212198SEiji.Ota@Sun.COM #define	rdsv3_ib_sg_dma_len(dev, scat)	rdsv3_sg_len(scat)
29312198SEiji.Ota@Sun.COM 
29412198SEiji.Ota@Sun.COM /* copied from sys/socket.h */
29512198SEiji.Ota@Sun.COM #if defined(__sparc)
29612198SEiji.Ota@Sun.COM /* To maintain backward compatibility, alignment needs to be 8 on sparc. */
29712198SEiji.Ota@Sun.COM #define	_CMSG_HDR_ALIGNMENT	8
29812198SEiji.Ota@Sun.COM #else
29912198SEiji.Ota@Sun.COM /* for __i386 (and other future architectures) */
30012198SEiji.Ota@Sun.COM #define	_CMSG_HDR_ALIGNMENT	4
30112198SEiji.Ota@Sun.COM #endif	/* defined(__sparc) */
30212198SEiji.Ota@Sun.COM 
30312198SEiji.Ota@Sun.COM /*
30412198SEiji.Ota@Sun.COM  * The cmsg headers (and macros dealing with them) were made available as
30512198SEiji.Ota@Sun.COM  * part of UNIX95 and hence need to be protected with a _XPG4_2 define.
30612198SEiji.Ota@Sun.COM  */
30712198SEiji.Ota@Sun.COM #define	_CMSG_DATA_ALIGNMENT	(sizeof (int))
30812198SEiji.Ota@Sun.COM #define	_CMSG_HDR_ALIGN(x)	(((uintptr_t)(x) + _CMSG_HDR_ALIGNMENT - 1) & \
30912198SEiji.Ota@Sun.COM 				    ~(_CMSG_HDR_ALIGNMENT - 1))
31012198SEiji.Ota@Sun.COM #define	_CMSG_DATA_ALIGN(x)	(((uintptr_t)(x) + _CMSG_DATA_ALIGNMENT - 1) & \
31112198SEiji.Ota@Sun.COM 				    ~(_CMSG_DATA_ALIGNMENT - 1))
31212198SEiji.Ota@Sun.COM #define	CMSG_DATA(c)							\
31312198SEiji.Ota@Sun.COM 	((unsigned char *)_CMSG_DATA_ALIGN((struct cmsghdr *)(c) + 1))
31412198SEiji.Ota@Sun.COM 
31512198SEiji.Ota@Sun.COM #define	CMSG_FIRSTHDR(m)						\
31612198SEiji.Ota@Sun.COM 	(((m)->msg_controllen < sizeof (struct cmsghdr)) ?		\
31712198SEiji.Ota@Sun.COM 	    (struct cmsghdr *)0 : (struct cmsghdr *)((m)->msg_control))
31812198SEiji.Ota@Sun.COM 
31912198SEiji.Ota@Sun.COM #define	CMSG_NXTHDR(m, c)						\
32012198SEiji.Ota@Sun.COM 	(((c) == 0) ? CMSG_FIRSTHDR(m) :			\
32112198SEiji.Ota@Sun.COM 	((((uintptr_t)_CMSG_HDR_ALIGN((char *)(c) +			\
32212198SEiji.Ota@Sun.COM 	((struct cmsghdr *)(c))->cmsg_len) + sizeof (struct cmsghdr)) >	\
32312198SEiji.Ota@Sun.COM 	(((uintptr_t)((struct msghdr *)(m))->msg_control) +		\
32412198SEiji.Ota@Sun.COM 	((uintptr_t)((struct msghdr *)(m))->msg_controllen))) ?		\
32512198SEiji.Ota@Sun.COM 	((struct cmsghdr *)0) :						\
32612198SEiji.Ota@Sun.COM 	((struct cmsghdr *)_CMSG_HDR_ALIGN((char *)(c) +		\
32712198SEiji.Ota@Sun.COM 	    ((struct cmsghdr *)(c))->cmsg_len))))
32812198SEiji.Ota@Sun.COM 
32912198SEiji.Ota@Sun.COM /* Amount of space + padding needed for a message of length l */
33012198SEiji.Ota@Sun.COM #define	CMSG_SPACE(l)							\
33112198SEiji.Ota@Sun.COM 	((unsigned int)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l)))
33212198SEiji.Ota@Sun.COM 
33312198SEiji.Ota@Sun.COM /* Value to be used in cmsg_len, does not include trailing padding */
33412198SEiji.Ota@Sun.COM #define	CMSG_LEN(l)							\
33512198SEiji.Ota@Sun.COM 	((unsigned int)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l))
33612198SEiji.Ota@Sun.COM 
33712198SEiji.Ota@Sun.COM /* OFUV -> IB */
33812198SEiji.Ota@Sun.COM #define	RDSV3_IBDEV2HCAHDL(device)	(device)->hca_hdl
33912198SEiji.Ota@Sun.COM #define	RDSV3_QP2CHANHDL(qp)		(qp)->ibt_qp
34012198SEiji.Ota@Sun.COM #define	RDSV3_PD2PDHDL(pd)		(pd)->ibt_pd
34112198SEiji.Ota@Sun.COM #define	RDSV3_CQ2CQHDL(cq)		(cq)->ibt_cq
34212198SEiji.Ota@Sun.COM 
34312198SEiji.Ota@Sun.COM struct rdsv3_hdrs_mr {
34412198SEiji.Ota@Sun.COM 	ibt_lkey_t	lkey;
34512198SEiji.Ota@Sun.COM 	caddr_t		addr;
34612198SEiji.Ota@Sun.COM 	size_t		size;
34712198SEiji.Ota@Sun.COM 	ibt_mr_hdl_t	hdl;
34812198SEiji.Ota@Sun.COM };
34912198SEiji.Ota@Sun.COM 
35012198SEiji.Ota@Sun.COM /* rdsv3_impl.c */
35112198SEiji.Ota@Sun.COM void rdsv3_trans_init();
35212198SEiji.Ota@Sun.COM boolean_t rdsv3_capable_interface(struct lifreq *lifrp);
35312198SEiji.Ota@Sun.COM int rdsv3_do_ip_ioctl(ksocket_t so4, void **ipaddrs, int *size, int *nifs);
35412198SEiji.Ota@Sun.COM int rdsv3_do_ip_ioctl_old(ksocket_t so4, void **ipaddrs, int *size, int *nifs);
35512198SEiji.Ota@Sun.COM boolean_t rdsv3_isloopback(ipaddr_t addr);
35612198SEiji.Ota@Sun.COM void rdsv3_cancel_delayed_work(rdsv3_delayed_work_t *dwp);
35712198SEiji.Ota@Sun.COM void rdsv3_flush_workqueue(rdsv3_workqueue_struct_t *wq);
35812198SEiji.Ota@Sun.COM void rdsv3_queue_work(rdsv3_workqueue_struct_t *wq, rdsv3_work_t *wp);
35912198SEiji.Ota@Sun.COM void rdsv3_queue_delayed_work(rdsv3_workqueue_struct_t *wq,
36012198SEiji.Ota@Sun.COM     rdsv3_delayed_work_t *dwp, uint_t delay);
36112198SEiji.Ota@Sun.COM struct rsock *rdsv3_sk_alloc();
36212198SEiji.Ota@Sun.COM void rdsv3_sock_init_data(struct rsock *sk);
36312198SEiji.Ota@Sun.COM void rdsv3_sock_exit_data(struct rsock *sk);
36412198SEiji.Ota@Sun.COM void rdsv3_destroy_task_workqueue(rdsv3_workqueue_struct_t *wq);
36512198SEiji.Ota@Sun.COM rdsv3_workqueue_struct_t *rdsv3_create_task_workqueue(char *name);
36612198SEiji.Ota@Sun.COM int rdsv3_conn_constructor(void *buf, void *arg, int kmflags);
36712198SEiji.Ota@Sun.COM void rdsv3_conn_destructor(void *buf, void *arg);
36812198SEiji.Ota@Sun.COM int rdsv3_conn_compare(const void *conn1, const void *conn2);
36912198SEiji.Ota@Sun.COM void rdsv3_loop_init();
37012198SEiji.Ota@Sun.COM int rdsv3_mr_compare(const void *mr1, const void *mr2);
37112198SEiji.Ota@Sun.COM int rdsv3_put_cmsg(struct nmsghdr *msg, int level, int type, size_t size,
37212198SEiji.Ota@Sun.COM     void *payload);
37312198SEiji.Ota@Sun.COM int rdsv3_verify_bind_address(ipaddr_t addr);
37412198SEiji.Ota@Sun.COM uint16_t rdsv3_ip_fast_csum(void *buffer, size_t length);
37512198SEiji.Ota@Sun.COM uint_t rdsv3_ib_dma_map_sg(struct ib_device *dev, struct rdsv3_scatterlist
37612198SEiji.Ota@Sun.COM 	*scat, uint_t num);
37712198SEiji.Ota@Sun.COM void rdsv3_ib_dma_unmap_sg(ib_device_t *dev, struct rdsv3_scatterlist *scat,
37812198SEiji.Ota@Sun.COM     uint_t num);
37912228SEiji.Ota@Sun.COM static inline void
rdsv3_sk_sock_hold(struct rsock * sk)38012198SEiji.Ota@Sun.COM rdsv3_sk_sock_hold(struct rsock *sk)
38112198SEiji.Ota@Sun.COM {
38212198SEiji.Ota@Sun.COM 	atomic_add_32(&sk->sk_refcount, 1);
38312198SEiji.Ota@Sun.COM }
38412228SEiji.Ota@Sun.COM static inline void
rdsv3_sk_sock_put(struct rsock * sk)38512198SEiji.Ota@Sun.COM rdsv3_sk_sock_put(struct rsock *sk)
38612198SEiji.Ota@Sun.COM {
38712198SEiji.Ota@Sun.COM 	if (atomic_dec_and_test(&sk->sk_refcount))
38812198SEiji.Ota@Sun.COM 		rdsv3_sock_exit_data(sk);
38912198SEiji.Ota@Sun.COM }
39012228SEiji.Ota@Sun.COM static inline int
rdsv3_sk_sock_flag(struct rsock * sk,uint_t flag)39112198SEiji.Ota@Sun.COM rdsv3_sk_sock_flag(struct rsock *sk, uint_t flag)
39212198SEiji.Ota@Sun.COM {
39312198SEiji.Ota@Sun.COM 	return (test_bit(flag, &sk->sk_flag));
39412198SEiji.Ota@Sun.COM }
39512228SEiji.Ota@Sun.COM static inline void
rdsv3_sk_sock_orphan(struct rsock * sk)39612198SEiji.Ota@Sun.COM rdsv3_sk_sock_orphan(struct rsock *sk)
39712198SEiji.Ota@Sun.COM {
39812198SEiji.Ota@Sun.COM 	set_bit(SOCK_DEAD, &sk->sk_flag);
39912198SEiji.Ota@Sun.COM }
40012198SEiji.Ota@Sun.COM 
401*12414SEiji.Ota@Sun.COM #define	rdsv3_sndtimeo(a, b)	b ? 0 : 3600	/* check this value on linux */
402*12414SEiji.Ota@Sun.COM #define	rdsv3_rcvtimeo(a, b)	b ? 0 : 3600	/* check this value on linux */
40312198SEiji.Ota@Sun.COM 
40412198SEiji.Ota@Sun.COM void rdsv3_ib_free_conn(void *arg);
40512198SEiji.Ota@Sun.COM 
40612198SEiji.Ota@Sun.COM #ifdef	__cplusplus
40712198SEiji.Ota@Sun.COM }
40812198SEiji.Ota@Sun.COM #endif
40912198SEiji.Ota@Sun.COM 
41012198SEiji.Ota@Sun.COM #endif /* _RDSV3_IMPL_H */
411