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