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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_IB_MGT_IBMF_IBMF_SAA_H
28 #define	_SYS_IB_MGT_IBMF_IBMF_SAA_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 #include <sys/ib/ib_types.h>
35 #include <sys/ib/mgt/sa_recs.h>
36 
37 /*
38  * SA Access Interface: Interfaces to enable access to the SA
39  */
40 
41 #define	IBMF_SAA_PKEY_WC	0	/* partition key wildcard */
42 #define	IBMF_SAA_MTU_WC		0	/* mtu wilcard for gid_to_pathrecords */
43 
44 typedef enum _ibmf_saa_access_type_t {
45 	IBMF_SAA_RETRIEVE,
46 	IBMF_SAA_UPDATE,
47 	IBMF_SAA_DELETE
48 } ibmf_saa_access_type_t;
49 
50 /*
51  * ibmf_saa_handle
52  *	Opaque handle to identify the consumer
53  */
54 typedef struct ibmf_saa_handle *ibmf_saa_handle_t;
55 
56 /*
57  * ibmf_saa_cb_t
58  * ibmf_saa's callback to clients to inform them that the response to an
59  * asynchronous request has arrived or that the request timed out.
60  *
61  * Input Arguments
62  * clnt_private - opaque handle to client specific data (sq_callback_arg)
63  * length - size of response returned
64  * result - pointer to buffer of response.  Data will be in host-endian format
65  * and unpacked.  Client can just cast to a pointer to the structure
66  * status - ibmf status.  Status can be any of the values returned by a
67  * synchronous ibmf_sa_access() call.
68  *
69  * Output Arguments
70  * none
71  *
72  * Returns
73  * none
74  */
75 typedef void (*ibmf_saa_cb_t) (
76     void 	*callback_arg,
77     size_t	length,
78     char	*result,
79     int		status);
80 
81 /*
82  * structure to provide parameters to ibmf_sa_access call
83  */
84 typedef struct ibmf_saa_access_args_s {
85 	/* MAD attribute ID */
86 	uint16_t		sq_attr_id;
87 
88 	/* retrieve, update, or delete */
89 	ibmf_saa_access_type_t 	sq_access_type;
90 
91 	/* SA MAD component mask indicating fields in template to query on */
92 	uint64_t		sq_component_mask;
93 
94 	/* pointer to template */
95 	void			*sq_template;
96 
97 	/*
98 	 * length, in bytes, of template size for attributes which ibmf does
99 	 * not know about; ignored for known attribute id's.  length should be
100 	 * wire length and template for unknown attributes should be in wire
101 	 * format as ibmf will not be able to pack data.
102 	 */
103 	size_t			sq_template_length;
104 
105 	/* callback and argument when asynchronous request returns */
106 	ibmf_saa_cb_t		sq_callback;
107 	void			*sq_callback_arg;
108 } ibmf_saa_access_args_t;
109 
110 /*
111  * enumeration of subnet events
112  *
113  * IBMF_SAA_EVENT_GID_AVAILABLE
114  *              the identified gid is available
115  * IBMF_SAA_EVENT_GID_UNAVAILABLE
116  *              the identified gid is unavailable
117  * IBMF_SAA_EVENT_MCG_CREATED
118  *              MC group identified by mgid is created
119  * IBMF_SAA_EVENT_MCG_DELETED
120  *              MC group identified by mgid is deleted
121  * IBMF_SAA_EVENT_CAP_MASK_CHG
122  *              Portinfo.CapabilityMask changed
123  * IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
124  *              System Image GUID changed
125  * IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG
126  *		Status of ibmf subscriptions changed
127  */
128 typedef enum ibmf_saa_subnet_event_e {
129 
130 	IBMF_SAA_EVENT_GID_AVAILABLE,
131 	IBMF_SAA_EVENT_GID_UNAVAILABLE,
132 	IBMF_SAA_EVENT_MCG_CREATED,
133 	IBMF_SAA_EVENT_MCG_DELETED,
134 	IBMF_SAA_EVENT_CAP_MASK_CHG,
135 	IBMF_SAA_EVENT_SYS_IMG_GUID_CHG,
136 	IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG
137 
138 } ibmf_saa_subnet_event_t;
139 
140 /*
141  * ibmf must subscribe with the Subnet Administrator to provide the subnet
142  * events for its clients.  It registers for the four trap producer types: CA,
143  * switch, router, and subnet management.  If any of these registrations fails
144  * the ibmf will notify each client that registered for events.  Clients are
145  * notified by ibmf through their registered callback and the
146  * SUBSCRIBER_STATUS_CHG event.
147  *
148  * For this event, the event_details producer_type_status_mask will be set.
149  * Each bit in the mask corresponds to a different producer type.  When the bit
150  * is on the ibmf was able to successfully subscribe for events from that
151  * producer.  When the bit is off, ibmf was unable to subscribe and clients may
152  * not receive events from that producer type.
153  *
154  * For example, if the status_mask is 0xb then events will be received that
155  * correspond to CA's, switches, and subnet management traps.  However, traps
156  * generated by routers may not be received.
157  *
158  * The ibmf re-registers for events when the port transitions to active.  If the
159  * event status mask changes the ibmf will generate another
160  * SUBSCRIBER_STATUS_CHG event with the new producer type status mask.  When
161  * clients register they should only expect to receive a SUBSCRIBER_STATUS_CHG
162  * event if one of the registrations failed.  If all four registrations
163  * succeeded no event will be generated.
164  *
165  * If the port goes down, a SUBSCRIBER_STATUS_CHG event is not generated.
166  * Clients should realize that events will not be forwarded.  If the port
167  * transitions back to active ibmf_saa will resubscribe on behalf of the client.
168  * If this subscription fails a SUBSCRIBER_STATUS_CHG event will be generated.
169  *
170  */
171 
172 #define	IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_CA		(1 << 0)
173 #define	IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SWITCH	(1 << 1)
174 #define	IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_ROUTER	(1 << 2)
175 #define	IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM		(1 << 3)
176 
177 /*
178  * structure passed as event_details argument of ibmf_saa subnet event
179  * callback.
180  *
181  * Only some of the structure members are valid for a given event as given
182  * below:
183  *
184  * member              		event type
185  * ------              		----------
186  * ie_gid               	IBMF_SAA_EVENT_GID_AVAILABLE,
187  *					IBMF_SAA_EVENT_GID_UNAVAILABLE,
188  *                              	IBMF_SAA_EVENT_MCG_CREATED, and
189  *                              	IBMF_SAA_EVENT_MCG_DELETED
190  * ie_lid               	IBMF_SAA_EVENT_CAP_MASK_CHG and
191  *                              	IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
192  * ie_capability_mask   	IBMF_SAA_EVENT_CAP_MASK_CHG
193  * ie_sysimg_guid       	IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
194  * ie_producer_type_status_mask	IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG
195  *
196  */
197 typedef struct ibmf_saa_event_details_s {
198 	ib_gid_t	ie_gid;
199 	ib_guid_t	ie_sysimg_guid;
200 	uint32_t	ie_capability_mask; /* values defined in sm_attr.h */
201 	ib_lid_t	ie_lid;
202 	uint8_t		ie_producer_event_status_mask;
203 } ibmf_saa_event_details_t;
204 
205 /*
206  * Callback invoked when one of the events the client subscribed for
207  * at ibmf_sa_session_open() time happens.
208  *
209  * This callback can occur before ibmf_sa_session_open() returns.
210  *
211  * Each callback is on a separate thread.  ibmf clients may block in the event
212  * callback.  However, under heavy system load ibmf may not be able to generate
213  * event callbacks.  Also, event callbacks, including SUBSCRIBER_STATUS_CHG,
214  * could be dispatched out-of-order.
215  *
216  * Arguments:
217  * ibmf_saa_handle              - Client's ibmf_saa_handle
218  * ibmf_saa_event               - event that caused the callback
219  * event_details                - additional data for the event
220  * callback_arg                 - event_callback_arg member of
221  *                                ibmf_saa_subnet_event_args_t
222  */
223 typedef void (*ibmf_saa_subnet_event_cb_t)(
224 	ibmf_saa_handle_t		ibmf_saa_handle,
225 	ibmf_saa_subnet_event_t		ibmf_saa_event,
226 	ibmf_saa_event_details_t	*event_details,
227 	void				*callback_arg);
228 
229 typedef struct ibmf_saa_subnet_event_args_s {
230 
231 	/* func to be called when a subnet event happens */
232 	ibmf_saa_subnet_event_cb_t	is_event_callback;
233 
234 	/* call back arg */
235 	void				*is_event_callback_arg;
236 
237 } ibmf_saa_subnet_event_args_t;
238 
239 /*
240  * ibmf_sa_session_open():
241  *
242  * Before using the ibmf_saa interface, consumers should register with the
243  * ibmf_saa interface by calling ibmf_sa_session_open(). Upon a successful
244  * registration, a handle is returned for use in subsequent interaction with the
245  * ibmf_saa interface; this handle is also provided as an argument to subnet
246  * event notification function.
247  *
248  * Consumers can register to be notified of subnet events such as GID
249  * being available/unavailable.  Clients which provide a non-NULL event args
250  * structure will have the is_event_callback function called when an event is
251  * received or there is a failure in subscribing for events.  This callback may
252  * be generated before the ibmf_sa_session_open() call returns.
253  *
254  * This interface blocks allocating memory, but not waiting for any packet
255  * responses.
256  *
257  * Arguments:
258  * port_guid            - GUID of the port.
259  * event_args		- subnet event registration details
260  * sm_key               - only filled in if the consumer is an SM
261  * ibmf_version         - version of the interface (IBMF_VERSION)
262  * flags                - unused
263  *
264  * Return values:
265  * IBMF_SUCCESS         - registration succeeded
266  * IBMF_BAD_PORT	- registration failed; active port not found
267  * IBMF_BAD_PORT_STATE  - registration failed; port found but not active or
268  * 			previous registration failed
269  * IBMF_NO_MEMORY	- registration failed; could not allocate memory
270  * IBMF_NO_RESOURCES    - registration failed due to a resource issue
271  * IBMF_BUSY            - registration failed; too many clients registered
272  *                      for this port
273  * IBMF_TRANSPORT_FAILURE - failure with underlying transport framework
274  * IBMF_INVALID_ARG     - ibmf_saa_handle arg was NULL
275  */
276 int ibmf_sa_session_open(
277 		ib_guid_t			port_guid,
278 		ib_smkey_t			sm_key,
279 		ibmf_saa_subnet_event_args_t	*event_args,
280 		uint_t				ibmf_version,
281 		uint_t				flags,
282 		ibmf_saa_handle_t		*ibmf_saa_handle);
283 
284 /*
285  * ibmf_sa_session_close()
286  *
287  * Unregister a consumer of the SA_Access interface
288  *
289  * This interface blocks.
290  *
291  * Arguments:
292  * ibmf_saa_handle	- handle returned from sa_session_open()
293  * flags		- unused
294  *
295  * Return values:
296  * IBMF_SUCCESS		- unregistration succeeded
297  * IBMF_BAD_HANDLE	- unregistration failed; handle is not valid or
298  *			  session_close has already been called
299  * IBMF_INVALID_ARG	- ibmf_saa_handle arg was NULL
300  *
301  * All outstanding callbacks will be canceled before this function returns.
302  */
303 int	ibmf_sa_session_close(
304 		ibmf_saa_handle_t	*ibmf_saa_handle,
305 		uint_t			flags);
306 
307 /*
308  * ibmf_sa_access
309  *
310  * Retrieve records from the SA given an AttributeID, ComponentMask,
311  * and a template
312  *
313  * This interface blocks if the callback parameter is NULL.
314  *
315  * Input Arguments:
316  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
317  * access_args 		- structure containing various parameters for the query
318  * flags 		- unsused
319  *
320  * Output Arguments:
321  * length		- size of buffer returned
322  * result		- pointer to buffer of records returned in response.
323  *			  Buffer is host-endian, unpacked can be cast to one of
324  *			  the record types in sa_recs.h
325  *
326  * Return values:
327  * IBMF_SUCCESS 	- query succeeded
328  * IBMF_BAD_HANDLE	- sa session handle is invalid
329  * IBMF_BAD_PORT_STATE	- port in incorrect state
330  * IBMF_INVALID_ARG	- one of the pointer parameters was NULL
331  * IBMF_NO_RESOURCES	- ibmf could not allocate ib resources or SA returned
332  *			  ERR_NO_RESOURCES
333  * IBMF_TRANS_TIMEOUT	- transaction timed out
334  * IBMF_TRANS_FAILURE	- transaction failure
335  * IBMF_NO_MEMORY	- ibmf could not allocate memory
336  * IBMF_REQ_INVALID	- send and recv buffer the same for a sequenced
337  *			  transaction or the SA returned an ERR_REQ_INVALID
338  * IBMF_NO_RECORDS	- no records matched query
339  * IBMF_TOO_MANY_RECORDS- SA returned SA_ERR_TOO_MANY_RECORDS
340  * IBMF_INVALID_GID	- SA returned SA_INVALID_GID
341  * IBMF_INSUFF_COMPS	- SA returned SA_ERR_INSUFFICIENT_COMPS
342  * IBMF_UNSUPP_METHOD	- SA returned MAD_STATUS_UNSUPP_METHOD
343  * IBMF_UNSUPP_METHOD_ATTR - SA returned MAD_STATUS_UNSUPP_METHOD_ATTR
344  * IBMF_INVALID_FIELD	- SA returned MAD_STATUS_INVALID_FIELD
345  * IBMF_NO_ACTIVE_PORTS - no active ports found
346  *
347  * Upon successful completion, result points to a buffer containing the records.
348  * length is the size in bytes of the buffer returned in result.  If there are
349  * no records or the call failed the length is 0.
350  *
351  * The consumer is responsible for freeing the memory associated with result.
352  */
353 int	ibmf_sa_access(
354 		ibmf_saa_handle_t	ibmf_saa_handle,
355 		ibmf_saa_access_args_t	*access_args,
356 		uint_t			flags,
357 		size_t			*length,
358 		void			**result);
359 
360 /*
361  * Helper Functions.
362  *	Ease of use functions so that the consumer doesn't
363  * 	have to do the overhead of calling ibmf_sa_access() for
364  *	commonly used queries
365  */
366 
367 /*
368  * ibmf_saa_gid_to_pathrecords
369  * 	Given a source gid and a destination gid, return paths
370  *	between the gids.
371  *
372  * This interface blocks.
373  *
374  * Input Arguments:
375  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
376  * sgid 		- source gid of path
377  * dgid			- destination gid of path
378  * p_key		- partition of path.  This value may be wildcarded with
379  *			  IBMF_SAA_PKEY_WC.
380  * mtu 			- preferred MTU of the path.  This argument may be
381  *			  wildcarded with IBMF_SAA_MTU_WC.
382  * reversible		- if B_TRUE, ibmf will query only reversible paths
383  *			  see Infiniband Specification table 171
384  * num_paths		- maximum number of paths to return
385  *			  numpaths should be checked for the actual number of
386  *			  records returned.
387  * flags		- unused
388  *
389  * Output Arguments:
390  * num_paths		- actual number of paths returned
391  * length		- size of buffer returned
392  * result		- pointer to buffer of path records returned in response
393  *
394  * Return values:
395  * Error codes are the same as ibmf_sa_access() return values
396  *
397  * Upon successful completion, result points to a buffer containing the records.
398  * length is the size in bytes of the buffer returned in result.  If there are
399  * no records or the call failed the length is 0.
400  *
401  * The consumer is responsible for freeing the memory associated with result.
402  */
403 int	ibmf_saa_gid_to_pathrecords(
404 		ibmf_saa_handle_t	ibmf_saa_handle,
405 		ib_gid_t		sgid,
406 		ib_gid_t		dgid,
407 		ib_pkey_t		p_key,
408 		ib_mtu_t		mtu,
409 		boolean_t		reversible,
410 		uint8_t			*num_paths,
411 		uint_t			flags,
412 		size_t			*length,
413 		sa_path_record_t	**result);
414 /*
415  * ibmf_saa_paths_from_gid
416  *      Given a source GID, return a path from the source gid
417  *	to every other port on the subnet.  It is assumed that the
418  *	subnet is fully connected.  Only one path per port on the subnet
419  *	is returned.
420  *
421  * This interface blocks.
422  *
423  * Arguments:
424  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
425  * sgid 		- source gid of path
426  * pkey			- paritition of path.  This value may be wildcarded with
427  *			  IBMF_SAA_PKEY_WC.
428  * reversible		- if B_TRUE, ibmf will query only reversible paths;
429  *			  see Infiniband Specification table 171
430  * flags		- unused
431  *
432  * Output Arguments:
433  * num_paths		- number of paths returned
434  * length		- size of buffer returned
435  * result		- pointer to buffer of path records returned in response
436  *
437  * Return values:
438  * Error codes are the same as ibmf_sa_access() return values
439  *
440  * Upon successful completion, result points to a buffer containing the records.
441  * and num_paths is the number of path records returned.  length is the size
442  * in bytes of the buffer returned in result.  If there are no records or the
443  * call failed the length is 0.
444  *
445  * The consumer is responsible for freeing the memory associated with result.
446  */
447 int	ibmf_saa_paths_from_gid(
448 		ibmf_saa_handle_t	ibmf_saa_handle,
449 		ib_gid_t		sgid,
450 		ib_pkey_t		pkey,
451 		boolean_t		reversible,
452 		uint_t			flags,
453 		uint_t			*num_paths,
454 		size_t			*length,
455 		sa_path_record_t	**result);
456 
457 /*
458  * ibmf_saa_name_to_service_record:
459  *	Given a service name, return the service records associated
460  *	with it.
461  *
462  * This interface blocks.
463  *
464  * Input Arguments:
465  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
466  * name			- service name, a null terminated string
467  * p_key		- partition that the service is requested on.  This
468  *			  value may be wildcarded with IBMF_SAA_PKEY_WC.
469  * flags		- unused
470  *
471  * Output Arguments:
472  * num_records		- number of service records returned
473  * length		- size of buffer returned
474  * result		- pointer to buffer of service records returned in
475  *			  response
476  *
477  * Return values:
478  * Error codes are the same as ibmf_sa_access() return values
479  *
480  * Upon successful completion, result points to a buffer containing the records.
481  * and num_records is the number of service records returned.  length is the
482  * size in bytes of the buffer returned in result.  If there are no records or
483  * the call failed the length is 0.
484  *
485  * The consumer is responsible for freeing the memory associated with result.
486  */
487 int	ibmf_saa_name_to_service_record(
488 		ibmf_saa_handle_t	ibmf_saa_handle,
489 		char			*service_name,
490 		ib_pkey_t		p_key,
491 		uint_t			flags,
492 		uint_t			*num_records,
493 		size_t			*length,
494 		sa_service_record_t	**result);
495 
496 /*
497  * ibmf_saa_id_to_service_record:
498  *      Given a service id, return the service records associated
499  *      with it.
500  *
501  * This interface blocks.
502  *
503  * Input Arguments:
504  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
505  * id			- service id
506  * p_key		- partition that the service is requested on.  This
507  *			  value may be wildcarded with IBMF_SAA_PKEY_WC.
508  * flags		- unused
509  *
510  * Output Arguments:
511  * num_records		- number of service records returned
512  * length		- size of buffer returned
513  * result		- pointer to buffer of service records returned in
514  *			  response
515  *
516  * Return values:
517  * Error codes are the same as ibmf_sa_access() return values
518  *
519  * Upon successful completion, result points to a buffer containing the records.
520  * and num_records is the number of service records returned.  length is the
521  * size in bytes of the buffer returned in result.  If there are no records or
522  * the call failed the length is 0.
523  *
524  * The consumer is responsible for freeing the memory associated with result.
525  */
526 int	ibmf_saa_id_to_service_record(
527 		ibmf_saa_handle_t	ibmf_saa_handle,
528 		ib_svc_id_t		service_id,
529 		ib_pkey_t		p_key,
530 		uint_t			flags,
531 		uint_t			*num_records,
532 		size_t			*length,
533 		sa_service_record_t	**result);
534 
535 /*
536  * ibmf_saa_update_service_record
537  *	Given a pointer to a service record, either insert or delete it
538  *
539  * This interface blocks.
540  *
541  * Input Arguments:
542  * ibmf_saa_handle	- handle returned from ibmf_sa_session_open()
543  * service_record	- service record is to be inserted or deleted.  To
544  *			  delete a service record the GID, ID, P_Key, and
545  *			  Service Key must match what is in the SA.
546  * access_type		- indicates whether this is an insertion or deletion.
547  *			  valid values are IBMF_SAA_UPDATE or IBMF_SAA_DELETE
548  * flags		- unused
549  *
550  * Ouptut Arguments
551  * none
552  *
553  * Return values:
554  * Error codes are the same as ibmf_sa_access() return values
555  */
556 int	ibmf_saa_update_service_record(
557 		ibmf_saa_handle_t	ibmf_saa_handle,
558 		sa_service_record_t	*service_record,
559 		ibmf_saa_access_type_t	access_type,
560 		uint_t			flags);
561 
562 #ifdef __cplusplus
563 }
564 #endif
565 
566 #endif	/* _SYS_IB_MGT_IBMF_IBMF_SAA_H */
567