xref: /illumos-gate/usr/src/uts/common/sys/ib/mgt/ibdm/ibdm_impl.h (revision 24da5b34f49324ed742a340010ed5bd3d4e06625)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_IB_MGT_IBDM_IBDM_IMPL_H
27 #define	_SYS_IB_MGT_IBDM_IBDM_IMPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 /*
32  * ibdm_impl.h
33  *
34  *	This file contains definitions of the data structures, macros etc
35  *	related to the IBDM module.
36  */
37 
38 #include <sys/ib/mgt/ibdm/ibdm_ibnex.h>
39 #include <sys/ib/ibtl/impl/ibtl_util.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 typedef struct ibdm_mad_classportinfo_s {
46 	uint8_t		BaseVersion;		/* ver. of MAD base format */
47 	uint8_t		ClassVersion;		/* ver. of MAD class format */
48 	uint16_t	CapabilityMask;		/* capabilities of this class */
49 	uint32_t	RespTimeValue;		/* reserved : 27 bits */
50 						/* resptime value : 5 bits */
51 	uint64_t	RedirectGID_hi;		/* dest gid of redirect msgs */
52 	uint64_t	RedirectGID_lo;		/* dest gid of redirect msgs */
53 	uint32_t	RedirectTC;		/* traffic class: 8 bits */
54 						/* SL: 4 bits */
55 						/* Flow label: 20 bits */
56 	ib_lid_t	RedirectLID;		/* dlid for class services */
57 	ib_pkey_t	RedirectP_Key;		/* p_key for class services */
58 	uint32_t	RedirectQP;		/* Reserved: 8 bits */
59 						/* QPN: 24 bits */
60 	ib_qkey_t	RedirectQ_Key;		/* q_key for class services */
61 	uint64_t	TrapGID_hi;		/* dest gid of trap msgs */
62 	uint64_t	TrapGID_lo;		/* dest gid of trap msgs */
63 	uint32_t	TrapTC;			/* Trap traffic class, etc., */
64 	ib_lid_t	TrapLID;		/* dlid for traps */
65 	ib_pkey_t	TrapP_Key;		/* p_key for traps */
66 	uint32_t	TrapHL;			/* Trap hop limit,etc., */
67 	ib_qkey_t	TrapQ_Key;		/* q_key for traps */
68 } ibdm_mad_classportinfo_t;
69 
70 /* values for "cb_req_type" */
71 #define	IBDM_REQ_TYPE_INVALID		0x0
72 #define	IBDM_REQ_TYPE_CLASSPORTINFO	0x1
73 #define	IBDM_REQ_TYPE_IOUINFO		0x2
74 #define	IBDM_REQ_TYPE_IOCINFO		0x4
75 #define	IBDM_REQ_TYPE_SRVENTS		0x8
76 #define	IBDM_REQ_TYPE_IOU_DIAGCODE	0x10
77 #define	IBDM_REQ_TYPE_IOC_DIAGCODE	0x20
78 
79 typedef struct ibdm_taskq_args_s {
80 	ibmf_handle_t		tq_ibmf_handle;
81 	ibmf_msg_t		*tq_ibmf_msg;
82 	void			*tq_args;
83 } ibdm_taskq_args_t;
84 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibdm_taskq_args_t))
85 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ib_mad_hdr_t))
86 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibmf_msg_t))
87 
88 #define	IBDM_GID_PRESENT		0x1
89 #define	IBDM_GID_NOT_PRESENT		0x0
90 
91 #define	IBDM_IBMF_PKT_DUP_RESP		0x1
92 #define	IBDM_IBMF_PKT_REUSED		0x2
93 #define	IBDM_IBMF_PKT_UNEXP_RESP	0x4
94 
95 #define	IBDM_MAX_SERV_ENTRIES_PER_REQ	4
96 
97 typedef struct ibdm_gid_s {
98 	uint64_t		gid_dgid_hi;
99 	uint64_t		gid_dgid_lo;
100 	struct ibdm_gid_s	*gid_next;
101 } ibdm_gid_t;
102 
103 #define	IBDM_GID_PROBE_NOT_DONE		0x00
104 #define	IBDM_GET_CLASSPORTINFO		0x01
105 #define	IBDM_GET_IOUNITINFO		0x02
106 #define	IBDM_GET_IOC_DETAILS		0x04
107 #define	IBDM_GID_PROBING_COMPLETE	0x08
108 #define	IBDM_GID_PROBING_SKIPPED	0x10
109 #define	IBDM_GID_PROBING_FAILED		0x20
110 
111 /*
112  * The state diagram for the gl_state
113  *
114  * IBDM_GID_PROBE_NOT_DONE  --- 1 -> IBDM_GID_GET_CLASSPORTINFO
115  *    |      |                                  |
116  *    |      2                                  3
117  *    |      |                                  |
118  *    |      v                                  v
119  *    |     IBDM_GID_PROBING_FAILED          IBDM_GET_IOUNITINFO
120  *    |                                         |
121  *    6                                         4
122  *    |                                         |
123  *    v                                         v
124  *  IBDM_GID_PROBING_SKIPPLED                IBDM_GET_IOC_DETAILS
125  *                                              |
126  *                                              5
127  *                                              |
128  *                                              v
129  *                                           IBDM_GID_PROBE_COMPLETE
130  *
131  * Initial state : IBDM_GID_PROBE_NOT_DONE
132  *	1 = Port supports DM MAD's and a request to ClassportInfor is sent
133  *	3 = Received ClassPortInfo and sent IOUnitInfo
134  *	4 = Recevied IOUunitInfo and sent IOC profile, diagcodes, and
135  *		service entries requests
136  *	5 = Received all the IOC information
137  *	2 = Failed to probe the GID
138  *		Port does not support DM MAD's
139  *		Port did not respond property
140  *	6 = A different GID for the same port, skip the probe
141  *
142  * Reprobe state transition :
143  *
144  * IBDM_GID_PROBE_COMPLETE
145  *	|
146  *	7
147  *	|
148  *	v
149  * IBDM_GET_IOC_DETAILS
150  *	|
151  *	8
152  *	|
153  *	v
154  * IBDM_GID_PROBE_COMPLETE
155  *
156  *	7 = Reprobe request for one or more IOCs initiated.
157  *	8 = Reprobe done(IOC COntroller Profile & Service entries)
158  */
159 
160 typedef struct ibdm_dp_gidinfo_s {
161 	kmutex_t		gl_mutex;
162 	uint_t			gl_state;
163 	int			gl_reprobe_flag;	/* pass this to taskq */
164 	struct ibdm_dp_gidinfo_s *gl_next;
165 	struct ibdm_dp_gidinfo_s *gl_prev;
166 	ibdm_iou_info_t		*gl_iou;
167 	int			gl_pending_cmds;
168 	ibmf_qp_handle_t	gl_qp_hdl;
169 	uint64_t		gl_transactionID;
170 	ibdm_timeout_cb_args_t	gl_iou_cb_args;
171 	ib_lid_t		gl_dlid;
172 	ib_lid_t		gl_slid;
173 	uint64_t		gl_dgid_hi;
174 	uint64_t		gl_dgid_lo;
175 	uint64_t		gl_sgid_hi;
176 	uint64_t		gl_sgid_lo;
177 	ib_guid_t		gl_nodeguid;
178 	ib_guid_t		gl_portguid;
179 	ib_pkey_t		gl_p_key;
180 	boolean_t		gl_redirected;
181 	uint32_t		gl_redirect_dlid;
182 	uint32_t		gl_redirect_QP;
183 	ib_pkey_t		gl_redirect_pkey;
184 	ib_qkey_t		gl_redirect_qkey;
185 	uint64_t		gl_redirectGID_hi;
186 	uint64_t		gl_redirectGID_lo;
187 	ibmf_handle_t		gl_ibmf_hdl;
188 	ibmf_saa_handle_t	gl_sa_hdl;
189 	timeout_id_t		gl_timeout_id;
190 	ibdm_timeout_cb_args_t	gl_cpi_cb_args;
191 	uint32_t		gl_ngids;
192 	ibdm_gid_t		*gl_gid;
193 	uint32_t		gl_resp_timeout;
194 	int			gl_num_iocs;
195 	ibdm_hca_list_t		*gl_hca_list;
196 	int			gl_disconnected;
197 	uint64_t		gl_min_transactionID;
198 	uint64_t		gl_max_transactionID;
199 	ibdm_iou_info_t		*gl_prev_iou;
200 } ibdm_dp_gidinfo_t;
201 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
202 	ibdm_dp_gidinfo_s::{gl_state gl_timeout_id gl_pending_cmds}))
203 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_dp_gidinfo_s))
204 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_dp_gidinfo_s::{gl_ibmf_hdl gl_sa_hdl}))
205 
206 /*
207  * The transaction ID for the GID contains of two parts :
208  *	1. Upper 32 bits which is unique for each GID.
209  *	2. Lower 32 bits which is unique for each MAD.
210  * The assumptions are :
211  *	1. At most 2 power 32 DM capable GIDs on the IB fabric
212  *	2. IBDM sends maximum of 2 power 32 MADs to the same DM GID
213  * The limits are sufficient for practical configurations.
214  */
215 #define	IBDM_GID_TRANSACTIONID_SHIFT	((ulong_t)32)
216 #define	IBDM_GID_TRANSACTIONID_MASK	0xFFFFFFFF00000000ULL
217 
218 typedef struct ibdm_s {
219 	/* Protects IBDM's critical data */
220 	kmutex_t		ibdm_mutex;
221 	uint32_t		ibdm_hca_count;
222 	kmutex_t		ibdm_hl_mutex;
223 	kmutex_t		ibdm_ibnex_mutex;
224 	ibdm_hca_list_t		*ibdm_hca_list_head;
225 	ibdm_hca_list_t		*ibdm_hca_list_tail;
226 
227 	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_head;
228 	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_tail;
229 
230 	kcondvar_t		ibdm_probe_cv;
231 	kcondvar_t		ibdm_busy_cv;
232 	uint32_t		ibdm_ngid_probes_in_progress;
233 	uint64_t		ibdm_transactionID;
234 	uint32_t		ibdm_ngids;
235 	uint32_t		ibdm_busy;
236 	int			ibdm_state;
237 	ibt_clnt_hdl_t		ibdm_ibt_clnt_hdl;
238 
239 	/*
240 	 * These are callback routines registered by the IB nexus driver.
241 	 * These callbacks are used to inform the IB nexus driver about
242 	 * the arrival/removal of HCA and IOC's
243 	 */
244 	ibdm_callback_t		ibdm_ibnex_callback;
245 
246 	/* Flag indicating - prev_iou during sweep */
247 	int			ibdm_prev_iou;
248 } ibdm_t;
249 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_mutex, ibdm_s::{ibdm_ibt_clnt_hdl
250 	ibdm_busy ibdm_state}))
251 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_s::ibdm_ibt_clnt_hdl))
252 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_hl_mutex,
253 	ibdm_s::{ibdm_hca_list_head ibdm_hca_list_tail}))
254 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_ibnex_mutex,
255 	ibdm_s::ibdm_ibnex_callback))
256 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_s))
257 _NOTE(LOCK_ORDER(ibdm_s::ibdm_mutex ibdm_dp_gidinfo_s::gl_mutex))
258 
259 /* valid values for ibdm_state */
260 #define	IBDM_LOCKS_ALLOCED	0x01		/* global locks alloced */
261 #define	IBDM_CVS_ALLOCED	0x02		/* global "cv"s alloced */
262 #define	IBDM_IBT_ATTACHED	0x04		/* ibt_attach() called */
263 #define	IBDM_HCA_ATTACHED	0x08		/* ibdm_handle_hca() called */
264 
265 #define	IBDM_8_BIT_MASK		0x00FF
266 #define	IBDM_16_BIT_MASK	0xFFFF
267 #define	IBDM_RETRY_COUNT	0x2
268 
269 #define	IBDM_BUSY		0x1
270 #define	IBDM_PROBE_IN_PROGRESS	0x2
271 
272 #define	IBDM_MAD_SIZE		256
273 #define	DM_CLASSPORTINFO_SZ	72
274 
275 #define	IBDM_DFT_TIMEOUT	4
276 #define	IBDM_DFT_NRETRIES	3
277 
278 #define	IBDM_ENABLE_TASKQ_HANDLING	1
279 #define	IBDM_DISABLE_TASKQ_HANLDING	0
280 
281 typedef struct ibdm_saa_event_arg_s {
282 	ibmf_saa_handle_t ibmf_saa_handle;
283 	ibmf_saa_subnet_event_t ibmf_saa_event;
284 	ibmf_saa_event_details_t event_details;
285 	void *callback_arg;
286 } ibdm_saa_event_arg_t;
287 
288 #define	IBDM_TIMEOUT_VALUE(t)	(drv_usectohz(t * 1000000))
289 
290 #define	IBDM_OUT_IBMFMSG_MADHDR(msg)\
291 		(msg->im_msgbufs_send.im_bufs_mad_hdr)
292 
293 #define	IBDM_IN_IBMFMSG_MADHDR(msg)\
294 		(msg->im_msgbufs_recv.im_bufs_mad_hdr)
295 
296 #define	IBDM_IN_IBMFMSG_STATUS(msg)\
297 		b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->Status)
298 
299 #define	IBDM_IN_IBMFMSG_ATTR(msg)\
300 		b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeID)
301 
302 #define	IBDM_IN_IBMFMSG_ATTRMOD(msg)\
303 		b2h32(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeModifier)
304 
305 #define	IBDM_IN_IBMFMSG2IOU(msg)	(ib_dm_io_unitinfo_t *)\
306 		(msg->im_msgbufs_recv.im_bufs_cl_data)
307 
308 #define	IBDM_IN_IBMFMSG2IOC(msg)	(ib_dm_ioc_ctrl_profile_t *)\
309 		(msg->im_msgbufs_recv.im_bufs_cl_data)
310 
311 #define	IBDM_IN_IBMFMSG2SRVENT(msg)	(ib_dm_srv_t *)\
312 		(msg->im_msgbufs_recv.im_bufs_cl_data)
313 
314 #define	IBDM_IN_IBMFMSG2DIAGCODE(msg)	(uint32_t *)\
315 		(msg->im_msgbufs_recv.im_bufs_cl_data)
316 
317 #define	IBDM_GIDINFO2IOCINFO(gid_info, idx) \
318 		(ibdm_ioc_info_t *)&gid_info->gl_iou->iou_ioc_info[idx];
319 
320 #define	IBDM_IS_IOC_NUM_INVALID(ioc_no, gid_info)\
321 		((ioc_no < 1) || (ioc_no >\
322 			gid_info->gl_iou->iou_info.iou_num_ctrl_slots))
323 
324 #define	IBDM_INVALID_PKEY(pkey)	\
325 		(((pkey) == IB_PKEY_INVALID_FULL) || \
326 		((pkey) == IB_PKEY_INVALID_LIMITED))
327 
328 #ifdef DEBUG
329 
330 void	ibdm_dump_ibmf_msg(ibmf_msg_t *, int);
331 void	ibdm_dump_path_info(sa_path_record_t *);
332 void	ibdm_dump_classportinfo(ibdm_mad_classportinfo_t *);
333 void	ibdm_dump_iounitinfo(ib_dm_io_unitinfo_t *);
334 void	ibdm_dump_ioc_profile(ib_dm_ioc_ctrl_profile_t *);
335 void	ibdm_dump_service_entries(ib_dm_srv_t *);
336 void	ibdm_dump_sweep_fabric_timestamp(int);
337 
338 #define	ibdm_dump_ibmf_msg(a, b)	ibdm_dump_ibmf_msg(a, b)
339 #define	ibdm_dump_path_info(a)		ibdm_dump_path_info(a)
340 #define	ibdm_dump_classportinfo(a)	ibdm_dump_classportinfo(a)
341 #define	ibdm_dump_iounitinfo(a)		ibdm_dump_iounitinfo(a)
342 #define	ibdm_dump_ioc_profile(a)	ibdm_dump_ioc_profile(a)
343 #define	ibdm_dump_service_entries(a)	ibdm_dump_service_entries(a)
344 
345 #else
346 
347 #define	ibdm_dump_ibmf_msg(a, b)
348 #define	ibdm_dump_path_info(a)
349 #define	ibdm_dump_classportinfo(a)
350 #define	ibdm_dump_iounitinfo(a)
351 #define	ibdm_dump_ioc_profile(a)
352 #define	ibdm_dump_service_entries(a)
353 #define	ibdm_dump_sweep_fabric_timestamp(a)
354 
355 #endif
356 
357 #ifdef __cplusplus
358 }
359 #endif
360 
361 #endif	/* _SYS_IB_MGT_IBDM_IBDM_IMPL_H */
362