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) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _SYS_IB_CLIENTS_OF_SOL_UVERBS_SOL_UVERBS_H 27 #define _SYS_IB_CLIENTS_OF_SOL_UVERBS_SOL_UVERBS_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * 35 * NAME: sol_uverbs.h 36 * 37 * DESC: Solaris OFED User Verbs Kernel Agent header file. 38 * 39 */ 40 #include <sys/ib/clients/of/ofed_kernel.h> 41 #include <sys/ib/clients/of/rdma/ib_user_verbs.h> 42 #include <sys/ib/clients/of/sol_uverbs/sol_uverbs_hca.h> 43 #include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h> 44 #include <sys/ib/clients/of/sol_uverbs/sol_uverbs2ucma.h> 45 46 /* 47 * Definitions 48 */ 49 #define SOL_UVERBS_DRIVER_MAX_HCA_MINOR (16) 50 #define SOL_UVERBS_DRIVER_EVENT_MINOR (17) 51 #define SOL_UVERBS_DRIVER_MAX_MINOR (18) 52 53 54 /* 55 * Structures 56 */ 57 58 /* 59 * Kernel User Verbs Events. 60 * 61 * User verbs kernel events (asynchronous and completion) representation. 62 * IBT events are mapped back to OFA events. 63 */ 64 typedef struct uverbs_event { 65 66 union { 67 struct ib_uverbs_async_event_desc async; 68 struct ib_uverbs_comp_event_desc comp; 69 } ev_desc; 70 71 llist_head_t ev_list; 72 llist_head_t ev_obj_list; 73 uint32_t *ev_counter; 74 } uverbs_event_t; 75 76 77 /* 78 * Module Context. 79 * 80 * There is a single module context which maintains the list 81 * of HCA's retrieved from IBT. A user process indicates the 82 * target HCA open via the uverbs unique minor device number 83 * associated with the HCA. 84 */ 85 typedef struct { 86 kmutex_t lock; 87 dev_info_t *dip; 88 89 /* 90 * Underlying IBT HCA Info 91 */ 92 93 ibt_clnt_modinfo_t clnt_modinfo; 94 ibt_clnt_hdl_t clnt_hdl; 95 uint32_t hca_count; 96 ib_guid_t *hca_guid_list; 97 sol_uverbs_hca_t *hcas; 98 99 /* 100 * Support user asyncrhonous and completion event delivery via 101 * user event filesystem. 102 */ 103 dev_t dev; 104 } uverbs_module_context_t; 105 106 /* 107 * User Event File. 108 * 109 * Used for delivery of asynchronous and synchronous events to the user. 110 * An asynchronous event file is created during the allocation of 111 * a user verbs consumer context, a completion event file is created 112 * when the user verbs consumer creates a completion channel. 113 */ 114 typedef struct uverbs_ufile_uobj { 115 sol_ofs_uobj_t uobj; 116 kmutex_t lock; 117 int ref; 118 kcondvar_t poll_wait; 119 struct pollhead poll_head; 120 struct uverbs_uctxt_uobj *uctxt; 121 int is_async; 122 llist_head_t event_list; 123 sol_uverbs_cq_ctrl_t ufile_notify_enabled; 124 uint32_t ufile_cq_cnt; 125 } uverbs_ufile_uobj_t; 126 127 /* 128 * Type of user context - 129 */ 130 #define SOL_UVERBS_UCTXT_VERBS 0x001 131 #define SOL_UVERBS_UCTXT_EVENT 0x100 132 #define SOL_UVERBS_UCTXT_ASYNC 0x101 133 #define SOL_UVERBS_UCTXT_COMPL 0x110 134 135 /* 136 * User Context. 137 * 138 * A user context is created when a user process opens a specific minor 139 * device. The context maintains a list of resources created by this 140 * user that allows the resources to be cleaned up on user close. 141 */ 142 typedef struct uverbs_uctxt_uobj { 143 sol_ofs_uobj_t uobj; 144 kmutex_t lock; 145 uverbs_module_context_t *mod_ctxt; 146 sol_uverbs_hca_t *hca; /* short cut to specific hca */ 147 148 /* 149 * List of user resource objects created by this context. The 150 * objects themselves live in the associated object table, and 151 * the code should use the table to access and use resources. 152 * Any objects that remain in these list will be destroyed at 153 * user close to free the associated resources. 154 * 155 * The user context "lock" should be held when invoking 156 * routines to manipulate the lists. 157 */ 158 genlist_t pd_list; 159 genlist_t mr_list; 160 genlist_t cq_list; 161 genlist_t qp_list; 162 genlist_t srq_list; 163 genlist_t ah_list; 164 165 /* 166 * Event filesystem interfaces for IB asyncrhonous events 167 * and completion events. 168 */ 169 uverbs_ufile_uobj_t *comp_evfile; 170 uverbs_ufile_uobj_t *async_evfile; 171 172 /* 173 * User context can be created for : 174 * 1. All Verbs API 175 * 2. For getting a file for async events. 176 * 3. For getting a file for completion events. 177 * For (1) - pointers to (2) & (3) will be updated. For (2) and (3) 178 * pointer to (1) will be maintained. 179 */ 180 uint16_t uctxt_type; 181 uint32_t uctxt_verbs_id; 182 uint32_t uctxt_async_id; 183 uint32_t uctxt_comp_id; 184 uint8_t uctxt_free_pending; 185 } uverbs_uctxt_uobj_t; 186 187 /* 188 * User PD objects created at PD allocation 189 */ 190 typedef struct uverbs_upd_uobj { 191 sol_ofs_uobj_t uobj; 192 ibt_pd_hdl_t pd; 193 genlist_entry_t *list_entry; /* per user ctx list entry */ 194 uint32_t active_qp_cnt; 195 uint8_t free_pending; 196 } uverbs_upd_uobj_t; 197 198 /* 199 * User MR objects created at MR registration 200 */ 201 typedef struct uverbs_umr_uobj { 202 sol_ofs_uobj_t uobj; 203 ibt_mr_hdl_t mr; 204 genlist_entry_t *list_entry; /* per user ctx list entry */ 205 } uverbs_umr_uobj_t; 206 207 /* 208 * User CQ objects created at CQ allocation 209 */ 210 typedef struct uverbs_ucq_uobj { 211 sol_ofs_uobj_t uobj; 212 ibt_cq_hdl_t cq; 213 genlist_entry_t *list_entry; /* per user ctx list entry */ 214 uverbs_uctxt_uobj_t *uctxt; 215 uverbs_ufile_uobj_t *comp_chan; 216 uint32_t comp_events_reported; 217 uint32_t async_events_reported; 218 llist_head_t async_list; 219 llist_head_t comp_list; 220 uint32_t active_qp_cnt; 221 uint8_t free_pending; 222 } uverbs_ucq_uobj_t; 223 224 /* 225 * User Shared Receive CQ objects created at SRQ allocation 226 */ 227 typedef struct uverbs_usrq_uobj { 228 sol_ofs_uobj_t uobj; 229 ibt_srq_hdl_t srq; 230 genlist_entry_t *list_entry; /* per user ctx list entry */ 231 uverbs_uctxt_uobj_t *uctxt; 232 uint32_t async_events_reported; 233 llist_head_t async_list; 234 uint32_t active_qp_cnt; 235 uint8_t free_pending; 236 } uverbs_usrq_uobj_t; 237 238 /* 239 * User address handle objects created at AH allocation 240 */ 241 typedef struct uverbs_uah_uobj { 242 sol_ofs_uobj_t uobj; 243 ibt_ah_hdl_t ah; 244 genlist_entry_t *list_entry; /* per user ctx list entry */ 245 } uverbs_uah_uobj_t; 246 247 /* 248 * User QP objects created at QP allocation 249 */ 250 #define SOL_UVERBS_UQP_RCQ_VALID 0x01 251 #define SOL_UVERBS_UQP_SRQ_VALID 0x02 252 253 typedef struct uverbs_uqp_uobj { 254 sol_ofs_uobj_t uobj; 255 ibt_qp_hdl_t qp; 256 genlist_entry_t *list_entry; /* per uctx list */ 257 uint32_t max_inline_data; 258 uverbs_uctxt_uobj_t *uctxt; 259 uint32_t qp_num; /* 24 bits valid */ 260 uint32_t disable_qp_mod; 261 enum ib_qp_type ofa_qp_type; 262 llist_head_t mcast_list; 263 llist_head_t async_list; 264 uint32_t async_events_reported; 265 uverbs_ucq_uobj_t *uqp_rcq; 266 uverbs_ucq_uobj_t *uqp_scq; 267 268 uint32_t uqp_pd_hdl; 269 uint32_t uqp_scq_hdl; 270 uint32_t uqp_rcq_hdl; 271 uint32_t uqp_srq_hdl; 272 uint8_t uqp_rcq_srq_valid; 273 274 sol_uverbs_qp_free_state_t uqp_free_state; 275 } uverbs_uqp_uobj_t; 276 277 extern sol_ofs_uobj_table_t uverbs_uctxt_uo_tbl; 278 extern sol_ofs_uobj_table_t uverbs_upd_uo_tbl; 279 extern sol_ofs_uobj_table_t uverbs_uah_uo_tbl; 280 extern sol_ofs_uobj_table_t uverbs_umr_uo_tbl; 281 extern sol_ofs_uobj_table_t uverbs_ucq_uo_tbl; 282 extern sol_ofs_uobj_table_t uverbs_usrq_uo_tbl; 283 extern sol_ofs_uobj_table_t uverbs_uqp_uo_tbl; 284 extern sol_ofs_uobj_table_t uverbs_ufile_uo_tbl; 285 286 /* 287 * The following structure is used currently to pass data back to 288 * libmthca on user allocation context. This should be passed opaquely 289 * to maintain a true hal, we'll look for a generic way to get this information 290 * and deliver it opaquely post EA-1. 291 */ 292 struct mthca_alloc_ucontext_resp { 293 uint32_t qp_tab_size; 294 uint32_t uarc_size; 295 }; 296 297 struct ib_udata { 298 void *inbuf; 299 void *outbuf; 300 size_t inlen; 301 size_t outlen; 302 }; 303 304 int sol_uverbs_dummy_command(uverbs_uctxt_uobj_t *uctxt, char *buf, 305 int in_len, int out_len); 306 int sol_uverbs_get_context(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 307 int out_len); 308 int sol_uverbs_alloc_pd(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 309 int out_len); 310 int sol_uverbs_dealloc_pd(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 311 int out_len); 312 int sol_uverbs_create_ah(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 313 int out_len); 314 int sol_uverbs_destroy_ah(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 315 int out_len); 316 int sol_uverbs_query_device(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 317 int out_len); 318 int sol_uverbs_query_port(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 319 int out_len); 320 int sol_uverbs_query_gid(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 321 int out_len); 322 int sol_uverbs_query_pkey(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 323 int out_len); 324 int sol_uverbs_reg_mr(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 325 int out_len); 326 int sol_uverbs_dereg_mr(uverbs_uctxt_uobj_t *uctxt, char *buf, int in_len, 327 int out_len); 328 int sol_uverbs_create_comp_channel(uverbs_uctxt_uobj_t *uctxt, char *buf, 329 int in_len, int out_len); 330 331 uint32_t 332 sol_uverbs_ibt_to_of_device_cap_flags(ibt_hca_flags_t flags, 333 ibt_hca_flags2_t flags2); 334 335 uint64_t 336 sol_uverbs_ibt_to_of_page_sz(ibt_page_sizes_t page_szs); 337 338 int sol_uverbs_ibt_to_kernel_status(ibt_status_t status); 339 uint32_t sol_uverbs_qpnum2uqpid(uint32_t qp_num); 340 341 int uverbs_upd_free(uverbs_upd_uobj_t *, uverbs_uctxt_uobj_t *); 342 int uverbs_uqp_free(uverbs_uqp_uobj_t *, uverbs_uctxt_uobj_t *); 343 int uverbs_usrq_free(uverbs_usrq_uobj_t *, uverbs_uctxt_uobj_t *); 344 int uverbs_ucq_free(uverbs_ucq_uobj_t *, uverbs_uctxt_uobj_t *); 345 346 /* 347 * The following helpers simply provide easy access for acquiring and locking 348 * User Objects. 349 */ 350 static inline uverbs_uctxt_uobj_t * 351 uverbs_uobj_get_uctxt_read(uint32_t id) 352 { 353 return (uverbs_uctxt_uobj_t *) 354 sol_ofs_uobj_get_read(&uverbs_uctxt_uo_tbl, id); 355 } 356 static inline uverbs_uctxt_uobj_t * 357 uverbs_uobj_get_uctxt_write(uint32_t id) 358 { 359 return (uverbs_uctxt_uobj_t *) 360 sol_ofs_uobj_get_write(&uverbs_uctxt_uo_tbl, id); 361 } 362 static inline uverbs_upd_uobj_t * 363 uverbs_uobj_get_upd_read(uint32_t id) 364 { 365 return (uverbs_upd_uobj_t *) 366 sol_ofs_uobj_get_read(&uverbs_upd_uo_tbl, id); 367 } 368 static inline uverbs_upd_uobj_t * 369 uverbs_uobj_get_upd_write(uint32_t id) 370 { 371 return (uverbs_upd_uobj_t *) 372 sol_ofs_uobj_get_write(&uverbs_upd_uo_tbl, id); 373 } 374 static inline uverbs_umr_uobj_t * 375 uverbs_uobj_get_umr_read(uint32_t id) 376 { 377 return (uverbs_umr_uobj_t *) 378 sol_ofs_uobj_get_read(&uverbs_umr_uo_tbl, id); 379 } 380 static inline uverbs_umr_uobj_t * 381 uverbs_uobj_get_umr_write(uint32_t id) 382 { 383 return (uverbs_umr_uobj_t *) 384 sol_ofs_uobj_get_write(&uverbs_umr_uo_tbl, id); 385 } 386 static inline uverbs_ucq_uobj_t * 387 uverbs_uobj_get_ucq_read(uint32_t id) 388 { 389 return (uverbs_ucq_uobj_t *) 390 sol_ofs_uobj_get_read(&uverbs_ucq_uo_tbl, id); 391 } 392 static inline uverbs_ucq_uobj_t * 393 uverbs_uobj_get_ucq_write(uint32_t id) 394 { 395 return (uverbs_ucq_uobj_t *) 396 sol_ofs_uobj_get_write(&uverbs_ucq_uo_tbl, (int)id); 397 } 398 static inline uverbs_usrq_uobj_t * 399 uverbs_uobj_get_usrq_read(uint32_t id) 400 { 401 return (uverbs_usrq_uobj_t *) 402 sol_ofs_uobj_get_read(&uverbs_usrq_uo_tbl, id); 403 } 404 static inline uverbs_usrq_uobj_t * 405 uverbs_uobj_get_usrq_write(uint32_t id) 406 { 407 return (uverbs_usrq_uobj_t *) 408 sol_ofs_uobj_get_write(&uverbs_usrq_uo_tbl, id); 409 } 410 static inline uverbs_uah_uobj_t * 411 uverbs_uobj_get_uah_read(uint32_t id) 412 { 413 return (uverbs_uah_uobj_t *) 414 sol_ofs_uobj_get_read(&uverbs_uah_uo_tbl, id); 415 } 416 static inline uverbs_uah_uobj_t * 417 uverbs_uobj_get_uah_write(uint32_t id) 418 { 419 return (uverbs_uah_uobj_t *) 420 sol_ofs_uobj_get_write(&uverbs_uah_uo_tbl, id); 421 } 422 static inline uverbs_uqp_uobj_t * 423 uverbs_uobj_get_uqp_read(uint32_t id) 424 { 425 return (uverbs_uqp_uobj_t *) 426 sol_ofs_uobj_get_read(&uverbs_uqp_uo_tbl, id); 427 } 428 static inline uverbs_uqp_uobj_t * 429 uverbs_uobj_get_uqp_write(uint32_t id) 430 { 431 return (uverbs_uqp_uobj_t *) 432 sol_ofs_uobj_get_write(&uverbs_uqp_uo_tbl, id); 433 } 434 435 #ifdef __cplusplus 436 } 437 #endif 438 #endif /* _SYS_IB_CLIENTS_OF_SOL_UVERBS_SOL_UVERBS_H */ 439