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