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 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #ifndef _SRPT_IMPL_H_
  27 #define _SRPT_IMPL_H_
  28 
  29 /*
  30  * Prototypes and data structures for the SRP Target Port Provider.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/ddi.h>
  35 #include <sys/ib/ibtl/ibti.h>
  36 #include <sys/modctl.h>
  37 
  38 #include <sys/stmf.h>
  39 #include <sys/stmf_ioctl.h>
  40 #include <sys/portif.h>
  41 
  42 #include <sys/ib/mgt/ibdma/ibdma.h>
  43 
  44 #ifdef __cplusplus
  45 extern "C" {
  46 #endif
  47 
  48 /* Format the session identifier */
  49 #define ALIAS_STR(s, a, b)                                              \
  50         ((void) snprintf((s), sizeof ((s)), "%016llx:%016llx",          \
  51             (u_longlong_t)(a), (u_longlong_t)(b)))
  52 
  53 /* Format the EUI name */
  54 #define EUI_STR(s, a)                                                   \
  55         ((void) snprintf((s), sizeof ((s)), "eui.%016llX", (u_longlong_t)(a)))
  56 
  57 /*
  58  * We should/could consider making some of these values tunables.
  59  * Specifically, SEND_MSG_SIZE and SEND_MSG_DEPTH.
  60  */
  61 enum {
  62         SRPT_DEFAULT_IOC_SRQ_SIZE = 4096,
  63         SRPT_DEFAULT_SEND_MSG_DEPTH = 128,
  64         /*
  65          * SEND_MSG_SIZE must be a multiple of 64 as it is registered
  66          * as memory regions with IB.  To support a scatter/gather table
  67          * size of 32, the size must be at not less than 960.  To support
  68          * the maximum scatter/gather table size of 255, the IU must
  69          * be at least 4160 bytes.
  70          */
  71         SRPT_DEFAULT_SEND_MSG_SIZE = 4160,
  72         SRPT_DEFAULT_MAX_RDMA_SIZE = 65536,
  73         SRPT_MIN_T_I_IU_LEN = 52,
  74         SRPT_EUI_ID_LEN = 20,
  75         SRPT_RECV_WC_POLL_SIZE = 16,
  76         SRPT_SEND_WC_POLL_SIZE = 16,
  77         SRPT_MAX_OUT_IO_PER_CMD = 16,
  78         SRPT_FENCE_SEND = 1,
  79         SRPT_NO_FENCE_SEND = 0
  80 };
  81 
  82 struct srpt_target_port_s;
  83 
  84 #define SRPT_ALIAS_LEN  (SRP_PORT_ID_LEN * 2 + 2)
  85 
  86 /*
  87  * SRP Session - represents a SCSI I_T_Nexus.
  88  *
  89  * Sessions map 1 or more initiator logins to a specific I/O
  90  * Controller SCSI Target Port.  Targets create sessions
  91  * at initiator login and release when no longer referenced
  92  * by a login.
  93  */
  94 typedef struct srpt_session_s {
  95         krwlock_t                       ss_rwlock;
  96         list_node_t                     ss_node;
  97 
  98         /*
  99          * ADVANCED FEATURE, NOT YET SUPPORTED.
 100          * In multi-channel mode, multiple RDMA communication
 101          * channels may reference the same SCSI session.  When
 102          * a channel releases its reference to the SCSI session,
 103          * it should have no tasks associated with the session.
 104          *
 105          * If multi-channel is implemented, add a channel list
 106          * to this object instead of tracking it on the target.
 107          *
 108          * Will also need a session state & mode.  Mode is to
 109          * track if the session is MULTI or SINGLE channel.
 110          */
 111 
 112         stmf_scsi_session_t             *ss_ss;
 113         struct srpt_target_port_s       *ss_tgt;
 114         list_t                          ss_task_list;
 115 
 116         /*
 117          * SRP Initiator and target identifiers are 128-bit.
 118          *
 119          * The specification defines the initiator to be 64-bits of
 120          * ID extension and 64 bits of GUID, but these are really
 121          * just a recommendation.  Generally the extension is used
 122          * to create unique I_T_Nexus from the same initiator and
 123          * target.  Initiators are inconsistent on the GUID they
 124          * use, some use the HCA Node, some the HCA port.
 125          *
 126          * The specification defines the target to be 64-bits of
 127          * service ID followed by 64-bits of I/O Controller GUID.
 128          * In the case where there is a single default target
 129          * service, they will be the same (our default).
 130          */
 131         uint8_t                         ss_i_id[SRP_PORT_ID_LEN];
 132         uint8_t                         ss_t_id[SRP_PORT_ID_LEN];
 133 
 134         /* So we can see the full 128-bit initiator login from stmfadm */
 135         char                            ss_i_alias[SRPT_ALIAS_LEN];
 136         uint8_t                         ss_hw_port;
 137 
 138         char                            ss_t_alias[SRPT_ALIAS_LEN];
 139         char                            ss_i_name[SRPT_EUI_ID_LEN + 1];
 140         char                            ss_t_name[SRPT_EUI_ID_LEN + 1];
 141         char                            ss_i_gid[SRPT_ALIAS_LEN];
 142         char                            ss_t_gid[SRPT_ALIAS_LEN];
 143 } srpt_session_t;
 144 
 145 /*
 146  * Send work request types.
 147  */
 148 typedef enum srpt_swqe_type_e {
 149         SRPT_SWQE_TYPE_DATA = 1,
 150         SRPT_SWQE_TYPE_RESP
 151 } srpt_swqe_type_t;
 152 
 153 typedef struct srpt_swqe_s {
 154         srpt_swqe_type_t        sw_type;
 155         void                    *sw_addr;
 156         ibt_wrid_t              sw_next;
 157 } srpt_swqe_t;
 158 
 159 /*
 160  * SRP Channel - the RDMA communications channel associated with
 161  * a specific SRP login.
 162  */
 163 typedef enum srpt_channel_state_e {
 164         SRPT_CHANNEL_CONNECTING = 0,
 165         SRPT_CHANNEL_CONNECTED,
 166         SRPT_CHANNEL_DISCONNECTING
 167 } srpt_channel_state_t;
 168 
 169 typedef struct srpt_channel_s {
 170         krwlock_t                       ch_rwlock;
 171 
 172         kmutex_t                        ch_reflock;
 173         uint_t                          ch_refcnt;
 174         kcondvar_t                      ch_cv_complete;
 175         uint_t                          ch_cv_waiters;
 176 
 177         list_node_t                     ch_stp_node;
 178         srpt_channel_state_t            ch_state;
 179         ibt_cq_hdl_t                    ch_scq_hdl;
 180         ibt_cq_hdl_t                    ch_rcq_hdl;
 181         ibt_channel_hdl_t               ch_chan_hdl;
 182         ibt_chan_sizes_t                ch_sizes;
 183 
 184         uint32_t                        ch_req_lim_delta;
 185         uint32_t                        ch_ti_iu_len;
 186         struct srpt_target_port_s       *ch_tgt;
 187         srpt_session_t                  *ch_session;
 188 
 189         /*
 190          * Map IB send WQE request IDs to the
 191          * apporpriate operation type (for errors).
 192          */
 193         kmutex_t                        ch_swqe_lock;
 194         srpt_swqe_t                     *ch_swqe;
 195         uint32_t                        ch_num_swqe;
 196         uint32_t                        ch_head;
 197         uint32_t                        ch_tail;
 198         uint32_t                        ch_swqe_posted;
 199 } srpt_channel_t;
 200 
 201 /*
 202  * SRP Information Unit (IU).  Each IU structure contains
 203  * the buffer for the IU itself (received over the RC
 204  * channel), and all of the context required by the target
 205  * to process this request represented by the IU.
 206  * Available IU structures are managed on the I/O Controller
 207  * shared receive queue.
 208  */
 209 enum {
 210         SRPT_IU_STMF_ABORTING   = 1 << 0, /* STMF called abort */
 211         SRPT_IU_SRP_ABORTING    = 1 << 1, /* SRP initiator aborting */
 212         SRPT_IU_ABORTED         = 1 << 2, /* Task has been aborted */
 213         SRPT_IU_RESP_SENT       = 1 << 3  /* Response queued */
 214 };
 215 
 216 typedef struct srpt_iu_s {
 217         /*
 218          * The buffer for the IU itself.  When unused (a
 219          * reference count of zero), this buffer is posted
 220          * on the I/O Controllers SRPT SRQ.
 221          */
 222         void                    *iu_buf;
 223         ibt_wr_ds_t             iu_sge;
 224         struct srpt_ioc_s       *iu_ioc;
 225         uint_t                  iu_pool_ndx;
 226         kmutex_t                iu_lock;
 227 
 228         /*
 229          * The following are reset for each IU request
 230          * processed by this buffer.
 231          */
 232         list_node_t             iu_ss_task_node;
 233         srpt_channel_t          *iu_ch;
 234 
 235         uint_t                  iu_num_rdescs;
 236         srp_direct_desc_t       *iu_rdescs;
 237         uint_t                  iu_tot_xfer_len;
 238 
 239         uint64_t                iu_tag;
 240         uint_t                  iu_flags;
 241         uint32_t                iu_sq_posted_cnt;
 242         scsi_task_t             *iu_stmf_task;
 243 } srpt_iu_t;
 244 
 245 /*
 246  * SRP SCSI Target Port.  By default each HCA creates a single
 247  * SCSI Target Port based on the associated I/O Controller
 248  * (HCA) node GUID and made available through each physical
 249  * hardware port of the I/O Controller.
 250  */
 251 typedef enum srpt_target_state_e {
 252         SRPT_TGT_STATE_OFFLINE = 0,
 253         SRPT_TGT_STATE_ONLINING,
 254         SRPT_TGT_STATE_ONLINE,
 255         SRPT_TGT_STATE_OFFLINING
 256 } srpt_target_state_t;
 257 
 258 typedef struct srpt_hw_port_s {
 259         ibt_sbind_hdl_t         hwp_bind_hdl;
 260         ib_gid_t                hwp_gid;
 261 } srpt_hw_port_t;
 262 
 263 typedef struct srpt_target_port_s {
 264         stmf_local_port_t       *tp_lport;
 265         struct srpt_ioc_s       *tp_ioc;
 266 
 267         kmutex_t                tp_lock;
 268         srpt_target_state_t     tp_state;
 269         kcondvar_t              tp_offline_complete;
 270         uint_t                  tp_drv_disabled;
 271 
 272         /*
 273          * We are using a simple list for channels right now, we
 274          * probably should  switch this over to the AVL
 275          * implementation eventually (but lookups are not done
 276          * in the data path so this is not urgent).
 277          */
 278         kmutex_t                tp_ch_list_lock;
 279         list_t                  tp_ch_list;
 280 
 281         /*
 282          * A list of active sessions.  Session lifetime is
 283          * determined by having active channels, but track
 284          * them here for easier determination to when a
 285          * target can truly be offlined, and as a step toward
 286          * being session-focused rather than channel-focused.
 287          * If we ever truly support multi-channel, move the
 288          * channels to be part of the session object.
 289          *
 290          * Sessions should remain on this list until they
 291          * are deregistered from STMF.  This allows the target
 292          * to properly track when it can consider itself 'offline'.
 293          */
 294         kmutex_t                tp_sess_list_lock;
 295         kcondvar_t              tp_sess_complete;
 296         list_t                  tp_sess_list;
 297 
 298         uint_t                  tp_srp_enabled;
 299         ibt_srv_hdl_t           tp_ibt_svc_hdl;
 300         ibt_srv_desc_t          tp_ibt_svc_desc;
 301         ib_svc_id_t             tp_ibt_svc_id;
 302         scsi_devid_desc_t       *tp_scsi_devid;
 303         uint8_t                 tp_srp_port_id[SRP_PORT_ID_LEN];
 304 
 305         uint_t                  tp_nports;
 306         srpt_hw_port_t          *tp_hw_port;
 307         /*
 308          * track the number of active ports so we can offline the target if
 309          * none
 310          */
 311         uint32_t                tp_num_active_ports;
 312         /* state STMF wants the target in.  We may be offline due to no ports */
 313         srpt_target_state_t     tp_requested_state;
 314 } srpt_target_port_t;
 315 
 316 /*
 317  * SRP Target hardware device.  A SRP Target hardware device
 318  * is an IB HCA.  All ports of the HCA comprise a single
 319  * I/O Controller that is registered with the IB Device
 320  * Managment Agent.
 321  */
 322 typedef struct srpt_ioc_s {
 323         list_node_t                     ioc_node;
 324 
 325         krwlock_t                       ioc_rwlock;
 326         ibt_hca_hdl_t                   ioc_ibt_hdl;
 327         ibt_hca_attr_t                  ioc_attr;
 328         ib_guid_t                       ioc_guid;
 329 
 330         /*
 331          * By default each HCA is a single SRP.T10 service based on
 332          * the HCA GUID.  We have implemented the target here as a
 333          * pointer to facilitate moving to a list of targets if
 334          * appropriate down the road.
 335          */
 336         srpt_target_port_t              *ioc_tgt_port;
 337 
 338 
 339         /*
 340          * Each HCA registers a single I/O Controller with the
 341          * IB Device Management Agent.
 342          */
 343         ibdma_hdl_t                     ioc_ibdma_hdl;
 344         ib_dm_ioc_ctrl_profile_t        ioc_profile;
 345         ib_dm_srv_t                     ioc_svc;
 346 
 347         ibt_pd_hdl_t                    ioc_pd_hdl;
 348         ibt_srq_sizes_t                 ioc_srq_attr;
 349         ibt_srq_hdl_t                   ioc_srq_hdl;
 350 
 351         /*
 352          * The I/O Controller pool of IU resources allocated
 353          * at controller creation.
 354          */
 355         uint32_t                        ioc_num_iu_entries;
 356         srpt_iu_t                       *ioc_iu_pool;
 357         ibt_mr_hdl_t                    ioc_iu_mr_hdl;
 358         void                            *ioc_iu_bufs;  /* iu buffer space */
 359 
 360         /*
 361          * Each I/O Controller has it's own data buffer
 362          * vmem arena.  Pool is created at controller creation,
 363          * and expanded as required.  This keeps IB memory
 364          * registrations to a minimum in the data path.
 365          */
 366         struct srpt_vmem_pool_s         *ioc_dbuf_pool;
 367         stmf_dbuf_store_t               *ioc_stmf_ds;
 368 } srpt_ioc_t;
 369 
 370 /*
 371  * Memory regions
 372  */
 373 typedef struct srpt_mr_s {
 374         ibt_mr_hdl_t                    mr_hdl;
 375         ib_vaddr_t                      mr_va;
 376         ib_memlen_t                     mr_len;
 377         ibt_lkey_t                      mr_lkey;
 378         ibt_rkey_t                      mr_rkey;
 379         avl_node_t                      mr_avl;
 380 } srpt_mr_t;
 381 
 382 /*
 383  * SRP Target vmem arena definition
 384  */
 385 typedef struct srpt_vmem_pool_s {
 386         srpt_ioc_t              *svp_ioc;
 387         ib_memlen_t             svp_chunksize;
 388         vmem_t                  *svp_vmem;
 389         uint64_t                svp_total_size;
 390         uint64_t                svp_max_size;
 391         avl_tree_t              svp_mr_list;
 392         krwlock_t               svp_lock;
 393         ibt_mr_flags_t          svp_flags;
 394 } srpt_vmem_pool_t;
 395 
 396 /*
 397  * SRP port provider data buffer, allocated and freed
 398  * via calls to the IOC datastore.
 399  */
 400 typedef struct srpt_ds_dbuf_s {
 401         stmf_data_buf_t                 *db_stmf_buf;
 402         srpt_ioc_t                      *db_ioc;
 403         ibt_mr_hdl_t                    db_mr_hdl;
 404         ibt_wr_ds_t                     db_sge;
 405         srpt_iu_t                       *db_iu;
 406 } srpt_ds_dbuf_t;
 407 
 408 /*
 409  * SRP Target service state
 410  */
 411 typedef enum {
 412         SRPT_SVC_DISABLED,
 413         SRPT_SVC_ENABLED
 414 } srpt_svc_state_t;
 415 
 416 typedef struct {
 417         ddi_modhandle_t         ibdmah;
 418         ibdma_hdl_t             (*ibdma_register)(ib_guid_t,
 419                                     ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *);
 420         ibdma_status_t          (*ibdma_unregister)(ibdma_hdl_t);
 421         ibdma_status_t          (*ibdma_update)(ibdma_hdl_t,
 422                                     ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *);
 423 } srpt_ibdma_ops_t;
 424 
 425 /*
 426  * SRP Target protocol driver context data structure, maintaining
 427  * the global state of the protocol.
 428  */
 429 typedef struct srpt_ctxt_s {
 430         dev_info_t                      *sc_dip;
 431         krwlock_t                       sc_rwlock;
 432         srpt_svc_state_t                sc_svc_state;
 433 
 434         ibt_clnt_hdl_t                  sc_ibt_hdl;
 435 
 436         /*
 437          * SRP Target I/O Controllers. Each IBT HCA represents an
 438          * I/O Controller.  Must hold rwlock as a writer to update.
 439          */
 440         list_t                          sc_ioc_list;
 441         uint_t                          sc_num_iocs;
 442 
 443         /* Back-end COMSTAR port provider interface. */
 444         stmf_port_provider_t            *sc_pp;
 445 
 446         /* IBDMA entry points */
 447         srpt_ibdma_ops_t                sc_ibdma_ops;
 448 
 449         /*
 450          *  List of explicitly configured HCAs and their configurable
 451          *  attributes.
 452          */
 453         nvlist_t                        *sc_cfg_hca_nv;
 454 } srpt_ctxt_t;
 455 
 456 typedef struct srpt_iu_data_s {
 457         union {
 458                 uint8_t                 srp_op;
 459                 srp_cmd_req_t           srp_cmd;
 460                 srp_tsk_mgmt_t          srp_tsk_mgmt;
 461                 srp_i_logout_t          srp_i_logout;
 462                 srp_rsp_t               srp_rsp;
 463         } rx_iu;
 464 } srpt_iu_data_t;
 465 
 466 extern srpt_ctxt_t *srpt_ctxt;
 467 
 468 /*
 469  * For Non recoverable or Major Errors
 470  */
 471 #define SRPT_LOG_L0     0
 472 
 473 /*
 474  * For additional information on Non recoverable errors and
 475  * warnings/informational message for sys-admin types.
 476  */
 477 #define SRPT_LOG_L1     1
 478 
 479 /*
 480  * debug only
 481  * for more verbose trace than L1, for e.g. recoverable errors,
 482  * or intersting trace
 483  */
 484 #define SRPT_LOG_L2     2
 485 
 486 /*
 487  * debug only
 488  * for more verbose trace than L2, for e.g. printing function entries....
 489  */
 490 #define SRPT_LOG_L3     3
 491 
 492 /*
 493  * debug only
 494  * for more verbose trace than L3, for e.g. printing minor function entries...
 495  */
 496 #define SRPT_LOG_L4     4
 497 
 498 /*
 499  * srpt_errlevel can be set in the debugger to enable additional logging.
 500  * You can also add set srpt:srpt_errlevel={0,1,2,3,4} in /etc/system.
 501  * The default log level is L1.
 502  */
 503 #define SRPT_LOG_DEFAULT_LEVEL SRPT_LOG_L1
 504 
 505 extern uint_t srpt_errlevel;
 506 
 507 
 508 #define SRPT_DPRINTF_L0(...) cmn_err(CE_WARN, __VA_ARGS__)
 509 #define SRPT_DPRINTF_L1(...) cmn_err(CE_NOTE, __VA_ARGS__)
 510 #define SRPT_DPRINTF_L2(...)    if (srpt_errlevel >= SRPT_LOG_L2) { \
 511                                         cmn_err(CE_NOTE, __VA_ARGS__);\
 512                                 }
 513 #ifdef  DEBUG
 514 #define SRPT_DPRINTF_L3(...)    if (srpt_errlevel >= SRPT_LOG_L3) { \
 515                                         cmn_err(CE_NOTE, __VA_ARGS__);\
 516                                 }
 517 #define SRPT_DPRINTF_L4(...)    if (srpt_errlevel >= SRPT_LOG_L4) { \
 518                                         cmn_err(CE_NOTE, __VA_ARGS__);\
 519                                 }
 520 #else
 521 #define SRPT_DPRINTF_L3         0 &&
 522 #define SRPT_DPRINTF_L4         0 &&
 523 #endif
 524 
 525 #ifdef __cplusplus
 526 }
 527 #endif
 528 
 529 #endif /* _SRPT_IMPL_H_ */