[DAPL2] updated old license header text to be consistent with OFA BSD license; 1st...
[mirror/winof/.git] / ulp / dapl2 / dapl / ibal / dapl_ibal_dto.h
1 /*\r
2  * Copyright (c) 2007 Intel Corporation.  All rights reserved.\r
3  * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
4  * \r
5  * This Software is licensed under one of the following licenses:\r
6  *\r
7  * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
8  *    in the file LICENSE.txt in the root directory. The license is also\r
9  *    available from the Open Source Initiative, see\r
10  *    http://www.opensource.org/licenses/cpl.php.\r
11  *\r
12  * 2) under the terms of the "The BSD License" a copy of which is in the file\r
13  *    LICENSE2.txt in the root directory. The license is also available from\r
14  *    the Open Source Initiative, see\r
15  *    http://www.opensource.org/licenses/bsd-license.php.\r
16  *\r
17  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a \r
18  *    copy of which is in the file LICENSE3.txt in the root directory. The \r
19  *    license is also available from the Open Source Initiative, see\r
20  *    http://www.opensource.org/licenses/gpl-license.php.\r
21  *\r
22  * Licensee has the right to choose one of the above licenses.\r
23  *\r
24  * Redistributions of source code must retain the above copyright\r
25  * notice and one of the license notices.\r
26  *\r
27  * Redistributions in binary form must reproduce both the above copyright\r
28  * notice, one of the license notices in the documentation\r
29  * and/or other materials provided with the distribution.\r
30  */\r
31 \r
32 /**********************************************************************\r
33  * \r
34  * MODULE: dapl_ibal_dto.h\r
35  *\r
36  * PURPOSE: Utility routines for data transfer operations using the\r
37  * IBAL APIs\r
38  *\r
39  * $Id: dapl_ibal_dto.h 33 2005-07-11 19:51:17Z ftillier $\r
40  *\r
41  **********************************************************************/\r
42 \r
43 #ifndef _DAPL_IBAL_DTO_H\r
44 #define _DAPL_IBAL_DTO_H\r
45 \r
46 #include "dapl_ibal_util.h"\r
47 \r
48 #ifdef DAT_EXTENSIONS\r
49 #include <dat/dat_ib_extensions.h>\r
50 #endif\r
51 \r
52 extern DAT_RETURN\r
53 dapls_ib_cq_late_alloc (\r
54         IN  ib_pd_handle_t      pd_handle,\r
55         IN  DAPL_EVD            *evd_ptr);\r
56 \r
57 #define DAPL_DEFAULT_DS_ENTRIES 8\r
58 \r
59 #ifdef NOT_SUPPORTED\r
60 extern DAT_RETURN \r
61 dapls_ib_post_recv_defered (\r
62         IN  DAPL_EP                     *ep_ptr,\r
63         IN  DAPL_COOKIE                 *cookie,\r
64         IN  DAT_COUNT                   num_segments,\r
65         IN  DAT_LMR_TRIPLET             *local_iov); // dapl_ibal_util.c\r
66 #endif\r
67 \r
68 static _INLINE_ char * dapls_dto_op_str(int dto);\r
69 \r
70 /*\r
71  * dapls_ib_post_recv\r
72  *\r
73  * Provider specific Post RECV function\r
74  */\r
75 STATIC _INLINE_ DAT_RETURN \r
76 dapls_ib_post_recv (\r
77         IN  DAPL_EP                             *ep_ptr,\r
78         IN  DAPL_COOKIE                 *cookie,\r
79         IN  DAT_COUNT                   num_segments,\r
80         IN  DAT_LMR_TRIPLET             *local_iov)\r
81 {\r
82     ib_api_status_t     ib_status;\r
83     ib_recv_wr_t        recv_wr, *failed_wr_p;\r
84     ib_local_ds_t       ds_array[DAPL_DEFAULT_DS_ENTRIES], *ds_array_p;\r
85     DAT_COUNT           i, total_len;\r
86 \r
87 #ifdef NOT_SUPPORTED\r
88     if (ep_ptr->qp_state == IB_QPS_INIT)\r
89     {\r
90         return dapls_ib_post_recv_defered ( ep_ptr,\r
91                                             cookie,\r
92                                             num_segments,\r
93                                             local_iov);\r
94     }\r
95 #endif\r
96     dapl_os_memzero(&recv_wr, sizeof(ib_recv_wr_t));\r
97     recv_wr.wr_id        = (DAT_UINT64) cookie;\r
98     recv_wr.num_ds       = num_segments;\r
99 \r
100     if( num_segments <= DAPL_DEFAULT_DS_ENTRIES )\r
101     {\r
102         ds_array_p = ds_array;\r
103     }\r
104     else\r
105     {\r
106         ds_array_p = dapl_os_alloc(num_segments*sizeof(ib_local_ds_t));\r
107     }\r
108     recv_wr.ds_array     = ds_array_p;\r
109 \r
110     if (NULL == ds_array_p)\r
111     {\r
112         return (DAT_INSUFFICIENT_RESOURCES);\r
113     }\r
114 \r
115     for (total_len = i = 0; i < num_segments; i++, ds_array_p++)\r
116     {\r
117         ds_array_p->length = (uint32_t)local_iov[i].segment_length;\r
118         ds_array_p->lkey  = htonl(local_iov[i].lmr_context);\r
119         ds_array_p->vaddr = local_iov[i].virtual_address;\r
120         total_len        += ds_array_p->length;\r
121     }\r
122 \r
123     if (cookie != NULL)\r
124     {\r
125                 cookie->val.dto.size = total_len;\r
126 \r
127         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
128                       "--> DsPR: EP = %p QP = %p cookie= %p, num_seg= %d\n", \r
129                       ep_ptr, ep_ptr->qp_handle, cookie, num_segments);\r
130     }\r
131 \r
132     recv_wr.p_next = NULL;\r
133 \r
134     ib_status = ib_post_recv( ep_ptr->qp_handle, &recv_wr, &failed_wr_p );\r
135 \r
136     if( num_segments > DAPL_DEFAULT_DS_ENTRIES )\r
137         dapl_os_free( recv_wr.ds_array, num_segments * sizeof(ib_local_ds_t) );\r
138 \r
139     if (IB_SUCCESS == ib_status)\r
140     {\r
141                 return DAT_SUCCESS;\r
142     }\r
143 \r
144     dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPR: post_recv status %s\n", \r
145                       ib_get_err_str(ib_status));\r
146     /*\r
147      * Moving QP to error state; \r
148      */\r
149     (void) dapls_modify_qp_state_to_error ( ep_ptr->qp_handle);\r
150     ep_ptr->qp_state = IB_QPS_ERROR;\r
151 \r
152         return (dapl_ib_status_convert (ib_status));\r
153 }\r
154 \r
155 \r
156 /*\r
157  * dapls_ib_post_send\r
158  *\r
159  * Provider specific Post SEND function\r
160  */\r
161 STATIC _INLINE_ DAT_RETURN \r
162 dapls_ib_post_send (\r
163         IN  DAPL_EP                             *ep_ptr,\r
164         IN  ib_send_op_type_t   op_type,\r
165         IN  DAPL_COOKIE                 *cookie,\r
166         IN  DAT_COUNT                   num_segments,\r
167         IN  DAT_LMR_TRIPLET             *local_iov,\r
168         IN  const DAT_RMR_TRIPLET       *remote_iov,\r
169         IN  DAT_COMPLETION_FLAGS        completion_flags)\r
170 {\r
171     ib_api_status_t     ib_status;\r
172     ib_send_wr_t                send_wr, *failed_wr_p;\r
173     ib_local_ds_t       ds_array[DAPL_DEFAULT_DS_ENTRIES], *ds_array_p;\r
174     DAT_COUNT                   i, total_len;\r
175 \r
176     if (ep_ptr->param.ep_state != DAT_EP_STATE_CONNECTED)\r
177     {\r
178         ib_qp_attr_t    qp_attr;\r
179 \r
180         ib_query_qp ( ep_ptr->qp_handle, &qp_attr );\r
181 \r
182         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsPS: !CONN EP (%p) ep_state=%d "\r
183                       "QP_state=%d\n", \r
184                       ep_ptr, ep_ptr->param.ep_state, qp_attr.state );\r
185 \r
186         return (DAT_ERROR(DAT_INVALID_STATE,DAT_INVALID_STATE_EP_DISCONNECTED));\r
187     }\r
188 \r
189     dapl_os_memzero (&send_wr, sizeof(ib_send_wr_t));\r
190     send_wr.wr_type             = op_type;\r
191     send_wr.num_ds              = num_segments;\r
192 \r
193     if( num_segments <= DAPL_DEFAULT_DS_ENTRIES )\r
194     {\r
195         ds_array_p = ds_array;\r
196     }\r
197     else\r
198     {\r
199         ds_array_p = dapl_os_alloc( num_segments * sizeof(ib_local_ds_t) );\r
200     }\r
201     send_wr.ds_array     = ds_array_p;\r
202 \r
203     if (NULL == ds_array_p)\r
204     {\r
205                 return (DAT_INSUFFICIENT_RESOURCES);\r
206     }\r
207 \r
208     total_len = 0;\r
209 \r
210     for (i = 0; i < num_segments; i++, ds_array_p++)\r
211     {\r
212                 ds_array_p->length = (uint32_t)local_iov[i].segment_length;\r
213                 ds_array_p->lkey   = htonl(local_iov[i].lmr_context);\r
214                 ds_array_p->vaddr  = local_iov[i].virtual_address;\r
215                 total_len         += ds_array_p->length;\r
216     }\r
217 \r
218     if (cookie != NULL)\r
219     {\r
220                 cookie->val.dto.size = total_len;\r
221 \r
222         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
223                                         "--> DsPS: EVD=%p EP=%p QP=%p type=%d, sg=%d "\r
224                                         "ln=%d, ck=%p 0x" F64x "\n", \r
225                                 ep_ptr->param.request_evd_handle, ep_ptr, ep_ptr->qp_handle,\r
226                                 op_type, num_segments, total_len,\r
227                                 cookie, cookie->val.dto.cookie.as_64 );\r
228     }\r
229 \r
230     send_wr.wr_id = (DAT_UINT64)cookie;\r
231 \r
232     /* RC for now */\r
233     if (total_len > 0)\r
234     {\r
235         send_wr.remote_ops.vaddr = remote_iov->virtual_address;\r
236         send_wr.remote_ops.rkey  = htonl(remote_iov->rmr_context);\r
237     }\r
238 \r
239     send_wr.send_opt    = 0;\r
240 \r
241     send_wr.send_opt    |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & \r
242                            completion_flags) ? IB_SEND_OPT_FENCE : 0;\r
243     send_wr.send_opt    |= (DAT_COMPLETION_SUPPRESS_FLAG & \r
244                            completion_flags) ? 0 : IB_SEND_OPT_SIGNALED;\r
245     send_wr.send_opt    |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & \r
246                            completion_flags) ? IB_SEND_OPT_SOLICITED : 0;\r
247 \r
248     dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPS: EP=%p QP=%p send_opt=0x%x,"\r
249                   "rem_addr=%p, rem_rkey=0x%x completion_flags=0x%x\n",\r
250                   ep_ptr, ep_ptr->qp_handle,  \r
251                   send_wr.send_opt, (void *)(uintptr_t)send_wr.remote_ops.vaddr,\r
252                   send_wr.remote_ops.rkey, completion_flags);\r
253 \r
254     send_wr.p_next = NULL;\r
255 \r
256     ib_status = ib_post_send( ep_ptr->qp_handle, &send_wr, &failed_wr_p );\r
257 \r
258     if( num_segments > DAPL_DEFAULT_DS_ENTRIES )\r
259         dapl_os_free( send_wr.ds_array, num_segments * sizeof(ib_local_ds_t) );\r
260 \r
261     if (IB_SUCCESS == ib_status)\r
262                 return DAT_SUCCESS;\r
263 \r
264     dapl_dbg_log (DAPL_DBG_TYPE_EP, "--> DsPS: EP=%p post_send status = %s\n", \r
265                   ep_ptr, ib_get_err_str(ib_status));\r
266     /*\r
267      * Moving QP to error state; \r
268      */\r
269     (void) dapls_modify_qp_state_to_error ( ep_ptr->qp_handle);\r
270     ep_ptr->qp_state = IB_QPS_ERROR;\r
271 \r
272     return (dapl_ib_status_convert (ib_status));\r
273 }\r
274 \r
275 /*\r
276  * dapls_ib_optional_prv_dat\r
277  *\r
278  * Allocate space for private data to be used in CR calls\r
279  *\r
280  * Input:\r
281  *      cr_ptr                  CR handle\r
282  *      event_data              data provided by the provider callback function\r
283  *      cr_pp                   Pointer for private data\r
284  *\r
285  * Output:\r
286  *      cr_pp                   Area \r
287  *\r
288  * Returns:\r
289  *      DAT_SUCCESS\r
290  *      DAT_INSUFFICIENT_RESOURCES\r
291  *\r
292  */\r
293 STATIC _INLINE_ DAT_RETURN\r
294 dapls_ib_optional_prv_dat (\r
295         IN  DAPL_CR             *cr_ptr,\r
296         IN  const void          *event_data,\r
297         OUT DAPL_CR             **cr_pp)\r
298 {\r
299         DAT_RETURN dat_status = DAT_SUCCESS;\r
300         DAPL_PRIVATE *p_prv_data = (DAPL_PRIVATE *)event_data;\r
301 \r
302         if ( ! cr_ptr->param.private_data_size )\r
303         {\r
304                 cr_ptr->param.private_data_size = sizeof(cr_ptr->private_data);\r
305                 cr_ptr->param.private_data = cr_ptr->private_data;\r
306                 dapl_os_memcpy( cr_ptr->private_data,\r
307                                 p_prv_data->private_data,                                                       cr_ptr->param.private_data_size );\r
308                 *cr_pp = (DAPL_CR *)cr_ptr->param.private_data;\r
309         }\r
310     return dat_status;\r
311 }\r
312 \r
313 \r
314 STATIC _INLINE_ int\r
315 dapls_cqe_opcode_convert (ib_work_completion_t *cqe_p)\r
316 {\r
317 #ifdef DAPL_DBG\r
318     int dop;\r
319     switch (((ib_work_completion_t *)cqe_p)->wc_type)\r
320     {\r
321         case IB_WC_SEND:\r
322             dop = (OP_SEND);\r
323             break;\r
324 \r
325         case IB_WC_RDMA_WRITE:\r
326             dop = (OP_RDMA_WRITE);\r
327             if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
328                 dop = (OP_RDMA_WRITE_IMM);\r
329             break;\r
330 \r
331         case IB_WC_RECV:        \r
332         case IB_WC_RECV_RDMA_WRITE:\r
333             dop = (OP_RECEIVE);\r
334             if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
335                 dop = (OP_RECEIVE_IMM);\r
336             break;\r
337 \r
338         case IB_WC_RDMA_READ:\r
339             dop = (OP_RDMA_READ);\r
340             break;\r
341 \r
342         case IB_WC_MW_BIND:\r
343             dop = (OP_BIND_MW);\r
344             break;\r
345 \r
346         case IB_WC_FETCH_ADD:\r
347             dop = (OP_FETCH_AND_ADD);\r
348             break;\r
349 \r
350         case IB_WC_COMPARE_SWAP:\r
351             dop = (OP_COMP_AND_SWAP);\r
352             break;\r
353 \r
354         default :       \r
355             /* error */ \r
356             dapl_dbg_log(DAPL_DBG_TYPE_ERR, "%s() Unknown IB_WC_TYPE %d?\n",\r
357                                 __FUNCTION__, cqe_p->wc_type);\r
358             dop = (OP_BAD_OPCODE);\r
359             break;\r
360     }\r
361 #if 0\r
362     dapl_dbg_log(DAPL_DBG_TYPE_ERR, "--> DsCqeCvt %s --> %s\n",\r
363                                         ib_get_wc_type_str(cqe_p->wc_type),\r
364                                         dapls_dto_op_str(dop));\r
365 #endif\r
366     return dop;\r
367 \r
368 #else /* ! DAPL_DBG */\r
369 \r
370     switch (((ib_work_completion_t *)cqe_p)->wc_type)\r
371     {\r
372         case IB_WC_SEND:\r
373             return (OP_SEND);\r
374 \r
375         case IB_WC_RDMA_WRITE:\r
376             if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
377                 return (OP_RDMA_WRITE_IMM);\r
378             return (OP_RDMA_WRITE);\r
379 \r
380         case IB_WC_RECV:        \r
381         case IB_WC_RECV_RDMA_WRITE:\r
382             if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
383                 return (OP_RECEIVE_IMM);\r
384             return (OP_RECEIVE);\r
385 \r
386         case IB_WC_RDMA_READ:\r
387             return (OP_RDMA_READ);\r
388 \r
389         case IB_WC_MW_BIND:\r
390             return (OP_BIND_MW);\r
391 \r
392         case IB_WC_FETCH_ADD:\r
393             return (OP_FETCH_AND_ADD);\r
394 \r
395         case IB_WC_COMPARE_SWAP:\r
396             return (OP_COMP_AND_SWAP);\r
397 \r
398         default :       \r
399            /* error */ \r
400             return (IB_ERROR);\r
401     }\r
402 #endif\r
403 }\r
404 \r
405 STATIC _INLINE_ char *\r
406 dat_dtos_type_str(DAT_DTOS dto)\r
407 {\r
408     static char err[20];\r
409     char *ops[] = {\r
410         "DAT_DTO_SEND",\r
411         "DAT_DTO_RDMA_WRITE",\r
412         "DAT_DTO_RDMA_READ",\r
413         "DAT_DTO_RECEIVE",\r
414         "DAT_DTO_RECEIVE_WITH_INVALIDATE",\r
415         "DAT_DTO_BIND_MW",  /* DAT 2.0, binds are reported via DTO events */\r
416         "DAT_DTO_LMR_FMR",              /* kdat specific                */\r
417         "DAT_DTO_LMR_INVALIDATE"        /* kdat specific                */\r
418     };\r
419 \r
420 #ifdef DAT_EXTENSIONS\r
421     /* "DAT_DTO_EXTENSION_BASE" used by DAT extensions as a starting point of\r
422      * extension DTOs.\r
423      */\r
424     char *ext_ops[] = {\r
425         "DAT_IB_DTO_RDMA_WRITE_IMMED",\r
426         "DAT_IB_DTO_RECV_IMMED",\r
427         "DAT_IB_DTO_FETCH_ADD",\r
428         "DAT_IB_DTO_CMP_SWAP"\r
429     };\r
430 \r
431     if (dto >= DAT_DTO_EXTENSION_BASE)\r
432     {\r
433         dto -= DAT_DTO_EXTENSION_BASE;\r
434         return ext_ops[dto];\r
435     }\r
436 #endif\r
437     return ops[dto];\r
438 }\r
439 \r
440 /* map Work Completions to DAT WR operations */\r
441 STATIC _INLINE_ DAT_DTOS dapls_cqe_dtos_opcode(ib_work_completion_t *cqe_p)\r
442 {\r
443 #ifdef DAPL_DBG\r
444     DAT_DTOS dto;\r
445     switch (cqe_p->wc_type) {\r
446 \r
447         case IB_WC_SEND:\r
448                 dto = (DAT_DTO_SEND);\r
449                 break;\r
450 \r
451         case IB_WC_MW_BIND:\r
452                 dto = (DAT_DTO_BIND_MW);\r
453                 break;\r
454 \r
455 #ifdef DAT_EXTENSIONS\r
456         case IB_WC_RDMA_WRITE:\r
457                 dto = (DAT_DTO_RDMA_WRITE);\r
458                 if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
459                         dto = (DAT_IB_DTO_RDMA_WRITE_IMMED);\r
460                 break;\r
461 \r
462         case IB_WC_COMPARE_SWAP:\r
463                 dto = (DAT_IB_DTO_CMP_SWAP);\r
464                 break;\r
465 \r
466         case IB_WC_FETCH_ADD:\r
467                 dto = (DAT_IB_DTO_FETCH_ADD);\r
468                 break;\r
469 \r
470         case IB_WC_RDMA_READ:\r
471                 dto = (DAT_DTO_RDMA_READ);\r
472                 break;\r
473 \r
474         case IB_WC_RECV:\r
475         case IB_WC_RECV_RDMA_WRITE:\r
476                 dto = (DAT_DTO_RECEIVE);\r
477                 if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
478                         dto = (DAT_IB_DTO_RECV_IMMED);\r
479                 break;\r
480 #else\r
481         case IB_WC_RDMA_READ:\r
482                 dto = (DAT_DTO_RDMA_READ);\r
483                 break;\r
484 \r
485         case IB_WC_RDMA_WRITE:\r
486         case IB_WC_RECV_RDMA_WRITE:\r
487                 dto = (DAT_DTO_RDMA_WRITE);\r
488                 break;\r
489 \r
490         case IB_WC_RECV:\r
491                 dto = (DAT_DTO_RECEIVE);\r
492                 break;\r
493 #endif\r
494         default:\r
495                 dapl_dbg_log(DAPL_DBG_TYPE_ERR, "%s() Unknown IB_WC_TYPE %d?\n",\r
496                                 __FUNCTION__, cqe_p->wc_type);\r
497                 dto = (0xff);\r
498                 break;\r
499     }\r
500 #if 0\r
501     dapl_dbg_log(DAPL_DBG_TYPE_ERR, "--> DsIBDTO %s --> %s\n",\r
502                                 ib_get_wc_type_str(cqe_p->wc_type),\r
503                                 dat_dtos_type_str(dto));\r
504 #endif\r
505     return dto;\r
506 \r
507 #else /* !DAPL_DBG */\r
508 \r
509     switch (cqe_p->wc_type) {\r
510 \r
511         case IB_WC_SEND:\r
512                 return (DAT_DTO_SEND);\r
513 \r
514         case IB_WC_MW_BIND:\r
515                 return (DAT_DTO_BIND_MW);\r
516 \r
517 #ifdef DAT_EXTENSIONS\r
518         case IB_WC_RDMA_WRITE:\r
519                 if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
520                         return (DAT_IB_DTO_RDMA_WRITE_IMMED);\r
521                 else\r
522                         return (DAT_DTO_RDMA_WRITE);\r
523 \r
524         case IB_WC_COMPARE_SWAP:\r
525                 return (DAT_IB_DTO_CMP_SWAP);\r
526 \r
527         case IB_WC_FETCH_ADD:\r
528                 return (DAT_IB_DTO_FETCH_ADD);\r
529 \r
530         case IB_WC_RDMA_READ:\r
531                 return (DAT_DTO_RDMA_READ);\r
532 \r
533         case IB_WC_RECV:\r
534         case IB_WC_RECV_RDMA_WRITE:\r
535                 if (cqe_p->recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE)\r
536                         return (DAT_IB_DTO_RECV_IMMED);\r
537                 else\r
538                         return (DAT_DTO_RECEIVE);\r
539 #else\r
540         case IB_WC_RDMA_READ:\r
541                 return (DAT_DTO_RDMA_READ);\r
542 \r
543         case IB_WC_RDMA_WRITE:\r
544                 return (DAT_DTO_RDMA_WRITE);\r
545 \r
546         case IB_WC_RECV:\r
547         case IB_WC_RECV_RDMA_WRITE:\r
548                 return (DAT_DTO_RECEIVE);\r
549 #endif\r
550         default:\r
551                 return (0xff);\r
552     }\r
553 #endif\r
554 }\r
555 \r
556 #define DAPL_GET_CQE_DTOS_OPTYPE(cqe_p) dapls_cqe_dtos_opcode(cqe_p)\r
557 \r
558 #define DAPL_GET_CQE_WRID(cqe_p) ((ib_work_completion_t *)cqe_p)->wr_id\r
559 #define DAPL_GET_CQE_OPTYPE(cqe_p) dapls_cqe_opcode_convert(cqe_p)\r
560 #define DAPL_GET_CQE_BYTESNUM(cqe_p) ((ib_work_completion_t *)cqe_p)->length\r
561 #define DAPL_GET_CQE_STATUS(cqe_p) ((ib_work_completion_t *)cqe_p)->status\r
562 #define DAPL_GET_CQE_IMMED_DATA(cqe_p) \\r
563                 ((ib_work_completion_t*)cqe_p)->recv.conn.immediate_data\r
564 \r
565 static _INLINE_ char *\r
566 dapls_dto_op_str(int op)\r
567 {\r
568     /* must match OP_SEND... defs in dapl_ibal_util.h */ \r
569     static char *optable[] =\r
570     {\r
571         "BAD OPcode",\r
572         "OP_SEND",\r
573         "OP_RDMA_WRITE",\r
574         "OP_RDMA_READ",\r
575         "OP_COMP_AND_SWAP", // 4\r
576         "OP_FETCH_AND_ADD", // 5\r
577         "OP_RECEIVE_RDMA_WRITE",\r
578         "PAD1",\r
579         "OP_RECEIVE",   // (8)\r
580         "OP_BIND_MW",\r
581         "OP_RDMA_WRITE_IMM",\r
582         "OP_RECEIVE_IMM",\r
583         "OP_SEND_IMM"\r
584     };\r
585     return ((op < 0 || op > 12) ? "Invalid DTO opcode?" : optable[op]);\r
586 }\r
587 \r
588 static _INLINE_ char *\r
589 dapls_cqe_op_str(IN ib_work_completion_t *cqe_ptr)\r
590 {\r
591     return dapls_dto_op_str(DAPL_GET_CQE_OPTYPE (cqe_ptr)); \r
592 }\r
593 \r
594 #define DAPL_GET_CQE_OP_STR(cqe) dapls_cqe_op_str(cqe)\r
595 \r
596 \r
597 #ifdef DAT_EXTENSIONS\r
598 /*\r
599  * dapls_ib_post_ext_send\r
600  *\r
601  * Provider specific extended Post SEND function for atomics\r
602  *      OP_COMP_AND_SWAP and OP_FETCH_AND_ADD\r
603  */\r
604 STATIC _INLINE_ DAT_RETURN \r
605 dapls_ib_post_ext_send (\r
606         IN  DAPL_EP                     *ep_ptr,\r
607         IN  ib_send_op_type_t           op_type,\r
608         IN  DAPL_COOKIE                 *cookie,\r
609         IN  DAT_COUNT                   num_segs,\r
610         IN  DAT_LMR_TRIPLET             *local_iov,\r
611         IN  const DAT_RMR_TRIPLET       *remote_iov,\r
612         IN  DAT_UINT32                  immed_data,\r
613         IN  DAT_UINT64                  compare_add,\r
614         IN  DAT_UINT64                  swap,\r
615         IN  DAT_COMPLETION_FLAGS        completion_flags)\r
616 {\r
617         ib_api_status_t ib_status;\r
618         ib_data_segment_t ds_array[DAPL_DEFAULT_DS_ENTRIES], *ds_array_p;\r
619         ib_send_wr_t wr, *bad_wr;\r
620         DAT_COUNT i, total_len;\r
621         \r
622         dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
623                      "  post_ext_send: ep %p op %d ck %p numSegs %d\n"\r
624                      "    loc_iov %p rem_iov %p flgs %d\n",\r
625                      ep_ptr, op_type, cookie, num_segs, local_iov, \r
626                      remote_iov, completion_flags);\r
627 \r
628         if (num_segs <= DAPL_DEFAULT_DS_ENTRIES) \r
629                 ds_array_p = ds_array;\r
630         else\r
631                 ds_array_p = dapl_os_alloc(num_segs*sizeof(ib_data_segment_t));\r
632 \r
633         if (NULL == ds_array_p)\r
634         {\r
635 #ifdef DAPL_DBG\r
636                 dapl_dbg_log(DAPL_DBG_TYPE_ERR,"  %s() os_alloc(%d) failed?\n",\r
637                              __FUNCTION__,(num_segs*sizeof(ib_data_segment_t)));\r
638 #endif\r
639                 return (DAT_INSUFFICIENT_RESOURCES);\r
640         }\r
641         \r
642         /* setup the work request */\r
643         dapl_os_memzero (&wr, sizeof(ib_send_wr_t));\r
644         wr.wr_type = op_type;\r
645         wr.wr_id = (uint64_t)(uintptr_t)cookie;\r
646         wr.ds_array = ds_array_p;\r
647 \r
648         total_len = 0;\r
649 \r
650         for (i = 0; i < num_segs; i++ ) {\r
651                 if ( !local_iov[i].segment_length )\r
652                         continue;\r
653 \r
654                 ds_array_p->vaddr = (uint64_t) local_iov[i].virtual_address;\r
655                 ds_array_p->length = local_iov[i].segment_length;\r
656                 ds_array_p->lkey = htonl(local_iov[i].lmr_context);\r
657                 \r
658                 dapl_dbg_log(DAPL_DBG_TYPE_EP, \r
659                              " post_snd: lkey 0x%x va %p len %d\n",\r
660                              ds_array_p->lkey, ds_array_p->vaddr, \r
661                              ds_array_p->length );\r
662 \r
663                 total_len += ds_array_p->length;\r
664                 wr.num_ds++;\r
665                 ds_array_p++;\r
666         }\r
667 \r
668         if (cookie != NULL) \r
669                 cookie->val.dto.size = total_len;\r
670 \r
671         switch (op_type) {\r
672 \r
673           case OP_RDMA_WRITE_IMM:\r
674                 wr.immediate_data = immed_data;\r
675                 wr.send_opt |= IB_SEND_OPT_IMMEDIATE;\r
676                 /* fall thru */\r
677           case OP_RDMA_WRITE:\r
678                 wr.wr_type = WR_RDMA_WRITE;\r
679 #if 1 // XXX\r
680                 if ( immed_data == 0 ) {\r
681                         dapl_dbg_log(DAPL_DBG_TYPE_EP,\r
682                                     "%s() immediate data == 0?\n",__FUNCTION__);\r
683                         break;\r
684                 }\r
685 #endif\r
686                 dapl_dbg_log(DAPL_DBG_TYPE_EP, \r
687                              " post_ext: OP_RDMA_WRITE_IMM rkey 0x%x va "\r
688                              "%#016Lx immed=0x%x\n",\r
689                              remote_iov->rmr_context, \r
690                              remote_iov->virtual_address, immed_data);\r
691 \r
692                 wr.remote_ops.vaddr = remote_iov->virtual_address;\r
693                 wr.remote_ops.rkey = htonl(remote_iov->rmr_context);\r
694                 break;\r
695 \r
696           case OP_COMP_AND_SWAP:\r
697                 wr.wr_type = WR_COMPARE_SWAP;\r
698                 dapl_dbg_log(DAPL_DBG_TYPE_ERR/*DAPL_DBG_TYPE_EP XXX*/, \r
699                              " post_ext: OP_COMP_AND_SWAP=%llx,%llx rkey 0x%x "\r
700                              "va %llx\n",\r
701                              compare_add, swap, remote_iov->rmr_context,\r
702                              remote_iov->virtual_address);\r
703                 \r
704                 wr.remote_ops.vaddr = remote_iov->virtual_address;\r
705                 wr.remote_ops.rkey = htonl(remote_iov->rmr_context);\r
706                 wr.remote_ops.atomic1 = compare_add;\r
707                 wr.remote_ops.atomic2 = swap;\r
708                 break;\r
709 \r
710           case OP_FETCH_AND_ADD:\r
711                 wr.wr_type = WR_FETCH_ADD;\r
712                 dapl_dbg_log(DAPL_DBG_TYPE_EP, \r
713                              " post_ext: OP_FETCH_AND_ADD=%lx,%lx rkey 0x%x\n",\r
714                                 remote_iov->virtual_address, compare_add,\r
715                                 remote_iov->rmr_context);\r
716 \r
717                 wr.remote_ops.vaddr = remote_iov->virtual_address;\r
718                 wr.remote_ops.rkey = htonl(remote_iov->rmr_context);\r
719                 wr.remote_ops.atomic1 = compare_add;\r
720                 wr.remote_ops.atomic2 = 0;\r
721                 break;\r
722 \r
723           default:\r
724                 break;\r
725         }\r
726 \r
727         /* set completion flags in work request */\r
728         wr.send_opt |= (DAT_COMPLETION_SUPPRESS_FLAG & \r
729                                 completion_flags) ? 0 : IB_SEND_OPT_SIGNALED;\r
730         wr.send_opt |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & \r
731                                 completion_flags) ? IB_SEND_OPT_FENCE : 0;\r
732         wr.send_opt |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & \r
733                                 completion_flags) ? IB_SEND_OPT_SOLICITED : 0;\r
734 \r
735         dapl_dbg_log(DAPL_DBG_TYPE_EP, " post_snd1: wr_type 0x%x snd_opt 0x%x "\r
736                                         "ds_arry %llx num_ds %d\n", \r
737                      wr.wr_type, wr.send_opt, wr.ds_array, wr.num_ds);\r
738 \r
739         ib_status = ib_post_send(ep_ptr->qp_handle, &wr, &bad_wr);\r
740 \r
741         if (num_segs > DAPL_DEFAULT_DS_ENTRIES)\r
742             dapl_os_free(wr.ds_array, num_segs * sizeof(ib_local_ds_t));\r
743 \r
744         if ( ib_status == IB_SUCCESS )\r
745                 return DAT_SUCCESS;\r
746 \r
747         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
748                       "--> DsPS: EP=%p post_send status = %s\n", \r
749                       ep_ptr, ib_get_err_str(ib_status));\r
750         /*\r
751          * Moving QP to error state; \r
752          */\r
753         ib_status = dapls_modify_qp_state_to_error ( ep_ptr->qp_handle);\r
754         ep_ptr->qp_state = IB_QPS_ERROR;\r
755 \r
756         return (dapl_ib_status_convert (ib_status));\r
757 }\r
758 \r
759 #endif  /* DAT_EXTENSIONS */\r
760 \r
761 #endif /* _DAPL_IBAL_DTO_H */\r