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) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _SYS_IB_ADAPTERS_HERMON_QP_H 27 #define _SYS_IB_ADAPTERS_HERMON_QP_H 28 29 /* 30 * 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). 37 * 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. 41 */ 42 43 #include <sys/types.h> 44 #include <sys/conf.h> 45 #include <sys/ddi.h> 46 #include <sys/sunddi.h> 47 48 #ifdef __cplusplus 49 extern "C" { 50 #endif 51 52 /* 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. 57 * 58 * Note: Increasing #QPs from 64K to 256K for reserved ranges for FCoIB. 59 */ 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 63 64 /* 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. 68 */ 69 #define HERMON_LOG_NUM_RDB_PER_QP 0x4 70 71 /* 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). 75 */ 76 #define HERMON_NUM_SGL_PER_WQE 0x10 77 78 /* 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. 82 */ 83 #define HERMON_QP_MAXNUMBER_MSK 0x7FFFFF 84 #define HERMON_QP_XRC_MSK 0x800000 85 86 /* 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. 91 */ 92 93 /* 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. 97 */ 98 99 /* 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 102 */ 103 104 #define HERMON_QP_SMI 0x1 105 #define HERMON_QP_GSI 0x2 106 107 #define HERMON_DEF_SCHED_POLICY 0x03 108 #define HERMON_DEF_SCHED_SELECTION 0x0F 109 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)) 116 117 118 /* 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. 123 */ 124 #define HERMON_QP_ACKREQ_FREQ 0x5 125 126 /* 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. 129 */ 130 #define HERMON_QP_LOG_MAX_MSGSZ 0x1F 131 132 /* 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. 136 */ 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)) 143 144 /* 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). 153 */ 154 155 typedef enum { 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 168 169 170 /* 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. 174 */ 175 typedef struct hermon_qp_range_s { 176 kmutex_t hqpr_lock; 177 hermon_rsrc_t *hqpr_qpcrsrc; 178 uint_t hqpr_refcnt; 179 } hermon_qp_range_t; 180 181 /* 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. 186 */ 187 typedef struct hermon_qp_info_s { 188 ibt_qp_alloc_attr_t *qpi_attrp; 189 uint_t qpi_type; 190 uint_t qpi_port; 191 ibtl_qp_hdl_t qpi_ibt_qphdl; 192 ibt_chan_sizes_t *qpi_queueszp; 193 ib_qpn_t *qpi_qpn; 194 hermon_qphdl_t qpi_qphdl; 195 } hermon_qp_info_t; 196 197 /* 198 * The QPN entry which is stored in the AVL tree 199 */ 200 typedef struct hermon_qpn_entry_s { 201 avl_node_t qpn_avlnode; 202 uint_t qpn_refcnt; 203 uint_t qpn_counter; 204 uint_t qpn_indx; 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 210 211 #define HERMON_QP_OH_SIZE 0x0800 212 /* 213 * 2KB, fixed per Mnox PRM 0.35c & conversation w/Mnox technical Sep 5, 2007 214 */ 215 216 /* 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. 221 * 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 225 * come from. 226 * 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). 232 * 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). 241 */ 242 struct hermon_sw_qp_s { 243 kmutex_t qp_lock; 244 uint_t qp_state; 245 uint32_t qp_qpnum; 246 hermon_pdhdl_t qp_pdhdl; 247 uint_t qp_serv_type; 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; 254 uint32_t qp_uarpg; 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 */ 258 uint_t qp_pkeyindx; 259 uint_t qp_no_prefetch; 260 /* prefetch == 0, none == 1, for headroom */ 261 uint_t qp_rlky; /* using reserved lkey */ 262 263 /* Send Work Queue */ 264 kmutex_t qp_sq_lock; 265 hermon_cqhdl_t qp_sq_cqhdl; 266 hermon_workq_avl_t qp_sq_wqavl; 267 hermon_workq_hdr_t *qp_sq_wqhdr; 268 uint32_t *qp_sq_buf; 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; 275 uint32_t qp_sq_sgl; 276 uint_t qp_uses_lso; 277 uint32_t qp_ring; 278 uint_t qp_state_for_post_send; /* copy of qp_state */ 279 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; 284 uint32_t *qp_rq_buf; 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; 290 uint32_t qp_rq_sgl; 291 292 /* DoorBell Record information */ 293 ddi_acc_handle_t qp_rq_dbr_acchdl; 294 hermon_dbr_t *qp_rq_vdbr; 295 uint64_t qp_rq_pdbr; 296 uint64_t qp_rdbr_mapoffset; /* user mode access */ 297 298 uint64_t qp_desc_off; 299 300 hermon_rsrc_t *qp_qpcrsrcp; 301 hermon_rsrc_t *qp_rsrcp; 302 void *qp_hdlrarg; 303 uint_t qp_forward_sqd_event; 304 uint_t qp_sqd_still_draining; 305 306 /* Shared Receive Queue */ 307 hermon_srqhdl_t qp_srqhdl; 308 309 /* Refcnt of QP belongs to an MCG */ 310 uint_t qp_mcg_refcnt; 311 312 /* save the mtu from init2rtr for future use */ 313 uint_t qp_save_mtu; 314 hermon_qpn_entry_t *qp_qpn_hdl; 315 316 struct hermon_qalloc_info_s qp_wqinfo; 317 318 ibt_fc_attr_t qp_fc_attr; 319 320 struct hermon_qp_range_s *qp_rangep; 321 322 /* Beware: 8-byte alignment needed here */ 323 324 struct hermon_hw_qpc_s qpc; 325 }; 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 354 hermon_sw_qp_s::qpc 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)) 363 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) 368 369 /* Defined in hermon_qp.c */ 370 int hermon_qp_alloc(hermon_state_t *state, hermon_qp_info_t *qpinfo, 371 uint_t sleepflag); 372 int hermon_special_qp_alloc(hermon_state_t *state, hermon_qp_info_t *qpinfo, 373 uint_t sleepflag); 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, 383 int flags); 384 void hermon_qpn_avl_init(hermon_state_t *state); 385 void hermon_qpn_avl_fini(hermon_state_t *state); 386 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); 392 393 #ifdef __cplusplus 394 } 395 #endif 396 397 #endif /* _SYS_IB_ADAPTERS_HERMON_QP_H */ 398