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