1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _ISER_H
27 #define	_ISER_H
28 
29 #ifdef	__cplusplus
30 extern "C" {
31 #endif
32 
33 #include <sys/types.h>
34 #include <sys/ddi.h>
35 #include <sys/cmn_err.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <sys/sunddi.h>
39 #include <sys/ib/ibtl/ibti.h>
40 #include <sys/ib/ibtl/ibtl_types.h>
41 
42 #include <sys/idm/idm.h>
43 #include <sys/ib/clients/iser/iser_ib.h>
44 #include <sys/ib/clients/iser/iser_resource.h>
45 #include <sys/ib/clients/iser/iser_cm.h>
46 #include <sys/ib/clients/iser/iser_xfer.h>
47 
48 /*
49  * iser.h
50  *	Definitions and macros related to iSER core functionality,
51  * 	softstate and DDI routines.
52  */
53 extern boolean_t iser_logging;
54 #define	ISER_LOG if (iser_logging) cmn_err
55 
56 #define	ISER_TASKQ_NTHREADS	4
57 
58 #define	ISER_HEADER_LENGTH	28
59 
60 #define	ISER_DELAY_HALF_SECOND	500000 /* for use with drv_usectohz() */
61 
62 /* iSER Operational Parameters */
63 #define	ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MIN		0x200
64 #define	ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MAX		0xFFFFFF
65 #define	ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX		0xFFFFFF
66 #define	ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_DEFAULT		\
67 	ISCSI_DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH
68 #define	ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MIN		0x200
69 #define	ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MAX		0xFFFFFF
70 #define	ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX	0xFFFFFF
71 #define	ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_DEFAULT		\
72 	ISCSI_DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH
73 #define	ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MIN		0x0
74 #define	ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MAX		0xFFFFFFFF
75 #define	ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_IMPL_MAX		0xFFFFFFFF
76 #define	ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_DEFAULT		0x0
77 
78 /* iSCSI key names that iSER is interested in */
79 #define	ISER_KV_KEY_NAME_RDMA_EXTENSIONS	"RDMAExtensions"
80 #define	ISER_KV_KEY_NAME_OF_MARKER		"OFMarker"
81 #define	ISER_KV_KEY_NAME_IF_MARKER		"IFMarker"
82 #define	ISER_KV_KEY_NAME_TGT_RECV_SEGLEN	"TargetRecvDataSegmentLength"
83 #define	ISER_KV_KEY_NAME_INI_RECV_SEGLEN	"InitiatorRecvDataSegmentLength"
84 #define	ISER_KV_KEY_NAME_MAX_OUTSTANDING_PDU	"MaxOutstandingUnexpectedPDUs"
85 
86 typedef struct iser_sbind_s {
87 	list_node_t		is_list_node;
88 	ibt_sbind_hdl_t		is_sbindhdl;
89 	ib_gid_t		is_gid;
90 	ib_guid_t		is_guid;
91 } iser_sbind_t;
92 
93 /* iSER-specific portion of idm_svc_t */
94 typedef struct iser_svc_s {
95 	idm_refcnt_t		is_refcnt;
96 	ib_svc_id_t		is_svcid;
97 	ibt_srv_hdl_t		is_srvhdl;
98 	/* list of service bind handles - one per HCA port */
99 	list_t			is_sbindlist;
100 } iser_svc_t;
101 
102 /*
103  * iSER endpoint connection type
104  */
105 typedef enum {
106 	ISER_CONN_TYPE_INI = 1,
107 	ISER_CONN_TYPE_TGT
108 } iser_conn_type_t;
109 
110 /*
111  * iSER Connection States to keep track of the connection going into
112  * iSER-assisted mode
113  */
114 typedef enum {
115 	ISER_CONN_STAGE_UNDEFINED,
116 	ISER_CONN_STAGE_ALLOCATED,	/* conn handle allocated */
117 	ISER_CONN_STAGE_IC_CONNECTED,	/* conn established */
118 	ISER_CONN_STAGE_HELLO_SENT,	/* hello exchange stages */
119 	ISER_CONN_STAGE_HELLO_SENT_FAIL,
120 	ISER_CONN_STAGE_HELLO_WAIT,
121 	ISER_CONN_STAGE_HELLO_RCV,
122 	ISER_CONN_STAGE_HELLO_RCV_FAIL,
123 	ISER_CONN_STAGE_HELLOREPLY_SENT,
124 	ISER_CONN_STAGE_HELLOREPLY_SENT_FAIL,
125 	ISER_CONN_STAGE_HELLOREPLY_RCV,
126 	ISER_CONN_STAGE_HELLOREPLY_RCV_FAIL,
127 	ISER_CONN_STAGE_LOGGED_IN,
128 	ISER_CONN_STAGE_IC_DISCONNECTED, /* conn disconnected */
129 	ISER_CONN_STAGE_IC_FREED,	/* conn handle allocated */
130 	ISER_CONN_STAGE_CLOSING,	/* channel closing */
131 	ISER_CONN_STAGE_CLOSED		/* channel closed */
132 } iser_conn_stage_t;
133 
134 /*
135  * iSER operations parameters negotiated for a given connection
136  */
137 typedef struct iser_op_params_s {
138 	uint32_t	op_header_digest:1,
139 			op_data_digest:1,
140 			op_rdma_extensions:1,
141 			op_ofmarker:1,
142 			op_ifmarker:1;
143 	uint64_t	op_target_recv_data_segment_length;
144 	uint64_t	op_initiator_recv_data_segment_length;
145 	uint64_t	op_max_outstanding_unexpected_pdus;
146 } iser_op_params_t;
147 
148 /*
149  * iSER connection information
150  */
151 typedef struct iser_conn_s {
152 	kmutex_t		ic_lock;
153 	kcondvar_t		ic_stage_cv;
154 	iser_conn_type_t	ic_type;
155 	iser_chan_t		*ic_chan;
156 	iser_conn_stage_t	ic_stage; /* for iSER-assisted mode */
157 	iser_op_params_t	ic_op_params;
158 	idm_conn_t		*ic_idmc;
159 	idm_svc_t		*ic_idms;
160 } iser_conn_t;
161 
162 /*
163  * iser_state_t is the iser driver's state structure, encoding all of
164  * the state information.
165  */
166 typedef struct iser_state_s {
167 	dev_info_t	*is_dip;
168 	int		is_instance;
169 
170 	/* IDM open ref counter and lock */
171 	kmutex_t	is_refcnt_lock;
172 	int		is_open_refcnt;
173 
174 	ibt_clnt_hdl_t	is_ibhdl;	/* IBT handle */
175 
176 	/* list of HCAs */
177 	kmutex_t	is_hcalist_lock; /* locked by is_hcalist_lock */
178 	list_t		is_hcalist;
179 	uint_t		is_num_hcas;
180 
181 	/* Connection list */
182 	iser_conn_t	*is_connlist;
183 
184 	/* Global work request handle cache */
185 	kmem_cache_t		*iser_wr_cache;
186 } iser_state_t;
187 
188 typedef enum {
189 	ISER_STATUS_SUCCESS = 0,
190 	ISER_STATUS_FAIL
191 } iser_status_t;
192 
193 int iser_idm_register();
194 
195 iser_status_t iser_register_service(idm_svc_t *idm_svc);
196 
197 iser_status_t iser_bind_service(idm_svc_t *idm_svc);
198 
199 void iser_unbind_service(idm_svc_t *idm_svc);
200 
201 void iser_deregister_service(idm_svc_t *idm_svc);
202 
203 boolean_t iser_path_exists(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr);
204 
205 iser_chan_t *iser_channel_alloc(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr);
206 
207 iser_status_t iser_channel_open(iser_chan_t *chan);
208 
209 void iser_channel_close(iser_chan_t *chan);
210 
211 void iser_channel_free(iser_chan_t *chan);
212 
213 void iser_internal_conn_destroy(iser_conn_t *ic);
214 
215 /* IDM refcnt utilities for the iSER tgt svc handle */
216 void iser_tgt_svc_hold(iser_svc_t *is);
217 void iser_tgt_svc_rele(iser_svc_t *is);
218 
219 
220 #ifdef	__cplusplus
221 }
222 #endif
223 
224 #endif /* _ISER_H */
225