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