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 */