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 *
uverbs_uobj_get_uctxt_read(uint32_t id)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 *
uverbs_uobj_get_uctxt_write(uint32_t id)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 *
uverbs_uobj_get_upd_read(uint32_t id)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 *
uverbs_uobj_get_upd_write(uint32_t id)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 *
uverbs_uobj_get_umr_read(uint32_t id)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 *
uverbs_uobj_get_umr_write(uint32_t id)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 *
uverbs_uobj_get_ucq_read(uint32_t id)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 *
uverbs_uobj_get_ucq_write(uint32_t id)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 *
uverbs_uobj_get_usrq_read(uint32_t id)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 *
uverbs_uobj_get_usrq_write(uint32_t id)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 *
uverbs_uobj_get_uah_read(uint32_t id)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 *
uverbs_uobj_get_uah_write(uint32_t id)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 *
uverbs_uobj_get_uqp_read(uint32_t id)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 *
uverbs_uobj_get_uqp_write(uint32_t id)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