root/usr/src/uts/common/sys/ib/mgt/ibmf/ibmf_saa.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_IB_MGT_IBMF_IBMF_SAA_H
#define _SYS_IB_MGT_IBMF_IBMF_SAA_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <sys/ib/ib_types.h>
#include <sys/ib/mgt/sa_recs.h>

/*
 * SA Access Interface: Interfaces to enable access to the SA
 */

#define IBMF_SAA_PKEY_WC        0       /* partition key wildcard */
#define IBMF_SAA_MTU_WC         0       /* mtu wilcard for gid_to_pathrecords */

typedef enum _ibmf_saa_access_type_t {
        IBMF_SAA_RETRIEVE,
        IBMF_SAA_UPDATE,
        IBMF_SAA_DELETE
} ibmf_saa_access_type_t;

/*
 * ibmf_saa_handle
 *      Opaque handle to identify the consumer
 */
typedef struct ibmf_saa_handle *ibmf_saa_handle_t;

/*
 * ibmf_saa_cb_t
 * ibmf_saa's callback to clients to inform them that the response to an
 * asynchronous request has arrived or that the request timed out.
 *
 * Input Arguments
 * clnt_private - opaque handle to client specific data (sq_callback_arg)
 * length - size of response returned
 * result - pointer to buffer of response.  Data will be in host-endian format
 * and unpacked.  Client can just cast to a pointer to the structure
 * status - ibmf status.  Status can be any of the values returned by a
 * synchronous ibmf_sa_access() call.
 *
 * Output Arguments
 * none
 *
 * Returns
 * none
 */
typedef void (*ibmf_saa_cb_t) (
    void        *callback_arg,
    size_t      length,
    char        *result,
    int         status);

/*
 * structure to provide parameters to ibmf_sa_access call
 */
typedef struct ibmf_saa_access_args_s {
        /* MAD attribute ID */
        uint16_t                sq_attr_id;

        /* retrieve, update, or delete */
        ibmf_saa_access_type_t  sq_access_type;

        /* SA MAD component mask indicating fields in template to query on */
        uint64_t                sq_component_mask;

        /* pointer to template */
        void                    *sq_template;

        /*
         * length, in bytes, of template size for attributes which ibmf does
         * not know about; ignored for known attribute id's.  length should be
         * wire length and template for unknown attributes should be in wire
         * format as ibmf will not be able to pack data.
         */
        size_t                  sq_template_length;

        /* callback and argument when asynchronous request returns */
        ibmf_saa_cb_t           sq_callback;
        void                    *sq_callback_arg;
} ibmf_saa_access_args_t;

/*
 * enumeration of subnet events
 *
 * IBMF_SAA_EVENT_GID_AVAILABLE
 *              the identified gid is available
 * IBMF_SAA_EVENT_GID_UNAVAILABLE
 *              the identified gid is unavailable
 * IBMF_SAA_EVENT_MCG_CREATED
 *              MC group identified by mgid is created
 * IBMF_SAA_EVENT_MCG_DELETED
 *              MC group identified by mgid is deleted
 * IBMF_SAA_EVENT_CAP_MASK_CHG
 *              Portinfo.CapabilityMask changed
 * IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
 *              System Image GUID changed
 * IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG
 *              Status of ibmf subscriptions changed
 */
typedef enum ibmf_saa_subnet_event_e {

        IBMF_SAA_EVENT_GID_AVAILABLE,
        IBMF_SAA_EVENT_GID_UNAVAILABLE,
        IBMF_SAA_EVENT_MCG_CREATED,
        IBMF_SAA_EVENT_MCG_DELETED,
        IBMF_SAA_EVENT_CAP_MASK_CHG,
        IBMF_SAA_EVENT_SYS_IMG_GUID_CHG,
        IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG

} ibmf_saa_subnet_event_t;

