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
42extern "C" {
43#endif
44
45/* DM return status codes from private interfaces */
46typedef 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 */
55typedef 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 */
77typedef 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 */
87typedef 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 */
99typedef 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 */
112typedef 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 */
173typedef 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 */
184typedef 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 */
194typedef 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 */
215typedef 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 */
245typedef 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 */
259void		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 */
268void		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 */
282ibdm_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 */
294ibdm_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 */
301void		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 */
318ibdm_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 */
327int	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 */
341ibdm_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 */
354ibdm_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 */
361void		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 */
376void		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 */
387ibdm_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 */
394void		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 */
403void	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 */
412void	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