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