/*
 * ibmf must subscribe with the Subnet Administrator to provide the subnet
 * events for its clients.  It registers for the four trap producer types: CA,
 * switch, router, and subnet management.  If any of these registrations fails
 * the ibmf will notify each client that registered for events.  Clients are
 * notified by ibmf through their registered callback and the
 * SUBSCRIBER_STATUS_CHG event.
 *
 * For this event, the event_details producer_type_status_mask will be set.
 * Each bit in the mask corresponds to a different producer type.  When the bit
 * is on the ibmf was able to successfully subscribe for events from that
 * producer.  When the bit is off, ibmf was unable to subscribe and clients may
 * not receive events from that producer type.
 *
 * For example, if the status_mask is 0xb then events will be received that
 * correspond to CA's, switches, and subnet management traps.  However, traps
 * generated by routers may not be received.
 *
 * The ibmf re-registers for events when the port transitions to active.  If the
 * event status mask changes the ibmf will generate another
 * SUBSCRIBER_STATUS_CHG event with the new producer type status mask.  When
 * clients register they should only expect to receive a SUBSCRIBER_STATUS_CHG
 * event if one of the registrations failed.  If all four registrations
 * succeeded no event will be generated.
 *
 * If the port goes down, a SUBSCRIBER_STATUS_CHG event is not generated.
 * Clients should realize that events will not be forwarded.  If the port
 * transitions back to active ibmf_saa will resubscribe on behalf of the client.
 * If this subscription fails a SUBSCRIBER_STATUS_CHG event will be generated.
 *
 */

#define IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_CA          (1 << 0)
#define IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SWITCH      (1 << 1)
#define IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_ROUTER      (1 << 2)
#define IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM          (1 << 3)

/*
 * structure passed as event_details argument of ibmf_saa subnet event
 * callback.
 *
 * Only some of the structure members are valid for a given event as given
 * below:
 *
 * member                       event type
 * ------                       ----------
 * ie_gid                       IBMF_SAA_EVENT_GID_AVAILABLE,
 *                                      IBMF_SAA_EVENT_GID_UNAVAILABLE,
 *                                      IBMF_SAA_EVENT_MCG_CREATED, and
 *                                      IBMF_SAA_EVENT_MCG_DELETED
 * ie_lid                       IBMF_SAA_EVENT_CAP_MASK_CHG and
 *                                      IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
 * ie_capability_mask           IBMF_SAA_EVENT_CAP_MASK_CHG
 * ie_sysimg_guid               IBMF_SAA_EVENT_SYS_IMG_GUID_CHG
 * ie_producer_type_status_mask IBMF_SAA_EVENT_SUBSCRIBER_STATUS_CHG
 *
 */
typedef struct ibmf_saa_event_details_s {
        ib_gid_t        ie_gid;
        ib_guid_t       ie_sysimg_guid;
        uint32_t        ie_capability_mask; /* values defined in sm_attr.h */
        ib_lid_t        ie_lid;
        uint8_t         ie_producer_event_status_mask;
} ibmf_saa_event_details_t;

/*
 * Callback invoked when one of the events the client subscribed for
 * at ibmf_sa_session_open() time happens.
 *
 * This callback can occur before ibmf_sa_session_open() returns.
 *
 * Each callback is on a separate thread.  ibmf clients may block in the event
 * callback.  However, under heavy system load ibmf may not be able to generate
 * event callbacks.  Also, event callbacks, including SUBSCRIBER_STATUS_CHG,
 * could be dispatched out-of-order.
 *
 * Arguments:
 * ibmf_saa_handle              - Client's ibmf_saa_handle
 * ibmf_saa_event               - event that caused the callback
 * event_details                - additional data for the event
 * callback_arg                 - event_callback_arg member of
 *                                ibmf_saa_subnet_event_args_t
 */
typedef void (*ibmf_saa_subnet_event_cb_t)(
        ibmf_saa_handle_t               ibmf_saa_handle,
        ibmf_saa_subnet_event_t         ibmf_saa_event,
        ibmf_saa_event_details_t        *event_details,
        void                            *callback_arg);

typedef struct ibmf_saa_subnet_event_args_s {

        /* func to be called when a subnet event happens */
        ibmf_saa_subnet_event_cb_t      is_event_callback;

        /* call back arg */
        void                            *is_event_callback_arg;

} ibmf_saa_subnet_event_args_t;

