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 _SYS_IB_MGT_IBDM_IBDM_IMPL_H
27#define	_SYS_IB_MGT_IBDM_IBDM_IMPL_H
28
29/*
30 * ibdm_impl.h
31 *
32 *	This file contains definitions of the data structures, macros etc
33 *	related to the IBDM module.
34 */
35
36#include <sys/ib/mgt/ibdm/ibdm_ibnex.h>
37#include <sys/ib/ibtl/impl/ibtl_util.h>
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/* values for "cb_req_type" */
44#define	IBDM_REQ_TYPE_INVALID		0x0
45#define	IBDM_REQ_TYPE_CLASSPORTINFO	0x1
46#define	IBDM_REQ_TYPE_IOUINFO		0x2
47#define	IBDM_REQ_TYPE_IOCINFO		0x4
48#define	IBDM_REQ_TYPE_SRVENTS		0x8
49#define	IBDM_REQ_TYPE_IOU_DIAGCODE	0x10
50#define	IBDM_REQ_TYPE_IOC_DIAGCODE	0x20
51
52typedef struct ibdm_taskq_args_s {
53	ibmf_handle_t		tq_ibmf_handle;
54	ibmf_msg_t		*tq_ibmf_msg;
55	void			*tq_args;
56} ibdm_taskq_args_t;
57_NOTE(SCHEME_PROTECTS_DATA("unique per call", ibdm_taskq_args_t))
58_NOTE(SCHEME_PROTECTS_DATA("unique per call", ib_mad_hdr_t))
59_NOTE(SCHEME_PROTECTS_DATA("unique per call", ibmf_msg_t))
60
61#define	IBDM_GID_PRESENT		0x1
62#define	IBDM_GID_NOT_PRESENT		0x0
63
64#define	IBDM_IBMF_PKT_DUP_RESP		0x1
65#define	IBDM_IBMF_PKT_REUSED		0x2
66#define	IBDM_IBMF_PKT_UNEXP_RESP	0x4
67
68#define	IBDM_MAX_SERV_ENTRIES_PER_REQ	4
69
70typedef struct ibdm_gid_s {
71	uint64_t		gid_dgid_hi;
72	uint64_t		gid_dgid_lo;
73	struct ibdm_gid_s	*gid_next;
74} ibdm_gid_t;
75
76#define	IBDM_GID_PROBE_NOT_DONE		0x00
77#define	IBDM_GET_CLASSPORTINFO		0x01
78#define	IBDM_GET_IOUNITINFO		0x02
79#define	IBDM_GET_IOC_DETAILS		0x04
80#define	IBDM_GID_PROBING_COMPLETE	0x08
81#define	IBDM_GID_PROBING_SKIPPED	0x10
82#define	IBDM_GID_PROBING_FAILED		0x20
83#define	IBDM_SET_CLASSPORTINFO		0x40
84
85/*
86 * Identifiers to distinguish a Cisco FC GW from others.
87 * Used to filter a setclassportinfo request.
88 */
89#define	IBDM_CISCO_COMPANY_ID		(0x5ad)
90#define	IBDM_CISCO_DEVICE_ID		(0xa87c)
91
92/*
93 * the bit-shift value for OUI in GUID
94 * A 64 bit globally unique identifier (GUID) composed of a 24 bit company id
95 * and an 48 bit extension identifier, and this value is used to extract
96 * the company id from the GUID.
97 */
98#define	IBDM_OUI_GUID_SHIFT		(40)
99
100/*
101 * The state diagram for the gl_state
102 *
103 *                          (in case of Cisco FC GW)
104 * IBDM_GID_PROBE_NOT_DONE  ---------- 40 -> IBDM_SET_CLASSPORTINFO
105 *                          ----.	        |
106 *    |      |			| (others)      |
107 *    |      |			1		|
108 *    |      |			|               1
109 *    |      |			`-------------.	|
110 *    |      |                                v v
111 *    |	     |				     IBDM_GET_CLASSPORTINFO
112 *    |      |
113 *    |      |                                  |
114 *    |      2                                  3
115 *    |      |                                  |
116 *    |      v                                  v
117 *    |     IBDM_GID_PROBING_FAILED          IBDM_GET_IOUNITINFO
118 *    |                                         |
119 *    6                                         4
120 *    |                                         |
121 *    v                                         v
122 *  IBDM_GID_PROBING_SKIPPLED                IBDM_GET_IOC_DETAILS
123 *                                              |
124 *                                              5
125 *                                              |
126 *                                              v
127 *                                           IBDM_GID_PROBE_COMPLETE
128 *
129 * Initial state : IBDM_GID_PROBE_NOT_DONE
130 *     40 = Port sends setClassPortInfo to activate Cisco FC GW
131 *	1 = Port supports DM MAD's and a request to ClassportInfo is sent
132 *	3 = Received ClassPortInfo and sent IOUnitInfo
133 *	4 = Recevied IOUunitInfo and sent IOC profile, diagcodes, and
134 *		service entries requests
135 *	5 = Received all the IOC information
136 *	2 = Failed to probe the GID
137 *		Port does not support DM MAD's
138 *		Port did not respond property
139 *	6 = A different GID for the same port, skip the probe
140 *
141 * Reprobe state transition :
142 *
143 * IBDM_GID_PROBE_COMPLETE
144 *	|
145 *	7
146 *	|
147 *	v
148 * IBDM_GET_IOC_DETAILS
149 *	|
150 *	8
151 *	|
152 *	v
153 * IBDM_GID_PROBE_COMPLETE
154 *
155 *	7 = Reprobe request for one or more IOCs initiated.
156 *	8 = Reprobe done(IOC COntroller Profile & Service entries)
157 */
158
159typedef struct ibdm_dp_gidinfo_s {
160	kmutex_t		gl_mutex;
161	uint_t			gl_state;
162	int			gl_reprobe_flag;	/* pass this to taskq */
163	struct ibdm_dp_gidinfo_s *gl_next;
164	struct ibdm_dp_gidinfo_s *gl_prev;
165	ibdm_iou_info_t		*gl_iou;
166	int			gl_pending_cmds;
167	ibmf_qp_handle_t	gl_qp_hdl;
168	uint64_t		gl_transactionID;
169	ibdm_timeout_cb_args_t	gl_iou_cb_args;
170	ib_lid_t		gl_dlid;
171	ib_lid_t		gl_slid;
172	uint64_t		gl_dgid_hi;
173	uint64_t		gl_dgid_lo;
174	uint64_t		gl_sgid_hi;
175	uint64_t		gl_sgid_lo;
176	ib_guid_t		gl_nodeguid;
177	ib_guid_t		gl_portguid;
178	ib_pkey_t		gl_p_key;
179	boolean_t		gl_is_dm_capable;
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	uint16_t		gl_devid;	/* device ID info */
201	kcondvar_t		gl_probe_cv;	/* sync for Cisco FC GW */
202	uint32_t		gl_flag;
203	uint8_t			gl_SL:4; 	/* SL from path_record */
204	uint8_t			gl_redirectSL:4; /* SL from redirection */
205} ibdm_dp_gidinfo_t;
206_NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
207	ibdm_dp_gidinfo_s::{gl_state gl_timeout_id gl_pending_cmds}))
208_NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_dp_gidinfo_s))
209_NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_dp_gidinfo_s::{gl_ibmf_hdl gl_sa_hdl}))
210_NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
211	ibdm_ioc_info_s::{ioc_timeout_id ioc_dc_timeout_id}))
212_NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex,
213	ibdm_srvents_info_s::se_timeout_id))
214
215/*
216 * The transaction ID for the GID contains of two parts :
217 *	1. Upper 32 bits which is unique for each GID.
218 *	2. Lower 32 bits which is unique for each MAD.
219 * The assumptions are :
220 *	1. At most 2 power 32 DM capable GIDs on the IB fabric
221 *	2. IBDM sends maximum of 2 power 32 MADs to the same DM GID
222 * The limits are sufficient for practical configurations.
223 */
224#define	IBDM_GID_TRANSACTIONID_SHIFT	((ulong_t)32)
225#define	IBDM_GID_TRANSACTIONID_MASK	0xFFFFFFFF00000000ULL
226
227typedef struct ibdm_s {
228	/* Protects IBDM's critical data */
229	kmutex_t		ibdm_mutex;
230	uint32_t		ibdm_hca_count;
231	kmutex_t		ibdm_hl_mutex;
232	kmutex_t		ibdm_ibnex_mutex;
233	ibdm_hca_list_t		*ibdm_hca_list_head;
234	ibdm_hca_list_t		*ibdm_hca_list_tail;
235
236	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_head;
237	ibdm_dp_gidinfo_t	*ibdm_dp_gidlist_tail;
238
239	kcondvar_t		ibdm_probe_cv;
240	kcondvar_t		ibdm_busy_cv;
241	kcondvar_t		ibdm_port_settle_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
331typedef 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
380void	ibdm_dump_mad_hdr(ib_mad_hdr_t *);
381void	ibdm_dump_ibmf_msg(ibmf_msg_t *, int);
382void	ibdm_dump_path_info(sa_path_record_t *);
383void	ibdm_dump_classportinfo(ib_mad_classportinfo_t *);
384void	ibdm_dump_iounitinfo(ib_dm_io_unitinfo_t *);
385void	ibdm_dump_ioc_profile(ib_dm_ioc_ctrl_profile_t *);
386void	ibdm_dump_service_entries(ib_dm_srv_t *);
387void	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