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