/*
 * ibmf_sa_session_open():
 *
 * Before using the ibmf_saa interface, consumers should register with the
 * ibmf_saa interface by calling ibmf_sa_session_open(). Upon a successful
 * registration, a handle is returned for use in subsequent interaction with the
 * ibmf_saa interface; this handle is also provided as an argument to subnet
 * event notification function.
 *
 * Consumers can register to be notified of subnet events such as GID
 * being available/unavailable.  Clients which provide a non-NULL event args
 * structure will have the is_event_callback function called when an event is
 * received or there is a failure in subscribing for events.  This callback may
 * be generated before the ibmf_sa_session_open() call returns.
 *
 * This interface blocks allocating memory, but not waiting for any packet
 * responses.
 *
 * Arguments:
 * port_guid            - GUID of the port.
 * event_args           - subnet event registration details
 * sm_key               - only filled in if the consumer is an SM
 * ibmf_version         - version of the interface (IBMF_VERSION)
 * flags                - unused
 *
 * Return values:
 * IBMF_SUCCESS         - registration succeeded
 * IBMF_BAD_PORT        - registration failed; active port not found
 * IBMF_BAD_PORT_STATE  - registration failed; port found but not active or
 *                      previous registration failed
 * IBMF_NO_MEMORY       - registration failed; could not allocate memory
 * IBMF_NO_RESOURCES    - registration failed due to a resource issue
 * IBMF_BUSY            - registration failed; too many clients registered
 *                      for this port
 * IBMF_TRANSPORT_FAILURE - failure with underlying transport framework
 * IBMF_INVALID_ARG     - ibmf_saa_handle arg was NULL
 */
int ibmf_sa_session_open(
                ib_guid_t                       port_guid,
                ib_smkey_t                      sm_key,
                ibmf_saa_subnet_event_args_t    *event_args,
                uint_t                          ibmf_version,
                uint_t                          flags,
                ibmf_saa_handle_t               *ibmf_saa_handle);

/*
 * ibmf_sa_session_close()
 *
 * Unregister a consumer of the SA_Access interface
 *
 * This interface blocks.
 *
 * Arguments:
 * ibmf_saa_handle      - handle returned from sa_session_open()
 * flags                - unused
 *
 * Return values:
 * IBMF_SUCCESS         - unregistration succeeded
 * IBMF_BAD_HANDLE      - unregistration failed; handle is not valid or
 *                        session_close has already been called
 * IBMF_INVALID_ARG     - ibmf_saa_handle arg was NULL
 *
 * All outstanding callbacks will be canceled before this function returns.
 */
int     ibmf_sa_session_close(
                ibmf_saa_handle_t       *ibmf_saa_handle,
                uint_t                  flags);

/*
 * ibmf_sa_access
 *
 * Retrieve records from the SA given an AttributeID, ComponentMask,
 * and a template
 *
 * This interface blocks if the callback parameter is NULL.
 *
 * Input Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * access_args          - structure containing various parameters for the query
 * flags                - unsused
 *
 * Output Arguments:
 * length               - size of buffer returned
 * result               - pointer to buffer of records returned in response.
 *                        Buffer is host-endian, unpacked can be cast to one of
 *                        the record types in sa_recs.h
 *
 * Return values:
 * IBMF_SUCCESS         - query succeeded
 * IBMF_BAD_HANDLE      - sa session handle is invalid
 * IBMF_BAD_PORT_STATE  - port in incorrect state
 * IBMF_INVALID_ARG     - one of the pointer parameters was NULL
 * IBMF_NO_RESOURCES    - ibmf could not allocate ib resources or SA returned
 *                        ERR_NO_RESOURCES
 * IBMF_TRANS_TIMEOUT   - transaction timed out
 * IBMF_TRANS_FAILURE   - transaction failure
 * IBMF_NO_MEMORY       - ibmf could not allocate memory
 * IBMF_REQ_INVALID     - send and recv buffer the same for a sequenced
 *                        transaction or the SA returned an ERR_REQ_INVALID
 * IBMF_NO_RECORDS      - no records matched query
 * IBMF_TOO_MANY_RECORDS- SA returned SA_ERR_TOO_MANY_RECORDS
 * IBMF_INVALID_GID     - SA returned SA_INVALID_GID
 * IBMF_INSUFF_COMPS    - SA returned SA_ERR_INSUFFICIENT_COMPS
 * IBMF_UNSUPP_METHOD   - SA returned MAD_STATUS_UNSUPP_METHOD
 * IBMF_UNSUPP_METHOD_ATTR - SA returned MAD_STATUS_UNSUPP_METHOD_ATTR
 * IBMF_INVALID_FIELD   - SA returned MAD_STATUS_INVALID_FIELD
 * IBMF_NO_ACTIVE_PORTS - no active ports found
 *
 * Upon successful completion, result points to a buffer containing the records.
 * length is the size in bytes of the buffer returned in result.  If there are
 * no records or the call failed the length is 0.
 *
 * The consumer is responsible for freeing the memory associated with result.
 */
