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]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 #ifndef _SYS_IB_ADAPTERS_HERMON_QP_H
27 #define _SYS_IB_ADAPTERS_HERMON_QP_H
31 * Contains all of the prototypes, #defines, and structures necessary
32 * for all of the Queue Pair Processing routines.
33 * Specifically it contains the various flags, structures used for managing
34 * Hermon queue pairs, and prototypes for many of the functions consumed by
35 * other parts of the Hermon driver (including those routines directly
36 * exposed through the IBTF CI interface).
38 * Most of the values defined below establish default values which,
39 * where indicated, can be controlled via their related patchable values,
40 * if 'hermon_alt_config_enable' is set.
43 #include <sys/types.h>
46 #include <sys/sunddi.h>
53 * The following defines the default number of Queue Pairs. This value is
54 * controlled via the "hermon_log_num_qp" configuration variables.
55 * We also have a define for the minimum size of a QP. QPs allocated
56 * with size 0, 1, 2, or 3 will always get back a QP of size 4.
58 * Note: Increasing #QPs from 64K to 256K for reserved ranges for FCoIB.
60 #define HERMON_NUM_QP_SHIFT 0x12
61 #define HERMON_NUM_QPS (1 << HERMON_NUM_QP_SHIFT) /* 256K */
62 #define HERMON_QP_MIN_SIZE 0xf
65 * The following defines the default number of Hermon RDMA Remote read
66 * database (RDB) entries per QP. This value is controllable through the
67 * "hermon_log_num_rdb_per_qp" configuration variable.
69 #define HERMON_LOG_NUM_RDB_PER_QP 0x4
72 * This defines the maximum number of SGLs per WQE. This value is
73 * controllable through the "hermon_wqe_max_sgl" configuration variable
74 * (but should not be set larger than this value).
76 #define HERMON_NUM_SGL_PER_WQE 0x10
79 * Maximum QP number mask (QP number is 24 bits).
80 * We reserve the most significant bit to indicate an "XRC" QP
81 * as recommended by the PRM. All XRC QPs will have this bit set.
83 #define HERMON_QP_MAXNUMBER_MSK 0x7FFFFF
84 #define HERMON_QP_XRC_MSK 0x800000
87 * This define and the following macro are used to find a schedule queue for
88 * a new QP based on its queue pair number. Note: This is a rather simple
89 * method that we use today. We simply choose from the schedule queue based
90 * on the 4 least significant bits of the QP number.
94 * The following defines are used to indicate whether a QP is special or
95 * not (and what type it is). They are used in the "qp_is_special" field
96 * below in qp_state. If "qp_is_special" == 0 then an ordinary data qp.
100 * The sl is selected based on the qpnum as it was for Tavor/Arbel, except for
101 * QP0, which is defined as being 0xF
104 #define HERMON_QP_SMI 0x1
105 #define HERMON_QP_GSI 0x2
107 #define HERMON_DEF_SCHED_POLICY 0x03
108 #define HERMON_DEF_SCHED_SELECTION 0x0F
110 #define HERMON_QP_SCHEDQ_GET(port, sl, issmi) \
111 (HERMON_DEF_SCHED_POLICY \
112 | (issmi == HERMON_QP_SMI ? (HERMON_DEF_SCHED_SELECTION << 2) : \
113 ((issmi == HERMON_QP_GSI ? 0 : (sl & 0XF)) << 2)) \
114 | ((port & 0x01) << 6) \
115 | ((issmi == HERMON_QP_SMI ? 0 : 1) << 7))
119 * This define determines the frequency with which the AckReq bit will be
120 * set in outgoing RC packets. By default it is set to five (5) or 2^5 = 32.
121 * So AckReq will be set once every 32 packets sent. This value is
122 * controllable through the "hermon_qp_ackreq_freq" configuration variable.
124 #define HERMON_QP_ACKREQ_FREQ 0x5
127 * Define the maximum message size (log 2). Note: This value corresponds
128 * to the maximum allowable message sized as defined by the IBA spec.
130 #define HERMON_QP_LOG_MAX_MSGSZ 0x1F
133 * This macro is used to determine if the hermon QP type (qp_serv) is the
134 * same as the caller passed in IBT type (qp_trans). This is used in QP modify
135 * to ensure the types match.
137 #define HERMON_QP_TYPE_VALID(qp_trans, qp_serv) \
138 ((qp_trans == IBT_RC_SRV && qp_serv == HERMON_QP_RC) || \
139 (qp_trans == IBT_UD_SRV && (qp_serv == HERMON_QP_UD || \
140 qp_serv == HERMON_QP_RFCI || qp_serv == HERMON_QP_FCMND || \
141 qp_serv == HERMON_QP_FEXCH)) || \
142 (qp_trans == IBT_UC_SRV && qp_serv == HERMON_QP_UC))
145 * The following enumerated type is used to capture all the various types
146 * of Hermon work queue types. It is specifically used as an argument to the
147 * to the hermon_qp_sgl_to_logwqesz() routine to determine the amount of
148 * overhead (in WQE header size) consumed by each of the types. This
149 * information is used to round the WQE size to the next largest power-of-2
150 * (and to determine the number of SGLs that are supported for the given WQE
151 * type). There is also a define below used to specify the minimum size for a
152 * WQE. The minimum size is set to 64 bytes (a single cacheline).
156 HERMON_QP_WQ_TYPE_SENDQ_UD
,
157 HERMON_QP_WQ_TYPE_SENDQ_CONN
,
158 HERMON_QP_WQ_TYPE_RECVQ
,
159 HERMON_QP_WQ_TYPE_SENDMLX_QP0
,
160 HERMON_QP_WQ_TYPE_SENDMLX_QP1
161 } hermon_qp_wq_type_t
;
162 #define HERMON_QP_WQE_MLX_SND_HDRS 0x40
163 #define HERMON_QP_WQE_MLX_RCV_HDRS 0x00
164 #define HERMON_QP_WQE_MLX_SRQ_HDRS 0x10
165 #define HERMON_QP_WQE_MLX_QP0_HDRS 0x40
166 #define HERMON_QP_WQE_MLX_QP1_HDRS 0x70
167 #define HERMON_QP_WQE_LOG_MINIMUM 0x6
171 * The hermon_qp_range_t is used to manage a qp_range for RSS and FEXCH.
172 * It has a reference count. When the reference count goes to 0,
173 * the qpc resource can be freed.
175 typedef struct hermon_qp_range_s
{
177 hermon_rsrc_t
*hqpr_qpcrsrc
;
182 * The hermon_qp_info_t structure is used internally by the Hermon driver to
183 * pass information to and from the hermon_qp_alloc() and
184 * hermon_special_qp_alloc() routines. It contains placeholders for all of the
185 * potential inputs and outputs that either routine can take.
187 typedef struct hermon_qp_info_s
{
188 ibt_qp_alloc_attr_t
*qpi_attrp
;
191 ibtl_qp_hdl_t qpi_ibt_qphdl
;
192 ibt_chan_sizes_t
*qpi_queueszp
;
194 hermon_qphdl_t qpi_qphdl
;
198 * The QPN entry which is stored in the AVL tree
200 typedef struct hermon_qpn_entry_s
{
201 avl_node_t qpn_avlnode
;
205 hermon_rsrc_t
*qpn_qpc
;
206 } hermon_qpn_entry_t
;
207 #define HERMON_QPN_NOFLAG 0x0
208 #define HERMON_QPN_RELEASE 0x1
209 #define HERMON_QPN_FREE_ONLY 0x2
211 #define HERMON_QP_OH_SIZE 0x0800
213 * 2KB, fixed per Mnox PRM 0.35c & conversation w/Mnox technical Sep 5, 2007
217 * The hermon_sw_qp_s structure is also referred to using the "hermon_qphdl_t"
218 * typedef (see hermon_typedef.h). It encodes all the information necessary
219 * to track the various resources needed to allocate, query, modify, and
220 * (later) free both normal QP and special QP.
222 * Specifically, it has a lock to ensure single threaded access to the QP.
223 * It has QP state, type, and number, pointers to the PD, MR, and CQ handles
224 * associated with the QP, and pointers to the buffer where the work queues
227 * It has two pointers (one per work queue) to the workQ headers for the WRID
228 * list, as well as pointers to the last WQE on each chain (used when
229 * connecting a new chain of WQEs to a previously executing chain - see
230 * hermon_wr.c). It's also got the real WQE size, real number of SGL per WQE,
231 * and the size of each of the work queues (in number of WQEs).
233 * Additionally, it has pointers to the resources associated with the QP,
234 * including the obligatory backpointer to the resource for the QP handle
235 * itself. But it also has some flags, like "qp_forward_sqd_event" and
236 * "qp_sqd_still_draining" (which are used to indicate whether a Send Queue
237 * Drained Event should be forwarded to the IBTF) or "qp_is_special",
238 * "qp_portnum", and "qp_pkeyindx" (which are used by special QP to store
239 * necessary information about the type of the QP, which port it's connected
240 * to, and what its current PKey index is set to).
242 struct hermon_sw_qp_s
{
246 hermon_pdhdl_t qp_pdhdl
;
248 ibt_qp_type_t qp_type
;
249 uint_t qp_sl
; /* service level */
250 hermon_mrhdl_t qp_mrhdl
;
251 uint_t qp_sq_sigtype
;
252 uint_t qp_is_special
;
253 ibt_qp_alloc_flags_t qp_alloc_flags
;
255 devmap_cookie_t qp_umap_dhp
;
256 uint_t qp_portnum
; /* port 0/1 for HCA */
257 uint_t qp_portnum_alt
; /* port 0/1 for HCA */
259 uint_t qp_no_prefetch
;
260 /* prefetch == 0, none == 1, for headroom */
261 uint_t qp_rlky
; /* using reserved lkey */
263 /* Send Work Queue */
265 hermon_cqhdl_t qp_sq_cqhdl
;
266 hermon_workq_avl_t qp_sq_wqavl
;
267 hermon_workq_hdr_t
*qp_sq_wqhdr
;
269 uint32_t qp_sq_bufsz
;
270 uint32_t qp_sq_logqsz
; /* used to check owner valid */
271 uint32_t qp_sq_log_wqesz
;
272 uint32_t qp_sq_headroom
; /* #bytes needed for headroom */
273 uint32_t qp_sq_hdrmwqes
; /* # wqes needed for headroom */
274 uint32_t qp_sq_baseaddr
;
278 uint_t qp_state_for_post_send
; /* copy of qp_state */
280 /* Receive Work Queue - not used when SRQ is used */
281 hermon_cqhdl_t qp_rq_cqhdl
;
282 hermon_workq_avl_t qp_rq_wqavl
; /* needed for srq */
283 hermon_workq_hdr_t
*qp_rq_wqhdr
;
285 uint32_t qp_rq_bufsz
;
286 uint32_t qp_rq_logqsz
; /* used to check owner valid */
287 uint32_t qp_rq_log_wqesz
;
288 uint32_t qp_rq_wqecntr
;
289 uint32_t qp_rq_baseaddr
;
292 /* DoorBell Record information */
293 ddi_acc_handle_t qp_rq_dbr_acchdl
;
294 hermon_dbr_t
*qp_rq_vdbr
;
296 uint64_t qp_rdbr_mapoffset
; /* user mode access */
298 uint64_t qp_desc_off
;
300 hermon_rsrc_t
*qp_qpcrsrcp
;
301 hermon_rsrc_t
*qp_rsrcp
;
303 uint_t qp_forward_sqd_event
;
304 uint_t qp_sqd_still_draining
;
306 /* Shared Receive Queue */
307 hermon_srqhdl_t qp_srqhdl
;
309 /* Refcnt of QP belongs to an MCG */
310 uint_t qp_mcg_refcnt
;
312 /* save the mtu from init2rtr for future use */
314 hermon_qpn_entry_t
*qp_qpn_hdl
;
316 struct hermon_qalloc_info_s qp_wqinfo
;
318 ibt_fc_attr_t qp_fc_attr
;
320 struct hermon_qp_range_s
*qp_rangep
;
322 /* Beware: 8-byte alignment needed here */
324 struct hermon_hw_qpc_s qpc
;
326 _NOTE(READ_ONLY_DATA(hermon_sw_qp_s::qp_qpnum
327 hermon_sw_qp_s::qp_sq_buf
328 hermon_sw_qp_s::qp_sq_log_wqesz
329 hermon_sw_qp_s::qp_sq_bufsz
330 hermon_sw_qp_s::qp_sq_sgl
331 hermon_sw_qp_s::qp_rq_buf
332 hermon_sw_qp_s::qp_rq_log_wqesz
333 hermon_sw_qp_s::qp_rq_bufsz
334 hermon_sw_qp_s::qp_rq_sgl
335 hermon_sw_qp_s::qp_desc_off
336 hermon_sw_qp_s::qp_mrhdl
337 hermon_sw_qp_s::qp_wqinfo
338 hermon_sw_qp_s::qp_qpcrsrcp
339 hermon_sw_qp_s::qp_rsrcp
340 hermon_sw_qp_s::qp_hdlrarg
341 hermon_sw_qp_s::qp_pdhdl
342 hermon_sw_qp_s::qp_sq_cqhdl
343 hermon_sw_qp_s::qp_rq_cqhdl
344 hermon_sw_qp_s::qp_sq_sigtype
345 hermon_sw_qp_s::qp_serv_type
346 hermon_sw_qp_s::qp_is_special
347 hermon_sw_qp_s::qp_alloc_flags
348 hermon_sw_qp_s::qp_uarpg
349 hermon_sw_qp_s::qp_sq_wqhdr
350 hermon_sw_qp_s::qp_rq_wqhdr
351 hermon_sw_qp_s::qp_qpn_hdl
))
352 _NOTE(MUTEX_PROTECTS_DATA(hermon_sw_qp_s::qp_lock
,
353 hermon_sw_qp_s::qp_state
355 hermon_sw_qp_s::qp_forward_sqd_event
356 hermon_sw_qp_s::qp_sqd_still_draining
357 hermon_sw_qp_s::qp_mcg_refcnt
358 hermon_sw_qp_s::qp_save_mtu
359 hermon_sw_qp_s::qp_umap_dhp
))
360 _NOTE(SCHEME_PROTECTS_DATA("safe sharing",
361 hermon_sw_qp_s::qp_pkeyindx
362 hermon_sw_qp_s::qp_portnum
))
364 #define HERMON_SET_QP_POST_SEND_STATE(qp, state) \
365 mutex_enter(&qp->qp_sq_lock); \
366 qp->qp_state_for_post_send = state; \
367 mutex_exit(&qp->qp_sq_lock)
369 /* Defined in hermon_qp.c */
370 int hermon_qp_alloc(hermon_state_t
*state
, hermon_qp_info_t
*qpinfo
,
372 int hermon_special_qp_alloc(hermon_state_t
*state
, hermon_qp_info_t
*qpinfo
,
374 int hermon_qp_alloc_range(hermon_state_t
*state
, uint_t log2
,
375 hermon_qp_info_t
*qpinfo
, ibtl_qp_hdl_t
*ibtl_qp_p
, ibc_cq_hdl_t
*send_cq_p
,
376 ibc_cq_hdl_t
*recv_cq_p
, hermon_qphdl_t
*qp_p
, uint_t sleepflag
);
377 int hermon_qp_free(hermon_state_t
*state
, hermon_qphdl_t
*qphdl
,
378 ibc_free_qp_flags_t free_qp_flags
, ibc_qpn_hdl_t
*qpnh
, uint_t sleepflag
);
379 int hermon_qp_query(hermon_state_t
*state
, hermon_qphdl_t qphdl
,
380 ibt_qp_query_attr_t
*attr_p
);
381 hermon_qphdl_t
hermon_qphdl_from_qpnum(hermon_state_t
*state
, uint_t qpnum
);
382 void hermon_qp_release_qpn(hermon_state_t
*state
, hermon_qpn_entry_t
*entry
,
384 void hermon_qpn_avl_init(hermon_state_t
*state
);
385 void hermon_qpn_avl_fini(hermon_state_t
*state
);
387 /* Defined in hermon_qpmod.c */
388 int hermon_qp_modify(hermon_state_t
*state
, hermon_qphdl_t qp
,
389 ibt_cep_modify_flags_t flags
, ibt_qp_info_t
*info_p
,
390 ibt_queue_sizes_t
*actual_sz
);
391 int hermon_qp_to_reset(hermon_state_t
*state
, hermon_qphdl_t qp
);
397 #endif /* _SYS_IB_ADAPTERS_HERMON_QP_H */