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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_IB_IBTL_IMPL_IBTL_H 28 #define _SYS_IB_IBTL_IMPL_IBTL_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * ibtl.h 34 * 35 * All data structures and function prototypes that are specific to the 36 * IBTL implementation. 37 */ 38 #include <sys/note.h> 39 #include <sys/ib/ibtl/ibvti.h> 40 #include <sys/ib/ibtl/ibti.h> 41 #include <sys/ib/ibtl/ibci.h> 42 #include <sys/ib/ibtl/impl/ibtl_util.h> 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /* 49 * Define a per IBT Client state structure. Its address is returned 50 * to the IBT client as an opaque IBT Client Handle - ibt_clnt_hdl_t. 51 * 52 * ibt_attach() allocates one of these structures. 53 * 54 * For each IBT Client registered with the IBTL, we maintain a list 55 * of HCAs, clnt_hca_list, that this IBT Client is using. 56 * 57 * This list is updated by ibt_open_hca(). 58 */ 59 typedef struct ibtl_clnt_s { 60 char clnt_name[8]; /* (just a debugging aid) */ 61 ibt_clnt_modinfo_t *clnt_modinfop; /* Pointer to IBT client's */ 62 /* module information */ 63 void *clnt_private; /* IBT Client's private ptr */ 64 dev_info_t *clnt_dip; /* IBT Client's dip */ 65 struct ibtl_clnt_s *clnt_list_link; 66 uint32_t clnt_async_cnt; 67 uint32_t clnt_srv_cnt; /* Service resource counter */ 68 struct ibtl_hca_s *clnt_hca_list; /* HCAs this client is using. */ 69 /* link is ha_hca_link */ 70 ibt_sm_notice_handler_t clnt_sm_trap_handler; /* may be NULL */ 71 void *clnt_sm_trap_handler_arg; 72 } ibtl_clnt_t; 73 74 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_clnt_s::{clnt_name clnt_modinfop 75 clnt_private clnt_dip})) 76 77 /* HCA Device State. */ 78 typedef enum ibtl_hca_state_e { 79 IBTL_HCA_DEV_ATTACHED = 1, /* new HCA attached */ 80 IBTL_HCA_DEV_DETACHED = 2, /* detached */ 81 IBTL_HCA_DEV_DETACHING = 3 /* not detached yet */ 82 } ibtl_hca_state_t; 83 84 /* 85 * Define a type to record hca async PORT_UP and PORT_DOWN events for 86 * processing by async thread(s). At the time an async is made by an 87 * HCA driver (presumably at interrupt level), a call is made to IBTL. 88 * IBTL marks this field, and wakes up an async thread for delivery 89 * to IBT clients as appropriate. 90 */ 91 92 typedef enum ibtl_async_port_status_e { 93 IBTL_HCA_PORT_UNKNOWN = 0x0, /* initial state */ 94 IBTL_HCA_PORT_UP = 0x1, 95 IBTL_HCA_PORT_DOWN = 0x2, 96 IBTL_HCA_PORT_CHANGED = 0x4 97 } ibtl_async_port_status_t; 98 99 /* 100 * Bit definition(s) for {qp,cq,eec,hd,ha,srq}_async_flags. 101 * 102 * IBTL_ASYNC_PENDING This structure is known by the async_threads. 103 * It will be checked for additional async work 104 * before this bit is cleared, so new async 105 * events/errors do not require this structure 106 * to be linked onto its async list. 107 * 108 * IBTL_ASYNC_FREE_OBJECT Client has called ibt_free_*, and the 109 * the structure should be kmem_freed when 110 * the outstanding asyncs complete. 111 */ 112 typedef enum ibtl_async_flags_e { 113 IBTL_ASYNC_PENDING = 0x1, 114 IBTL_ASYNC_FREE_OBJECT = 0x2 115 } ibtl_async_flags_t; 116 117 /* 118 * Define a per CI HCA Device structure. Its address is returned 119 * to the CI as an opaque IBTL HCA Handle - ibc_hdl_t. 120 * 121 * ibc_ci_attach() allocates one of these and adds it to ibtl_hca_list. 122 * 123 * The hd_hca_dev_link is the link for the ibtl_hca_list. It is the 124 * list of HCA devices registered with the IBTL. 125 * 126 * The hd_clnt_list is a list of IBT Clients using this HCA. 127 * The hd_clnt_list->l_head points to the ha_clnt_link field of a client's 128 * ibtl_hca_s structure. 129 * 130 * This list is updated by ibt_open_hca(). 131 */ 132 typedef struct ibtl_hca_devinfo_s { 133 struct ibtl_hca_devinfo_s *hd_hca_dev_link; /* Next HCA Device */ 134 ibtl_hca_state_t hd_state; /* HCA device state: */ 135 /* attached/detached */ 136 uint_t hd_portinfo_len; /* #bytes of portinfo */ 137 ibt_hca_portinfo_t *hd_portinfop; /* ptr to portinfo cache */ 138 struct ibtl_hca_s *hd_clnt_list; /* IBT Client using this HCA. */ 139 ibc_hca_hdl_t hd_ibc_hca_hdl; /* CI HCA handle */ 140 ibc_operations_t *hd_ibc_ops; /* operations vector */ 141 ibt_hca_attr_t *hd_hca_attr; /* hca attributes */ 142 dev_info_t *hd_hca_dip; /* HCA devinfo pointer */ 143 struct ibtl_hca_devinfo_s *hd_async_link; /* async list link */ 144 kcondvar_t hd_portinfo_cv; /* waiting for ibc_query */ 145 int hd_portinfo_waiters; /* any waiters */ 146 uint8_t hd_portinfo_locked_port; 147 /* port whose info is queried */ 148 kcondvar_t hd_async_busy_cv; /* wakeup when #clients = 0 */ 149 int hd_async_busy; /* only 1 async at a time */ 150 ibt_async_code_t hd_async_codes; /* all codes for this HCA */ 151 ibt_async_code_t hd_async_code; /* current code being run */ 152 ibt_async_event_t hd_async_event; /* current event being run */ 153 ibtl_async_flags_t hd_async_flags; /* see *_async_flags above */ 154 uint64_t hd_fma_ena; /* FMA data for LOCAL CATASTR */ 155 uint32_t hd_async_task_cnt; /* #clients doing asyncs */ 156 kcondvar_t hd_async_task_cv; /* wakeup when #clients = 0 */ 157 uint_t hd_multism; /* 1 - MultiSM, 0 - Single SM */ 158 /* The following must be at the end of this struct */ 159 ibtl_async_port_status_t hd_async_port[1]; /* per-port async data */ 160 } ibtl_hca_devinfo_t; 161 162 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_ibc_ops)) 163 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_ibc_hca_hdl)) 164 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_hca_attr)) 165 _NOTE(SCHEME_PROTECTS_DATA("hd_async_busy and hd_async_busy_cv", 166 ibtl_hca_devinfo_s::{hd_async_code hd_async_event})) 167 168 /* 169 * Define a HCA info structure. 170 * 171 * The IBTL function ibt_open_hca() allocates one of these. 172 * 173 * For each client instance registered with the IBTL, we maintain a list 174 * of HCAs that it is using. The elements of that list include the 175 * address of the CI HCA device structure, a pointer to the client 176 * structure, and reference counts of HCA resources that this client 177 * device is using. 178 * 179 * Note: ha_qpn_cnt is protected by a global mutex to deal with a client 180 * trying to open the HCA while it is actively being closed. 181 * 182 * ha_hca_link is the link to the next HCA info struct that this client is 183 * using. 184 * 185 * ha_clnt_link is the link to the next IBT client (ibtl_clnt_t) that is using 186 * the same CI HCA (ibtl_hca_devinfo_t). The link points to that client's 187 * ibtl_hca_t because an IBT client can use more than one CI HCA. 188 */ 189 typedef struct ibtl_hca_s { 190 struct ibtl_hca_s *ha_hca_link; /* Next HCA used by client */ 191 struct ibtl_hca_s *ha_clnt_link; /* Next client using same HCA */ 192 ibtl_hca_devinfo_t *ha_hca_devp; /* CI HCA device structure. */ 193 ibtl_clnt_t *ha_clnt_devp; /* Client state struct */ 194 void *ha_clnt_private; 195 kmutex_t ha_mutex; /* Mutex to protect resource */ 196 /* counters. */ 197 int ha_flags; /* misc. flags */ 198 uint32_t ha_qp_cnt; /* QP resource counter */ 199 uint32_t ha_eec_cnt; /* EEC resource counter */ 200 uint32_t ha_cq_cnt; /* CQ resource counter */ 201 uint32_t ha_pd_cnt; /* PD resource counter */ 202 uint32_t ha_ah_cnt; /* AH resource counter */ 203 uint32_t ha_mr_cnt; /* Mem Region resource count */ 204 uint32_t ha_mw_cnt; /* Mem Window resource count */ 205 uint32_t ha_qpn_cnt; /* QPN resource counter */ 206 uint32_t ha_srq_cnt; /* SRQ resource counter */ 207 ibtl_async_flags_t ha_async_flags; /* see *_async_flags above */ 208 uint32_t ha_async_cnt; /* #asyncs in progress */ 209 uint32_t ha_fmr_pool_cnt; /* FMR Pool resource count */ 210 uint32_t ha_ma_cnt; /* Mem Area resource count */ 211 } ibtl_hca_t; 212 213 /* ha_flags values */ 214 #define IBTL_HA_CLOSING 1 /* In process of closing, so don't allow open */ 215 216 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_s::ha_clnt_devp)) 217 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_s::ha_hca_devp)) 218 219 /* 220 * Bit definition(s) for cq_impl_flags. 221 * 222 * IBTL_CQ_PENDING This CQ is known by the ibtl_cq_threads, 223 * and it will be checked for additional work 224 * before this bit is cleared, so new work 225 * will be seen without this cq being added 226 * to the cq list. 227 * 228 * IBTL_CQ_CALL_CLIENT Mark that the HCA driver has called 229 * ibc_cq_handler with new work on this CQ, 230 * so IBTL should call the client handler 231 * again before it is considered done. 232 * 233 * IBTL_CQ_FREE Mark that ibt_free_cq is sleeping until 234 * ibtl_cq_threads is done with this CQ. 235 */ 236 typedef enum ibtl_cq_impl_flags_e { 237 IBTL_CQ_PENDING = 0x1, 238 IBTL_CQ_CALL_CLIENT = 0x2, 239 IBTL_CQ_FREE = 0x4 240 } ibtl_cq_impl_flags_t; 241 242 243 /* 244 * Define a per CQ state structure. 245 * 246 * The ibt_alloc_cq() allocates one of these. A CQ is associated with a 247 * particular HCA, whose handle is recorded in the cq_hca field. 248 * The cq_ibc_cq_hdl field is initialized with the CI CQ handle returned 249 * from the ibc_alloc_cq() call to the HCA driver. 250 * 251 * In order to set/get the client's private data, cq_clnt_private, clients 252 * need to use ibt_set_cq_private() and ibt_get_cq_private() calls. 253 * 254 * An IBT client registers a CQ completion handler callback and private 255 * callback argument (probably the client instance soft state structure) using 256 * the ibt_set_cq_handler() IBT routine. The comp_handler, arg fields of the 257 * structure are initialized with the values passed in by the IBTL client. 258 * These two fields are the only fields protected by the cq_mutex. 259 * 260 * When a completion event is posted to an IBT client, the 261 * client completion handler is called with the following arguments: 262 * 263 * - The Client Handle, that is passed into the IBTL on ibt_attach call. 264 * - The CQ Handle upon which the completion occurred. 265 * - The private client argument, set during handler registration via 266 * ibt_set_cq_handler() call. 267 * 268 * The address of the ibtl_cq_s structure is passed in as the ibt_cq_hdl_t 269 * (callback arg) in the CI ibc_alloc_cq() function. Thus when a CI calls 270 * the IBTL completion handler (ibc_ci_cq_handler()) we can de-mux 271 * directly to the targeted IBT client. 272 * 273 */ 274 typedef struct ibtl_cq_s { 275 ibc_cq_hdl_t cq_ibc_cq_hdl; /* CI CQ handle */ 276 ibtl_hca_t *cq_hca; /* IBTL HCA hdl */ 277 ibt_cq_handler_t cq_comp_handler; /* Completion handler */ 278 void *cq_arg; /* CQ handler's argument */ 279 kmutex_t cq_mutex; /* Mutex. */ 280 void *cq_clnt_private; /* Client's Private. */ 281 struct ibtl_cq_s *cq_link; /* link for queuing cq to */ 282 /* to be handled in a thread */ 283 struct ibtl_cq_s *cq_async_link; /* list link for asyncs */ 284 ibtl_cq_impl_flags_t cq_impl_flags; /* dynamic bits if cq */ 285 /* handler runs in a thread */ 286 int cq_in_thread; /* mark if cq handler is to */ 287 /* be called in a thread */ 288 ibt_async_code_t cq_async_codes; 289 ibtl_async_flags_t cq_async_flags; /* see *_async_flags above */ 290 uint64_t cq_fma_ena; /* FMA data */ 291 } ibtl_cq_t; 292 293 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_cq_s::{cq_in_thread cq_hca 294 cq_ibc_cq_hdl})) 295 296 /* 297 * Define a per SRQ state structure. 298 * 299 * ibt_alloc_srq() allocates one of these. A SRQ is associated with a 300 * particular HCA, whose handle is recorded in the srq_hca field. 301 * The srq_ibc_srq_hdl field is initialized with the CI SRQ handle returned 302 * from the ibc_alloc_srq() call to the HCA driver. 303 * 304 * In order to set/get the client's private data, srq_clnt_private, clients 305 * need to use ibt_set_srq_private() and ibt_get_srq_private() calls. 306 * 307 * The address of the ibtl_srq_s structure is passed in as the ibt_srq_hdl_t 308 * (callback arg) in the CI ibc_alloc_srq() function. 309 */ 310 typedef struct ibtl_srq_s { 311 ibc_srq_hdl_t srq_ibc_srq_hdl; /* CI SRQ handle */ 312 ibtl_hca_t *srq_hca; /* IBTL HCA hdl */ 313 void *srq_clnt_private; /* Client's Private. */ 314 struct ibtl_srq_s *srq_async_link; /* Async Link list */ 315 ibt_async_code_t srq_async_codes; 316 ibtl_async_flags_t srq_async_flags; /* Async_flags */ 317 uint64_t srq_fma_ena; /* FMA data */ 318 } ibtl_srq_t; 319 320 /* 321 * Define a per QP state structure. 322 * 323 * The qp_hca field is initialized with the ibtl_hca_hdl_t of the HCA in 324 * which the QP was allocated. The qp_ibc_qp_hdl field is initialized with 325 * the CI QP handle. 326 * 327 * The ibtl_qp_t structure also maintains a channel connection state 328 * structure that is only valid for RC and RD QP's. The information about 329 * the respective Send and Receive CQ, the RDD and PD Handles are also stored. 330 * 331 * The IBTA spec does not include the signal type or PD on a QP query 332 * operation. In order to implement the "CLONE" feature of the alloc rc|ud 333 * channel functions we need to cache these values. 334 */ 335 typedef struct ibtl_qp_s { 336 ibt_tran_srv_t qp_type; /* QP type */ 337 ibt_attr_flags_t qp_flags; 338 ibc_qp_hdl_t qp_ibc_qp_hdl; /* CI QP handle */ 339 ibc_pd_hdl_t qp_pd_hdl; /* CI PD Hdl */ 340 ibtl_hca_t *qp_hca; /* IBTL HCA handle */ 341 ibtl_cq_t *qp_send_cq; /* IBTL CQ handle */ 342 ibtl_cq_t *qp_recv_cq; /* IBTL CQ handle */ 343 struct ibtl_qp_s *qp_async_link; /* async list link */ 344 ibt_async_code_t qp_async_codes; 345 ibtl_async_flags_t qp_async_flags; /* see *_async_flags above */ 346 uint64_t qp_cat_fma_ena; /* FMA data */ 347 uint64_t qp_pth_fma_ena; /* FMA data */ 348 uint64_t qp_inv_fma_ena; /* FMA data */ 349 uint64_t qp_acc_fma_ena; /* FMA data */ 350 } ibtl_qp_t; 351 352 353 /* 354 * Define a per EEC state structure. 355 * 356 * The ibt_alloc_eec() allocates an ibt_eec_s structure and initializes 357 * the eec_hca field with the ibtl_hca_hdl_t of the HCA in which the EEC 358 * was allocated. The eec_ibc_eec_hdl field is initialized with the 359 * CI EEC handle. 360 * 361 * The information about CI's RDD Handle and channel connection state structure 362 * is also maintained. 363 */ 364 typedef struct ibtl_eec_s { 365 ibc_eec_hdl_t eec_ibc_eec_hdl; /* CI EEC Handle. */ 366 ibtl_hca_t *eec_hca; /* IBTL HCA Hdl */ 367 ibc_rdd_hdl_t eec_ibc_rdd_hdl; /* CI RDD Handle. */ 368 struct ibtl_channel_s *eec_channel; 369 struct ibtl_eec_s *eec_async_link; /* async list link */ 370 ibt_async_code_t eec_async_codes; 371 ibtl_async_flags_t eec_async_flags; 372 uint64_t eec_cat_fma_ena; /* FMA data */ 373 uint64_t eec_pth_fma_ena; /* FMA data */ 374 } ibtl_eec_t; 375 376 /* 377 * Define an ibt RD communication channel struct. This holds information 378 * specific to an RD QP. 379 */ 380 typedef struct ibtl_rd_chan_s { 381 ibtl_eec_t *rd_eec; /* point to the EEC */ 382 } ibtl_rd_chan_t; 383 384 /* 385 * Define an ibt UD communication channel struct. This holds information 386 * specific to a UD QP. 387 */ 388 typedef struct ibtl_ud_chan_s { 389 uint8_t ud_port_num; /* track the port number for */ 390 /* ibt_modify_reply_ud_dest() */ 391 ib_qkey_t ud_qkey; /* track the qkey */ 392 } ibtl_ud_chan_t; 393 394 /* 395 * Define an ibt RC communication channel struct. This holds information 396 * specific to an RC QP. 397 */ 398 typedef struct ibtl_rc_chan_s { 399 int rc_free_flags; /* Track connection state as */ 400 /* we will need to delay for */ 401 /* TIMEWAIT before freeing. */ 402 ibc_qpn_hdl_t rc_qpn_hdl; /* Store qpn_hdl while in */ 403 /* TIMEWAIT delay. */ 404 } ibtl_rc_chan_t; 405 406 /* bit definitions for rc_free_flags */ 407 #define IBTL_RC_QP_CONNECTED 0x1 408 #define IBTL_RC_QP_CLOSING 0x2 409 #define IBTL_RC_QP_CLOSED 0x4 410 #define IBTL_RC_QP_FREED 0x8 411 412 /* 413 * Define a per Channel state structure. 414 * 415 * A ibtl_channel_s is allocated each time a TI client calls a 416 * channel allocation routine ibt_alloc_rc_channel() or ibt_alloc_ud_channel() 417 * or VTI client calls ibt_alloc_qp() or ibt_alloc_special_qp(). 418 * 419 * In order to set/get the client's private data, ch_clnt_private, 420 * TI client's need to use ibt_set_chan_private() and ibt_get_chan_private() 421 * or VTI clients need to use ibt_set_qp_private() and ibt_get_qp_private(). 422 */ 423 typedef struct ibtl_channel_s { 424 /* The ibtl_qp_t must be at the first of this struct */ 425 ibtl_qp_t ch_qp; /* IBTL QP handle */ 426 union { /* transport specific */ 427 ibtl_rc_chan_t rc; /* RC Channel specific */ 428 ibtl_rd_chan_t rd; /* RD Channel specific */ 429 ibtl_ud_chan_t ud; /* UD Channel specific */ 430 } ch_transport; 431 ibt_cep_state_t ch_current_state; /* track the current state */ 432 void *ch_clnt_private; /* Client's Private data */ 433 kmutex_t ch_cm_mutex; /* for ch_cm_private, etc. */ 434 kcondvar_t ch_cm_cv; /* for recycle_rc */ 435 void *ch_cm_private; /* Ptr to CM state */ 436 } ibtl_channel_t; 437 438 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_channel_s)) 439 440 /* 441 * MACROS 442 */ 443 #define IBTL_CHAN2QP(ibt_chan) (&(ibt_chan)->ch_qp) 444 #define IBTL_CHAN2HCA(ibt_chan) (ibt_chan)->ch_qp.qp_hca 445 446 #define IBTL_CHAN2CIQP(ibt_chan) (ibt_chan->ch_qp.qp_ibc_qp_hdl) 447 448 #define IBTL_QP2CHAN(ibtl_qp) (ibtl_channel_t *)(ibtl_qp) 449 #define IBTL_EEC2CHAN(ibtl_eec) (ibtl_eec)->eec_channel 450 451 /* 452 * Get IBC HCA Handle from IBT Handles. 453 */ 454 #define IBTL_HDIP2CIHCA(hca_devp) (hca_devp)->hd_ibc_hca_hdl 455 #define IBTL_HCA2CIHCA(ibtl_hca) IBTL_HDIP2CIHCA(ibtl_hca->ha_hca_devp) 456 #define IBTL_ECC2CIHCA(ibtl_eec) IBTL_HCA2CIHCA((ibtl_eec)->eec_hca) 457 #define IBTL_CQ2CIHCA(ibtl_cq) IBTL_HCA2CIHCA((ibtl_cq)->cq_hca) 458 #define IBTL_CHAN2CIHCA(ibt_chan) IBTL_HCA2CIHCA((ibt_chan)->ch_qp.qp_hca) 459 #define IBTL_SRQ2CIHCA(ibtl_srq) IBTL_HCA2CIHCA((ibtl_srq)->srq_hca) 460 461 /* 462 * Get a pointer to the HCA ops structure from IBT handles. 463 */ 464 #define IBTL_HDIP2CIHCAOPS_P(hca_devp) (hca_devp)->hd_ibc_ops 465 #define IBTL_HCA2CIHCAOPS_P(ibtl_hca) \ 466 IBTL_HDIP2CIHCAOPS_P(ibtl_hca->ha_hca_devp) 467 #define IBTL_CQ2CIHCAOPS_P(ibtl_cq) IBTL_HCA2CIHCAOPS_P((ibtl_cq)->cq_hca) 468 #define IBTL_CHAN2CIHCAOPS_P(ibt_chan) \ 469 IBTL_HCA2CIHCAOPS_P((ibt_chan)->ch_qp.qp_hca) 470 #define IBTL_SRQ2CIHCAOPS_P(ibtl_srq) \ 471 IBTL_HCA2CIHCAOPS_P((ibtl_srq)->srq_hca) 472 473 /* 474 * Get Client Handle from IBT Handles. 475 */ 476 #define IBTL_HCA2CLNT(ibtl_hca) (ibtl_hca)->ha_clnt_devp 477 #define IBTL_ECC2CLNT(ibtl_eec) IBTL_HCA2CLNT((ibtl_eec)->eec_hca) 478 #define IBTL_CQ2CLNT(ibtl_cq) IBTL_HCA2CLNT((ibtl_cq)->cq_hca) 479 #define IBTL_CHAN2CLNT(ibt_chan) IBTL_HCA2CLNT((ibt_chan)->ch_qp.qp_hca) 480 481 /* 482 * Get a Pointer to the client modinfo from IBT Handles. 483 */ 484 #define IBTL_HCA2MODI_P(ibtl_hca) \ 485 ((IBTL_HCA2CLNT(ibtl_hca))->clnt_modinfop) 486 487 #define IBTL_EEC2MODI_P(ibtl_eec) \ 488 ((IBTL_EEC2CLNT(ibtl_eec))->clnt_modinfop) 489 490 #define IBTL_CQ2MODI_P(ibtl_cq) ((IBTL_CQ2CLNT(ibtl_cq))->clnt_modinfop) 491 492 #define IBTL_CHAN2MODI_P(chan) ((IBTL_CHAN2CLNT(chan))->clnt_modinfop) 493 494 /* 495 * Using HCA Device Info Pointer, access HCA Attributes values for 496 * Max SGID Table Size, Max PKEY Table Size. 497 */ 498 #define IBTL_HDIP2SGIDTBLSZ(hca) \ 499 (hca)->hd_hca_attr->hca_max_port_sgid_tbl_sz 500 #define IBTL_HDIP2PKEYTBLSZ(hca) \ 501 (hca)->hd_hca_attr->hca_max_port_pkey_tbl_sz 502 503 /* 504 * Using IBTL HCA Handle, access HCA Attributes values. 505 * viz. HCA Node GUID, 506 * Number of Ports on this HCA Device, 507 * Max SGID Table Size 508 * Max PKEY Table Size 509 */ 510 #define IBTL_HCA2HCAGUID(hca_hdl) \ 511 (hca_hdl)->ha_hca_devp->hd_hca_attr->hca_node_guid 512 #define IBTL_HCA2NPORTS(hca_hdl) \ 513 (hca_hdl)->ha_hca_devp->hd_hca_attr->hca_nports 514 #define IBTL_HCA2SGIDTBLSZ(hca_hdl) \ 515 (hca_hdl)->ha_hca_devp->hd_hca_attr->hca_max_port_sgid_tbl_sz 516 #define IBTL_HCA2PKEYTBLSZ(hca_hdl) \ 517 (hca_hdl)->ha_hca_devp->hd_hca_attr->hca_max_port_pkey_tbl_sz 518 519 /* possible strlen of a IB driver's name */ 520 #define IBTL_DRVNAME_LEN 40 521 522 /* strings passed to ib_dprintfN() are this long */ 523 #define IBTL_PRINT_BUF_LEN 4096 524 525 /* Check if client isn't CM/DM/IBMA */ 526 #define IBTL_GENERIC_CLIENT(clntp) \ 527 (((clntp)->clnt_modinfop->mi_clnt_class != IBT_CM) && \ 528 ((clntp)->clnt_modinfop->mi_clnt_class != IBT_DM) && \ 529 ((clntp)->clnt_modinfop->mi_clnt_class != IBT_IBMA)) 530 531 /* 532 * Function Prototypes that are specific to the IBTL implementation. 533 */ 534 ibtl_hca_devinfo_t *ibtl_get_hcadevinfo(ib_guid_t hca_guid); 535 ibt_status_t ibtl_init_hca_portinfo(ibtl_hca_devinfo_t *hca_devp); 536 void ibtl_reinit_hca_portinfo(ibtl_hca_devinfo_t *hca_devp, uint8_t port); 537 538 void ibtl_init_cep_states(void); 539 void ibtl_ib2usec_init(void); 540 void ibtl_logging_initialization(void); 541 void ibtl_logging_destroy(void); 542 void ibtl_thread_init(void); 543 void ibtl_thread_init2(void); 544 void ibtl_thread_fini(void); 545 void ibtl_announce_new_hca(ibtl_hca_devinfo_t *hca_devp); 546 void ibtl_another_cq_handler_in_thread(void); 547 int ibtl_detach_all_clients(ibtl_hca_devinfo_t *hcap); 548 void ibtl_qp_flow_control_enter(void); 549 void ibtl_qp_flow_control_exit(void); 550 551 /* synchronization of asyncs when freeing an object */ 552 void ibtl_free_qp_async_check(ibtl_qp_t *ibtl_qp); 553 void ibtl_free_cq_async_check(ibtl_cq_t *ibtl_cq); 554 void ibtl_free_srq_async_check(ibtl_srq_t *ibtl_srq); 555 void ibtl_free_eec_async_check(ibtl_eec_t *ibtl_eec); 556 void ibtl_free_hca_async_check(ibt_hca_hdl_t ibt_hca); 557 void ibtl_free_clnt_async_check(ibtl_clnt_t *clntp); 558 559 /* synchronization of cq_handler callbacks and free_cq */ 560 void ibtl_free_cq_check(ibtl_cq_t *ibtl_cq); 561 562 /* release_qpn and close_hca synchronization */ 563 void ibtl_close_hca_check(ibt_hca_hdl_t ibt_hca); 564 565 /* Global List of HCA devices, and associated lock. */ 566 extern struct ibtl_hca_devinfo_s *ibtl_hca_list; /* link is hd_hca_dev_link */ 567 568 /* Global List of IBT Client Instances, and associated lock. */ 569 extern struct ibtl_clnt_s *ibtl_clnt_list; /* link is clnt_list_link */ 570 extern kmutex_t ibtl_clnt_list_mutex; 571 572 /* Lock for the race between the client and CM to free QPs. */ 573 extern kmutex_t ibtl_free_qp_mutex; 574 575 /* Lock for the race between the client closing the HCA and QPN being freed. */ 576 extern kcondvar_t ibtl_close_hca_cv; 577 578 /* Limit the flow of QP verb calls */ 579 extern kmutex_t ibtl_qp_mutex; 580 extern kcondvar_t ibtl_qp_cv; 581 582 /* Async handlers and client private for well known clients of IBTL */ 583 extern ibt_async_handler_t ibtl_cm_async_handler; 584 extern ibt_async_handler_t ibtl_dm_async_handler; 585 extern ibt_async_handler_t ibtl_ibma_async_handler; 586 extern void *ibtl_cm_clnt_private; 587 extern void *ibtl_dm_clnt_private; 588 extern void *ibtl_ibma_clnt_private; 589 590 /* cache for fast GID => portinfo lookup */ 591 extern boolean_t ibtl_fast_gid_cache_valid; 592 593 594 /* The following structs are used to pass info in and out of the APIs */ 595 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_alloc_args_s)) 596 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_query_attr_s)) 597 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_modify_attr_s)) 598 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_dest_query_attr_s)) 599 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_alloc_args_s)) 600 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_query_attr_s)) 601 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_modify_attr_s)) 602 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_dest_s)) 603 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_qp_alloc_attr_s)) 604 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_qp_info_s)) 605 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_hca_portinfo_s)) 606 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_adds_vect_s)) 607 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_cep_path_s)) 608 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_mr_desc_s)) 609 _NOTE(SCHEME_PROTECTS_DATA("GIDs are transient", ib_gid_s)) 610 611 #ifdef __cplusplus 612 } 613 #endif 614 615 #endif /* _SYS_IB_IBTL_IMPL_IBTL_H */ 616