int     ibmf_sa_access(
                ibmf_saa_handle_t       ibmf_saa_handle,
                ibmf_saa_access_args_t  *access_args,
                uint_t                  flags,
                size_t                  *length,
                void                    **result);

/*
 * Helper Functions.
 *      Ease of use functions so that the consumer doesn't
 *      have to do the overhead of calling ibmf_sa_access() for
 *      commonly used queries
 */

/*
 * ibmf_saa_gid_to_pathrecords
 *      Given a source gid and a destination gid, return paths
 *      between the gids.
 *
 * This interface blocks.
 *
 * Input Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * sgid                 - source gid of path
 * dgid                 - destination gid of path
 * p_key                - partition of path.  This value may be wildcarded with
 *                        IBMF_SAA_PKEY_WC.
 * mtu                  - preferred MTU of the path.  This argument may be
 *                        wildcarded with IBMF_SAA_MTU_WC.
 * reversible           - if B_TRUE, ibmf will query only reversible paths
 *                        see Infiniband Specification table 171
 * num_paths            - maximum number of paths to return
 *                        numpaths should be checked for the actual number of
 *                        records returned.
 * flags                - unused
 *
 * Output Arguments:
 * num_paths            - actual number of paths returned
 * length               - size of buffer returned
 * result               - pointer to buffer of path records returned in response
 *
 * Return values:
 * Error codes are the same as ibmf_sa_access() return values
 *
 * Upon successful completion, result points to a buffer containing the records.
 * length is the size in bytes of the buffer returned in result.  If there are
 * no records or the call failed the length is 0.
 *
 * The consumer is responsible for freeing the memory associated with result.
 */
int     ibmf_saa_gid_to_pathrecords(
                ibmf_saa_handle_t       ibmf_saa_handle,
                ib_gid_t                sgid,
                ib_gid_t                dgid,
                ib_pkey_t               p_key,
                ib_mtu_t                mtu,
                boolean_t               reversible,
                uint8_t                 *num_paths,
                uint_t                  flags,
                size_t                  *length,
                sa_path_record_t        **result);
/*
 * ibmf_saa_paths_from_gid
 *      Given a source GID, return a path from the source gid
 *      to every other port on the subnet.  It is assumed that the
 *      subnet is fully connected.  Only one path per port on the subnet
 *      is returned.
 *
 * This interface blocks.
 *
 * Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * sgid                 - source gid of path
 * pkey                 - paritition of path.  This value may be wildcarded with
 *                        IBMF_SAA_PKEY_WC.
 * reversible           - if B_TRUE, ibmf will query only reversible paths;
 *                        see Infiniband Specification table 171
 * flags                - unused
 *
 * Output Arguments:
 * num_paths            - number of paths returned
 * length               - size of buffer returned
 * result               - pointer to buffer of path records returned in response
 *
 * Return values:
 * Error codes are the same as ibmf_sa_access() return values
 *
 * Upon successful completion, result points to a buffer containing the records.
 * and num_paths is the number of path records returned.  length is the size
 * in bytes of the buffer returned in result.  If there are no records or the
 * call failed the length is 0.
 *
 * The consumer is responsible for freeing the memory associated with result.
 */
