xref: /illumos-gate/usr/src/uts/common/sys/ib/mgt/ibdm/ibdm_impl.h (revision 18edb70c0508fecdd79c3166ebb2b05bbd3bbe73)
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 2008 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 /* values for "cb_req_type" */
46 #define	IBDM_REQ_TYPE_INVALID		0x0
47 #define	IBDM_REQ_TYPE_CLASSPORTINFO	0x1
48 #define	IBDM_REQ_TYPE_IOUINFO		0x2
49 #define	IBDM_REQ_TYPE_IOCINFO		0x4
50 #define	IBDM_REQ_TYPE_SRVENTS		0x8
51 #define	IBDM_REQ_TYPE_IOU_DIAGCODE	0x10
52 #define	IBDM_REQ_TYPE_IOC_DIAGCODE	0x20
53 
54 typedef struct ibdm_taskq_args_s {
55 	ibmf_handle_t		tq_ibmf_handle;
56 	ibmf_msg_t		*tq_ibmf_msg;
57 	void			*tq_args;
58 } ibdm_taskq_args_t;
59 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibdm_taskq_args_t))
60 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ib_mad_hdr_t))
61 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibmf_msg_t))
62 
63 #define	IBDM_GID_PRESENT		0x1
64 #define	IBDM_GID_NOT_PRESENT		0x0
65 
66 #define	IBDM_IBMF_PKT_DUP_RESP		0x1
67 #define	IBDM_IBMF_PKT_REUSED		0x2
68 #define	IBDM_IBMF_PKT_UNEXP_RESP	0x4
69 
70 #define	IBDM_MAX_SERV_ENTRIES_PER_REQ	4
71 
72 typedef struct ibdm_gid_s {
73 	uint64_t		gid_dgid_hi;
74 	uint64_t		gid_dgid_lo;
75 	struct ibdm_gid_s	*gid_next;
76 } ibdm_gid_t;
77 
78 #define	IBDM_GID_PROBE_NOT_DONE		0x00
79 #define	IBDM_GET_CLASSPORTINFO		0x01
80 #define	IBDM_GET_IOUNITINFO		0x02
81 #define	IBDM_GET_IOC_DETAILS		0x04
82 #define	IBDM_GID_PROBING_COMPLETE	0x08
83 #define	IBDM_GID_PROBING_SKIPPED	0x10
84 #define	IBDM_GID_PROBING_FAILED		0x20
85 #define	IBDM_SET_CLASSPORTINFO		0x40
86 
87 /*
88  * Identifiers to distinguish a Cisco FC GW from others.
89  * Used to filter a setclassportinfo request.
90  */
91 #define	IBDM_CISCO_COMPANY_ID		(0x5ad)
92 #define	IBDM_CISCO_DEVICE_ID		(0xa87c)
93 
94 /*
95  * the bit-shift value for OUI in GUID
96  * A 64 bit globally unique identifier (GUID) composed of a 24 bit company id
97  * and an 48 bit extension identifier, and this value is used to extract
98  * the company id from the GUID.
99  */
100 #define	IBDM_OUI_GUID_SHIFT		(40)
101 
102 /*
103  * The state diagram for the gl_state
104  *
105  *                          (in case of Cisco FC GW)
106  * IBDM_GID_PROBE_NOT_DONE  ---------- 40 -> IBDM_SET_CLASSPORTINFO
107  *                          ----.	        |
108  *    |      |			| (others)      |
109  *    |      |			1		|
110  *    |      |			|               1
111  *    |      |			`-------------.	|
112  *    |      |                                v v
113  *    |	     |				     IBDM_GET_CLASSPORTINFO
114  *    |      |
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  *     40 = Port sends setClassPortInfo to activate Cisco FC GW
133  *	1 = Port supports DM MAD's and a request to ClassportInfo is sent
134  *	3 = Received ClassPortInfo and sent IOUnitInfo
135  *	4 = Recevied IOUunitInfo and sent IOC profile, diagcodes, and
136  *		service entries requests
137  *	5 = Received all the IOC information
138  *	2 = Failed to probe the GID
139  *		Port does not support DM MAD's
140  *		Port did not respond property
141  *	6 = A different GID for the same port, skip the probe
142  *
143  * Reprobe state transition :
144  *
145  * IBDM_GID_PROBE_COMPLETE
146  *	|
147  *	7
148  *	|
149  *	v
150  * IBDM_GET_IOC_DETAILS
151  *	|
152  *	8
153  *	|
154  *	v
155  * IBDM_GID_PROBE_COMPLETE
156  *
157  *	7 = Reprobe request for one or more IOCs initiated.
158  *	8 = Reprobe done(IOC COntroller Profile & Service entries)
159  */
160 
161 typedef struct ibdm_dp_gidinfo_s {
162 	kmutex_t		gl_mutex;
163 	uint_t			gl_state;
164 	int			gl_reprobe_flag;	/* pass this to taskq */
165 	struct ibdm_dp_gidinfo_s *gl_next;
166 	struct ibdm_dp_gidinfo_s *gl_prev;
167 	ibdm_iou_info_t		*gl_iou;
168 	int			gl_pending_cmds;
169 	ibmf_qp_handle_t	gl_qp_hdl;
170 	uint64_t		gl_transactionID;
171 	ibdm_timeout_cb_args_t	gl_iou_cb_args;
172 	ib_lid_t		gl_dlid;
173 	ib_lid_t		gl_slid;
174 	uint64_t		gl_dgid_hi;
175 	uint64_t		gl_dgid_lo;
176 	uint64_t		gl_sgid_hi;
177 	uint64_t		gl_sgid_lo;
178 	ib_guid_t		gl_nodeguid;
179 	ib_guid_t		gl_portguid;
180 	ib_pkey_t		gl_p_key;
181 	boolean_t		gl_redirected;
182 	uint32_t		gl_redirect_dlid;
183 	uint32_t		gl_redirect_QP;
184 	ib_pkey_t		gl_redirect_pkey;
185 	ib_qkey_t		gl_redirect_qkey;
186 	uint64_t		gl_redirectGID_hi;
187 	uint64_t		gl_redirectGID_lo;
188 	ibmf_handle_t		gl_ibmf_hdl;
189 	ibmf_saa_handle_t	gl_sa_hdl;
190 	timeout_id_t		gl_timeout_id;
191 	ibdm_timeout_cb_args_t	gl_cpi_cb_args;
192 	uint32_t		gl_ngids;
193 	ibdm_gid_t		*gl_gid;
194 	uint32_t		gl_resp_timeout;
195 	int			gl_num_iocs;
196 	ibdm_hca_list_t		*gl_hca_list;
197 	int			gl_disconnected;
198 	uint64_t		gl_min_transactionID;
199 	uint64_t		gl_max_transactionID;
200 	ibdm_iou_info_t		*gl_prev_iou;
201 	uint16_t		gl_devid;	/* device ID info */
202 	kcondvar_t		gl_probe_cv;	/* sync for Cisco FC GW */
203 	uint32_t		gl_flag;
204 	uint8_t			gl_SL:4; 	/* SL from path_record */
205 	uint8_t			gl_redirectSL:4; /* SL from redirection */
206 } ibdm_dp_gidinfo_t;
207 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
208 	ibdm_dp_gidinfo_s::{gl_state gl_timeout_id gl_pending_cmds}))
209 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_dp_gidinfo_s))
210 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_dp_gidinfo_s::{gl_ibmf_hdl gl_sa_hdl}))
211 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
212 	ibdm_ioc_info_s::{ioc_timeout_id ioc_dc_timeout_id}))
213 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
214 	ibdm_srvents_info_s::se_timeout_id))
215 
216 /*
217  * The transaction ID for the GID contains of two parts :
218  *	1. Upper 32 bits which is unique for each GID.
219  *	2. Lower 32 bits which is unique for each MAD.
220  * The assumptions are :
221  *	1. At most 2 power 32 DM capable GIDs on the IB fabric
222  *	2. IBDM sends maximum of 2 power 32 MADs to the same DM GID
223  * The limits are sufficient for practical configurations.
224  */
225 #define	IBDM_GID_TRANSACTIONID_SHIFT	((ulong_t)32)
226 #define	IBDM_GID_TRANSACTIONID_MASK	0xFFFFFFFF00000000ULL
227 
228 typedef struct ibdm_s {
229 	/* Protects IBDM's critical data */
230 	kmutex_t		ibdm_mutex;
231 	uint32_t		ibdm_hca_count;
232 	kmutex_t		ibdm_hl_mutex;
233 	kmutex_t		ibdm_ibnex_mutex;
234 	ibdm_hca_list_t		*ibdm_hca_list_head;
235 	ibdm_hca_list_t		*ibdm_hca_list_tail;
236 
237 	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_head;
238 	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_tail;
239 
240 	kcondvar_t		ibdm_probe_cv;
241 	kcondvar_t		ibdm_busy_cv;
242 	uint32_t		ibdm_ngid_probes_in_progress;
243 	uint64_t		ibdm_transactionID;
244 	uint32_t		ibdm_ngids;
245 	uint32_t		ibdm_busy;
246 	int			ibdm_state;
247 	ibt_clnt_hdl_t		ibdm_ibt_clnt_hdl;
248 
249 	/*
250 	 * These are callback routines registered by the IB nexus driver.
251 	 * These callbacks are used to inform the IB nexus driver about
252 	 * the arrival/removal of HCA and IOC's
253 	 */
254 	ibdm_callback_t		ibdm_ibnex_callback;
255 
256 	/* Flag indicating - prev_iou during sweep */
257 	int			ibdm_prev_iou;
258 } ibdm_t;
259 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_mutex, ibdm_s::{ibdm_ibt_clnt_hdl
260 	ibdm_busy ibdm_state}))
261 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_s::ibdm_ibt_clnt_hdl))
262 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_hl_mutex,
263 	ibdm_s::{ibdm_hca_list_head ibdm_hca_list_tail}))
264 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_ibnex_mutex,
265 	ibdm_s::ibdm_ibnex_callback))
266 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_s))
267 _NOTE(LOCK_ORDER(ibdm_s::ibdm_mutex ibdm_dp_gidinfo_s::gl_mutex))
268 
269 /* valid values for ibdm_state */
270 #define	IBDM_LOCKS_ALLOCED	0x01		/* global locks alloced */
271 #define	IBDM_CVS_ALLOCED	0x02		/* global "cv"s alloced */
272 #define	IBDM_IBT_ATTACHED	0x04		/* ibt_attach() called */
273 #define	IBDM_HCA_ATTACHED	0x08		/* ibdm_handle_hca() called */
274 
275 #define	IBDM_8_BIT_MASK		0x00FF
276 #define	IBDM_16_BIT_MASK	0xFFFF
277 #define	IBDM_RETRY_COUNT	0x2
278 
279 #define	IBDM_BUSY		0x1
280 #define	IBDM_PROBE_IN_PROGRESS	0x2
281 #define	IBDM_CISCO_PROBE	0x4
282 #define	IBDM_CISCO_PROBE_DONE	0x8
283 
284 /*
285  * Device Management MAD packet format
286  * +--------+------------+------------+------------+------------+
287  * | offset |   byte 0   |   byte 1   |   byte 2   |   byte 3   |
288  * +--------+------------+------------+------------+------------+ --
289  * |   0    |                                                   |  ^
290  * +--------+                                                   | sizeof(
291  * |   ...  |              Common MAD Header                    | ib_mad_hdr_t)
292  * +--------+                                                   |  | (A)
293  * |   20   |                                                   |  v
294  * +--------+------------+------------+------------+------------+ --
295  * |   24   |                                                   |  ^
296  * +--------+                                                   |  |
297  * |   ...  |              RMPP Header                          |  |
298  * +--------+                                                   |  |
299  * |   32   |                                                   |  |
300  * +--------+------------+------------+------------+------------+  |
301  * |   36   |                                                   |  |
302  * +--------+              Access_Key                           |
303  * |   40   |                                                   | IBDM_DM_MAD_
304  * +--------+------------+------------+------------+------------+ HDR_SZ
305  * |   44   |  KeyType   |              reserved                |    (B)
306  * +--------+------------+------------+------------+------------+  |
307  * |   48   |                                                   |  |
308  * +--------+                                                   |  |
309  * |   52   |              Reserved                             |  |
310  * +--------+                                                   |  |
311  * |   56   |                                                   |  |
312  * +--------+------------+------------+------------+------------+  |
313  * |   60   |       Change_ID         |     ComponentMask       |  v
314  * +--------+------------+------------+------------+------------+ --
315  * |   64   |                                                   |  ^
316  * +--------+                                                   | IBDM_MAD_SIZE
317  * |   ...  |              Device Management Data               | - (A) - (B)
318  * +--------+                                                   |  |
319  * |  252   |                                                   |  v
320  * +--------+------------+------------+------------+------------+ --
321  */
322 #define	IBDM_MAD_SIZE		256
323 #define	IBDM_DM_MAD_HDR_SZ	40
324 
325 #define	IBDM_DFT_TIMEOUT	4
326 #define	IBDM_DFT_NRETRIES	3
327 
328 #define	IBDM_ENABLE_TASKQ_HANDLING	1
329 #define	IBDM_DISABLE_TASKQ_HANLDING	0
330 
331 typedef struct ibdm_saa_event_arg_s {
332 	ibmf_saa_handle_t ibmf_saa_handle;
333 	ibmf_saa_subnet_event_t ibmf_saa_event;
334 	ibmf_saa_event_details_t event_details;
335 	void *callback_arg;
336 } ibdm_saa_event_arg_t;
337 
338 #define	IBDM_TIMEOUT_VALUE(t)	(drv_usectohz(t * 1000000))
339 
340 #define	IBDM_OUT_IBMFMSG_MADHDR(msg)\
341 		(msg->im_msgbufs_send.im_bufs_mad_hdr)
342 
343 #define	IBDM_IN_IBMFMSG_MADHDR(msg)\
344 		(msg->im_msgbufs_recv.im_bufs_mad_hdr)
345 
346 #define	IBDM_IN_IBMFMSG_STATUS(msg)\
347 		b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->Status)
348 
349 #define	IBDM_IN_IBMFMSG_ATTR(msg)\
350 		b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeID)
351 
352 #define	IBDM_IN_IBMFMSG_ATTRMOD(msg)\
353 		b2h32(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeModifier)
354 
355 #define	IBDM_IN_IBMFMSG2IOU(msg)	(ib_dm_io_unitinfo_t *)\
356 		(msg->im_msgbufs_recv.im_bufs_cl_data)
357 
358 #define	IBDM_IN_IBMFMSG2IOC(msg)	(ib_dm_ioc_ctrl_profile_t *)\
359 		(msg->im_msgbufs_recv.im_bufs_cl_data)
360 
361 #define	IBDM_IN_IBMFMSG2SRVENT(msg)	(ib_dm_srv_t *)\
362 		(msg->im_msgbufs_recv.im_bufs_cl_data)
363 
364 #define	IBDM_IN_IBMFMSG2DIAGCODE(msg)	(uint32_t *)\
365 		(msg->im_msgbufs_recv.im_bufs_cl_data)
366 
367 #define	IBDM_GIDINFO2IOCINFO(gid_info, idx) \
368 		(ibdm_ioc_info_t *)&gid_info->gl_iou->iou_ioc_info[idx];
369 
370 #define	IBDM_IS_IOC_NUM_INVALID(ioc_no, gid_info)\
371 		((ioc_no < 1) || (ioc_no >\
372 			gid_info->gl_iou->iou_info.iou_num_ctrl_slots))
373 
374 #define	IBDM_INVALID_PKEY(pkey)	\
375 		(((pkey) == IB_PKEY_INVALID_FULL) || \
376 		((pkey) == IB_PKEY_INVALID_LIMITED))
377 
378 #ifdef DEBUG
379 
380 void	ibdm_dump_mad_hdr(ib_mad_hdr_t *);
381 void	ibdm_dump_ibmf_msg(ibmf_msg_t *, int);
382 void	ibdm_dump_path_info(sa_path_record_t *);
383 void	ibdm_dump_classportinfo(ib_mad_classportinfo_t *);
384 void	ibdm_dump_iounitinfo(ib_dm_io_unitinfo_t *);
385 void	ibdm_dump_ioc_profile(ib_dm_ioc_ctrl_profile_t *);
386 void	ibdm_dump_service_entries(ib_dm_srv_t *);
387 void	ibdm_dump_sweep_fabric_timestamp(int);
388 
389 #define	ibdm_dump_mad_hdr(a)		ibdm_dump_mad_hdr(a)
390 #define	ibdm_dump_ibmf_msg(a, b)	ibdm_dump_ibmf_msg(a, b)
391 #define	ibdm_dump_path_info(a)		ibdm_dump_path_info(a)
392 #define	ibdm_dump_classportinfo(a)	ibdm_dump_classportinfo(a)
393 #define	ibdm_dump_iounitinfo(a)		ibdm_dump_iounitinfo(a)
394 #define	ibdm_dump_ioc_profile(a)	ibdm_dump_ioc_profile(a)
395 #define	ibdm_dump_service_entries(a)	ibdm_dump_service_entries(a)
396 
397 #else
398 
399 #define	ibdm_dump_mad_hdr(a)
400 #define	ibdm_dump_ibmf_msg(a, b)
401 #define	ibdm_dump_path_info(a)
402 #define	ibdm_dump_classportinfo(a)
403 #define	ibdm_dump_iounitinfo(a)
404 #define	ibdm_dump_ioc_profile(a)
405 #define	ibdm_dump_service_entries(a)
406 #define	ibdm_dump_sweep_fabric_timestamp(a)
407 
408 #endif
409 
410 #ifdef __cplusplus
411 }
412 #endif
413 
414 #endif	/* _SYS_IB_MGT_IBDM_IBDM_IMPL_H */
415