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  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
27  */
28 
29 #ifndef _SYS_IB_MGT_IBDM_IBDM_IBNEX_H
30 #define	_SYS_IB_MGT_IBDM_IBDM_IBNEX_H
31 
32 /*
33  * This file contains the definitions of private interfaces
34  * and data structures used between IB nexus and IBDM.
35  */
36 
37 #include <sys/ib/ibtl/ibti_common.h>
38 #include <sys/ib/mgt/ibmf/ibmf.h>
39 #include <sys/ib/mgt/ib_dm_attr.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /* DM return status codes from private interfaces */
46 typedef enum ibdm_status_e {
47 	IBDM_SUCCESS = 0,
48 	IBDM_FAILURE = 1
49 } ibdm_status_t;
50 
51 /*
52  * IBDM events that are passed to IB nexus driver
53  * NOTE: These are different from ibt_async_code_t
54  */
55 typedef enum ibdm_events_e {
56 	IBDM_EVENT_HCA_ADDED,
57 	IBDM_EVENT_HCA_REMOVED,
58 	IBDM_EVENT_IOC_PROP_UPDATE,
59 	IBDM_EVENT_PORT_UP,
60 	IBDM_EVENT_PORT_PKEY_CHANGE
61 } ibdm_events_t;
62 
63 /*
64  * Flags for ibdm_ibnex_get_ioc_list.
65  * The flags determine the functioning of ibdm_ibnex_get_ioc_list.
66  *
67  * 	IBDM_IBNEX_NORMAL_PROBE
68  *		Sweep fabric and discover new GIDs only
69  *		This value should be same as IBNEX_PROBE_ALLOWED_FLAG
70  *	IBDM_IBNEX_DONOT_PROBE
71  *		Do not probe, just get the current ioc_list.
72  *		This value should be same as IBNEX_DONOT_PROBE_FLAG
73  *	IBDM_IBNEX_REPROBE_ALL
74  *		Sweep fabric, discover new GIDs. For GIDs
75  *		discovered before, reprobe the IOCs on it.
76  */
77 typedef enum ibdm_ibnex_get_ioclist_mtd_e {
78 	IBDM_IBNEX_NORMAL_PROBE,
79 	IBDM_IBNEX_DONOT_PROBE,
80 	IBDM_IBNEX_REPROBE_ALL
81 } ibdm_ibnex_get_ioclist_mtd_t;
82 
83 
84 /*
85  * Private data structure called from IBDM timeout handler
86  */
87 typedef struct ibdm_timeout_cb_args_s {
88 	struct ibdm_dp_gidinfo_s	*cb_gid_info;
89 	int				cb_req_type;
90 	int				cb_ioc_num;		/* IOC# */
91 	int				cb_retry_count;
92 	int				cb_srvents_start;
93 	int				cb_srvents_end;
94 } ibdm_timeout_cb_args_t;
95 
96 /*
97  * Service entry structure
98  */
99 typedef struct ibdm_srvents_info_s {
100 	int				se_state;
101 	ib_dm_srv_t			se_attr;
102 	timeout_id_t			se_timeout_id;	/* IBDM specific */
103 	ibdm_timeout_cb_args_t		se_cb_args;
104 } ibdm_srvents_info_t;
105 
106 /* values for "se_state" */
107 #define	IBDM_SE_VALID			0x1
108 #define	IBDM_SE_INVALID			0x0
109 
110 
111 /* I/O Controller information */
112 typedef struct ibdm_ioc_info_s {
113 	ib_dm_ioc_ctrl_profile_t	ioc_profile;
114 	int				ioc_state;
115 	ibdm_srvents_info_t		*ioc_serv;
116 	struct ibdm_gid_s		*ioc_gid_list;
117 	uint_t				ioc_nportgids;
118 	ib_guid_t			ioc_iou_guid;
119 	timeout_id_t			ioc_timeout_id;
120 	timeout_id_t			ioc_dc_timeout_id;
121 	boolean_t			ioc_dc_valid;
122 	boolean_t			ioc_iou_dc_valid;
123 	ibdm_timeout_cb_args_t		ioc_cb_args;
124 	ibdm_timeout_cb_args_t		ioc_dc_cb_args;
125 	ib_guid_t			ioc_nodeguid;
126 	uint16_t			ioc_diagcode;
127 	uint16_t			ioc_iou_diagcode;
128 	uint16_t			ioc_diagdeviceid;
129 	struct ibdm_iou_info_s		*ioc_iou_info;
130 	struct ibdm_ioc_info_s 		*ioc_next;
131 
132 	/* Previous fields for reprobe */
133 	ibdm_srvents_info_t		*ioc_prev_serv;
134 	struct ibdm_gid_s		*ioc_prev_gid_list;
135 	uint8_t				ioc_prev_serv_cnt;
136 	uint_t				ioc_prev_nportgids;
137 
138 	/* Flag indicating which IOC info has changed */
139 	ibt_prop_update_payload_t	ioc_info_updated;
140 
141 	/*
142 	 * List of HCAs through which IOC is accessible
143 	 * This field will be initialized in ibdm_ibnex_probe_ioc
144 	 * and ibdm_get_ioc_list for all IOCs in the fabric.
145 	 *
146 	 * HCAs could have been added or deleted from the list,
147 	 * on calls to ibdm_ibnex_get_ioc_list & ibdm_ibnex_probe_ioc.
148 	 *
149 	 * Updates to HCAs in the list will be reported by
150 	 * IBDM_EVENT_HCA_DOWN and IBDM_EVENT_IOC_HCA_UNREACHABLE events
151 	 * in the IBDM<->IBDM callback.
152 	 *
153 	 * IOC not visible to the host system(because all HCAs cannot
154 	 * reach the IOC) will be reported in the same manner as TCA
155 	 * ports getting to 0 (using IOC_PROP_UPDATE event).
156 	 */
157 	struct ibdm_hca_list_s			*ioc_hca_list;
158 
159 } ibdm_ioc_info_t;
160 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv",
161 	ibdm_ioc_info_s::ioc_next))
162 _NOTE(SCHEME_PROTECTS_DATA("Unique per copy of ibdm_ioc_info_t",
163 	ibdm_ioc_info_s::ioc_info_updated))
164 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_ioc_info_s::ioc_dc_valid))
165 
166 /* values for "ioc_state */
167 #define	IBDM_IOC_STATE_PROBE_SUCCESS	0x0
168 #define	IBDM_IOC_STATE_PROBE_INVALID	0x1
169 #define	IBDM_IOC_STATE_PROBE_FAILED	0x2
170 #define	IBDM_IOC_STATE_REPROBE_PROGRESS	0x4
171 
172 /* I/O Unit Information */
173 typedef struct ibdm_iou_info_s {
174 	ib_dm_io_unitinfo_t	iou_info;
175 	ibdm_ioc_info_t		*iou_ioc_info;
176 	ib_guid_t		iou_guid;
177 	boolean_t		iou_dc_valid;
178 	uint16_t		iou_diagcode;
179 	int			iou_niocs_probe_in_progress;
180 } ibdm_iou_info_t;
181 
182 
183 /* P_Key table related info */
184 typedef struct ibdm_pkey_tbl_s {
185 	ib_pkey_t		pt_pkey;		/* P_Key value */
186 	ibmf_qp_handle_t	pt_qp_hdl;		/* QP handle */
187 } ibdm_pkey_tbl_t;
188 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_pkey_tbl_s))
189 
190 
191 /*
192  * Port Attributes structure
193  */
194 typedef struct ibdm_port_attr_s {
195 	ibdm_pkey_tbl_t		*pa_pkey_tbl;
196 	ib_guid_t		pa_hca_guid;
197 	ib_guid_t		pa_port_guid;
198 	uint16_t		pa_npkeys;
199 	ibmf_handle_t		pa_ibmf_hdl;
200 	ib_sn_prefix_t		pa_sn_prefix;
201 	uint16_t		pa_port_num;
202 	uint32_t		pa_vendorid;
203 	uint32_t		pa_productid;
204 	uint32_t		pa_dev_version;
205 	ibt_port_state_t	pa_state;
206 	ibmf_saa_handle_t	pa_sa_hdl;
207 	ibmf_impl_caps_t	pa_ibmf_caps;
208 	ibt_hca_hdl_t		pa_hca_hdl;
209 } ibdm_port_attr_t;
210 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_port_attr_s))
211 
212 /*
213  * HCA list structure.
214  */
215 typedef struct ibdm_hca_list_s {
216 	ibdm_port_attr_t	*hl_port_attr;		/* port attributes */
217 	struct ibdm_hca_list_s	*hl_next;		/* ptr to next list */
218 	ib_guid_t		hl_hca_guid;		/* HCA GUID */
219 	uint32_t		hl_nports;		/* #ports of this HCA */
220 	uint32_t		hl_nports_active;	/* #ports active */
221 	hrtime_t		hl_attach_time;		/* attach time */
222 	ibt_hca_hdl_t		hl_hca_hdl;		/* HCA handle */
223 	ibdm_port_attr_t	*hl_hca_port_attr;	/* Dummy Port Attr */
224 							/* for HCA node */
225 } ibdm_hca_list_t;
226 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_hca_list_s))
227 
228 /*
229  * The DM callback definitions
230  *
231  * ibdm_callback_t
232  *	Pointer to DM callback function
233  *	IBDM notifies IB nexus of ibdm_event_t using this callback.
234  * Arguments
235  *	arg	: The value of "arg" depends on the "event"
236  *		IBDM_EVENT_CREATE_HCA_NODE	(pointer to HCA GUID)
237  *		IBDM_EVENT_REMOVE_HCA_NODE	(pointer to HCA GUID)
238  *		IBDM_EVENT_IOC_PROP_UPDATE	(ibdm_ioc_info_t *)
239  *
240  *	event 	: ibdm_event_t values
241  *
242  * Returns		: None
243  *
244  */
245 typedef void (*ibdm_callback_t)(void *arg, ibdm_events_t event);
246 
247 
248 /*
249  * DM interface functions
250  */
251 
252 /*
253  * ibdm_ibnex_register_callback
254  *	Register the IB nexus IBDM callback routine
255  *
256  * Arguments		: IB nexus IBDM callback routine
257  * Return Values	: None
258  */
259 void		ibdm_ibnex_register_callback(ibdm_callback_t cb);
260 
261 /*
262  * ibdm_ibnex_unregister_callback
263  *	Unregister IB nexus DM callback with IBDM
264  *
265  * Arguments		: None
266  * Return Values	: None
267  */
268 void		ibdm_ibnex_unregister_callback();
269 
270 
271 /*
272  * PORT devices handling interfaces.
273  *
274  * ibdm_ibnex_probe_hcaport
275  *	Probes the HCA port. If found, returns the port attributes.
276  *	Caller is responsible for  freeing the memory for the port
277  *	attribute structure by calling ibdm_ibnex_free_port_attr()
278  *
279  * Arguments		: GUID of the HCA and port number
280  * Return Values	: ibdm_port_attr_t on SUCCESS, NULL on FAILURE.
281  */
282 ibdm_port_attr_t *ibdm_ibnex_probe_hcaport(ib_guid_t, uint8_t);
283 
284 /*
285  * ibdm_ibnex_get_port_attrs
286  *	Scans the HCA ports for a matching port_guid. If found,
287  *	returns the port attributes.
288  *	Caller is responsible for freeing the memory for the port
289  *	attribute structure by calling ibdm_ibnex_free_port_attr()
290  *
291  * Arguments		: GUID of the port
292  * Return Values	: ibdm_port_attr_t on SUCCESS, NULL on FAILURE.
293  */
294 ibdm_port_attr_t *ibdm_ibnex_get_port_attrs(ib_guid_t);
295 
296 /*
297  * ibdm_ibnex_free_port_attr()
298  *	Deallocates the memory from ibnex_get_dip_from_port_guid() and
299  *	ibdm_ibnex_get_port_attrs() functions.
300  */
301 void		ibdm_ibnex_free_port_attr(ibdm_port_attr_t *);
302 
303 
304 /*
305  * IOC devices handling interfaces.
306  *
307  * ibdm_ibnex_probe_ioc
308  *	Probes the  IOC device on the fabric. If found, allocates and
309  *	returns pointer to the ibdm_ioc_info_t. Caller is responsible
310  *	to free the memory for the ioc attribute structure by calling
311  *	ibdm_ibnex_free_ioc_list.
312  *
313  * Arguments		:
314  *	GUID of the IOU and GUID of the IOC
315  *	reprobe_flag - Set if IOC information has to be reprobed.
316  * Return Values	: ibdm_ioc_info_t on SUCCESS, NULL on FAILURE.
317  */
318 ibdm_ioc_info_t	*ibdm_ibnex_probe_ioc(ib_guid_t iou_guid, ib_guid_t ioc_guid,
319     int reprobe_flag);
320 
321 /*
322  * ibdm_ibnex_get_ioc_count
323  *	Returns number of IOCs currently discovered in the fabric.
324  * Arguments	  : NONE
325  * Return Values  : number of IOCs seen
326  */
327 int	ibdm_ibnex_get_ioc_count(void);
328 
329 /*
330  * ibdm_ibnex_get_ioc_list
331  *	Returns linked list of ibdm_ioc_info_t structures for all the
332  *	IOCs  present on the fabric. Caller is responsible for freeing
333  *	the  memory allocated for the ioc  attribute  structure(s) by
334  *	calling ibdm_ibnex_free_ioc_list().
335  *
336  * Arguments	  : list_flag :
337  *		Get list according to ibdm_ibnex_get_ioclist_mtd_t defination.
338  * Return Values  : IOC list based containing "ibdm_ioc_info_t"s if
339  *			  successful, otherwise NULL.
340  */
341 ibdm_ioc_info_t	*ibdm_ibnex_get_ioc_list(ibdm_ibnex_get_ioclist_mtd_t);
342 
343 /*
344  * ibdm_ibnex_get_ioc_info
345  *	Returns pointer  ibdm_ioc_info_t structures for the request
346  *	"ioc_guid".  Caller is  responsible to  free the  memory by
347  *	calling ibdm_ibnex_free_ioc_list() when the return value is
348  *	not NULL.
349  *
350  * Arguments		: GUID of the IOC
351  * Return Values	: Address of kmem_alloc'ed memory if the IOC exists,
352  *			  otherwise NULL.
353  */
354 ibdm_ioc_info_t *ibdm_ibnex_get_ioc_info(ib_guid_t ioc_guid);
355 
356 /*
357  * ibdm_ibnex_free_ioc_list()
358  *	Deallocates the memory from ibdm_ibnex_probe_ioc(),
359  *	ibdm_ibnex_get_ioc_list() and ibdm_ibnex_get_ioc_info()
360  */
361 void		ibdm_ibnex_free_ioc_list(ibdm_ioc_info_t *);
362 
363 /*
364  * HCA handling interfaces.
365  *
366  * ibdm_ibnex_get_hca_list
367  *	Returns linked list of ibdm_hca_list_t structures for all
368  *	the HCAs present on the fabric. Caller is responsible for
369  *	freeing the memory for the hca attribute structure(s) by
370  *	calling ibdm_ibnex_free_hca_list().
371  *
372  * Arguments		: "hca" contains pointer to pointer of ibdm_hca_list_t
373  *			: "cnt" contains pointer to number of hca's
374  * Return Values	: None
375  */
376 void		ibdm_ibnex_get_hca_list(ibdm_hca_list_t **hca, int *cnt);
377 
378 /*
379  * ibdm_ibnex_get_hca_info_by_guid
380  *	Returns a linked list of ibdm_hca_list_t structure that matches the
381  *	given argument. The caller is responsible for freeing the memory for
382  *	the hca attribute structure by calling ibdm_ibnex_free_hca_list().
383  *
384  * Arguments		: HCA GUID
385  * Return Values	: Linked list of ibdm_hca_list_t(s)
386  */
387 ibdm_hca_list_t *ibdm_ibnex_get_hca_info_by_guid(ib_guid_t);
388 
389 /*
390  * ibdm_ibnex_free_hca_list()
391  *	Deallocates the memory from ibdm_ibnex_get_hca_list() and
392  *	ibdm_ibnex_get_hca_info_by_guid() functions.
393  */
394 void		ibdm_ibnex_free_hca_list(ibdm_hca_list_t *);
395 
396 /*
397  * ibdm_ibnex_update_pkey_tbls
398  *	Updates the DM P_Key database.
399  *
400  * Arguments		: NONE
401  * Return Values	: NONE
402  */
403 void	ibdm_ibnex_update_pkey_tbls(void);
404 
405 /*
406  * ibdm_ibnex_port_settle_wait
407  *	Wait until the ports come up
408  *
409  * Arguments
410  *      HCA GUID and the maximum wait time since the hca instance attach
411  */
412 void	ibdm_ibnex_port_settle_wait(ib_guid_t, int);
413 
414 
415 #ifdef __cplusplus
416 }
417 #endif
418 
419 #endif	/* _SYS_IB_MGT_IBDM_IBDM_IBNEX_H */
420