int     ibmf_saa_paths_from_gid(
                ibmf_saa_handle_t       ibmf_saa_handle,
                ib_gid_t                sgid,
                ib_pkey_t               pkey,
                boolean_t               reversible,
                uint_t                  flags,
                uint_t                  *num_paths,
                size_t                  *length,
                sa_path_record_t        **result);

/*
 * ibmf_saa_name_to_service_record:
 *      Given a service name, return the service records associated
 *      with it.
 *
 * This interface blocks.
 *
 * Input Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * name                 - service name, a null terminated string
 * p_key                - partition that the service is requested on.  This
 *                        value may be wildcarded with IBMF_SAA_PKEY_WC.
 * flags                - unused
 *
 * Output Arguments:
 * num_records          - number of service records returned
 * length               - size of buffer returned
 * result               - pointer to buffer of service records returned in
 *                        response
 *
 * Return values:
 * Error codes are the same as ibmf_sa_access() return values
 *
 * Upon successful completion, result points to a buffer containing the records.
 * and num_records is the number of service records returned.  length is the
 * size in bytes of the buffer returned in result.  If there are no records or
 * the call failed the length is 0.
 *
 * The consumer is responsible for freeing the memory associated with result.
 */
int     ibmf_saa_name_to_service_record(
                ibmf_saa_handle_t       ibmf_saa_handle,
                char                    *service_name,
                ib_pkey_t               p_key,
                uint_t                  flags,
                uint_t                  *num_records,
                size_t                  *length,
                sa_service_record_t     **result);

/*
 * ibmf_saa_id_to_service_record:
 *      Given a service id, return the service records associated
 *      with it.
 *
 * This interface blocks.
 *
 * Input Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * id                   - service id
 * p_key                - partition that the service is requested on.  This
 *                        value may be wildcarded with IBMF_SAA_PKEY_WC.
 * flags                - unused
 *
 * Output Arguments:
 * num_records          - number of service records returned
 * length               - size of buffer returned
 * result               - pointer to buffer of service records returned in
 *                        response
 *
 * Return values:
 * Error codes are the same as ibmf_sa_access() return values
 *
 * Upon successful completion, result points to a buffer containing the records.
 * and num_records is the number of service records returned.  length is the
 * size in bytes of the buffer returned in result.  If there are no records or
 * the call failed the length is 0.
 *
 * The consumer is responsible for freeing the memory associated with result.
 */
int     ibmf_saa_id_to_service_record(
                ibmf_saa_handle_t       ibmf_saa_handle,
                ib_svc_id_t             service_id,
                ib_pkey_t               p_key,
                uint_t                  flags,
                uint_t                  *num_records,
                size_t                  *length,
                sa_service_record_t     **result);

/*
 * ibmf_saa_update_service_record
 *      Given a pointer to a service record, either insert or delete it
 *
 * This interface blocks.
 *
 * Input Arguments:
 * ibmf_saa_handle      - handle returned from ibmf_sa_session_open()
 * service_record       - service record is to be inserted or deleted.  To
 *                        delete a service record the GID, ID, P_Key, and
 *                        Service Key must match what is in the SA.
 * access_type          - indicates whether this is an insertion or deletion.
 *                        valid values are IBMF_SAA_UPDATE or IBMF_SAA_DELETE
 * flags                - unused
 *
 * Ouptut Arguments
 * none
 *
 * Return values:
 * Error codes are the same as ibmf_sa_access() return values
 */
int     ibmf_saa_update_service_record(
                ibmf_saa_handle_t       ibmf_saa_handle,
                sa_service_record_t     *service_record,
                ibmf_saa_access_type_t  access_type,
                uint_t                  flags);

#ifdef __cplusplus
}
#endif

#endif  /* _SYS_IB_MGT_IBMF_IBMF_SAA_H */